diff --git a/__init__.py b/__init__.py index ab6bc50..06185d7 100644 --- a/__init__.py +++ b/__init__.py @@ -15,11 +15,11 @@ from . import utils from . import bolt from . import faux_bevel -from . import sketch_bevel -from . import view_align +from . import vertex_bevel +from . import face_sketch from . import thickener from . import spinner -from . import new_sketch +from . import blank_sketch from . import ui_panel from . import menu @@ -30,21 +30,21 @@ def register(): importlib.reload(bolt) importlib.reload(faux_bevel) - importlib.reload(sketch_bevel) - importlib.reload(view_align) + importlib.reload(vertex_bevel) + importlib.reload(face_sketch) importlib.reload(thickener) importlib.reload(spinner) - importlib.reload(new_sketch) + importlib.reload(blank_sketch) importlib.reload(ui_panel) importlib.reload(menu) bolt.register() faux_bevel.register() - sketch_bevel.register() - view_align.register() + vertex_bevel.register() + face_sketch.register() thickener.register() spinner.register() - new_sketch.register() + blank_sketch.register() ui_panel.register() menu.register() @@ -52,10 +52,10 @@ def register(): def unregister(): bolt.unregister() faux_bevel.unregister() - sketch_bevel.unregister() - view_align.unregister() + vertex_bevel.unregister() + face_sketch.unregister() thickener.unregister() spinner.unregister() - new_sketch.unregister() + blank_sketch.unregister() ui_panel.unregister() menu.unregister() \ No newline at end of file diff --git a/new_sketch.py b/blank_sketch.py similarity index 90% rename from new_sketch.py rename to blank_sketch.py index 3abe7b0..734c9be 100644 --- a/new_sketch.py +++ b/blank_sketch.py @@ -4,9 +4,9 @@ from . utils import add_single_vertex_object, align_object_to_3d_cursor -class ND_OT_new_sketch(bpy.types.Operator): - bl_idname = "nd.new_sketch" - bl_label = "New Sketch" +class ND_OT_blank_sketch(bpy.types.Operator): + bl_idname = "nd.blank_sketch" + bl_label = "Blank Sketch" bl_description = "Helps with vertex-extrude based sketching" bl_options = {'UNDO'} @@ -94,16 +94,16 @@ def draw_text_callback(self): def menu_func(self, context): - self.layout.operator(ND_OT_new_sketch.bl_idname, text=ND_OT_new_sketch.bl_label) + self.layout.operator(ND_OT_blank_sketch.bl_idname, text=ND_OT_blank_sketch.bl_label) def register(): - bpy.utils.register_class(ND_OT_new_sketch) + bpy.utils.register_class(ND_OT_blank_sketch) bpy.types.VIEW3D_MT_object.append(menu_func) def unregister(): - bpy.utils.unregister_class(ND_OT_new_sketch) + bpy.utils.unregister_class(ND_OT_blank_sketch) bpy.types.VIEW3D_MT_object.remove(menu_func) unregister_draw_handler(self) diff --git a/view_align.py b/face_sketch.py similarity index 58% rename from view_align.py rename to face_sketch.py index c4eb140..03436c6 100644 --- a/view_align.py +++ b/face_sketch.py @@ -1,23 +1,30 @@ import bpy import bmesh -from . overlay import update_overlay, init_overlay, register_draw_handler, unregister_draw_handler, draw_header, draw_hint +from math import radians +from . overlay import update_overlay, init_overlay, register_draw_handler, unregister_draw_handler, draw_header, draw_hint, draw_property from . utils import averaged_vector, set_3d_cursor, create_rotation_matrix_from_face -class ND_OT_view_align(bpy.types.Operator): - bl_idname = "nd.view_align" - bl_label = "View Align" - bl_description = "Orientates the view so it is looking directly at a face, sets the 3D cursor, and adds a custom transform orientation." +class ND_OT_face_sketch(bpy.types.Operator): + bl_idname = "nd.face_sketch" + bl_label = "Face Sketch" + bl_description = "Orientate the view to a face, and optionally lift a copy of the face as a new starting sketch" bl_options = {'UNDO'} def modal(self, context, event): - if not self.pin_overlay and event.type == 'MOUSEMOVE': - update_overlay(self, context, event) - - elif event.type == 'P' and event.value == 'PRESS': + self.key_alt = event.alt + + if event.type == 'P' and event.value == 'PRESS': self.pin_overlay = not self.pin_overlay - update_overlay(self, context, event, pinned=self.pin_overlay, x_offset=270, lines=1) + + elif event.type == 'WHEELUPMOUSE': + if event.alt: + self.face_operation_mode = (self.face_operation_mode + 1) % 2 + + elif event.type == 'WHEELDOWNMOUSE': + if event.alt: + self.face_operation_mode = (self.face_operation_mode - 1) % 2 elif event.type == 'LEFTMOUSE': return {'PASS_THROUGH'} @@ -28,17 +35,23 @@ def modal(self, context, event): return {'FINISHED'} elif event.type in {'RIGHTMOUSE', 'ESC'}: - self.revert(context) + self.clean_up(context) return {'CANCELLED'} elif event.type == 'MIDDLEMOUSE' or (event.alt and event.type in {'LEFTMOUSE', 'RIGHTMOUSE'}) or event.type.startswith('NDOF'): return {'PASS_THROUGH'} + update_overlay(self, context, event, pinned=self.pin_overlay, x_offset=320, lines=2) + return {'RUNNING_MODAL'} def invoke(self, context, event): + self.face_operation_mode = 0 # Sketch Only (0), Extract & Sketch (1) + + self.key_alt = False + self.prepare_face_selection_mode(context) self.pin_overlay = False @@ -72,6 +85,9 @@ def prepare_face_selection_mode(self, context): bpy.ops.object.mode_set_with_submode(mode='EDIT', mesh_select_mode={'FACE'}) + context.object.name = 'ND — Face Extract' + context.object.data.name = 'ND — Face Extract' + def set_3d_cursor_to_face(self, context): mesh = bmesh.from_edit_mesh(context.object.data) @@ -90,19 +106,36 @@ def set_3d_cursor_to_face(self, context): def set_face_transform_orientation(self): - bpy.ops.transform.create_orientation(name="ND — " + ND_OT_view_align.bl_label, use=True) + bpy.ops.transform.create_orientation(name="ND — Sketch Surface", use=True) - def finish(self, context): + def prepare_face_sketch(self, context): bpy.ops.view3d.view_axis(type='TOP', align_active=True) self.set_face_transform_orientation() self.set_3d_cursor_to_face(context) - self.revert(context) + + + def isolate_face(self, context): + bpy.ops.mesh.select_all(action='INVERT') + bpy.ops.mesh.delete(type='FACE') + bpy.ops.mesh.select_all(action='SELECT') + + + def finish(self, context): + self.isolate_face(context) + self.prepare_face_sketch(context) + self.clean_up(context) - def revert(self, context): + def clean_up(self, context): bpy.ops.object.mode_set(mode='OBJECT') - bpy.ops.object.delete() + bpy.ops.object.origin_set(type='ORIGIN_GEOMETRY', center='MEDIAN') + + context.object.show_in_front = False + + if self.face_operation_mode == 0: + bpy.ops.object.delete() + unregister_draw_handler(self) @@ -111,18 +144,25 @@ def draw_text_callback(self): draw_hint(self, "Select a single face...", "Press space to confirm") + draw_property( + self, + "Face Mode: {0}".format(['Sketch Only', 'Extract & Sketch'][self.face_operation_mode]), + "Alt (Sketch Only, Extract & Sketch)", + active=(self.key_alt), + alt_mode=False) + def menu_func(self, context): - self.layout.operator(ND_OT_view_align.bl_idname, text=ND_OT_view_align.bl_label) + self.layout.operator(ND_OT_face_sketch.bl_idname, text=ND_OT_face_sketch.bl_label) def register(): - bpy.utils.register_class(ND_OT_view_align) + bpy.utils.register_class(ND_OT_face_sketch) bpy.types.VIEW3D_MT_object.append(menu_func) def unregister(): - bpy.utils.unregister_class(ND_OT_view_align) + bpy.utils.unregister_class(ND_OT_face_sketch) bpy.types.VIEW3D_MT_object.remove(menu_func) unregister_draw_handler(self) diff --git a/menu.py b/menu.py index 873251c..b569ea8 100644 --- a/menu.py +++ b/menu.py @@ -11,9 +11,9 @@ class ND_MT_menu(bpy.types.Menu): def draw(self, context): layout = self.layout layout.operator_context = 'INVOKE_DEFAULT' - layout.operator("nd.view_align", icon='FACESEL') - layout.operator("nd.new_sketch", icon='GREASEPENCIL') - layout.operator("nd.sketch_bevel", icon='MOD_BEVEL') + layout.operator("nd.face_sketch", icon='FACESEL') + layout.operator("nd.blank_sketch", icon='GREASEPENCIL') + layout.operator("nd.vertex_bevel", icon='MOD_BEVEL') layout.separator() layout.operator("nd.faux_bevel", icon='MOD_BEVEL') layout.operator("nd.thickener", icon='MOD_SOLIDIFY') diff --git a/ui_panel.py b/ui_panel.py index 5b284e6..6b77932 100644 --- a/ui_panel.py +++ b/ui_panel.py @@ -27,15 +27,15 @@ def draw(self, context): row = column.row(align=True) row.scale_y = 1.2 - row.operator("nd.view_align", icon='FACESEL') + row.operator("nd.face_sketch", icon='FACESEL') row = column.row(align=True) row.scale_y = 1.2 - row.operator("nd.new_sketch", icon='GREASEPENCIL') + row.operator("nd.blank_sketch", icon='GREASEPENCIL') row = column.row(align=True) row.scale_y = 1.2 - row.operator("nd.sketch_bevel", icon='MOD_BEVEL') + row.operator("nd.vertex_bevel", icon='MOD_BEVEL') box = layout.box() box.label(text="Power Mods", icon='MODIFIER') diff --git a/sketch_bevel.py b/vertex_bevel.py similarity index 94% rename from sketch_bevel.py rename to vertex_bevel.py index bef330e..69127da 100644 --- a/sketch_bevel.py +++ b/vertex_bevel.py @@ -3,9 +3,9 @@ from . overlay import update_overlay, init_overlay, register_draw_handler, unregister_draw_handler, draw_header, draw_property -class ND_OT_sketch_bevel(bpy.types.Operator): - bl_idname = "nd.sketch_bevel" - bl_label = "Sketch Bevel" +class ND_OT_vertex_bevel(bpy.types.Operator): + bl_idname = "nd.vertex_bevel" + bl_label = "Vertex Bevel" bl_description = "Adds a vertex group bevel and weld modifier" bl_options = {'UNDO'} @@ -148,16 +148,16 @@ def draw_text_callback(self): def menu_func(self, context): - self.layout.operator(ND_OT_sketch_bevel.bl_idname, text=ND_OT_sketch_bevel.bl_label) + self.layout.operator(ND_OT_vertex_bevel.bl_idname, text=ND_OT_vertex_bevel.bl_label) def register(): - bpy.utils.register_class(ND_OT_sketch_bevel) + bpy.utils.register_class(ND_OT_vertex_bevel) bpy.types.VIEW3D_MT_object.append(menu_func) def unregister(): - bpy.utils.unregister_class(ND_OT_sketch_bevel) + bpy.utils.unregister_class(ND_OT_vertex_bevel) bpy.types.VIEW3D_MT_object.remove(menu_func) unregister_draw_handler(self)