Skip to content
Snippets Groups Projects
object_boolean_tools.py 44 KiB
Newer Older
  • Learn to ignore specific revisions
  •     bl_space_type = 'VIEW_3D'
    
        bl_region_type = 'UI'
    
        bl_context = 'objectmode'
    
    
        @classmethod
        def poll(cls, context):
            actObj = bpy.context.active_object
    
            if isCanvas(actObj):
                return True
            else:
                return False
    
        def draw(self, context):
    
            actObj = bpy.context.active_object
            icon = ""
    
            if isCanvas(actObj):
    
                for mod in actObj.modifiers:
                    container = self.layout.box()
    
                    row = container.row(align=True)
    
                    icon = ""
                    if ("BTool_" in mod.name):
                        if (mod.operation == "UNION"):
    
                            icon = "PIVOT_INDIVIDUAL"
    
                        if (mod.operation == "DIFFERENCE"):
    
                            icon = "PIVOT_MEDIAN"
    
                        if (mod.operation == "INTERSECT"):
    
                            icon = "PIVOT_ACTIVE"
    
                        if (mod.operation == "SLICE"):
    
                            icon = "PIVOT_MEDIAN"
    
    
                        objSelect = row.operator("btool.find_brush", text=mod.object.name, icon=icon, emboss=False)
                        objSelect.obj = mod.object.name
    
                        EnableIcon = "RESTRICT_VIEW_ON"
                        if (mod.show_viewport):
                            EnableIcon = "RESTRICT_VIEW_OFF"
                        Enable = row.operator(BTool_EnableBrush.bl_idname, icon=EnableIcon, emboss=False)
                        Enable.thisObj = mod.object.name
    
                        Remove = row.operator("btool.remove", icon="CANCEL", emboss=False)
                        Remove.thisObj = mod.object.name
                        Remove.Prop = "THIS"
    
                        # Stack Changer
                        Up = row.operator("btool.move_stack", icon="TRIA_UP", emboss=False)
                        Up.modif = mod.name
                        Up.direction = "UP"
    
                        Dw = row.operator("btool.move_stack", icon="TRIA_DOWN", emboss=False)
                        Dw.modif = mod.name
                        Dw.direction = "DOWN"
    
                    else:
                        row.label(mod.name)
                        # Stack Changer
                        Up = row.operator("btool.move_stack", icon="TRIA_UP", emboss=False)
                        Up.modif = mod.name
                        Up.direction = "UP"
    
                        Dw = row.operator("btool.move_stack", icon="TRIA_DOWN", emboss=False)
                        Dw.modif = mod.name
                        Dw.direction = "DOWN"
    
    # ------------------ BOOL TOOL 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):
            layout = self.layout
    
            layout.label(text="To use:")
            layout.label(text="Select two or more objects,")
            layout.label(text="choose one option from the panel")
            layout.label(text="or from the Ctrl + Shift + B menu")
    
            layout.label(text="Auto Boolean")
    
            layout.label(text="Apply Boolean operation directly.")
    
            layout.label(text="Brush Boolean")
    
            layout.label(text="Create a Boolean brush setup.")
    
    
        def execute(self, context):
            return {'FINISHED'}
    
        def invoke(self, context, event):
    
            return context.window_manager.invoke_popup(self, width=220)
    
    # ------------------ BOOL TOOL ADD-ON PREFERENCES ----------------------------
    
    
    def UpdateBoolTool_Pref(self, context):
        if self.fast_transform:
            RegisterFastT()
        else:
            UnRegisterFastT()
    
    
    
    # Add-ons Preferences Update Panel
    
    # Define Panel classes for updating
    
        VIEW3D_PT_booltool_tools,
        VIEW3D_PT_booltool_config,
        VIEW3D_PT_booltool_bviewer,
    
    def update_panels(self, context):
    
            for panel in panels:
                if "bl_rna" in panel.__dict__:
                    bpy.utils.unregister_class(panel)
    
            for panel in panels:
    
                panel.bl_category = context.preferences.addons[__name__].preferences.category
    
                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))
    
    class PREFS_BoolTool_Props(AddonPreferences):
    
        fast_transform : BoolProperty(
    
                name="Fast Transformations",
                default=False,
                update=UpdateBoolTool_Pref,
    
                description="Replace the Transform HotKeys (G,R,S)\n"
    
                            "for a custom version that can optimize the visualization of Brushes",
    
        make_vertex_groups : BoolProperty(
    
                name="Make Vertex Groups",
                default=False,
    
                description="When Applying a Brush to the Object it will create\n"
                            "a new vertex group for the new faces",
    
        make_boundary : BoolProperty(
    
                description="When Apply a Brush to the Object it will create a\n"
    
                            "new vertex group of the boundary boolean area",
    
        use_wire : BoolProperty(
    
                description="Use The Wireframe Instead of Bounding Box for visualization",
    
        category : StringProperty(
    
                name="Tab Category",
                description="Choose a name for the category of the panel",
    
                update=update_panels,
    
        Enable_Tab_01 : BoolProperty(
    
        def draw(self, context):
            layout = self.layout
    
            split_percent = 0.3
    
            split = layout.split(factor=split_percent)
    
            col.label(text="Tab Category:")
    
            col.prop(self, "category", text="")
    
            split = layout.split(factor=split_percent)
    
            col = split.column()
    
            col.label(text="Experimental Features:")
    
            col = split.column()
    
            col.prop(self, "fast_transform")
            col.prop(self, "use_wire", text="Use Wire Instead Of Bbox")
    
    
            layout.separator()
    
            layout.prop(self, "Enable_Tab_01", text="Hot Keys", icon="KEYINGSET")
            if self.Enable_Tab_01:
    
                col.label(text="Hotkey List:")
                col.label(text="Menu: Ctrl Shift B")
    
                row = layout.row()
                col = row.column()
    
                col.label(text="Brush Operators:")
                col.label(text="Union: Ctrl Num +")
                col.label(text="Diff: Ctrl Num -")
                col.label(text="Intersect: Ctrl Num *")
                col.label(text="Slice: Ctrl Num /")
    
                row = layout.row()
                col = row.column()
    
                col.label(text="Auto Operators:")
                col.label(text="Difference: Ctrl Shift Num -")
                col.label(text="Union: Ctrl Shift Num +")
                col.label(text="Intersect: Ctrl Shift Num *")
                col.label(text="Slice: Ctrl Shift Num /")
                col.label(text="BTool Brush To Mesh: Ctrl Num Enter")
                col.label(text="BTool All Brush To Mesh: Ctrl Shift Num Enter")
    
    
    # ------------------- Class List ------------------------------------------------
    
        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,
    
        BTool_Union,
        BTool_Diff,
        BTool_Inters,
        BTool_Slice,
    
        # TODO Draw Poly Brush
    
        # BTool_DrawPolyBrush,
    
        BTool_Remove,
        BTool_AllBrushToMesh,
        BTool_BrushToMesh,
        BTool_FindBrush,
        BTool_MoveStack,
        BTool_EnableBrush,
        BTool_EnableThisBrush,
        BTool_EnableFTransform,
        BTool_FastTransform,
    
    # ------------------- REGISTER ------------------------------------------------
    
    addon_keymaps = []
    addon_keymapsFastT = []
    
    
    # Fast Transform HotKeys Register
    def RegisterFastT():
        wm = bpy.context.window_manager
        km = wm.keyconfigs.addon.keymaps.new(name='Object Mode', space_type='EMPTY')
    
        kmi = km.keymap_items.new(BTool_FastTransform.bl_idname, 'G', 'PRESS')
        kmi.properties.operator = "Translate"
        addon_keymapsFastT.append((km, kmi))
    
        kmi = km.keymap_items.new(BTool_FastTransform.bl_idname, 'R', 'PRESS')
        kmi.properties.operator = "Rotate"
        addon_keymapsFastT.append((km, kmi))
    
        kmi = km.keymap_items.new(BTool_FastTransform.bl_idname, 'S', 'PRESS')
        kmi.properties.operator = "Scale"
        addon_keymapsFastT.append((km, kmi))
    
    
    # Fast Transform HotKeys UnRegister
    def UnRegisterFastT():
        wm = bpy.context.window_manager
    
        kc = wm.keyconfigs.addon
        if kc:
            for km, kmi in addon_keymapsFastT:
                km.keymap_items.remove(kmi)
    
    
        addon_keymapsFastT.clear()
    
    
    def register():
        for cls in classes:
            bpy.utils.register_class(cls)
    
        update_panels(None, bpy.context)
    
        bpy.types.Scene.BoolHide = BoolProperty(
    
                description="Hide boolean objects",
    
                update=update_BoolHide,
                )
    
        bpy.types.VIEW3D_MT_object.append(VIEW3D_BoolTool_Menu)
    
        try:
            bpy.types.VIEW3D_MT_Object.prepend(VIEW3D_BoolTool_Menu)
        except:
            pass
    
        wm = bpy.context.window_manager
    
    
        # create the boolean menu hotkey
        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 = 'VIEW3D_MT_booltool_menu'
    
        addon_keymaps.append((km, kmi))
    
    
        # Brush Operators
        kmi = km.keymap_items.new(BTool_Union.bl_idname, 'NUMPAD_PLUS', 'PRESS', ctrl=True)
    
        addon_keymaps.append((km, kmi))
    
        kmi = km.keymap_items.new(BTool_Diff.bl_idname, 'NUMPAD_MINUS', 'PRESS', ctrl=True)
    
        addon_keymaps.append((km, kmi))
    
        kmi = km.keymap_items.new(BTool_Inters.bl_idname, 'NUMPAD_ASTERIX', 'PRESS', ctrl=True)
    
        addon_keymaps.append((km, kmi))
    
        kmi = km.keymap_items.new(BTool_Slice.bl_idname, 'NUMPAD_SLASH', 'PRESS', ctrl=True)
    
        addon_keymaps.append((km, kmi))
    
        kmi = km.keymap_items.new(BTool_BrushToMesh.bl_idname, 'NUMPAD_ENTER', 'PRESS', ctrl=True)
    
        addon_keymaps.append((km, kmi))
    
        kmi = km.keymap_items.new(BTool_AllBrushToMesh.bl_idname, 'NUMPAD_ENTER', 'PRESS', ctrl=True, shift=True)
    
        addon_keymaps.append((km, kmi))
    
        # Auto Operators
    
        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(OBJECT_OT_BoolTool_Auto_Difference.bl_idname,
                'NUMPAD_MINUS', 'PRESS', ctrl=True, shift=True)
    
        addon_keymaps.append((km, kmi))
    
        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(OBJECT_OT_BoolTool_Auto_Slice.bl_idname,
                'NUMPAD_SLASH', 'PRESS', ctrl=True, shift=True)
    
        addon_keymaps.append((km, kmi))
    
    
    
    def unregister():
        # Keymapping
        # remove keymaps when add-on is deactivated
        wm = bpy.context.window_manager
    
        kc = wm.keyconfigs.addon
        if kc:
            for km, kmi in addon_keymaps:
                km.keymap_items.remove(kmi)
    
        addon_keymaps.clear()
        UnRegisterFastT()
    
    
        bpy.types.VIEW3D_MT_object.remove(VIEW3D_BoolTool_Menu)
    
        try:
            bpy.types.VIEW3D_MT_Object.remove(VIEW3D_BoolTool_Menu)
        except:
            pass
    
    
        del bpy.types.Scene.BoolHide
    
        for cls in classes:
            bpy.utils.unregister_class(cls)
    
    
    if __name__ == "__main__":
    
        register()