diff --git a/__init__.py b/__init__.py index b8dd24e..936ece6 100644 --- a/__init__.py +++ b/__init__.py @@ -15,6 +15,7 @@ from bpy.types import AddonPreferences from bpy.props import BoolProperty from . import lib +from . import booleans from . import interface from . import sketching from . import power_mods @@ -23,6 +24,7 @@ registerables = ( + booleans, interface, sketching, power_mods, diff --git a/booleans/__init__.py b/booleans/__init__.py new file mode 100644 index 0000000..531f7f3 --- /dev/null +++ b/booleans/__init__.py @@ -0,0 +1,14 @@ +import importlib +from . import vanilla + + +def reload(): + importlib.reload(vanilla) + + +def register(): + vanilla.register() + + +def unregister(): + vanilla.unregister() diff --git a/booleans/vanilla.py b/booleans/vanilla.py new file mode 100644 index 0000000..f0d0ddd --- /dev/null +++ b/booleans/vanilla.py @@ -0,0 +1,50 @@ +import bpy + + +class ND_OT_bool_vanilla(bpy.types.Operator): + bl_idname = "nd.bool_vanilla" + bl_label = "Boolean" + bl_description = "Perform a boolean operation on the selected objects" + bl_options = {'UNDO'} + + + mode: bpy.props.EnumProperty(items=[ + ('DIFFERENCE', 'Difference', 'Perform a difference operation'), + ('UNION', 'Union', 'Perform a union operation'), + ('INTERSECT', 'Intersect', 'Perform an intersect operation'), + ], name="Mode", default='DIFFERENCE') + + + @classmethod + def poll(cls, context): + if context.mode == 'OBJECT': + return len(context.selected_objects) == 2 + + + def execute(self, context): + a, b = context.selected_objects + reference_obj = a if a.name != context.object.name else b + + boolean = context.object.modifiers.new(" — ".join([self.mode.capitalize(), "ND Bool"]), 'BOOLEAN') + boolean.operation = self.mode + boolean.object = reference_obj + boolean.solver = 'EXACT' + + reference_obj.display_type = 'WIRE' + reference_obj.hide_render = True + + return {'FINISHED'} + + +def menu_func(self, context): + self.layout.operator(ND_OT_bool_vanilla.bl_idname, text=ND_OT_bool_vanilla.bl_label) + + +def register(): + bpy.utils.register_class(ND_OT_bool_vanilla) + bpy.types.VIEW3D_MT_object.append(menu_func) + + +def unregister(): + bpy.utils.unregister_class(ND_OT_bool_vanilla) + bpy.types.VIEW3D_MT_object.remove(menu_func) diff --git a/interface/main_menu.py b/interface/main_menu.py index 2c02b4e..37b6883 100644 --- a/interface/main_menu.py +++ b/interface/main_menu.py @@ -18,6 +18,9 @@ def draw(self, context): layout.operator("nd.blank_sketch", icon='GREASEPENCIL') layout.operator("nd.vertex_bevel", icon='MOD_BEVEL') layout.separator() + layout.operator("nd.bool_vanilla", text="Difference", icon='MOD_BOOLEAN').mode = 'DIFFERENCE' + layout.operator("nd.bool_vanilla", text="Union", icon='MOD_BOOLEAN').mode = 'UNION' + layout.operator("nd.bool_vanilla", text="Intersect", icon='MOD_BOOLEAN').mode = 'INTERSECT' layout.operator("nd.weighted_normal_bevel", icon='MOD_BEVEL') layout.operator("nd.solidify", icon='MOD_SOLIDIFY') layout.operator("nd.screw", icon='MOD_SCREW') diff --git a/interface/main_ui_panel.py b/interface/main_ui_panel.py index 36a5ca6..2f5cbbe 100644 --- a/interface/main_ui_panel.py +++ b/interface/main_ui_panel.py @@ -55,6 +55,18 @@ def draw(self, context): box.label(text="Power Mods", icon='MODIFIER') column = box.column() + row = column.row(align=True) + row.scale_y = 1.2 + row.operator("nd.bool_vanilla", text="Difference", icon='MOD_BOOLEAN').mode = 'DIFFERENCE' + + row = column.row(align=True) + row.scale_y = 1.2 + row.operator("nd.bool_vanilla", text="Union", icon='MOD_BOOLEAN').mode = 'UNION' + + row = column.row(align=True) + row.scale_y = 1.2 + row.operator("nd.bool_vanilla", text="Intersect", icon='MOD_BOOLEAN').mode = 'INTERSECT' + row = column.row(align=True) row.scale_y = 1.2 row.operator("nd.weighted_normal_bevel", icon='MOD_BEVEL')