Skip to content

Commit

Permalink
feat: unify input controls across all operators and add revert/cancel…
Browse files Browse the repository at this point in the history
… functionality
  • Loading branch information
tristan-hm committed Jan 23, 2022
1 parent 4faad28 commit 5a79040
Show file tree
Hide file tree
Showing 4 changed files with 149 additions and 87 deletions.
100 changes: 68 additions & 32 deletions bolt.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,54 +4,58 @@


class ND_OT_bolt(bpy.types.Operator):
"""Adds a bolt using the 3D cursor position & rotation"""
bl_idname = "nd.bolt"
bl_label = "Bolt (& Hole Cutter)"
bl_options = {'REGISTER', 'UNDO', 'GRAB_CURSOR', 'BLOCKING'}
bl_description = "Adds a bolt using the 3D cursor position & rotation"
bl_options = {'UNDO'}


def modal(self, context, event):
if event.type == 'MOUSEMOVE':
factor = 0.001 if event.shift else 0.01

if event.alt:
self.solidify.thickness = max(0, event.mouse_x * factor)
offset_factor = 0.001 if event.shift else 0.01
radius_factor = 0.001 if event.shift else 0.01
thickness_factor = 0.001 if event.shift else 0.01

if event.type == 'WHEELUPMOUSE':
if event.alt and event.ctrl:
self.offset += offset_factor
elif event.alt:
self.radius += radius_factor
elif event.ctrl:
self.displace.strength = event.mouse_x * factor
self.thickness += thickness_factor
else:
self.screwX.screw_offset = max(0, event.mouse_x * factor)

elif event.type == 'WHEELUPMOUSE':
self.adjust_segments(1)

self.segments += 1

elif event.type == 'WHEELDOWNMOUSE':
self.adjust_segments(-1)
if event.alt and event.ctrl:
self.offset -= offset_factor
elif event.alt:
self.radius = max(0, self.radius - radius_factor)
elif event.ctrl:
self.thickness = max(0, self.thickness - thickness_factor)
else:
self.segments = max(3, self.segments - 1)

elif event.type == 'LEFTMOUSE':
self.handle_optional_boolean_ops(context)
self.finish(context)

return {'FINISHED'}

elif event.type in {'RIGHTMOUSE', 'ESC'}:
self.revert(context)

return {'CANCELLED'}

self.operate(context)

return {'RUNNING_MODAL'}


def invoke(self, context, event):
return self.handle_modal(context)


def execute(self, context):
return self.handle_modal(context)


@classmethod
def poll(cls, context):
return context.mode == 'OBJECT'
self.segments = 3
self.radius = 0.02
self.thickness = 0.02
self.offset = 0


def handle_modal(self, context):
self.add_object(context)
self.add_screw_x_modifier()
self.add_screw_z_modifer()
Expand All @@ -63,6 +67,11 @@ def handle_modal(self, context):
context.window_manager.modal_handler_add(self)

return {'RUNNING_MODAL'}


@classmethod
def poll(cls, context):
return context.mode == 'OBJECT'


def add_object(self, context):
Expand All @@ -86,7 +95,7 @@ def add_screw_x_modifier(self):
screwX = self.obj.modifiers.new("ND — Radius", 'SCREW')
screwX.axis = 'X'
screwX.angle = 0
screwX.screw_offset = 1
screwX.screw_offset = self.radius
screwX.steps = 1
screwX.render_steps = 1
screwX.use_merge_vertices = True
Expand All @@ -97,8 +106,8 @@ def add_screw_x_modifier(self):
def add_screw_z_modifer(self):
screwZ = self.obj.modifiers.new("ND — Segments", 'SCREW')
screwZ.axis = 'Z'
screwZ.steps = 32
screwZ.render_steps = 32
screwZ.steps = self.segments
screwZ.render_steps = self.segments
screwZ.use_merge_vertices = True

self.screwZ = screwZ
Expand All @@ -113,19 +122,22 @@ def add_decimate_modifier(self):
decimate = self.obj.modifiers.new("ND — Decimate", 'DECIMATE')
decimate.decimate_type = 'DISSOLVE'
decimate.angle_limit = radians(.25)
decimate.show_viewport = False if self.segments <= 3 else True

self.decimate = decimate


def add_displace_modifier(self):
displace = self.obj.modifiers.new("ND — Displace", 'DISPLACE')
displace.mid_level = 0.5
displace.strength = 0
displace.strength = self.offset

