diff --git a/object_boolean_tools.py b/object_boolean_tools.py index ad01c402178e8b3ccffc2ce525e85eaa5fc21976..abd38aba6a75f183f127dc0949b5e27f37a5b395 100644 --- a/object_boolean_tools.py +++ b/object_boolean_tools.py @@ -24,7 +24,7 @@ bl_info = { "version": (0, 3, 8), "blender": (2, 78, 0), "location": "View3D > Toolshelf", - "description": "Bool Tools Hotkey: Ctrl Shift B", + "description": "Bool Tool Hotkey: Ctrl Shift B", "wiki_url": "https://wiki.blender.org/index.php/Extensions:2.6/Py/" "Scripts/Object/BoolTool", "category": "Object", @@ -609,17 +609,19 @@ class BTool_Slice(Operator): return {'FINISHED'} -# Auto Boolean operators (maintainer Mikhail Rachinskiy) ------------------------------- +# Auto Boolean operators (maintainer Mikhail Rachinskiy) +# -------------------------------------------------------------------------------------- -class AutoBoolean: + +class Auto_Boolean: solver = EnumProperty( name="Boolean Solver", + description="Specify solver for boolean operation", items=(('BMESH', "BMesh", "BMesh solver is faster, but less stable " "and cannot handle coplanar geometry"), ('CARVE', "Carve", "Carve solver is slower, but more stable " "and can handle simple cases of coplanar geometry")), - description="Specify solver for boolean operation", options={'SKIP_SAVE'}, ) @@ -671,9 +673,9 @@ class AutoBoolean: bpy.data.objects.remove(ob) -class Auto_Union(AutoBoolean, Operator): - bl_idname = "btool.auto_union" - bl_label = "Union" +class OBJECT_OT_BoolTool_Auto_Union(Operator, Auto_Boolean): + bl_idname = "object.booltool_auto_union" + bl_label = "Bool Tool Union" bl_description = "Combine selected objects" bl_options = {'REGISTER', 'UNDO'} @@ -685,9 +687,9 @@ class Auto_Union(AutoBoolean, Operator): return {'FINISHED'} -class Auto_Difference(AutoBoolean, Operator): - bl_idname = "btool.auto_difference" - bl_label = "Difference" +class OBJECT_OT_BoolTool_Auto_Difference(Operator, Auto_Boolean): + bl_idname = "object.booltool_auto_difference" + bl_label = "Bool Tool Difference" bl_description = "Subtract selected objects from active object" bl_options = {'REGISTER', 'UNDO'} @@ -699,9 +701,9 @@ class Auto_Difference(AutoBoolean, Operator): return {'FINISHED'} -class Auto_Intersect(AutoBoolean, Operator): - bl_idname = "btool.auto_intersect" - bl_label = "Intersect" +class OBJECT_OT_BoolTool_Auto_Intersect(Operator, Auto_Boolean): + bl_idname = "object.booltool_auto_intersect" + bl_label = "Bool Tool Intersect" bl_description = "Keep only intersecting geometry" bl_options = {'REGISTER', 'UNDO'} @@ -713,11 +715,10 @@ class Auto_Intersect(AutoBoolean, Operator): return {'FINISHED'} -class Auto_Slice(AutoBoolean, Operator): - bl_idname = "btool.auto_slice" - bl_label = "Slice" - bl_description = ("Slice active object along the selected object\n" - "(can handle only two objects at a time)") +class OBJECT_OT_BoolTool_Auto_Slice(Operator, Auto_Boolean): + bl_idname = "object.booltool_auto_slice" + bl_label = "Bool Tool Slice" + bl_description = "Slice active object along the selected object" bl_options = {'REGISTER', 'UNDO'} def execute(self, context): @@ -743,11 +744,10 @@ class Auto_Slice(AutoBoolean, Operator): return {'FINISHED'} -class Auto_Subtract(AutoBoolean, Operator): - bl_idname = "btool.auto_subtract" - bl_label = "Subtract" - bl_description = ("Subtract selected object from active object, subtracted object not removed\n" - "(can handle only two objects at a time)") +class OBJECT_OT_BoolTool_Auto_Subtract(Operator, Auto_Boolean): + bl_idname = "object.booltool_auto_subtract" + bl_label = "Bool Tool Subtract" + bl_description = "Subtract selected object from active object, subtracted object not removed" bl_options = {'REGISTER', 'UNDO'} def execute(self, context): @@ -922,19 +922,18 @@ class BTool_BrushToMesh(Operator): # ------------------- MENU CLASSES ------------------------------ # 3Dview Header Menu -class BoolTool_Menu(Menu): +class VIEW3D_MT_booltool_menu(Menu): bl_label = "BoolTool Operators" - bl_idname = "OBJECT_MT_BoolTool_Menu" def draw(self, context): layout = self.layout layout.label("Auto Boolean:") - layout.operator(Auto_Difference.bl_idname, icon="ROTACTIVE") - layout.operator(Auto_Union.bl_idname, icon="ROTATECOLLECTION") - layout.operator(Auto_Intersect.bl_idname, icon="ROTATECENTER") - layout.operator(Auto_Slice.bl_idname, icon="ROTATECENTER") - layout.operator(Auto_Subtract.bl_idname, icon="ROTACTIVE") + layout.operator(OBJECT_OT_BoolTool_Auto_Difference.bl_idname, text='Difference', icon="ROTACTIVE") + layout.operator(OBJECT_OT_BoolTool_Auto_Union.bl_idname, text='Union', icon="ROTATECOLLECTION") + layout.operator(OBJECT_OT_BoolTool_Auto_Intersect.bl_idname, text='Intersect', icon="ROTATECENTER") + layout.operator(OBJECT_OT_BoolTool_Auto_Slice.bl_idname, text='Slice', icon="ROTATECENTER") + layout.operator(OBJECT_OT_BoolTool_Auto_Subtract.bl_idname, text='Subtract', icon="ROTACTIVE") layout.separator() layout.label("Brush Boolean:") @@ -959,17 +958,16 @@ class BoolTool_Menu(Menu): def VIEW3D_BoolTool_Menu(self, context): - self.layout.menu(BoolTool_Menu.bl_idname) + self.layout.menu(VIEW3D_MT_booltool_menu.bl_idname) # ---------------- Toolshelf: Tools --------------------- -class BoolTool_Tools(Panel): +class VIEW3D_PT_booltool_tools(Panel): bl_category = "Tools" - bl_label = "Bool Tools" - bl_idname = "BoolTool_Tools" - bl_space_type = "VIEW_3D" - bl_region_type = "TOOLS" + bl_label = "Bool Tool" + bl_space_type = 'VIEW_3D' + bl_region_type = 'TOOLS' bl_context = 'objectmode' @classmethod @@ -982,8 +980,8 @@ class BoolTool_Tools(Panel): obs_len = len(context.selected_objects) row = layout.split(0.7) - row.label("Bool Tools:") - row.operator("help.bool_tool", text="", icon="QUESTION") + row.label("Help:") + row.operator("wm.booltool_help", text="", icon="QUESTION") main = layout.column(align=True) main.enabled = obj.type == 'MESH' and obs_len > 0 @@ -994,16 +992,16 @@ class BoolTool_Tools(Panel): col.enabled = obs_len > 1 col.label("Auto Boolean:", icon="MODIFIER") col.separator() - col.operator(Auto_Difference.bl_idname, icon="ROTACTIVE") - col.operator(Auto_Union.bl_idname, icon="ROTATECOLLECTION") - col.operator(Auto_Intersect.bl_idname, icon="ROTATECENTER") + col.operator(OBJECT_OT_BoolTool_Auto_Difference.bl_idname, text='Difference', icon="ROTACTIVE") + col.operator(OBJECT_OT_BoolTool_Auto_Union.bl_idname, text='Union', icon="ROTATECOLLECTION") + col.operator(OBJECT_OT_BoolTool_Auto_Intersect.bl_idname, text='Intersect', icon="ROTATECENTER") main.separator() col = main.column(align=True) col.enabled = obs_len == 2 - col.operator(Auto_Slice.bl_idname, icon="ROTATECENTER") - col.operator(Auto_Subtract.bl_idname, icon="ROTACTIVE") + col.operator(OBJECT_OT_BoolTool_Auto_Slice.bl_idname, text='Slice', icon="ROTATECENTER") + col.operator(OBJECT_OT_BoolTool_Auto_Subtract.bl_idname, text='Subtract', icon="ROTACTIVE") main.separator() @@ -1026,13 +1024,12 @@ class BoolTool_Tools(Panel): # ---------- Toolshelf: Properties -------------------------------------------------------- -class BoolTool_Config(Panel): +class VIEW3D_PT_booltool_config(Panel): bl_category = "Tools" bl_label = "Properties" - bl_idname = "BoolTool_BConfig" - bl_space_type = "VIEW_3D" - bl_region_type = "TOOLS" - bl_context = "objectmode" + bl_space_type = 'VIEW_3D' + bl_region_type = 'TOOLS' + bl_context = 'objectmode' @classmethod def poll(cls, context): @@ -1119,13 +1116,12 @@ class BoolTool_Config(Panel): # ---------- Toolshelf: Brush Viewer ------------------------------------------------------- -class BoolTool_BViwer(Panel): - bl_label = "Brush Viewer" - bl_idname = "BoolTool_BViwer" - bl_space_type = "VIEW_3D" - bl_region_type = "TOOLS" +class VIEW3D_PT_booltool_bviewer(Panel): bl_category = "Tools" - bl_context = "objectmode" + bl_label = "Brush Viewer" + bl_space_type = 'VIEW_3D' + bl_region_type = 'TOOLS' + bl_context = 'objectmode' @classmethod def poll(cls, context): @@ -1192,9 +1188,11 @@ class BoolTool_BViwer(Panel): # ------------------ BOOL TOOL Help ---------------------------- -class BoolTool_help(Operator): - bl_idname = "help.bool_tool" - bl_label = "Help" + + +class WM_OT_BoolTool_Help(Operator): + bl_idname = "wm.booltool_help" + bl_label = "Bool Tool Help" bl_description = "Tool Help - click to read some basic information" def draw(self, context): @@ -1204,9 +1202,13 @@ class BoolTool_help(Operator): layout.label("choose one option from the panel") layout.label("or from the Ctrl + Shift + B menu") + layout.separator() + layout.label("Auto Boolean:") layout.label("Apply Boolean operation directly.") + layout.separator() + layout.label("Brush Boolean:") layout.label("Create a Boolean brush setup.") @@ -1219,6 +1221,7 @@ class BoolTool_help(Operator): # ------------------ BOOL TOOL ADD-ON PREFERENCES ---------------------------- + def UpdateBoolTool_Pref(self, context): if self.fast_transform: RegisterFastT() @@ -1230,14 +1233,13 @@ def UpdateBoolTool_Pref(self, context): # Define Panel classes for updating panels = ( - BoolTool_Tools, - BoolTool_Config, - BoolTool_BViwer, + VIEW3D_PT_booltool_tools, + VIEW3D_PT_booltool_config, + VIEW3D_PT_booltool_bviewer, ) -def update_panel(self, context): - message = "Bool Tool: Updating Panel locations has failed" +def update_panels(self, context): try: for panel in panels: if "bl_rna" in panel.__dict__: @@ -1248,11 +1250,11 @@ def update_panel(self, context): bpy.utils.register_class(panel) except Exception as e: + message = "Bool Tool: Updating Panel locations has failed" print("\n[{}]\n{}\n\nError:\n{}".format(__name__, message, e)) - pass -class BoolTool_Pref(AddonPreferences): +class PREFS_BoolTool_Props(AddonPreferences): bl_idname = __name__ fast_transform = BoolProperty( @@ -1283,7 +1285,7 @@ class BoolTool_Pref(AddonPreferences): name="Tab Category", description="Choose a name for the category of the panel", default="Tools", - update=update_panel, + update=update_panels, ) solver = EnumProperty( name="Boolean Solver", @@ -1359,17 +1361,18 @@ class BoolTool_Pref(AddonPreferences): # ------------------- Class List ------------------------------------------------ classes = ( - BoolTool_Pref, - BoolTool_Menu, - BoolTool_Tools, - BoolTool_Config, - BoolTool_BViwer, - - Auto_Union, - Auto_Difference, - Auto_Intersect, - Auto_Slice, - Auto_Subtract, + PREFS_BoolTool_Props, + + VIEW3D_MT_booltool_menu, + VIEW3D_PT_booltool_tools, + VIEW3D_PT_booltool_config, + VIEW3D_PT_booltool_bviewer, + + OBJECT_OT_BoolTool_Auto_Union, + OBJECT_OT_BoolTool_Auto_Difference, + OBJECT_OT_BoolTool_Auto_Intersect, + OBJECT_OT_BoolTool_Auto_Slice, + OBJECT_OT_BoolTool_Auto_Subtract, BTool_Union, BTool_Diff, @@ -1386,7 +1389,7 @@ classes = ( BTool_EnableFTransform, BTool_FastTransform, - BoolTool_help, + WM_OT_BoolTool_Help, ) @@ -1428,7 +1431,7 @@ def UnRegisterFastT(): def register(): for cls in classes: bpy.utils.register_class(cls) - update_panel(None, bpy.context) + update_panels(None, bpy.context) # Scene variables bpy.types.Scene.BoolHide = BoolProperty( @@ -1451,7 +1454,7 @@ def register(): km = wm.keyconfigs.addon.keymaps.new(name='Object Mode') kmi = km.keymap_items.new('wm.call_menu', 'B', 'PRESS', ctrl=True, shift=True) - kmi.properties.name = 'OBJECT_MT_BoolTool_Menu' + kmi.properties.name = 'VIEW3D_MT_booltool_menu' addon_keymaps.append((km, kmi)) # Brush Operators @@ -1469,13 +1472,13 @@ def register(): addon_keymaps.append((km, kmi)) # Auto Operators - kmi = km.keymap_items.new(Auto_Union.bl_idname, 'NUMPAD_PLUS', 'PRESS', ctrl=True, shift=True) + kmi = km.keymap_items.new(OBJECT_OT_BoolTool_Auto_Union.bl_idname, 'NUMPAD_PLUS', 'PRESS', ctrl=True, shift=True) addon_keymaps.append((km, kmi)) - kmi = km.keymap_items.new(Auto_Difference.bl_idname, 'NUMPAD_MINUS', 'PRESS', ctrl=True, shift=True) + kmi = km.keymap_items.new(OBJECT_OT_BoolTool_Auto_Difference.bl_idname, 'NUMPAD_MINUS', 'PRESS', ctrl=True, shift=True) addon_keymaps.append((km, kmi)) - kmi = km.keymap_items.new(Auto_Intersect.bl_idname, 'NUMPAD_ASTERIX', 'PRESS', ctrl=True, shift=True) + kmi = km.keymap_items.new(OBJECT_OT_BoolTool_Auto_Intersect.bl_idname, 'NUMPAD_ASTERIX', 'PRESS', ctrl=True, shift=True) addon_keymaps.append((km, kmi)) - kmi = km.keymap_items.new(Auto_Slice.bl_idname, 'NUMPAD_SLASH', 'PRESS', ctrl=True, shift=True) + kmi = km.keymap_items.new(OBJECT_OT_BoolTool_Auto_Slice.bl_idname, 'NUMPAD_SLASH', 'PRESS', ctrl=True, shift=True) addon_keymaps.append((km, kmi))