Skip to content
Snippets Groups Projects
object_boolean_tools.py 44.9 KiB
Newer Older
  • Learn to ignore specific revisions
  •         if isPolyBrush(actObj):
    
                row = layout.row(align=False)
                row.label(text="POLY BRUSH", icon="LINE_DATA")
    
                mod = actObj.modifiers["BTool_PolyBrush"]
    
                row = layout.row(align=False)
    
                row.prop(mod, "thickness", text="Size")
                layout.separator()
    
            if isBrush(actObj):
    
                row = layout.row(align=True)
    
                row.operator(BTool_BrushToMesh.bl_idname, icon="MOD_LATTICE", text="Apply Brush")
    
                row = layout.row(align=True)
    
                Rem = row.operator(BTool_Remove.bl_idname, icon="X", text="Remove Brush")
    
                Rem.thisObj = ""
                Rem.Prop = "BRUSH"
    
            layout.separator()
    
    
    
    # ---------- Toolshelf: Brush Viewer -------------------------------------------------------
    
    
    class VIEW3D_PT_booltool_bviewer(Panel):
    
        bl_category = "objectmode"
    
        bl_label = "Brush Viewer"
    
        bl_space_type = "VIEW_3D"
        bl_region_type = "UI"
        bl_context = "objectmode"
    
        bl_parent_id = "VIEW3D_PT_booltool_tools"
    
    
        @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)
    
                    if "BTool_" in mod.name:
                        if mod.operation == "DIFFERENCE":
    
                            icon = "SELECT_SUBTRACT"
                        elif mod.operation == "UNION":
                            icon = "SELECT_EXTEND"
                        elif mod.operation == "INTERSECT":
                            icon = "SELECT_INTERSECT"
                        elif mod.operation == "SLICE":
                            icon = "SELECT_DIFFERENCE"
    
    
                        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="X", 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 = "Help - click to read 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 to mesh.")
    
            layout.label(text="Brush Boolean:")
    
            layout.label(text="Create a Boolean brush modifier setup.")
    
            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(
            name="Make Boundary",
            default=False,
            description="When Apply a Brush to the Object it will create a\n"
            "new vertex group of the boundary boolean area",
        )
        use_wire: BoolProperty(
            name="Use Bmesh",
            default=False,
            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(default=False)
    
        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(
    
            default=False,
            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
    
        kc = wm.keyconfigs.addon
    
        # create the boolean menu hotkey
    
        if kc is not None:
            km = kc.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
    
            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__":