diff options
author | Spivak Vladimir (cwolf3d) <cwolf3d@gmail.com> | 2019-08-09 00:26:26 +0300 |
---|---|---|
committer | Spivak Vladimir (cwolf3d) <cwolf3d@gmail.com> | 2019-08-09 00:26:26 +0300 |
commit | 9ce456d94f0b706f2591d7d2e2c353a61c730e8e (patch) | |
tree | fd027370bffe6e004d6f189388639a748c504813 | |
parent | 3735dcdc0067815e56298f49635edaa8d321518e (diff) |
Addon: Mesh Extra Objects: Gears, Wallfactory, Beam: Converted to parametric objects
-rw-r--r-- | add_mesh_extra_objects/Wallfactory.py | 125 | ||||
-rw-r--r-- | add_mesh_extra_objects/__init__.py | 50 | ||||
-rw-r--r-- | add_mesh_extra_objects/add_mesh_beam_builder.py | 93 | ||||
-rw-r--r-- | add_mesh_extra_objects/add_mesh_gears.py | 292 |
4 files changed, 312 insertions, 248 deletions
diff --git a/add_mesh_extra_objects/Wallfactory.py b/add_mesh_extra_objects/Wallfactory.py index 8fb09e19..db7918c3 100644 --- a/add_mesh_extra_objects/Wallfactory.py +++ b/add_mesh_extra_objects/Wallfactory.py @@ -34,6 +34,7 @@ from bpy.types import Operator from bpy.props import ( BoolProperty, FloatProperty, + StringProperty, ) from .Blocks import ( NOTZERO, PI, @@ -53,7 +54,7 @@ from .Blocks import ( stepOnly, stepBack, ) - +from bpy_extras import object_utils class add_mesh_wallb(Operator): bl_idname = "mesh.wall_add" @@ -63,6 +64,18 @@ class add_mesh_wallb(Operator): # UI items - API for properties - User accessible variables... # not all options are via UI, and some operations just don't work yet + + Wall : BoolProperty(name = "Wall", + default = True, + description = "Wall") + + #### change properties + name : StringProperty(name = "Name", + description = "Name") + + change : BoolProperty(name = "Change", + default = False, + description = "change Wall") # only create object when True # False allows modifying several parameters without creating object @@ -859,25 +872,97 @@ class add_mesh_wallb(Operator): stepBack ) - # Create new mesh - mesh = bpy.data.meshes.new("Wall") - - # Make a mesh from a list of verts/edges/faces. - mesh.from_pydata(verts_array, [], faces_array) - - # Deselect all objects. - bpy.ops.object.select_all(action='DESELECT') - + if self.change == True and self.change != None: + obj = context.active_object + oldmesh = obj.data + oldmeshname = obj.data.name + mesh = bpy.data.meshes.new("Wall") + mesh.from_pydata(verts_array, [], faces_array) + obj.data = mesh + bpy.data.meshes.remove(oldmesh) + obj.data.name = oldmeshname + else: + mesh = bpy.data.meshes.new("Wall") + mesh.from_pydata(verts_array, [], faces_array) + obj = object_utils.object_data_add(context, mesh, operator=None) + mesh.update() - - ob_new = bpy.data.objects.new("Wall", mesh) - context.collection.objects.link(ob_new) - # leave this out to prevent 'Tab key" going into edit mode :) - # Use rmb click to select and still modify. - context.view_layer.objects.active = ob_new - ob_new.select_set(True) - - ob_new.location = tuple(context.scene.cursor.location) - ob_new.rotation_quaternion = [1.0, 0.0, 0.0, 0.0] + + obj.data["Wall"] = True + obj.data["change"] = False + for prm in WallParameters(): + obj.data[prm] = getattr(self, prm) return {'FINISHED'} + +def WallParameters(): + WallParameters = [ + "ConstructTog", + "RadialTog", + "SlopeTog", + "WallStart", + "WallEnd", + "WallBottom", + "WallTop", + "EdgeOffset", + "Width", + "WidthVariance", + "WidthMinimum", + "Height", + "HeightVariance", + "HeightMinimum", + "Depth", + "DepthVariance", + "DepthMinimum", + "MergeBlock", + "Grout", + "GroutVariance", + "GroutDepth", + "GroutDepthVariance", + "GroutEdge", + "Opening1Tog", + "Opening1Width", + "Opening1Height", + "Opening1X", + "Opening1Z", + "Opening1Repeat", + "Opening1TopArchTog", + "Opening1TopArch", + "Opening1TopArchThickness", + "Opening1BtmArchTog", + "Opening1BtmArch", + "Opening1BtmArchThickness", + "CrenelTog", + "CrenelXP", + "CrenelZP", + "SlotTog", + "SlotRpt", + "SlotWdg", + "SlotX", + "SlotGap", + "SlotV", + "SlotVH", + "SlotVBtm", + "SlotH", + "SlotHW", + "SlotHBtm", + "ShelfTog", + "ShelfX", + "ShelfZ", + "ShelfH", + "ShelfW", + "ShelfD", + "ShelfBack", + "StepTog", + "StepX", + "StepZ", + "StepH", + "StepW", + "StepD", + "StepV", + "StepT", + "StepLeft", + "StepOnly", + "StepBack", + ] + return WallParameters
\ No newline at end of file diff --git a/add_mesh_extra_objects/__init__.py b/add_mesh_extra_objects/__init__.py index a918f96d..560305be 100644 --- a/add_mesh_extra_objects/__init__.py +++ b/add_mesh_extra_objects/__init__.py @@ -86,6 +86,7 @@ else: import bpy from bpy.types import Menu +from sys import * class VIEW3D_MT_mesh_vert_add(Menu): # Define the "Single Vert" menu @@ -260,39 +261,32 @@ def Extras_contex_menu(self, context): obj = context.object layout = self.layout - if 'Gear' in obj.keys(): + if 'Gear' in obj.data.keys(): props = layout.operator("mesh.primitive_gear", text="Change Gear") props.change = True - props.delete = obj.name - props.startlocation = obj.location - props.rotation_euler = obj.rotation_euler - props.number_of_teeth = obj["number_of_teeth"] - props.radius = obj["radius"] - props.addendum = obj["addendum"] - props.dedendum = obj["dedendum"] - props.base = obj["base"] - props.angle = obj["angle"] - props.width = obj["width"] - props.skew = obj["skew"] - props.conangle = obj["conangle"] - props.crown = obj["crown"] + for prm in add_mesh_gears.GearParameters(): + setattr(props, prm, obj.data[prm]) layout.separator() - if 'WormGear' in obj.keys(): + if 'WormGear' in obj.data.keys(): props = layout.operator("mesh.primitive_worm_gear", text="Change WormGear") props.change = True - props.delete = obj.name - props.startlocation = obj.location - props.rotation_euler = obj.rotation_euler - props.number_of_teeth = obj["number_of_teeth"] - props.number_of_rows = obj["number_of_rows"] - props.radius = obj["radius"] - props.addendum = obj["addendum"] - props.dedendum = obj["dedendum"] - props.angle = obj["angle"] - props.row_height = obj["row_height"] - props.skew = obj["skew"] - props.crown = obj["crown"] + for prm in add_mesh_gears.WormGearParameters(): + setattr(props, prm, obj.data[prm]) + layout.separator() + + if 'Beam' in obj.data.keys(): + props = layout.operator("mesh.add_beam", text="Change Beam") + props.change = True + for prm in add_mesh_beam_builder.BeamParameters(): + setattr(props, prm, obj.data[prm]) + layout.separator() + + if 'Wall' in obj.data.keys(): + props = layout.operator("mesh.wall_add", text="Change Wall") + props.change = True + for prm in Wallfactory.WallParameters(): + setattr(props, prm, obj.data[prm]) layout.separator() # Register @@ -335,7 +329,7 @@ classes = [ add_empty_as_parent.PreFix, add_mesh_beam_builder.addBeam, Wallfactory.add_mesh_wallb, - add_mesh_triangles.MakeTriangle + add_mesh_triangles.MakeTriangle, ] def register(): diff --git a/add_mesh_extra_objects/add_mesh_beam_builder.py b/add_mesh_extra_objects/add_mesh_beam_builder.py index 207883cc..9aa89ef1 100644 --- a/add_mesh_extra_objects/add_mesh_beam_builder.py +++ b/add_mesh_extra_objects/add_mesh_beam_builder.py @@ -10,8 +10,9 @@ from bpy.props import ( EnumProperty, FloatProperty, IntProperty, + StringProperty, ) - +from bpy_extras import object_utils # ##################### # Create vertices for end of mesh @@ -639,9 +640,9 @@ def create_I_beam(sRef): # ###################### # -# Generate beam object. +# Generate beam mesh. -def addBeamObj(sRef, context): +def addBeamMesh(sRef, context): verts = [] faces = [] @@ -662,25 +663,11 @@ def addBeamObj(sRef, context): verts, faces = create_beam(sRef) beamMesh = bpy.data.meshes.new("Beam") - beamObj = bpy.data.objects.new("Beam", beamMesh) - context.collection.objects.link(beamObj) - context.view_layer.objects.active = beamObj - beamObj.select_set(True) beamMesh.from_pydata(verts, [], faces) beamMesh.update(calc_edges=True) - if sRef.Type == '2': # Rotate C shape - bpy.ops.transform.rotate(value=1.570796, constraint_axis=[False, True, False]) - bpy.ops.object.transform_apply(location=False, rotation=True, scale=False) - - if sRef.Cursor: - if beamObj.select_get() is True: - # we also have to check if we're considered to be in 3D View (view3d) - if bpy.ops.view3d.snap_selected_to_cursor.poll(): - bpy.ops.view3d.snap_selected_to_cursor() - else: - sRef.Cursor = False + return beamMesh # ###################### @@ -692,8 +679,20 @@ class addBeam(Operator): bl_idname = "mesh.add_beam" bl_label = "Beam Builder" bl_description = "Create beam meshes of various profiles" - bl_options = {'REGISTER', 'UNDO'} + bl_options = {'REGISTER', 'UNDO', 'PRESET'} + + Beam : BoolProperty(name = "Beam", + default = True, + description = "Beam") + #### change properties + name : StringProperty(name = "Name", + description = "Name") + + change : BoolProperty(name = "Change", + default = False, + description = "change Beam") + Type: EnumProperty( items=( ('0', "Box Profile", "Square Beam"), @@ -707,28 +706,32 @@ class addBeam(Operator): ) beamZ: FloatProperty( name="Height", - min=0.01, max=100, + min=0.01, + #max=100, default=1 ) beamX: FloatProperty( name="Width", - min=0.01, max=100, + min=0.01, + #max=100, default=.5 ) beamY: FloatProperty( name="Depth", min=0.01, - max=100, + #max=100, default=2 ) beamW: FloatProperty( name="Thickness", - min=0.01, max=1, + min=0.01, + #max=1, default=0.1 ) edgeA: IntProperty( name="Taper", - min=0, max=100, + min=0, + #max=100, default=0, description="Angle beam edges" ) @@ -756,8 +759,48 @@ class addBeam(Operator): def execute(self, context): if bpy.context.mode == "OBJECT": - addBeamObj(self, context) + + if self.change == True and self.change != None: + obj = context.active_object + oldmesh = obj.data + oldmeshname = obj.data.name + mesh = addBeamMesh(self, context) + obj.data = mesh + bpy.data.meshes.remove(oldmesh) + obj.data.name = oldmeshname + else: + mesh = addBeamMesh(self, context) + obj = object_utils.object_data_add(context, mesh, operator=None) + + if self.Type == '2': # Rotate C shape + bpy.ops.transform.rotate(value=1.570796, constraint_axis=[False, True, False]) + bpy.ops.object.transform_apply(location=False, rotation=True, scale=False) + + if self.Cursor: + if beamObj.select_get() is True: + # we also have to check if we're considered to be in 3D View (view3d) + if bpy.ops.view3d.snap_selected_to_cursor.poll(): + bpy.ops.view3d.snap_selected_to_cursor() + else: + self.Cursor = False + + obj.data["Beam"] = True + obj.data["change"] = False + for prm in BeamParameters(): + obj.data[prm] = getattr(self, prm) + return {'FINISHED'} self.report({'WARNING'}, "Option only valid in Object mode") return {'CANCELLED'} + +def BeamParameters(): + BeamParameters = [ + "beamZ", + "beamX", + "beamY", + "beamW", + "edgeA", + "Cursor", + ] + return BeamParameters
\ No newline at end of file diff --git a/add_mesh_extra_objects/add_mesh_gears.py b/add_mesh_extra_objects/add_mesh_gears.py index c38636d5..35ec12bd 100644 --- a/add_mesh_extra_objects/add_mesh_gears.py +++ b/add_mesh_extra_objects/add_mesh_gears.py @@ -19,6 +19,7 @@ from mathutils import ( Matrix, ) from bpy_extras import object_utils +from sys import * # A very simple "bridge" tool. # Connects two equally long vertex rows with faces. @@ -534,22 +535,27 @@ def add_worm(teethNum, rowNum, radius, Ad, De, p_angle, edgeloop_prev = edgeloop return verts, faces, vgroup_top, vgroup_valley + +def AddGearMesh(self, context): -##------------------------------------------------------------ -# calculates the matrix for the new object -# depending on user pref -def align_matrix(context, location): - - loc = Matrix.Translation(location) - obj_align = context.preferences.edit.object_align - if (context.space_data.type == 'VIEW_3D' - and obj_align == 'VIEW'): - rot = context.space_data.region_3d.view_matrix.to_3x3().inverted().to_4x4() - else: - rot = Matrix() - align_matrix = loc @ rot + verts, faces, verts_tip, verts_valley = add_gear( + self.number_of_teeth, + self.radius, + self.addendum, + self.dedendum, + self.base, + self.angle, + width=self.width, + skew=self.skew, + conangle=self.conangle, + crown=self.crown + ) + + mesh = bpy.data.meshes.new("Gear") + mesh.from_pydata(verts, [], faces) + + return mesh, verts_tip, verts_valley - return align_matrix class AddGear(Operator): bl_idname = "mesh.primitive_gear" @@ -572,21 +578,6 @@ class AddGear(Operator): default = False, description = "change Gear") - delete : StringProperty(name = "Delete", - description = "Delete Gear") - - startlocation : FloatVectorProperty(name = "", - description = "Start location", - default = (0.0, 0.0, 0.0), - subtype = 'XYZ') - - rotation_euler : FloatVectorProperty( - name="", - description="Rotation", - default=(0.0, 0.0, 0.0), - subtype='EULER' - ) - number_of_teeth: IntProperty(name="Number of Teeth", description="Number of teeth on the gear", min=2, @@ -678,81 +669,76 @@ class AddGear(Operator): box.prop(self, 'conangle') box.prop(self, 'crown') - box = layout.box() - box.label(text="Location:") - box.prop(self, "startlocation") - box = layout.box() - box.label(text="Rotation:") - box.prop(self, "rotation_euler") - def execute(self, context): + + if self.change == True and self.change != None: + obj = context.active_object + if 'Gear' in obj.data.keys(): + oldmesh = obj.data + oldmeshname = obj.data.name + mesh, verts_tip, verts_valley = AddGearMesh(self, context) + obj.data = mesh + try: + bpy.ops.object.vertex_group_remove(all=True) + except: + pass + bpy.data.meshes.remove(oldmesh) + obj.data.name = oldmeshname + else: + mesh, verts_tip, verts_valley = AddGearMesh(self, context) + obj = object_utils.object_data_add(context, mesh, operator=None) + else: + mesh, verts_tip, verts_valley = AddGearMesh(self, context) + obj = object_utils.object_data_add(context, mesh, operator=None) + + # Create vertex groups from stored vertices. + tipGroup = obj.vertex_groups.new(name='Tips') + tipGroup.add(verts_tip, 1.0, 'ADD') + + valleyGroup = obj.vertex_groups.new(name='Valleys') + valleyGroup.add(verts_valley, 1.0, 'ADD') + + obj.data["Gear"] = True + obj.data["change"] = False + for prm in GearParameters(): + obj.data[prm] = getattr(self, prm) + + return {'FINISHED'} - verts, faces, verts_tip, verts_valley = add_gear( +def GearParameters(): + GearParameters = [ + "number_of_teeth", + "radius", + "addendum", + "dedendum", + "base", + "angle", + "width", + "skew", + "conangle", + "crown", + ] + return GearParameters + +def AddWormGearMesh(self, context): + + verts, faces, verts_tip, verts_valley = add_worm( self.number_of_teeth, + self.number_of_rows, self.radius, self.addendum, self.dedendum, - self.base, self.angle, - width=self.width, + width=self.row_height, skew=self.skew, - conangle=self.conangle, crown=self.crown ) - - if self.change: - obj = context.active_object - mesh = bpy.data.meshes.new("Gear") - mesh.from_pydata(verts, [], faces) - obj.data = mesh - bpy.ops.object.vertex_group_remove(all=True) - else: - mesh = bpy.data.meshes.new("Gear") - mesh.from_pydata(verts, [], faces) - obj = object_utils.object_data_add(context, mesh, operator=None) - - self.align_matrix = align_matrix(context, self.startlocation) - - obj.matrix_world = self.align_matrix # apply matrix - obj.rotation_euler = self.rotation_euler - - # XXX, supporting adding in editmode is move involved - if obj.mode != 'EDIT': - # Create vertex groups from stored vertices. - tipGroup = obj.vertex_groups.new(name='Tips') - tipGroup.add(verts_tip, 1.0, 'ADD') - - valleyGroup = obj.vertex_groups.new(name='Valleys') - valleyGroup.add(verts_valley, 1.0, 'ADD') - - obj["Gear"] = True - obj["change"] = False - obj["number_of_teeth"] = self.number_of_teeth - obj["radius"] = self.radius - obj["addendum"] = self.addendum - obj["dedendum"] = self.dedendum - obj["base"] = self.base - obj["angle"] = self.angle - obj["width"] = self.width - obj["skew"] = self.skew - obj["conangle"] = self.conangle - obj["crown"] = self.crown - - return {'FINISHED'} - - ##### INVOKE ##### - def invoke(self, context, event): - bpy.context.view_layer.update() - if self.change: - bpy.context.scene.cursor.location = self.startlocation - else: - self.startlocation = bpy.context.scene.cursor.location - - self.align_matrix = align_matrix(context, self.startlocation) - - self.execute(context) + + mesh = bpy.data.meshes.new("Worm Gear") + mesh.from_pydata(verts, [], faces) + + return mesh, verts_tip, verts_valley - return {'FINISHED'} class AddWormGear(Operator): bl_idname = "mesh.primitive_worm_gear" @@ -760,9 +746,6 @@ class AddWormGear(Operator): bl_description = "Construct a worm gear mesh" bl_options = {'REGISTER', 'UNDO', 'PRESET'} - # align_matrix for the invoke - align_matrix : Matrix() - WormGear : BoolProperty(name = "WormGear", default = True, description = "WormGear") @@ -775,21 +758,6 @@ class AddWormGear(Operator): default = False, description = "change WormGear") - delete : StringProperty(name = "Delete", - description = "Delete WormGear") - - startlocation : FloatVectorProperty(name = "", - description = "Start location", - default = (0.0, 0.0, 0.0), - subtype = 'XYZ') - - rotation_euler : FloatVectorProperty( - name="", - description="Rotation", - default=(0.0, 0.0, 0.0), - subtype='EULER' - ) - number_of_teeth: IntProperty( name="Number of Teeth", description="Number of teeth on the gear", @@ -878,78 +846,52 @@ class AddWormGear(Operator): box.prop(self, "skew") box.prop(self, "crown") - box = layout.box() - box.label(text="Location:") - box.prop(self, "startlocation") - box = layout.box() - box.label(text="Rotation:") - box.prop(self, "rotation_euler") - def execute(self, context): - verts, faces, verts_tip, verts_valley = add_worm( - self.number_of_teeth, - self.number_of_rows, - self.radius, - self.addendum, - self.dedendum, - self.angle, - width=self.row_height, - skew=self.skew, - crown=self.crown - ) - - if self.change: + if self.change == True and self.change != None: obj = context.active_object - mesh = bpy.data.meshes.new("Worm Gear") - mesh.from_pydata(verts, [], faces) - obj.data = mesh - bpy.ops.object.vertex_group_remove(all=True) + if 'WormGear' in obj.data.keys(): + oldmesh = obj.data + oldmeshname = obj.data.name + mesh, verts_tip, verts_valley = AddWormGearMesh(self, context) + obj.data = mesh + try: + bpy.ops.object.vertex_group_remove(all=True) + except: + pass + bpy.data.meshes.remove(oldmesh) + obj.data.name = oldmeshname + else: + mesh, verts_tip, verts_valley = AddWormGearMesh(self, context) + obj = object_utils.object_data_add(context, mesh, operator=None) else: - mesh = bpy.data.meshes.new("Worm Gear") - mesh.from_pydata(verts, [], faces) + mesh, verts_tip, verts_valley = AddWormGearMesh(self, context) obj = object_utils.object_data_add(context, mesh, operator=None) - - self.align_matrix = align_matrix(context, self.startlocation) - - obj.matrix_world = self.align_matrix # apply matrix - obj.rotation_euler = self.rotation_euler - # XXX, supporting adding in editmode is move involved - if obj.mode != 'EDIT': - # Create vertex groups from stored vertices. - tipGroup = obj.vertex_groups.new(name = 'Tips') - tipGroup.add(verts_tip, 1.0, 'ADD') + # Create vertex groups from stored vertices. + tipGroup = obj.vertex_groups.new(name = 'Tips') + tipGroup.add(verts_tip, 1.0, 'ADD') - valleyGroup = obj.vertex_groups.new(name = 'Valleys') - valleyGroup.add(verts_valley, 1.0, 'ADD') - - self.align_matrix = align_matrix(context, self.startlocation) + valleyGroup = obj.vertex_groups.new(name = 'Valleys') + valleyGroup.add(verts_valley, 1.0, 'ADD') - obj["WormGear"] = True - obj["change"] = False - obj["number_of_teeth"] = self.number_of_teeth - obj["number_of_rows"] = self.number_of_rows - obj["radius"] = self.radius - obj["addendum"] = self.addendum - obj["dedendum"] = self.dedendum - obj["angle"] = self.angle - obj["row_height"] = self.row_height - obj["skew"] = self.skew - obj["crown"] = self.crown + obj.data["WormGear"] = True + obj.data["change"] = False + for prm in WormGearParameters(): + obj.data[prm] = getattr(self, prm) return {'FINISHED'} - ##### INVOKE ##### - def invoke(self, context, event): - bpy.context.view_layer.update() - if self.change: - bpy.context.scene.cursor.location = self.startlocation - else: - self.startlocation = bpy.context.scene.cursor.location - - self.align_matrix = align_matrix(context, self.startlocation) - - self.execute(context) - - return {'FINISHED'} +def WormGearParameters(): + WormGearParameters = [ + "number_of_teeth", + "number_of_rows", + "radius", + "addendum", + "dedendum", + "angle", + "row_height", + "skew", + "crown", + ] + return WormGearParameters
\ No newline at end of file |