self.displace = displace


def add_solidify_modifier(self):
solidify = self.obj.modifiers.new("ND — Solidify", 'SOLIDIFY')
solidify.thickness = 0.50
solidify.thickness = self.thickness
solidify.offset = 1

self.solidify = solidify
Expand All @@ -148,6 +160,30 @@ def handle_optional_boolean_ops(self, context):
self.obj.display_type = 'SOLID'


def operate(self, context):
self.decimate.show_viewport = False if self.segments <= 3 else True
self.screwX.screw_offset = self.radius
self.screwZ.steps = self.segments
self.screwZ.render_steps = self.segments
self.solidify.thickness = self.thickness
self.displace.strength = self.offset


def finish(self, context):
self.handle_optional_boolean_ops(context)
self.select_bolt(context)


def select_bolt(self, context):
bpy.ops.object.select_all(action='DESELECT')
self.obj.select_set(True)


def revert(self, context):
self.select_bolt(context)
bpy.ops.object.delete()


def menu_func(self, context):
self.layout.operator(ND_OT_bolt.bl_idname, text=ND_OT_bolt.bl_label)

Expand Down
49 changes: 27 additions & 22 deletions faux_bevel.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,45 +4,37 @@


class ND_OT_faux_bevel(bpy.types.Operator):
"""Adds a single segment bevel and a weighted normal modifier"""
bl_idname = "nd.faux_bevel"
bl_label = "Faux Bevel"
bl_options = {'REGISTER', 'UNDO', 'GRAB_CURSOR', 'BLOCKING'}
bl_description = "Adds a single segment bevel and a weighted normal modifier"
bl_options = {'UNDO'}


def modal(self, context, event):
width_factor = 0.0001 if event.shift else 0.001

if event.type == 'WHEELUPMOUSE':
step = 0.0001 if event.shift else 0.001
self.adjust_bevel_width(step)
self.bevel_width += width_factor

elif event.type == 'WHEELDOWNMOUSE':
step = 0.0001 if event.shift else 0.001
self.adjust_bevel_width(-step)
self.bevel_width = max(0, self.bevel_width - width_factor)

elif event.type == 'LEFTMOUSE':
return {'FINISHED'}

elif event.type in {'RIGHTMOUSE', 'ESC'}:
self.revert(context)

return {'CANCELLED'}

self.operate(context)

return {'RUNNING_MODAL'}


def invoke(self, context, event):
return self.handle_modal(context)


def execute(self, context):
return self.handle_modal(context)


@classmethod
def poll(cls, context):
if context.mode == 'OBJECT':
return len(context.selected_objects) == 1
self.bevel_width = 0.001


def handle_modal(self, context):
self.add_bevel_modifier(context)
self.add_weighted_normal_modifer(context)

Expand All @@ -51,10 +43,16 @@ def handle_modal(self, context):
return {'RUNNING_MODAL'}


@classmethod
def poll(cls, context):
if context.mode == 'OBJECT':
return len(context.selected_objects) == 1


def add_bevel_modifier(self, context):
bevel = context.object.modifiers.new("ND — Bevel", 'BEVEL')
bevel.segments = 1
bevel.width = 0
bevel.width = self.bevel_width

self.bevel = bevel

Expand All @@ -63,9 +61,16 @@ def add_weighted_normal_modifer(self, context):
wn = context.object.modifiers.new("ND — Weighted Normal", 'WEIGHTED_NORMAL')
wn.weight = 100

self.wn = wn


def operate(self, context):
self.bevel.width = self.bevel_width


def adjust_bevel_width(self, amount):
self.bevel.width += amount
def revert(self, context):
bpy.ops.object.modifier_remove(modifier=self.bevel.name)
bpy.ops.object.modifier_remove(modifier=self.wn.name)


def menu_func(self, context):
Expand Down
1 change: 1 addition & 0 deletions menu.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ class ND_MT_menu(bpy.types.Menu):

def draw(self, context):
layout = self.layout
layout.operator_context = 'INVOKE_DEFAULT'
layout.operator("nd.sketch_bevel", icon = 'MOD_BEVEL')
layout.operator("nd.faux_bevel", icon = 'MOD_BEVEL')
layout.separator()
Expand Down
Loading

0 comments on commit 5a79040

Please sign in to comment.