-
-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 9a7d8f1
Showing
3 changed files
with
312 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
import bpy | ||
import bmesh | ||
from math import radians | ||
|
||
|
||
class NDBolt(bpy.types.Operator): | ||
"""Adds a bolt using the 3D cursor position & rotation""" | ||
bl_idname = "nd.bolt" | ||
bl_label = "ND Bolt" | ||
bl_options = {'GRAB_CURSOR', 'BLOCKING'} | ||
|
||
|
||
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) | ||
elif event.ctrl: | ||
self.displace.strength = event.mouse_x * factor | ||
else: | ||
self.screwX.screw_offset = max(0, event.mouse_x * factor) | ||
|
||
elif event.type == 'WHEELUPMOUSE': | ||
self.adjust_segments(1) | ||
|
||
elif event.type == 'WHEELDOWNMOUSE': | ||
self.adjust_segments(-1) | ||
|
||
elif event.type == 'LEFTMOUSE': | ||
self.handle_optional_boolean_ops(context) | ||
|
||
return {'FINISHED'} | ||
|
||
elif event.type in {'RIGHTMOUSE', 'ESC'}: | ||
return {'CANCELLED'} | ||
|
||
return {'RUNNING_MODAL'} | ||
|
||
|
||
def invoke(self, context, event): | ||
self.add_object(context) | ||
self.add_screw_x_modifier() | ||
self.add_screw_z_modifer() | ||
self.add_decimate_modifier() | ||
self.add_displace_modifier() | ||
self.add_solidify_modifier() | ||
self.align_object_to_3d_cursor(context) | ||
|
||
context.window_manager.modal_handler_add(self) | ||
|
||
return {'RUNNING_MODAL'} | ||
|
||
|
||
def add_object(self, context): | ||
mesh = bpy.data.meshes.new("ND Bolt") | ||
obj = bpy.data.objects.new("ND Bolt", mesh) | ||
bpy.data.collections[context.collection.name].objects.link(obj) | ||
bm = bmesh.new() | ||
bm.verts.new() | ||
bm.to_mesh(mesh) | ||
bm.free() | ||
obj.select_set(True) | ||
context.view_layer.objects.active = obj | ||
bpy.ops.object.shade_smooth() | ||
obj.data.use_auto_smooth = True | ||
obj.data.auto_smooth_angle = radians(30) | ||
|
||
self.obj = obj | ||
|
||
|
||
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.steps = 1 | ||
screwX.render_steps = 1 | ||
screwX.use_merge_vertices = True | ||
|
||
self.screwX = screwX | ||
|
||
|
||
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.use_merge_vertices = True | ||
|
||
self.screwZ = screwZ | ||
|
||
|
||
def adjust_segments(self, amount): | ||
self.screwZ.steps = max(3, self.screwZ.steps + amount) | ||
self.screwZ.render_steps = max(3, self.screwZ.render_steps + amount) | ||
|
||
|
||
def add_decimate_modifier(self): | ||
decimate = self.obj.modifiers.new("ND — Decimate", 'DECIMATE') | ||
decimate.decimate_type = 'DISSOLVE' | ||
decimate.angle_limit = radians(.25) | ||
|
||
|
||
def add_displace_modifier(self): | ||
displace = self.obj.modifiers.new("ND — Displace", 'DISPLACE') | ||
displace.mid_level = 0.5 | ||
displace.strength = 0 | ||
|
||
self.displace = displace | ||
|
||
|
||
def add_solidify_modifier(self): | ||
solidify = self.obj.modifiers.new("ND — Solidify", 'SOLIDIFY') | ||
solidify.thickness = 0.50 | ||
solidify.offset = 1 | ||
|
||
self.solidify = solidify | ||
|
||
|
||
def align_object_to_3d_cursor(self, context): | ||
self.obj.location = context.scene.cursor.location | ||
self.obj.rotation_euler = context.scene.cursor.rotation_euler | ||
|
||
|
||
def handle_optional_boolean_ops(self, context): | ||
if len(context.selected_objects) > 1: | ||
self.obj.display_type = 'WIRE' | ||
targets = [o for o in context.selected_objects if not (o == self.obj)] | ||
|
||
for target in targets: | ||
boolean = target.modifiers.new("ND Bolt Cutter", 'BOOLEAN') | ||
boolean.object = self.obj | ||
else: | ||
self.obj.display_type = 'SOLID' | ||
|
||
|
||
def menu_func(self, context): | ||
self.layout.operator(NDBolt.bl_idname, text=NDBolt.bl_label) | ||
|
||
|
||
def register(): | ||
bpy.utils.register_class(NDBolt) | ||
bpy.types.VIEW3D_MT_object.append(menu_func) | ||
|
||
|
||
def unregister(): | ||
bpy.utils.unregister_class(NDBolt) | ||
bpy.types.VIEW3D_MT_object.remove(menu_func) | ||
|
||
|
||
if __name__ == "__main__": | ||
register() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import bpy | ||
import bmesh | ||
from math import radians | ||
|
||
|
||
class NDFauxBevel(bpy.types.Operator): | ||
"""Adds a single segment bevel and a weighted normal modifier""" | ||
bl_idname = "nd.faux_bevel" | ||
bl_label = "ND Faux Bevel" | ||
bl_options = {'GRAB_CURSOR', 'BLOCKING'} | ||
|
||
|
||
def modal(self, context, event): | ||
if event.type == 'WHEELUPMOUSE': | ||
step = 0.0001 if event.shift else 0.001 | ||
self.adjust_bevel_width(step) | ||
|
||
elif event.type == 'WHEELDOWNMOUSE': | ||
step = 0.0001 if event.shift else 0.001 | ||
self.adjust_bevel_width(-step) | ||
|
||
elif event.type == 'LEFTMOUSE': | ||
return {'FINISHED'} | ||
|
||
elif event.type in {'RIGHTMOUSE', 'ESC'}: | ||
return {'CANCELLED'} | ||
|
||
return {'RUNNING_MODAL'} | ||
|
||
|
||
def invoke(self, context, event): | ||
self.add_bevel_modifier(context) | ||
self.add_weighted_normal_modifer(context) | ||
|
||
context.window_manager.modal_handler_add(self) | ||
|
||
return {'RUNNING_MODAL'} | ||
|
||
|
||
def add_bevel_modifier(self, context): | ||
bevel = context.object.modifiers.new("ND — Bevel", 'BEVEL') | ||
bevel.segments = 1 | ||
bevel.width = 0 | ||
|
||
self.bevel = bevel | ||
|
||
|
||
def add_weighted_normal_modifer(self, context): | ||
weighted = context.object.modifiers.new("ND — Weighted Normal", 'WEIGHTED_NORMAL') | ||
|
||
|
||
def adjust_bevel_width(self, amount): | ||
self.bevel.width += amount | ||
|
||
|
||
def menu_func(self, context): | ||
self.layout.operator(NDFauxBevel.bl_idname, text=NDFauxBevel.bl_label) | ||
|
||
|
||
def register(): | ||
bpy.utils.register_class(NDFauxBevel) | ||
bpy.types.VIEW3D_MT_object.append(menu_func) | ||
|
||
|
||
def unregister(): | ||
bpy.utils.unregister_class(NDFauxBevel) | ||
bpy.types.VIEW3D_MT_object.remove(menu_func) | ||
|
||
|
||
if __name__ == "__main__": | ||
register() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
import bpy | ||
|
||
|
||
class NDSketchBevel(bpy.types.Operator): | ||
"""Adds a vertex group based bevel and weld modifier""" | ||
bl_idname = "nd.vgroup_bevel" | ||
bl_label = "ND Sketch Bevel & Weld" | ||
bl_options = {'GRAB_CURSOR', 'BLOCKING'} | ||
|
||
|
||
def modal(self, context, event): | ||
if event.type == 'MOUSEMOVE': | ||
factor = 0.001 if event.shift else 0.01 | ||
self.adjust_bevel_width(event.mouse_x * factor) | ||
|
||
elif event.type == 'WHEELUPMOUSE': | ||
self.adjust_bevel_segments(1) | ||
|
||
elif event.type == 'WHEELDOWNMOUSE': | ||
self.adjust_bevel_segments(-1) | ||
|
||
elif event.type == 'LEFTMOUSE': | ||
self.add_weld_modifier(context) | ||
|
||
return {'FINISHED'} | ||
|
||
elif event.type in {'RIGHTMOUSE', 'ESC'}: | ||
return {'CANCELLED'} | ||
|
||
return {'RUNNING_MODAL'} | ||
|
||
|
||
def invoke(self, context, event): | ||
if context.object and context.object.type == 'MESH' and context.mode == 'EDIT_MESH' and context.object.data.total_vert_sel > 0: | ||
self.add_vertex_group(context) | ||
self.add_bevel_modifier(context) | ||
|
||
context.window_manager.modal_handler_add(self) | ||
return {'RUNNING_MODAL'} | ||
else: | ||
self.report({'WARNING'}, "No active object, could not finish") | ||
return {'CANCELLED'} | ||
|
||
|
||
def add_vertex_group(self, context): | ||
context.object.vertex_groups.new(name = "ND — Bevel") | ||
bpy.ops.object.vertex_group_assign() | ||
|
||
|
||
def add_bevel_modifier(self, context): | ||
bevel = context.object.modifiers.new("ND — Sketch Bevel", type = 'BEVEL') | ||
bevel.affect = 'VERTICES' | ||
bevel.limit_method = 'VGROUP' | ||
bevel.vertex_group = context.object.vertex_groups[-1].name | ||
bevel.segments = 8 | ||
|
||
self.bevel = bevel | ||
|
||
|
||
def add_weld_modifier(self, context): | ||
weld = context.object.modifiers.new("ND — Weld", type = 'WELD') | ||
weld.merge_threshold = 0.00001 | ||
|
||
|
||
def adjust_bevel_width(self, width): | ||
self.bevel.width = width | ||
|
||
|
||
def adjust_bevel_segments(self, amount): | ||
self.bevel.segments += amount | ||
|
||
|
||
def menu_func(self, context): | ||
self.layout.operator(NDSketchBevel.bl_idname, text=NDSketchBevel.bl_label) | ||
|
||
|
||
def register(): | ||
bpy.utils.register_class(NDSketchBevel) | ||
bpy.types.VIEW3D_MT_object.append(menu_func) | ||
|
||
|
||
def unregister(): | ||
bpy.utils.unregister_class(NDSketchBevel) | ||
bpy.types.VIEW3D_MT_object.remove(menu_func) | ||
|
||
|
||
if __name__ == "__main__": | ||
register() |