Skip to content

Instantly share code, notes, and snippets.

@patmo141
Created June 19, 2019 13:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save patmo141/883e7a9e4e68b11edacddf549a627a20 to your computer and use it in GitHub Desktop.
Save patmo141/883e7a9e4e68b11edacddf549a627a20 to your computer and use it in GitHub Desktop.
import bpy
import bmesh
import math
class D3PLINT_OT_ortho_model_base_former(bpy.types.Operator):
"""Make Ortho Model Base Former"""
bl_idname = "d3splint.ortho_base_former"
bl_label = "Model Base Former"
bl_options = {'REGISTER', 'UNDO'}
base_thickness = bpy.props.FloatProperty(name = 'Base Thickness', default = 10, min = -50, max = 50, description = 'Base height added in mm')
molar_width = bpy.props.FloatProperty(name = 'Molar Width', default = 60, min = 10, max = 100, description = 'Molar Width')
molar_bevel = bpy.props.FloatProperty(name = 'Molar Bevel', default = 10, min = 2, max = 20, description = 'Molar Bevel')
molar_height = bpy.props.FloatProperty(name = 'Molar Height', default = 20, min = 2, max = 50, description = 'Molar Height')
bevel_angle = bpy.props.IntProperty(name = 'Bevel Angle', default = 45, min = 35, max = 70, description = 'Bevel Angle')
posterior_length = bpy.props.FloatProperty(name = 'Posterior Length', default = 40, min = 15, max = 100, description = 'Posterior Length')
canine_width = bpy.props.FloatProperty(name = 'Canine Width', default = 45, min = 10, max = 100, description = 'Canine Bevel')
canine_height = bpy.props.FloatProperty(name = 'Canine Height', default = 10, min = 5, max = 100, description = 'Canine Height')
anterior_length = bpy.props.FloatProperty(name = 'Anterior Length', default = 15, min = 5, max = 25, description = 'Anterior Length')
anterior_height = bpy.props.FloatProperty(name = 'Anterior Height', default = 10, min = 5, max = 25, description = 'Anterior Length')
maxilla = bpy.props.BoolProperty(name = 'Maxilla', default = False, description = 'Is this the upper or lower jaw')
solidify = bpy.props.BoolProperty(name = 'Solidify', default = False, description = 'Solidify the top surface for boolean joining')
land = bpy.props.BoolProperty(name = 'Land', default = False, description = 'Make a Land/Dish like an actual base former')
@classmethod
def poll(cls, context):
return True
def execute(self, context):
bme = bmesh.new()
total_len = self.anterior_length + self.posterior_length
v0 = Vector((0, 0, 0))
adj = math.cos(self.bevel_angle * math.pi/180) * self.molar_bevel
opp = math.sin(self.bevel_angle * math.pi/180) * self.molar_bevel
v1 = Vector((.5 * (.5 * self.molar_width - adj), 0, 0))
v2 = Vector((.5 * self.molar_width - adj, 0, 0))
v3 = Vector((.5 * self.molar_width, opp, 0))
v4 = Vector((0.5 * self.canine_width, self.posterior_length, 0))
if self.maxilla:
v5 = Vector((0, total_len, 0))
else:
#this gives room to bevel the point backward
v5 = Vector((0, total_len + .5 * self.anterior_length, 0))
v6 = v0 + Vector((0,0,self.base_thickness))
v7 = v1 + Vector((0,0,self.base_thickness))
v8 = v2 + Vector((0,0,self.molar_height))
v9 = v3 + Vector((0,0,self.molar_height))
v10 = v4 + Vector((0,0,self.canine_height))
v11 = v5 + Vector((0,0,self.anterior_height))
bmverts = []
for co in [v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11]:
bmverts.append(bme.verts.new(co))
bme.faces.new((bmverts[0], bmverts[1], bmverts[7], bmverts[6]))
bme.faces.new((bmverts[1], bmverts[2], bmverts[8], bmverts[7]))
bme.faces.new((bmverts[2], bmverts[3], bmverts[9], bmverts[8]))
bme.faces.new((bmverts[3], bmverts[4], bmverts[10], bmverts[9]))
bme.faces.new((bmverts[4], bmverts[5], bmverts[11], bmverts[10]))
bme.faces.new((bmverts[5], bmverts[4], bmverts[3], bmverts[2], bmverts[1], bmverts[0]))
base_me = bpy.data.meshes.new('Base')
base_ob = bpy.data.objects.new('Ortho Base', base_me)
context.scene.objects.link(base_ob)
bme.to_mesh(base_me)
bme.free()
mir = base_ob.modifiers.new('Mirror', type = 'MIRROR')
if not self.maxilla:
bgroup = base_ob.vertex_groups.new('Bevel')
bgroup.add([5, 11], 1, type = 'REPLACE')
bev = base_ob.modifiers.new('Bevel', type = 'BEVEL')
bev.use_clamp_overlap = False
bev.width = 1.2 * self.anterior_length
bev.profile = 0.5
bev.limit_method = 'VGROUP'
bev.segments = 20
bev.vertex_group = 'Bevel'
bev.offset_type = 'DEPTH'
if self.land:
solid = base_ob.modifiers.new('Solidify', type = 'SOLIDIFY')
solid.thickness = 3
solid.offset = 1
if self.solidify:
rem = base_ob.modifiers.new('Remesh', type = 'REMESH')
rem.octree_depth = 7
base_ob.location = context.scene.cursor_location
return {'FINISHED'}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment