diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..424d9cb --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,8 @@ +{ + "workbench.colorCustomizations": { + "activityBar.background": "#1F3301", + "titleBar.activeBackground": "#2C4702", + "titleBar.activeForeground": "#F2FEE0" + }, + "window.title": "${dirty}${activeEditorShort}${separator}${rootName}${separator}${appName} ${separator} [Branch: main]" +} \ No newline at end of file diff --git a/README.md b/README.md index a1317e4..49a032b 100644 --- a/README.md +++ b/README.md @@ -10,9 +10,34 @@ Quick Tools is a Blender addon to be used on Blender 2.8 +. The tools in this ad ## Swap Objects -### Process +### Location -1. Input Search Term to find **Base Object to Swap** +- View3D > Quick Tools > Swap Objects +- View3D > N Addon Bar > Quick Tools + - Open with the ```N``` key. + +| Name | Description | Location | Gif | +| --------------------- | ------------------------------------------------------------ | ----------------------------------------------------------- | ------------------------------------------------------------ | +| Swap Objects By Name | Swap objects with the matching name patterns. | View3D > Quick Tools > Swap Objects > Swap Objects By Name | ![](https://vltmediablog.ml/content/images/2020/12/201207-ARH-QuickToolsv031_SwapByName_01.gif) | +| Swap Selected Objects | Swap selected objects the selected objects with the matching Template Object. | View3D > Quick Tools > Swap Objects > Swap Selected Objects | ![](https://vltmediablog.ml/content/images/2020/12/201207-ARH-QuickToolsv031_SwapSelected_01.gif) | + + + +### Guide + +1. Input ```Source Name Pattern``` to find **Base Objects to Swap** 1. ``` CubeBig.*``` Searches for all objects named **CubeBig.** and anything after the Period. - 2. ```CubeBig.02``` Searches strictly for object named **CubeBig.02**. + 2. ```CubeBig.02``` Searches strictly for object named **CubeBig.02 ** +2. Input ```Template Object``` Name to find **The Object You Want To Copy** +3. Input ```New Mesh Name Template``` string for the new names of the cloned objects +4. Select a choice from ```Source Handling``` . + 1. Hide - Hides the Source objects + 2. Delete - Deletes the Source Objects + 3. Nothing - Nothing, the Source Objects stay after cloning. +5. Select a choice from ```Target Collection``` . + 1. Copy - Will place the cloned objects in the **same Collection** as the Source Objects + 2. Default - The cloned objects will be placed in the base **Collection** collection. +6. Click one of the buttons to run the function + 1. ```Swap Objects By Name``` - Use everything that you previously set. Swap objects with the matching name patterns. + 2. ```Swap Selected Objects``` - Select the objects to replace. ```The Source Name Pattern``` will not be used or referenced if this is clicked. diff --git a/__init__.py b/__init__.py index c2819b8..d22cd15 100644 --- a/__init__.py +++ b/__init__.py @@ -8,7 +8,7 @@ 'author': 'VLT Media LLC', 'license': 'GPL', 'deps': '', - 'version': (0, 1, 10), + 'version': (0, 1, 3, 1), 'blender': (2, 90, 1), 'location': 'View3D > Quick Tools', 'warning': '', diff --git a/__pycache__/addoninfo.cpython-37.pyc b/__pycache__/addoninfo.cpython-37.pyc index 50703d0..435b294 100644 Binary files a/__pycache__/addoninfo.cpython-37.pyc and b/__pycache__/addoninfo.cpython-37.pyc differ diff --git a/addoninfo.py b/addoninfo.py index e8d7656..351ff7a 100644 --- a/addoninfo.py +++ b/addoninfo.py @@ -7,7 +7,7 @@ class addonInfo(): 'author': 'VLT Media LLC', 'license': 'GPL', 'deps': '', - 'version': (0, 1, 10), + 'version': (0, 1, 3, 1), 'blender': (2, 90, 1), 'location': 'View3D > Quick Tools', 'warning': '', diff --git a/menus/swapObject.py b/menus/swapObject.py index b9886dd..b9831bd 100644 --- a/menus/swapObject.py +++ b/menus/swapObject.py @@ -33,7 +33,7 @@ class swapObjectVars(PropertyGroup): # bpy.utils.register_class(SwapNameSettings) class OBJECT_OT_swapobjectsingle(bpy.types.Operator): bl_idname = 'object.swapobjectsingle' - bl_label = 'Swap Object Single' + bl_label = 'Swap Objects By Name' bl_options = {'REGISTER', 'UNDO'} NamePattern: bpy.props.StringProperty(name="Source Name Pattern", default="Cube.*") TemplateObject: bpy.props.StringProperty(name="Template Object Name", default="Template") @@ -48,56 +48,73 @@ def execute(self, context): selects = context.selected_objects currentcount = 0 transformss = [] - - for obj in selects: - bpy.data.objects[self.TemplateObject].select_set(True) - templatee = bpy.context.selected_objects[0] - if obj != templatee: + try: + # bpy.data.objects[self.TemplateObject].select_set(True) + objjj = bpy.data.objects[self.TemplateObject] + print(objjj) - transformss.append([obj.location, obj.rotation_quaternion, obj.scale]) - collectionss = obj.users_collection - - # ob = bpy.data.objects.get(self.TemplateObject) - - ob_dup = templatee.copy() + for obj in selects: + + bpy.data.objects[self.TemplateObject].select_set(True) + templatee = bpy.context.selected_objects[0] + + if obj != templatee: + transformss.append([obj.location, obj.rotation_quaternion, obj.scale]) + collectionss = obj.users_collection + + # ob = bpy.data.objects.get(self.TemplateObject) + + ob_dup = templatee.copy() + + + if self.TargetCollectionPost == "COPY": + for collection in collectionss: + collection.objects.link(ob_dup) + if self.TargetCollectionPost == "BASE": + bpy.data.collections['Collection'].objects.link(ob_dup) + ob_dup.name = self.NewMeshName + str(currentcount) - if self.TargetCollectionPost == "COPY": - for collection in collectionss: - collection.objects.link(ob_dup) - if self.TargetCollectionPost == "BASE": - bpy.data.collections['Collection'].objects.link(ob_dup) - ob_dup.name = self.NewMeshName + str(currentcount) + # Create the new object by linking to the template's mesh data + new_object = ob_dup + new_object.location = obj.location + new_object.rotation_quaternion = obj.rotation_quaternion + new_object.scale = obj.scale + + + if self.SourcePost == "HIDE": + obj.hide_viewport = True + obj.hide_render = True + if self.SourcePost == "DELETE": + bpy.ops.object.select_all(action='DESELECT') + # select the object + obj.select_set(True) + # delete all selected objects + bpy.ops.object.delete() + + # Create a new animation for the newly created object + nextcount = currentcount + 1 + currentcount = nextcount + ShowMessageBox("Finished Swaping objects!", "Quick Tools : Swap Complete!", 'HEART') + except : + #Shows a message box with a message, custom title, and a specific icon + ShowMessageBox("Please Set the Template Object Name Correctly Then Hit Enter.", "Template Object Not Found", 'ERROR') - # Create the new object by linking to the template's mesh data - new_object = ob_dup - new_object.location = obj.location - new_object.rotation_quaternion = obj.rotation_quaternion - new_object.scale = obj.scale - - - if self.SourcePost == "HIDE": - obj.hide_viewport = True - obj.hide_render = True - if self.SourcePost == "DELETE": - bpy.ops.object.select_all(action='DESELECT') - # select the object - obj.select_set(True) - # delete all selected objects - bpy.ops.object.delete() - - # Create a new animation for the newly created object - nextcount = currentcount + 1 - currentcount = nextcount return {'FINISHED'} +def ShowMessageBox(message = "", title = "Message Box", icon = 'INFO'): + + def draw(self, context): + self.layout.label(text=message) + + bpy.context.window_manager.popup_menu(draw, title = title, icon = icon) # bpy.utils.register_class(SwapNameSettings) class OBJECT_OT_swapobjectselections(bpy.types.Operator): bl_idname = 'object.swapobjectselections' - bl_label = 'Swap Object Selections' + bl_label = 'Swap Selected Objects' bl_options = {'REGISTER', 'UNDO'} TemplateObject: bpy.props.StringProperty(name="Template Object Name", default="Template") NewMeshName: bpy.props.StringProperty(name="New Mesh Name Template", default="NewObjectName_") @@ -111,46 +128,54 @@ def execute(self, context): currentcount = 0 transformss = [] lastindex = len(selects) - 1 - - for obj in selects: - bpy.data.objects[self.TemplateObject].select_set(True) - templatee = bpy.context.selected_objects[0] - if obj != templatee: - transformss.append([obj.location, obj.rotation_quaternion, obj.scale]) - collectionss = obj.users_collection - - - # ob = bpy.data.objects.get(self.TemplateObject) - - ob_dup = templatee.copy() - + try: + objjj = bpy.data.objects[self.TemplateObject] + print(objjj) + for obj in selects: + bpy.data.objects[self.TemplateObject].select_set(True) + templatee = bpy.context.selected_objects[0] + if obj != templatee: + transformss.append([obj.location, obj.rotation_quaternion, obj.scale]) + collectionss = obj.users_collection + + + # ob = bpy.data.objects.get(self.TemplateObject) + + ob_dup = templatee.copy() + + + if self.TargetCollectionPost == "COPY": + for collection in collectionss: + collection.objects.link(ob_dup) + if self.TargetCollectionPost == "BASE": + bpy.data.collections['Collection'].objects.link(ob_dup) + ob_dup.name = self.NewMeshName + str(currentcount) - if self.TargetCollectionPost == "COPY": - for collection in collectionss: - collection.objects.link(ob_dup) - if self.TargetCollectionPost == "BASE": - bpy.data.collections['Collection'].objects.link(ob_dup) - ob_dup.name = self.NewMeshName + str(currentcount) + # Create the new object by linking to the template's mesh data + new_object = ob_dup + new_object.location = obj.location + new_object.rotation_quaternion = obj.rotation_quaternion + new_object.scale = obj.scale + + if self.SourcePost == "HIDE": + obj.hide_viewport = True + obj.hide_render = True + if self.SourcePost == "DELETE": + bpy.ops.object.select_all(action='DESELECT') + # select the object + obj.select_set(True) + # delete all selected objects + bpy.ops.object.delete() + + # Create a new animation for the newly created object + nextcount = currentcount + 1 + currentcount = nextcount + ShowMessageBox("Finished Swaping objects!", "Quick Tools : Swap Complete!", 'HEART') + + except : + #Shows a message box with a message, custom title, and a specific icon + ShowMessageBox("Please set the Template Object Name correctly then hit enter.", "Template Object Not Found", 'ERROR') - # Create the new object by linking to the template's mesh data - new_object = ob_dup - new_object.location = obj.location - new_object.rotation_quaternion = obj.rotation_quaternion - new_object.scale = obj.scale - - if self.SourcePost == "HIDE": - obj.hide_viewport = True - obj.hide_render = True - if self.SourcePost == "DELETE": - bpy.ops.object.select_all(action='DESELECT') - # select the object - obj.select_set(True) - # delete all selected objects - bpy.ops.object.delete() - - # Create a new animation for the newly created object - nextcount = currentcount + 1 - currentcount = nextcount return {'FINISHED'} @@ -163,6 +188,7 @@ class OBJECT_MT_swapmenu(bpy.types.Menu): def draw(self, context): layout = self.layout layout.operator(OBJECT_OT_swapobjectsingle.bl_idname) + layout.operator(OBJECT_OT_swapobjectselections.bl_idname) classes = [ OBJECT_OT_swapobjectsingle, OBJECT_OT_swapobjectselections, @@ -178,8 +204,8 @@ class swapObject_PT_panel(Panel): bl_category = 'QuickTools' def draw(self, context): - operator = self.layout.operator('object.swapobjectsingle', icon='BLENDER', text='Swap Objects By Name') - operatorb = self.layout.operator('object.swapobjectselections', icon='BLENDER', text='Swap Selected Objects') + operator = self.layout.operator('object.swapobjectsingle', icon='SMALL_CAPS', text='Swap Objects By Name') + operatorb = self.layout.operator('object.swapobjectselections', icon='SYSTEM', text='Swap Selected Objects') operator.NamePattern = context.window_manager.swapObject_vars.NamePattern operator.TemplateObject = context.window_manager.swapObject_vars.TemplateObject operator.NewMeshName = context.window_manager.swapObject_vars.NewMeshName