def execute(self, context): settings = get_settings() dbg = settings.debug #if bpy.context.mode != 'OBJECT': # bpy.ops.object.mode_set(mode = 'OBJECT') sce = context.scene world_mx = Matrix.Identity(4) world_mx[0][3]=sce.cursor_location[0] world_mx[1][3]=sce.cursor_location[1] world_mx[2][3]=sce.cursor_location[2] #is this more memory friendly than listing all objects? current_obs = [ob.name for ob in bpy.data.objects] #link the new implant from the library obj_from_lib(settings.ortho_lib,self.ob) #this is slightly more robust than trusting we don't have duplicate names. for ob in bpy.data.objects: if ob.name not in current_obs: Bracket = ob sce.objects.link(Bracket) rv3d = context.region_data view_mx = rv3d.view_rotation.to_matrix() Bracket.matrix_world = world_mx * view_mx.to_4x4() return {'FINISHED'}
def draw(self, context): sce = bpy.context.scene layout = self.layout addon_prefs = get_settings() row = layout.row() row.label(text="Dentures") row.operator( "wm.url_open", text="", icon="INFO").url = "https://github.com/patmo141/odc_public/wiki" row = layout.row() col = row.column(align=True) #col.operator("opendental.add_implant_restoration", text = "Add a Space") col.operator("opendental.meta_scaffold_create", text="Make Baseplate Scaffold") col.operator("opendental.meta_offset_surface", text="Make Meta Baseplate") col.operator("opendental.meta_rim_from_curve", text="Make Meta Wax Rim") if context.object and context.object.type == 'META': col.operator("object.convert", text="Convert Meta Baseplate to Mesh") col.operator("opendental.denture_boolean_intaglio", text="Boolean with Master Cast")
def __init__(self, context, bracket_data_manager): ''' Gets info from bracket manager and siplays orthogonal slices on the snap object ''' if not bracket_data_manager.bracket_obj: return None elif not bracket_data_manager.snap_ob: return None self.bracket_data = bracket_data_manager ob = self.bracket_data.snap_ob bme = bmesh.new() bme.from_object(ob, context.scene) self.snap_ob = ob self.bme = bme self.bvh = BVHTree.FromBMesh(self.bme) self.cut_pt = None self.cut_no_x = None self.cut_no_y = None self.slice_points_x = [] self.slice_points_y = [] self.reference_L = [] self.points_2d = [] self.active_point_2d = Vector((0,0,0)) self.mx = self.bracket_data.bracket_obj.matrix_world.to_3x3() self.incisal_d = get_settings().incisal_ed_d
def execute(self,context): curve = context.object settings = get_settings() dbg = settings.debug full_arch_methods.keep_arch_plan(context, curve,debug = dbg) return {'FINISHED'}
def execute(self, context): settings = get_settings() dbg = settings.debug ob = context.object view = context.space_data.region_3d.view_rotation * Vector((0,0,1)) odcutils.silouette_brute_force(context, ob, view, self.world, self.smooth, debug = dbg) return {'FINISHED'}
def execute(self,context): settings = get_settings() dbg = settings.debug odcutils.scene_verification(context.scene, debug = dbg) spaces = odcutils.implant_selection(context) layers_copy = [layer for layer in context.scene.layers] context.scene.layers[0] = True if context.mode != 'OBJECT': bpy.ops.object.mode_set(mode='OBJECT') for space in spaces: if not space.implant: self.report({'WARNING'}, "It seems you have not yet placed an implant for %s" % space.name) else: if self.use_thickness: thickness = self.thickness else: thickness = None implant_utils.implant_inner_cylinder(context, space, thickness = thickness, debug = dbg) odcutils.material_management(context, context.scene.odc_implants) odcutils.layer_management(context.scene.odc_implants, debug = dbg) for i, layer in enumerate(layers_copy): context.scene.layers[i] = layer context.scene.layers[9] = True return {'FINISHED'}
def execute(self, context): settings = get_settings() dbg = settings.debug odcutils.scene_verification(context.scene, debug=dbg) spaces = odcutils.implant_selection(context) layers_copy = [layer for layer in context.scene.layers] context.scene.layers[0] = True if context.mode != 'OBJECT': bpy.ops.object.mode_set(mode='OBJECT') for space in spaces: if not space.implant: self.report( {'WARNING'}, "It seems you have not yet placed an implant for %s" % space.name) else: if self.use_thickness: thickness = self.thickness else: thickness = None implant_utils.implant_inner_cylinder(context, space, thickness=thickness, debug=dbg) odcutils.material_management(context, context.scene.odc_implants) odcutils.layer_management(context.scene.odc_implants, debug=dbg) for i, layer in enumerate(layers_copy): context.scene.layers[i] = layer context.scene.layers[9] = True return {'FINISHED'}
def execute(self, context): curve = context.object settings = get_settings() dbg = settings.debug full_arch_methods.keep_arch_plan(context, curve, debug=dbg) return {'FINISHED'}
def execute(self, context): settings = get_settings() dbg = settings.debug #if bpy.context.mode != 'OBJECT': # bpy.ops.object.mode_set(mode = 'OBJECT') sce = context.scene world_mx = Matrix.Identity(4) world_mx[0][3] = sce.cursor_location[0] world_mx[1][3] = sce.cursor_location[1] world_mx[2][3] = sce.cursor_location[2] #is this more memory friendly than listing all objects? current_obs = [ob.name for ob in bpy.data.objects] #link the new implant from the library obj_from_lib(settings.ortho_lib, self.ob) #this is slightly more robust than trusting we don't have duplicate names. for ob in bpy.data.objects: if ob.name not in current_obs: Bracket = ob sce.objects.link(Bracket) rv3d = context.region_data view_mx = rv3d.view_rotation.to_matrix() Bracket.matrix_world = world_mx * view_mx.to_4x4() return {'FINISHED'}
def __init__(self, context, bracket_data_manager): ''' Gets info from bracket manager and siplays orthogonal slices on the snap object ''' if not bracket_data_manager.bracket_obj: return None elif not bracket_data_manager.snap_ob: return None self.bracket_data = bracket_data_manager ob = self.bracket_data.snap_ob bme = bmesh.new() bme.from_object(ob, context.scene) self.snap_ob = ob self.bme = bme self.bvh = BVHTree.FromBMesh(self.bme) self.cut_pt = None self.cut_no_x = None self.cut_no_y = None self.slice_points_x = [] self.slice_points_y = [] self.reference_L = [] self.points_2d = [] self.active_point_2d = Vector((0, 0, 0)) self.mx = self.bracket_data.bracket_obj.matrix_world.to_3x3() self.incisal_d = get_settings().incisal_ed_d
def register(bl_info): Tracker.initialize( appurl = "https://apg-tracking.firebaseio.com/", version = str(bl_info["version"]) ) prefs = get_settings() if prefs.dev == True: Tracker.dev = True else: Tracker.dev = False if Tracker.dev == True: Tracker.verbose = False Tracker.background = True # test either way Tracker.failsafe = False # test either way Tracker.tracking_enabled = True # enabled automatically for testing else: Tracker.verbose = False Tracker.background = True Tracker.failsafe = True Tracker.tracking_enabled = True # User accepted on download if not internet(): print('no internet') return # try running install trackInstalled()
def execute(self, context): settings = get_settings() dbg = settings.debug Bridge = bpy.data.objects[self.odc_bridge.bridge] mes_tooth_distal_connector = self.b + self.b_group dis_tooth_mesial_connector = self.a + self.a_group [ob_sets, tool_sets, space_sets] = odcutils.scene_preserv(context, debug=dbg) #TODO: global debug bridge_methods.bridge_loop(context, Bridge, mes_tooth_distal_connector, dis_tooth_mesial_connector, 2, self.twist, self.bulbous, group3="Connectors", debug=True) odcutils.scene_reconstruct(context, ob_sets, tool_sets, space_sets, debug=dbg) return {'FINISHED'}
def execute(self,context): settings = get_settings() dbg =settings.debug n = context.scene.odc_splint_index odc_splint = context.scene.odc_splints[n] full_arch_methods.link_selection_to_splint(context, odc_splint, debug=dbg) return {'FINISHED'}
def execute(self, context): loop_obj = context.object oct = self.oct smooth = self.smooth settings = get_settings() dbg = settings.debug full_arch_methods.cloth_fill_main(context, loop_obj, oct, smooth, debug = dbg) return {'FINISHED'}
def invoke(self, context, event): self.objs.clear() settings = get_settings() libpath = settings.drill_lib assets = odcutils.obj_list_from_lib(libpath, include = 'Drill', exclude = 'Sleeve') for asset_object_name in assets: self.objs.add().name = asset_object_name context.window_manager.invoke_search_popup(self) return {'FINISHED'}
def invoke(self,context,event): self.objs.clear() #here we grab the asset library from the addon prefs settings = get_settings() libpath = settings.imp_lib assets = odcutils.obj_list_from_lib(libpath, exclude = '_') for asset_object_name in assets: self.objs.add().name = asset_object_name #context.window_manager.invoke_search_popup(self.ob_list) context.window_manager.invoke_search_popup(self) return {'FINISHED'}
def execute(self,context): settings = get_settings() dbg = settings.debug #TODO: Scene Preservation recording teeth = odcutils.tooth_selection(context) sce = bpy.context.scene layers_copy = [layer for layer in context.scene.layers] context.scene.layers[0] for tooth in teeth: #see if there is a corresponding implant if tooth.name in sce.odc_implants: contour = bpy.data.objects.get(tooth.contour) Z = Vector((0,0,-1)) if contour: if tooth.axis: Axis = bpy.data.objects.get(tooth.axis) if Axis: neg_z = Axis.matrix_world.to_quaternion() * Z rot_diff = odcutils.rot_between_vecs(Vector((0,0,1)), neg_z) else: neg_z = contour.matrix_world.to_quaternion() * Z rot_diff = odcutils.rot_between_vecs(Vector((0,0,1)), neg_z) else: neg_z = contour.matrix_world.to_quaternion() * Z rot_diff = odcutils.rot_between_vecs(Vector((0,0,1)), neg_z) mx = contour.matrix_world x = mx[0][3] y = mx[1][3] z = mx[2][3] #CEJ Location new_loc = odcutils.box_feature_locations(contour, Vector((0,0,-1))) Imp = implant_utils.place_implant(context, sce.odc_implants[tooth.name], new_loc, rot_diff, self.imp, hardware = self.hardware) #reposition platform below CEJ world_mx = Imp.matrix_world delta = Imp.dimensions[2] * world_mx.to_3x3() * Vector((0,0,1)) + self.depth * world_mx.to_3x3() * Vector((0,0,1)) world_mx[0][3] += delta[0] world_mx[1][3] += delta[1] world_mx[2][3] += delta[2] #odcutils.reorient_object(Imp, rot_diff) odcutils.layer_management(sce.odc_implants, debug = False) for i, layer in enumerate(layers_copy): context.scene.layers[i] = layer context.scene.layers[11] = True return {'FINISHED'}
def invoke(self, context, event): self.objs.clear() settings = get_settings() libpath = settings.ortho_lib assets = obj_list_from_lib(libpath) for asset_object_name in assets: self.objs.add().name = asset_object_name context.window_manager.invoke_search_popup(self) return {'FINISHED'}
def invoke(self, context, event): self.objs.clear() #here we grab the asset library from the addon prefs settings = get_settings() libpath = settings.imp_lib assets = odcutils.obj_list_from_lib(libpath, exclude='_') for asset_object_name in assets: self.objs.add().name = asset_object_name #context.window_manager.invoke_search_popup(self.ob_list) context.window_manager.invoke_search_popup(self) return {'FINISHED'}
def quick_lic_check(): prefs = get_settings() license_ley = prefs.heal_license_key raw_key = license_ley.replace('-','') if len(raw_key) == 0: res = {'status':'FAILED'} elif len(raw_key) != 16: res = {'status':'FAILED'} else: res = checkLicense(raw_key) return res
def invoke(self, context, event): self.objs.clear() settings = get_settings() libpath = settings.drill_lib assets = odcutils.obj_list_from_lib(libpath, include='Drill', exclude='Sleeve') for asset_object_name in assets: self.objs.add().name = asset_object_name context.window_manager.invoke_search_popup(self) return {'FINISHED'}
def __init__(self, context, bracket_data_manager): ''' Gets info from bracket manager and siplays orthogonal slices on the snap object ''' if not bracket_data_manager.bracket_obj: return None elif not bracket_data_manager.snap_ob: return None self.bracket_data = bracket_data_manager ob = self.bracket_data.snap_ob bme = bmesh.new() bme.from_object(ob, context.scene) self.snap_ob = ob self.bme = bme self.bvh = BVHTree.FromBMesh(self.bme) self.cut_pt = None self.cut_no_x = None self.cut_no_y = None self.slice_points_x = [] self.slice_points_y = [] self.reference_L = [] self.points_2d = [] self.active_point_2d = Vector((0, 0, 0)) self.mx = self.bracket_data.bracket_obj.matrix_world.to_3x3() b_gauge = self.bracket_data.bracket_obj.get('bracket_gauge') if b_gauge and not get_settings().bgauge_override: #read the prescription value from the objects self.b_gauge = b_gauge else: #override the rx value self.b_gauge = get_settings().bracket_gauge
def execute(self,context): settings = get_settings() dbg = settings.debug Bridge = bpy.data.objects[self.odc_bridge.bridge] mes_tooth_distal_connector = self.b + self.b_group dis_tooth_mesial_connector = self.a + self.a_group [ob_sets, tool_sets, space_sets] = odcutils.scene_preserv(context, debug=dbg) #TODO: global debug bridge_methods.bridge_loop(context, Bridge, mes_tooth_distal_connector, dis_tooth_mesial_connector, 2, self.twist, self.bulbous, group3 = "Connectors", debug=True) odcutils.scene_reconstruct(context, ob_sets, tool_sets, space_sets, debug=dbg) return {'FINISHED'}
def execute(self,context): settings = get_settings() dbg =settings.debug n = context.scene.odc_splint_index if len(context.scene.odc_splints) != 0: odc_splint = context.scene.odc_splints[n] odc_splint.model = context.object.name else: self.report({'WARNING'}, "there are not guides, bone will not be linked to a guide") context.scene.odc_props.bone = context.object.name return {'FINISHED'}
def poll(cls, context): if len(context.scene.odc_splints): settings = get_settings() dbg = settings.debug b = settings.behavior behave_mode = settings.behavior_modes[int(b)] if behave_mode in {'ACTIVE','ACTIVE_SELECTED'} and dbg > 2: obs = context.selected_objects cond_1 = len(obs) == 2 ob_types = set([obs[0].type, obs[1].type]) cond_2 = ('MESH' in ob_types) and ('CURVE' in ob_types) return cond_1 and cond_2 else: #we know there are splints..we will determine active one later return context.mode == 'OBJECT' else: return False
def execute(self,context): settings = get_settings() dbg = settings.debug layers_copy = [layer for layer in context.scene.layers] context.scene.layers[0] = True odc_bridge = bridge_methods.active_spanning_restoration(context)[0] bridge_methods.make_pre_bridge(context, odc_bridge, debug=dbg) #TODO: debug settings for i, layer in enumerate(layers_copy): context.scene.layers[i] = layer context.scene.layers[5] = True odcutils.layer_management(context.scene.odc_bridges, debug = dbg) return {'FINISHED'}
def update_link_operators(): #unregister get crown bpy.utils.unregister_class(OPENDENTAL_OT_place_implant) bpy.utils.unregister_class(OPENDENTAL_OT_implant_from_contour) #redefinte list from user prefs prop global lib_teeth_enum global lib_teeth lib_teeth_enum = [] lib_teeth = [] settings = get_settings() dbg = settings.debug lib_teeth = odcutils.obj_list_from_lib(settings.tooth_lib, exclude = '_', debug = dbg) for ind, obj in enumerate(lib_teeth): lib_teeth_enum.append((str(ind), obj, str(ind))) #reregister. bpy.utils.register_class(OPENDENTAL_OT_place_implant) bpy.utils.register_class(OPENDENTAL_OT_implant_from_contour)
def invoke(self, context, event): settings = get_settings() libpath = settings.ortho_lib assets = obj_list_from_lib(libpath) if settings.bracket in assets: current_obs = [ob.name for ob in bpy.data.objects] obj_from_lib(settings.ortho_lib, settings.bracket) for ob in bpy.data.objects: if ob.name not in current_obs: Bracket = ob Bracket.hide = False context.scene.objects.link(Bracket) else: Bracket = None if context.object and context.object.type == 'MESH': self.bracket_manager = BracketDataManager( context, snap_type='OBJECT', snap_object=context.object, name='Bracket', bracket=Bracket) self.bracket_slicer = BracektSlicer(context, self.bracket_manager) else: self.bracket_manager = BracketDataManager(context, snap_type='SCENE', snap_object=None, name='Bracket', bracket=Bracket) self.bracket_slicer = None help_txt = "DRAW MARGIN OUTLINE\n\nLeft Click on model to place bracket.\n G to grab \n S to show slice \n ENTER to confirm \n ESC to cancel" self.help_box = TextBox(context, 500, 500, 300, 200, 10, 20, help_txt) self.help_box.snap_to_corner(context, corner=[1, 1]) self.mode = 'start' self._handle = bpy.types.SpaceView3D.draw_handler_add( bracket_placement_draw_callback, (self, context), 'WINDOW', 'POST_PIXEL') context.window_manager.modal_handler_add(self) return {'RUNNING_MODAL'}
def invoke(self, context, event): settings = get_settings() dbg = settings.debug if context.space_data.region_3d.is_perspective: #context.space_data.region_3d.is_perspective = False bpy.ops.view3d.view_persportho() if context.space_data.type != 'VIEW_3D': self.report({'WARNING'}, "Active space must be a View3d") return {'CANCELLED'} #gather all the teeth in the scene TODO, keep better track self.target = 11 self.message = "Set axis for " + str(self.target) if context.mode != 'OBJECT': bpy.ops.object.mode_set(mode='OBJECT') #check for an armature bpy.ops.object.select_all(action='DESELECT') help_txt = "Left click on the tooth indicated to label it. Right click skip a tooth \n Up or Dn Arrow to change label\n Enter to finish \n ESC to cancel" self.help_box = TextBox(context, 500, 500, 300, 200, 10, 20, help_txt) self.help_box.fit_box_width_to_text_lines() self.help_box.fit_box_height_to_text_lines() self.help_box.snap_to_corner(context, corner=[1, 1]) aspect, mid = menu_utils.view3d_get_size_and_mid(context) self.target_box = TextBox(context, mid[0], aspect[1] - 20, 300, 200, 10, 20, self.message) self.target_box.format_and_wrap_text() self.target_box.fit_box_width_to_text_lines() self.target_box.fit_box_height_to_text_lines() self.mode = 'main' context.window_manager.modal_handler_add(self) self._handle = bpy.types.SpaceView3D.draw_handler_add( rapid_label_teeth_callback, (self, context), 'WINDOW', 'POST_PIXEL') return {'RUNNING_MODAL'}
def draw(self, context): if not context.scene.odc_props.show_ortho: return sce = bpy.context.scene layout = self.layout addon_prefs = get_settings() row = layout.row() row.label(text = "Orthodontics") row.operator("wm.url_open", text = "", icon="INFO").url = "https://github.com/patmo141/odc_public/wiki" row = layout.row() row.prop(addon_prefs, "ortho_lib") row = layout.row() col = row.column(align=True) #col.operator("opendental.add_implant_restoration", text = "Add a Space") col.operator("opendental.place_ortho_bracket", text = "Place Bracket") col.operator("opendental.place_static_bracket", text = "Place Bracket Static")
def update_link_operators(): #unregister get crown bpy.utils.unregister_class(OPENDENTAL_OT_place_implant) bpy.utils.unregister_class(OPENDENTAL_OT_implant_from_contour) #redefinte list from user prefs prop global lib_teeth_enum global lib_teeth lib_teeth_enum = [] lib_teeth = [] settings = get_settings() dbg = settings.debug lib_teeth = odcutils.obj_list_from_lib(settings.tooth_lib, exclude='_', debug=dbg) for ind, obj in enumerate(lib_teeth): lib_teeth_enum.append((str(ind), obj, str(ind))) #reregister. bpy.utils.register_class(OPENDENTAL_OT_place_implant) bpy.utils.register_class(OPENDENTAL_OT_implant_from_contour)
def draw(self, context): sce = bpy.context.scene layout = self.layout addon_prefs = get_settings() row = layout.row() row.label(text = "Dentures") row.operator("wm.url_open", text = "", icon="INFO").url = "https://github.com/patmo141/odc_public/wiki" row = layout.row() col = row.column(align=True) #col.operator("opendental.add_implant_restoration", text = "Add a Space") col.operator("opendental.meta_scaffold_create", text = "Make Baseplate Scaffold") col.operator("opendental.meta_offset_surface", text = "Make Meta Baseplate") col.operator("opendental.meta_rim_from_curve", text = "Make Meta Wax Rim") if context.object and context.object.type == 'META': col.operator("object.convert", text = "Convert Meta Baseplate to Mesh") col.operator("opendental.denture_boolean_intaglio", text = "Boolean with Master Cast")
def draw(self, context): if not context.scene.odc_props.show_ortho: return sce = bpy.context.scene layout = self.layout addon_prefs = get_settings() row = layout.row() row.label(text="Orthodontics") row.operator( "wm.url_open", text="", icon="INFO").url = "https://github.com/patmo141/odc_public/wiki" row = layout.row() row.prop(addon_prefs, "ortho_lib") row = layout.row() col = row.column(align=True) #col.operator("opendental.add_implant_restoration", text = "Add a Space") col.operator("opendental.place_ortho_bracket", text="Place Bracket") col.operator("opendental.place_static_bracket", text="Place Bracket Static")
def draw(self, context): sce = bpy.context.scene layout = self.layout addon_prefs = get_settings() row = layout.row() row.label(text="Model Operators") row.operator( "wm.url_open", text="", icon="INFO").url = "https://github.com/patmo141/odc_public/wiki" row = layout.row() col = row.column(align=True) col.operator("opendental.meta_scaffold_create", text="Decimate Surface") col.operator("opendental.meta_offset_surface", text="Meta Offset Surface") if context.object and context.object.type == 'META': col.operator("object.convert", text="Convert Meta Surface to Mesh") col.operator("opendental.simple_offset_surface", text="Simple Offset") col.operator("opendental.simple_base", text="Simple Base")
def execute(self, context): settings = get_settings() dbg = settings.debug #first, ensure all models are present and not deleted etc odcutils.scene_verification(context.scene, debug = dbg) b = settings.behavior behave_mode = settings.behavior_modes[int(b)] settings = get_settings() dbg = settings.debug [ob_sets, tool_sets, space_sets] = odcutils.scene_preserv(context, debug=dbg) #this is sneaky way of letting me test different things if behave_mode in {'ACTIVE','ACTIVE_SELECTED'} and dbg > 2: obs = context.selected_objects if obs[0].type == 'CURVE': model = obs[1] margin = obs[0] else: model = obs[0] margin = obs[1] exclude = ['name','teeth','implants','tooth_string','implant_string'] splint = odcutils.active_odc_item_candidate(context.scene.odc_splints, obs[0], exclude) else: j = context.scene.odc_splint_index splint =context.scene.odc_splints[j] if splint.model in bpy.data.objects and splint.margin in bpy.data.objects: model = bpy.data.objects[splint.model] margin = bpy.data.objects[splint.margin] else: print('whoopsie...margin and model not defined or something is wrong') return {'CANCELLED'} layers_copy = [layer for layer in context.scene.layers] context.scene.layers[0] = True z = Vector((0,0,1)) vrot= context.space_data.region_3d.view_rotation Z = vrot*z [Splint, Falloff, Refractory] = full_arch_methods.splint_bezier_step_1(context, model, margin, Z, self.thickness, debug=dbg) splint.splint = Splint.name #that's a pretty funny statement. if splint.bone and splint.bone in bpy.data.objects: mod = Splint.modifiers['Bone'] mod.target = bpy.data.objects[splint.bone] if self.cleanup: context.scene.objects.active = Splint Splint.select = True for mod in Splint.modifiers: if mod.name != 'Bone': if mod.type in {'BOOLEAN', 'SHRINKWRAP'}: if mod.type == 'BOOLEAN' and mod.object: bpy.ops.object.modifier_apply(modifier=mod.name) elif mod.type == 'SHRINKWRAP' and mod.target: bpy.ops.object.modifier_apply(modifier=mod.name) else: bpy.ops.object.modifier_apply(modifier=mod.name) context.scene.objects.unlink(Falloff) Falloff.user_clear() bpy.data.objects.remove(Falloff) context.scene.objects.unlink(Refractory) Refractory.user_clear() bpy.data.objects.remove(Refractory) odcutils.scene_reconstruct(context, ob_sets, tool_sets, space_sets, debug=dbg) else: odcutils.scene_reconstruct(context, ob_sets, tool_sets, space_sets, debug=dbg) Falloff.hide = True Refractory.hide = True for i, layer in enumerate(layers_copy): context.scene.layers[i] = layer context.scene.layers[10] = True odcutils.material_management(context, context.scene.odc_splints, debug = dbg) odcutils.layer_management(context.scene.odc_splints, debug = dbg) return {'FINISHED'}
def place_implant(context, implant_space, location,orientation,imp, hardware = True): ''' args: context implant_space - ODC Implant Space type location - Vector orientation - Matrix or Quaternion lib_implants - imp - string representing implant object name in link library ''' #check if space already has an implant object. #if so, delete, replace, print warning sce = context.scene if implant_space.implant and implant_space.implant in bpy.data.objects: print("replacing the existing implant with the one you chose") Implant = bpy.data.objects[implant_space.implant] #unlink it from the scene, clear it's useres, remove it. if Implant.children: for child in Implant.children: sce.objects.unlink(child) child.user_clear bpy.data.objects.remove(child) sce.objects.unlink(Implant) implant_mesh = Implant.data Implant.user_clear() #remove the object bpy.data.objects.remove(Implant) implant_mesh.user_clear() bpy.data.meshes.remove(implant_mesh) sce.update() #TDOD what about the children/hardwares? world_mx = Matrix.Identity(4) world_mx[0][3]=location[0] world_mx[1][3]=location[1] world_mx[2][3]=location[2] #mx_b = Matrix.Identity(4) #mx_l = Matrix.Identity(4) #is this more memory friendly than listing all objects? current_obs = [ob.name for ob in bpy.data.objects] #link the new implant from the library settings = get_settings() odcutils.obj_from_lib(settings.imp_lib, imp) #this is slightly more robust than trusting we don't have duplicate names. for ob in bpy.data.objects: if ob.name not in current_obs: Implant = ob sce.objects.link(Implant) #Implant.matrix_basis = mx_b Implant.matrix_world = world_mx Implant.update_tag() sce.update() Implant.rotation_mode = 'QUATERNION' Implant.rotation_quaternion = orientation sce.update() #Implant.matrix_local = mx_l #Implant.location = L if sce.odc_props.master: Master = bpy.data.objects[sce.odc_props.master] odcutils.parent_in_place(Implant, Master) else: print('No Master Model, placing implant anyway, moving objects may not preserve spatial relationships') #looks a little redundant, but it ensure if any #duplicates exist our referencing stays accurate Implant.name = implant_space.name + "_" + Implant.name implant_space.implant = Implant.name if hardware: current_obs = [ob.name for ob in bpy.data.objects] inc = imp + '_' settings = get_settings() hardware_list = odcutils.obj_list_from_lib(settings.imp_lib, include = inc) print(hardware_list) for ob in hardware_list: odcutils.obj_from_lib(settings.imp_lib,ob) for ob in bpy.data.objects: if ob.name not in current_obs: sce.objects.link(ob) ob.parent = Implant ob.layers[11] = True #TODO: put this in layer management. return Implant
def execute(self,context): settings = get_settings() dbg = settings.debug n = context.scene.odc_splint_index odc_splint = context.scene.odc_splints[n] if not odc_splint.splint: self.report({'ERROR'},'No splint model to add guide cylinders too') if dbg: start_time = time.time() layers_copy = [layer for layer in context.scene.layers] context.scene.layers[0] = True if context.mode != 'OBJECT': bpy.ops.object.mode_set(mode='OBJECT') sce = context.scene bpy.ops.object.select_all(action='DESELECT') new_objs = [] implants = [] imp_list = odc_splint.implant_string.split(sep=":") for name in imp_list: implant = context.scene.odc_implants.get(name) if implant: implants.append(implant) for space in implants: if space.outer and space.outer in bpy.data.objects: Guide_Cylinder = bpy.data.objects[space.outer] Guide_Cylinder.hide = True new_data = Guide_Cylinder.to_mesh(sce,True, 'RENDER') new_obj = bpy.data.objects.new("temp_guide", new_data) new_obj.matrix_world = Guide_Cylinder.matrix_world new_objs.append(new_obj) sce.objects.link(new_obj) new_obj.select = True if len(new_objs): sce.objects.active = new_objs[0] bpy.ops.object.join() else: return{'CANCELLED'} bpy.ops.object.select_all(action='DESELECT') Splint = bpy.data.objects[odc_splint.splint] Splint.select = True Splint.hide = False sce.objects.active = Splint if self.finalize: for mod in Splint.modifiers: if mod.type in {'BOOLEAN', 'SHRINKWRAP'}: if mod.type == 'BOOLEAN' and mod.object: bpy.ops.object.modifier_apply(modifier=mod.name) elif mod.type == 'SHRINKWRAP' and mod.target: bpy.ops.object.modifier_apply(modifier=mod.name) else: bpy.ops.object.modifier_apply(modifier=mod.name) bool_mod = Splint.modifiers.new('OUTER','BOOLEAN') bool_mod.operation = 'UNION' bool_mod.object = new_objs[0] #hopefully this is still the object? new_objs[0].hide = True for i, layer in enumerate(layers_copy): context.scene.layers[i] = layer context.scene.layers[11] = True if dbg: finish = time.time() - start_time print("finished merging guides in %f seconds..boy that took a long time" % finish) return {'FINISHED'}
def execute(self, context): settings = get_settings() dbg = settings.debug #if bpy.context.mode != 'OBJECT': # bpy.ops.object.mode_set(mode = 'OBJECT') sce = context.scene implants = odcutils.implant_selection(context) layers_copy = [layer for layer in context.scene.layers] context.scene.layers[0] = True if implants != []: for implant_space in implants: #check if space already has an implant object. #if so, delete, replace, print warning Implant = bpy.data.objects[implant_space.implant] if Implant.rotation_mode != 'QUATERNION': Implant.rotation_mode = 'QUATERNION' Implant.update_tag() sce.update() if bpy.data.objects.get(implant_space.drill): self.report( {'WARNING'}, "replacing the existing drill with the one you chose") Sleeve = bpy.data.objects[implant_space.drill] #unlink it from the scene, clear it's users, remove it. sce.objects.unlink(Sleeve) Implant.user_clear() #remove the object bpy.data.objects.remove(Sleeve) current_obs = [ob.name for ob in bpy.data.objects] #link the new implant from the library settings = get_settings() odcutils.obj_from_lib(settings.drill_lib, self.drill) #this is slightly more robust than trusting we don't have duplicate names. for ob in bpy.data.objects: if ob.name not in current_obs: Sleeve = ob sce.objects.link(Sleeve) Sleeve.layers[19] = True mx_w = Implant.matrix_world.copy() #point the right direction Sleeve.rotation_mode = 'QUATERNION' Sleeve.rotation_quaternion = mx_w.to_quaternion() Sleeve.update_tag() context.scene.update() Trans = Sleeve.rotation_quaternion * Vector( (0, 0, -self.depth)) Sleeve.matrix_world[0][3] = mx_w[0][3] + Trans[0] Sleeve.matrix_world[1][3] = mx_w[1][3] + Trans[1] Sleeve.matrix_world[2][3] = mx_w[2][3] + Trans[2] Sleeve.name = implant_space.name + '_' + Sleeve.name implant_space.drill = Sleeve.name Sleeve.update_tag() context.scene.update() odcutils.parent_in_place(Sleeve, Implant) odcutils.layer_management(sce.odc_implants, debug=dbg) for i, layer in enumerate(layers_copy): context.scene.layers[i] = layer context.scene.layers[19] = True return {'FINISHED'}
def execute(self, context): settings = get_settings() dbg = settings.debug #if bpy.context.mode != 'OBJECT': # bpy.ops.object.mode_set(mode = 'OBJECT') sce = context.scene n = sce.odc_implant_index implant_space = sce.odc_implants[n] implants = odcutils.implant_selection(context) layers_copy = [layer for layer in context.scene.layers] context.scene.layers[0] if implants != []: for implant_space in implants: #check if space already has an implant object. #if so, delete, replace, print warning if implant_space.implant and implant_space.implant in bpy.data.objects: self.report({'WARNING'}, "replacing the existing implant with the one you chose") Implant = bpy.data.objects[implant_space.implant] #the origin/location of the implant is it's apex L = Implant.location.copy() world_mx = Implant.matrix_world.copy() #the platorm is the length of the implant above the apex, in the local Z direction #local Z positive is out the apex, soit's negative. #Put the cursor there sce.cursor_location = L - Implant.dimensions[2] * world_mx.to_3x3() * Vector((0,0,1)) #first get rid of children...so we can use the #parent to find out who the children are if Implant.children: for child in Implant.children: sce.objects.unlink(child) child.user_clear() bpy.data.objects.remove(child) #unlink it from the scene, clear it's users, remove it. sce.objects.unlink(Implant) Implant.user_clear() #remove the object bpy.data.objects.remove(Implant) #TDOD what about the children/hardwares? else: world_mx = Matrix.Identity(4) world_mx[0][3]=sce.cursor_location[0] world_mx[1][3]=sce.cursor_location[1] world_mx[2][3]=sce.cursor_location[2] #is this more memory friendly than listing all objects? current_obs = [ob.name for ob in bpy.data.objects] #link the new implant from the library odcutils.obj_from_lib(settings.imp_lib,self.imp) #this is slightly more robust than trusting we don't have duplicate names. for ob in bpy.data.objects: if ob.name not in current_obs: Implant = ob sce.objects.link(Implant) #this relies on the associated hardware objects having the parent implant #name inside them if self.hardware: current_obs = [ob.name for ob in bpy.data.objects] inc = self.imp + '_' hardware_list = odcutils.obj_list_from_lib(settings.imp_lib, include = inc) print(hardware_list) for ob in hardware_list: odcutils.obj_from_lib(settings.imp_lib,ob) for ob in bpy.data.objects: if ob.name not in current_obs: sce.objects.link(ob) ob.parent = Implant ob.layers[11] = True delta = Implant.dimensions[2] * world_mx.to_3x3() * Vector((0,0,1)) print(delta.length) world_mx[0][3] += delta[0] world_mx[1][3] += delta[1] world_mx[2][3] += delta[2] Implant.matrix_world = world_mx if sce.odc_props.master: Master = bpy.data.objects[sce.odc_props.master] odcutils.parent_in_place(Implant, Master) else: self.report({'WARNING'}, 'No Master Model, placing implant anyway, moving objects may not preserve spatial relationships') #looks a little redundant, but it ensure if any #duplicates exist our referencing stays accurate Implant.name = implant_space.name + '_' + Implant.name implant_space.implant = Implant.name odcutils.layer_management(sce.odc_implants, debug = dbg) for i, layer in enumerate(layers_copy): context.scene.layers[i] = layer context.scene.layers[11] = True return {'FINISHED'}
def active_spanning_restoration(context, exclude = [], debug = False): ''' TODO: test robustness and implications of this logic looks at addon preferences returns a list, ''' sce = context.scene bridges = [] if not hasattr(context.scene, 'odc_props'): return [None] if len(context.scene.odc_bridges) == 0: return [None] settings = get_settings() b = settings.behavior behave_mode = settings.behavior_modes[int(b)] if behave_mode == 'LIST': #choose just one tooth in the list if len(sce.odc_bridges): bridge = sce.odc_bridges[sce.odc_bridge_index] bridges.append(bridge) elif behave_mode == 'ACTIVE': if len(sce.odc_bridges): for bridge in context.scene.odc_bridges: prop_keys = bridge.keys() prop_vals = bridge.values() if debug > 1: print(prop_keys) print(prop_vals) ob = context.object if ob.name in prop_vals: n = prop_vals.index(ob.name) this_key = prop_keys[n] if debug: print("found the object named %s as the property value: %s in bridge: %s" %(ob.name, this_key, bridge.name)) if this_key and (this_key not in exclude): bridges.append(bridge) tooth = odcutils.tooth_selection(context)[0] for bridge in sce.odc_bridges: if tooth.name in bridge.tooth_string.split(sep=":"): if debug: print('found tooth %s in bridge: %s' % (tooth.name, bridge.name)) bridges.append(bridge) elif behave_mode == 'ACTIVE_SELECTED': #make sure the active object has priority by checking that first. if len(sce.odc_bridges): for bridge in context.scene.odc_bridges: prop_keys = bridge.keys() prop_vals = bridge.values() if context.object: if context.object.name in prop_vals: n = prop_vals.index(context.object.name) this_key = prop_keys[n] if debug: print("found the object named %s as the property value: %s in bridge: %s" %(ob.name, this_key, bridge.name)) bridges.append(bridge) teeth = odcutils.tooth_selection(context) if teeth: for tooth in teeth: for bridge in sce.odc_bridges: if tooth.name in bridge.tooth_string.split(sep=":"): if debug: print('found tooth %s in bridge: %s' % (tooth.name, bridge.name)) if bridge not in bridges: bridges.append(bridge) if debug > 1: print(bridges) return bridges
def execute(self, context): settings = get_settings() dbg = settings.debug bridge_methods.bridge_from_selection(context, debug=dbg) return {'FINISHED'}
def update_brackets(self,context): settings = odcutils.get_settings() libpath = settings.ortho_lib assets = odcutils.obj_list_from_lib(libpath) return [(asset,asset, asset) for asset in assets]
def invoke(self, context, event): settings = get_settings() dbg = settings.debug if context.space_data.region_3d.is_perspective: #context.space_data.region_3d.is_perspective = False bpy.ops.view3d.view_persportho() if context.space_data.type != 'VIEW_3D': self.report({'WARNING'}, "Active space must be a View3d") return {'CANCELLED'} #gather all the teeth in the scene TODO, keep better track self.units = [] for i in TOOTH_NUMBERS: ob = context.scene.objects.get(str(i)) if ob != None and not ob.hide: self.units.append(ob) if not len(self.units): self.report({ 'ERROR' }, "There are no teeth in the scene!, Teeth must be named 2 digits eg 11 or 46" ) return {'CANCELLED'} self.target = self.units[0] self.message = "Set axis for %s" % self.target.name #check for an armature bpy.ops.object.select_all(action='DESELECT') if context.mode != 'OBJECT': bpy.ops.object.mode_set(mode='OBJECT') if context.scene.objects.get('Roots'): root_arm = context.scene.objects.get('Roots') root_arm.select = True root_arm.hide = False context.scene.objects.active = root_arm bpy.ops.object.mode_set(mode='EDIT') for ob in self.units: if ob.name + 'root' not in root_arm.data.bones: bpy.ops.armature.bone_primitive_add(name=ob.name + 'root') else: root_data = bpy.data.armatures.new('Roots') root_arm = bpy.data.objects.new('Roots', root_data) context.scene.objects.link(root_arm) root_arm.select = True context.scene.objects.active = root_arm bpy.ops.object.mode_set(mode='EDIT') for ob in self.units: bpy.ops.armature.bone_primitive_add(name=ob.name + 'root') bpy.ops.object.mode_set(mode='OBJECT') root_arm.select = False self.units[0].select = True help_txt = "Right click to select a tooth \n Align View with root, mes and distal\n Up Arrow and Dn Arrow to select different units \n Left click in middle of prep to set axis \n Enter to finish \n ESC to cancel" self.help_box = TextBox(context, 500, 500, 300, 200, 10, 20, help_txt) self.help_box.fit_box_width_to_text_lines() self.help_box.fit_box_height_to_text_lines() self.help_box.snap_to_corner(context, corner=[1, 1]) aspect, mid = menu_utils.view3d_get_size_and_mid(context) self.target_box = TextBox(context, mid[0], aspect[1] - 20, 300, 200, 10, 20, self.message) self.target_box.format_and_wrap_text() self.target_box.fit_box_width_to_text_lines() self.target_box.fit_box_height_to_text_lines() self.mode = 'main' context.window_manager.modal_handler_add(self) self._handle = bpy.types.SpaceView3D.draw_handler_add( insertion_axis_draw_callback, (self, context), 'WINDOW', 'POST_PIXEL') return {'RUNNING_MODAL'}
def draw(self, context): sce = bpy.context.scene layout = self.layout addon_prefs = get_settings() row = layout.row() row.label(text = "Preferences") row = layout.row() col = row.column() col.prop(addon_prefs, "heal_workflow") col.prop(addon_prefs, "heal_profile") col.prop(addon_prefs, "profile_scale") col.prop(addon_prefs, "heal_print_type", text = "Print Type") col.prop(addon_prefs, "heal_number_sys", text = "Number System") row = layout.row() row.prop(addon_prefs, "heal_show_prefs", text = "Show Settings") if addon_prefs.heal_show_prefs: row = layout.row() col = row.column() col.prop(addon_prefs, "heal_passive_offset", text = "Passive Gap") col.prop(addon_prefs, "heal_block_border_x", text = "Border Horizontal") col.prop(addon_prefs, "heal_block_border_y", text = "Border Vertical") col.prop(addon_prefs, "heal_inter_space_x", text = "Spacing Horizontal") col.prop(addon_prefs, "heal_inter_space_y", text = "Spacing Vertical") col.prop(addon_prefs, "heal_middle_space_x", text = "Spacing Middle") col.prop(addon_prefs, "heal_bevel_width", text = "Bevel Width") col.prop(addon_prefs, "mould_wall_thickness", text = "Wall Thickness") col.prop(addon_prefs, "default_text_size", text = "Label Font Size") #col.prop(addon_prefs, "heal_abutment_depth", text = "Abutment Depth") #col.prop(addon_prefs, "heal_show_prefs", text = "Show Settings") #col.prop(addon_prefs, "heal_show_prefs", text = "Show Settings") #operator save settings row = layout.row() row.operator("wm.save_userpref",text = "Save Settings") row = layout.row() row.label("Select Teeth (" + addon_prefs.heal_number_sys + " system)") row = layout.row() row.label("(expand Menu to see tooth numbers") row = layout.row() row.prop(addon_prefs, "heal_tooth_preset") box = layout.box() split = box.column_flow(8) if addon_prefs.heal_number_sys == 'UNIVERSAL': for i in range(0,7): c = split.column() if i == 0: c.row().label('R') #spacer else: c.row().label('') c.row().prop(addon_prefs, "heal_teeth", index = i+1, text = str(i+2), toggle= True) c.row().prop(addon_prefs, "heal_teeth", index = 30 - i, text = str(31 -i), toggle= True) if i == 0: c.row().label('L') #spacer else: c.row().label('') c.row().prop(addon_prefs, "heal_teeth", index = i + 8, text = str(i+9), toggle= True) c.row().prop(addon_prefs, "heal_teeth", index = 23 - i, text = str(24 -i), toggle= True) elif addon_prefs.heal_number_sys == 'F.D.I.': for i in range(0,7): c = split.column() if i == 0: c.row().label('R') #spacer else: c.row().label('') c.row().prop(addon_prefs, "heal_teeth", index = i+1, text = FDI[i+2], toggle= True) c.row().prop(addon_prefs, "heal_teeth", index = 30 - i, text = FDI[31 -i], toggle= True) if i == 0: c.row().label('L') #spacer else: c.row().label('') c.row().prop(addon_prefs, "heal_teeth", index = i + 8, text = FDI[i+9], toggle= True) c.row().prop(addon_prefs, "heal_teeth", index = 23 - i, text = FDI[24 -i], toggle= True) elif addon_prefs.heal_number_sys == 'PALMER': for i in range(0,7): c = split.column() if i == 0: c.row().label('R') #spacer else: c.row().label('') c.row().prop(addon_prefs, "heal_teeth", index = i+1, text = PAL[i+2], toggle= True) c.row().prop(addon_prefs, "heal_teeth", index = 30 - i, text = PAL[31 -i], toggle= True) if i == 0: c.row().label('L') #spacer else: c.row().label('') c.row().prop(addon_prefs, "heal_teeth", index = i + 8, text = PAL[i+9], toggle= True) c.row().prop(addon_prefs, "heal_teeth", index = 23 - i, text = PAL[24 -i], toggle= True) if addon_prefs.heal_workflow == 'WIZARD': box = layout.box() row = box.row() row.label('Basic Steps') row = box.row() row = box.row() row.prop(addon_prefs, "heal_abutment_file") row = box.row() col = row.column(align=True) col.operator("opendental.heal_import_abutment", text = "Import Abutment") row = box.row() col = row.column(align = True) col.operator("opendental.heal_abutment_generator", text = "Create Abutment From Measurements") row = box.row() row.prop(addon_prefs, "heal_abutment_depth", text = "Depth to Collar") row = box.row() col = row.column() col.prop(addon_prefs, "heal_block_label") col.operator("opendental.heal_auto_generate") col.operator("apg.export_block", text = "Export Model") box = layout.box() row = box.row() row.label('Boolean Fixes') row = box.row() col = row.column() col.operator("opendental.heal_boolean_change_solver", text = "Change Solver") col.operator("opendental.heal_boolean_nudge", text = "Nudge Booleans") col.operator("opendental.heal_boolean_nudge_block",text = "Fix Booleans in Bottom") box = layout.box() row = box.row() row.label('Issues/Bugs and Help') row = box.row() col = row.column() col.operator("wm.console_toggle",text = "Open Console") col.operator("wm.url_open",text = "Report Issue").url = "https://bitbucket.org/impdental/waxing_designer/issues" return row = layout.row() row.label('Abutment Fns') row = layout.row() row.prop(addon_prefs, "heal_abutment_file") row = layout.row() col = row.column(align=True) col.operator("opendental.heal_import_abutment", text = "Import Abutment") row = layout.row() row.label('Abutment Cleanup Ops') row = layout.row() col = row.column() col.operator("opendental.heal_mark_abutment_shoulder", text = "Mark Abutment Shoulder") col.operator("opendental.heal_mark_abutment_timing", text = "Mark Abutment Timing") col.prop(addon_prefs, "heal_advanced_abutment") if addon_prefs.heal_advanced_abutment: col.operator("opendental.heal_abutment_generator", text = "Create Abutment From Measurements") col.operator("opendental.heal_remove_internal", text = "Remove Internal Geom") col.operator("opendental.ucla_remove_timing", text = "Remove Timing Geom") col.operator("opendental.heal_cut_at_cursor", text = "Cut at Cursor") col.operator("opendental.heal_extend_flat", text = "Extend From Cursor") col.operator("apg.export_abutment", text = "Export Abutment") row = layout.row() row.label('Generate Profiles and Shapes') row = layout.row() col = row.column() col.prop(addon_prefs, "heal_abutment_depth", text = "Depth CEJ to Platform") #col.operator("opendental.heal_generate_profiles", text = "Generate Profiles") cejs = [ob.name for ob in context.scene.objects if ":CEJ" in ob.name] if len(cejs) == 0: col.operator("opendental.heal_database_profiles", text = "Database Profiles (Mesh)") col.operator("opendental.heal_database_curve_profiles", text = "Database Profiles (Curve)") row = layout.row() col = row.column() col.prop(addon_prefs, "heal_show_ob") if addon_prefs.heal_mirror_transform == True: col.operator("opendental.heal_stop_mirror") else: col.operator("opendental.heal_mirror_transform") if addon_prefs.heal_show_ob and context.object != None: if ":CEJ" in context.object.name: col.prop(context.object, "dimensions") col.prop(context.object, "location") col.operator("opendental.heal_mesh_convert", text = "Connect CEJ to Base") row = layout.row() row.label('Edit Profile Shapes') row = layout.row() col = row.column() col.prop(addon_prefs, 'heal_show_edit') if context.object != None and addon_prefs.heal_show_edit: vis_obs = [ob for ob in context.scene.objects if not ob.hide] local = len(vis_obs) <= 1 if ":Profile" in context.object.name and "Final" not in context.object.name: col.label(context.object.name) if local == False: col.operator("opendental.heal_isolate_view", text = "Isolate View") elif local and context.mode != 'SCULPT': col.operator("opendental.heal_global_view", text = "Global View") if context.object.mode == 'OBJECT': col.operator("object.mode_set", text = 'Go Sculpt').mode = 'SCULPT' col.operator("opendental.heal_reprofile", text = 'Cone Profile').preset = 'CONE' col.operator("opendental.heal_reprofile", text = 'Hour Glass Profile').preset = 'HOURGLASS' col.operator("opendental.heal_reprofile", text = 'Convex Profile').preset = 'BOWL' col.operator("opendental.heal_reprofile", text = 'Deep Convex Profile').preset = 'DEEP_BOWL' elif context.object.mode == 'SCULPT': col.operator("object.mode_set", text = 'Finish Sculpt').mode = 'OBJECT' is_local = False for area in context.screen.areas: if area.type == 'VIEW_3D': space = area.spaces[0] if space.local_view: #check if using local view is_local = True break if is_local: row = layout.row() row.label('Need Global View to continue!') return row = layout.row() row.label('Generate Box') row = layout.row() col = row.column() col.prop(addon_prefs, "heal_print_type") col.operator("opendental.heal_generate_box", text = "Generate Box") row = layout.row() row.label('Labels and Custom Text') row = layout.row() col = row.column() col.operator("opendental.heal_generate_text", text = "Generate Labels") row = layout.row() row.prop(addon_prefs, "heal_custom_text") row = layout.row() row.operator("opendental.heal_custom_text", text = "Add Text at 3D Cursor") row = layout.row() row.label("Prepare CAD Model") row = layout.row() col = row.column() col.operator("opendental.heal_emboss_text", text = "Emboss All Text") col.operator("opendental.heal_create_final_template", text = "Boolean Profiles") col.operator("opendental.heal_boolean_nudge", text = "Fix Boolean") col.operator("opendental.heal_boolean_nudge_block",text = "Fix Booleans in Bottom") row = layout.row() row.label("Export CAD Model") row = layout.row() if len(context.selected_objects) == 0: row.label('Select the object!') elif len(context.selected_objects) > 1: row.label('Select only 1 object!') elif context.object != None: row.label(context.object.name) row = layout.row() col = row.column() col.operator("apg.export_block", text = "Export Block") box = layout.box() row = box.row() row.label('Issues/Bugs and Help') row = box.row() col = row.column() col.operator("wm.console_toggle",text = "Open Console") col.operator("wm.url_open",text = "Report Issue").url = "https://bitbucket.org/impdental/waxing_designer/issues"
def execute(self, context): settings = get_settings() dbg = settings.debug odc_bridge = bridge_methods.active_spanning_restoration(context)[0] sce = context.scene Bridge = bpy.data.objects.get(odc_bridge.bridge) if not Bridge: self.report({ 'ERROR' }, 'Use "Boolean Bridge" to join individual units to an outer shell first' ) go_local = False if context.space_data.local_view: go_local = True bpy.ops.view3d.localview() if len(Bridge.modifiers): me = Bridge.to_mesh(context.scene, True, 'PREVIEW') mods = [mod for mod in Bridge.modifiers] for mod in mods: Bridge.modifiers.remove(mod) Bridge.data = me ### Remove the bottom 3 edge loops bridge_bme = bmesh.new() bridge_bme.from_object(Bridge, context.scene) bridge_bme.edges.ensure_lookup_table() bridge_bme.verts.ensure_lookup_table() bridge_bme.faces.ensure_lookup_table() for i in range(0, 3): non_man_eds = [ed for ed in bridge_bme.edges if not ed.is_manifold] bmesh.ops.delete(bridge_bme, geom=non_man_eds, context=2) non_man_vs = [v for v in bridge_bme.verts if not v.is_manifold] bmesh.ops.delete(bridge_bme, geom=non_man_vs, context=1) bridge_bme.edges.ensure_lookup_table() bridge_bme.verts.ensure_lookup_table() bridge_bme.faces.ensure_lookup_table() bridge_bme.to_mesh(Bridge.data) ### DONE Removing bottom 3 edge loops ### bridge_teeth = [ context.scene.odc_teeth[name] for name in odc_bridge.tooth_string.split(sep=":") ] intag_objects = [ bpy.data.objects.get(tooth.intaglio) for tooth in bridge_teeth if tooth.rest_type != '1' ] if None in intag_objects: self.report({'ERROR'}, 'Missing Intaglio for some abutments') bpy.ops.object.select_all(action='DESELECT') join_obs = [] for ob in intag_objects: new_me = ob.to_mesh(context.scene, True, 'PREVIEW') new_ob = bpy.data.objects.new(ob.name + ' dupli', new_me) new_ob.matrix_world = ob.matrix_world context.scene.objects.link(new_ob) join_obs.append(new_ob) print(join_obs) bpy.ops.object.select_all(action='DESELECT') for ob in join_obs: ob.select = True Bridge.hide = False Bridge.select = True context.scene.objects.active = Bridge Bridge.name += '_solid' bpy.ops.object.join() bridge_bme.free() bridge_bme = bmesh.new() bridge_bme.from_mesh(Bridge.data, True) bridge_bme.edges.ensure_lookup_table() bridge_bme.verts.ensure_lookup_table() bridge_bme.faces.ensure_lookup_table() non_man = [ed for ed in bridge_bme.edges if not ed.is_manifold] bmesh.ops.bridge_loops(bridge_bme, edges=non_man, use_pairs=True) #non_man = [ed.index for ed in bridge_bme.edges if not ed.is_manifold] #loops = mesh_cut.edge_loops_from_bmedges(bridge_bme, non_man) #for loop in loops: #for i in loop: #bridge_bme.verts[i].select_set(True) bmesh.ops.recalc_face_normals(bridge_bme, faces=bridge_bme.faces[:]) bridge_bme.to_mesh(Bridge.data) #bridge_bme.transform(Bridge.matrix_world) #new_me = bpy.data.meshes.new(odc_bridge.name + '_solid') #bridge_bme.to_mesh(new_me) bridge_bme.free() #new_ob = bpy.data.objects.new(odc_bridge.name + '_solid', new_me) #context.scene.objects.link(new_ob) if go_local: bpy.ops.view3d.localview() return {'FINISHED'}
def execute(self, context): settings = get_settings() dbg = settings.debug #TODO: Scene Preservation recording teeth = odcutils.tooth_selection(context) sce = bpy.context.scene layers_copy = [layer for layer in context.scene.layers] context.scene.layers[0] for tooth in teeth: #see if there is a corresponding implant if tooth.name in sce.odc_implants: contour = bpy.data.objects.get(tooth.contour) Z = Vector((0, 0, -1)) if contour: if tooth.axis: Axis = bpy.data.objects.get(tooth.axis) if Axis: neg_z = Axis.matrix_world.to_quaternion() * Z rot_diff = odcutils.rot_between_vecs( Vector((0, 0, 1)), neg_z) else: neg_z = contour.matrix_world.to_quaternion() * Z rot_diff = odcutils.rot_between_vecs( Vector((0, 0, 1)), neg_z) else: neg_z = contour.matrix_world.to_quaternion() * Z rot_diff = odcutils.rot_between_vecs( Vector((0, 0, 1)), neg_z) mx = contour.matrix_world x = mx[0][3] y = mx[1][3] z = mx[2][3] #CEJ Location new_loc = odcutils.box_feature_locations( contour, Vector((0, 0, -1))) Imp = implant_utils.place_implant( context, sce.odc_implants[tooth.name], new_loc, rot_diff, self.imp, hardware=self.hardware) #reposition platform below CEJ world_mx = Imp.matrix_world delta = Imp.dimensions[2] * world_mx.to_3x3() * Vector( (0, 0, 1)) + self.depth * world_mx.to_3x3() * Vector( (0, 0, 1)) world_mx[0][3] += delta[0] world_mx[1][3] += delta[1] world_mx[2][3] += delta[2] #odcutils.reorient_object(Imp, rot_diff) odcutils.layer_management(sce.odc_implants, debug=False) for i, layer in enumerate(layers_copy): context.scene.layers[i] = layer context.scene.layers[11] = True return {'FINISHED'}
def execute(self,context): settings = get_settings() dbg = settings.debug odc_bridge = bridge_methods.active_spanning_restoration(context)[0] layers_copy = [layer for layer in context.scene.layers] context.scene.layers[0] = True bridge_teeth = [context.scene.odc_teeth[name] for name in odc_bridge.tooth_string.split(sep=":")] contour_obs = [bpy.data.objects.get(tooth.contour) for tooth in bridge_teeth] if None in contour_obs: bad_unit = contour_obs.index(None) bad_tooth = bridge_teeth[bad_unit].name self.report({'ERROR'}, 'Full Contour design missing for ' + bad_tooth) return {'CANCELLED'} left_teeth = [] right_teeth = [] for tooth in bridge_teeth: if tooth.name.startswith('2') or tooth.name.startswith('3'): left_teeth.append(tooth) else: right_teeth.append(tooth) print('left teeth') print([tooth.name for tooth in left_teeth]) def get_key(tooth): return tooth.name print([tooth.name for tooth in sorted(left_teeth, key = get_key, reverse = True)]) if len(left_teeth): left_teeth_sorted = [tooth for tooth in sorted(left_teeth, key = get_key, reverse = True)] left_contours = [bpy.data.objects.get(tooth.contour) for tooth in left_teeth_sorted] left_base_ob = left_contours[0] print(left_base_ob.name) left_bridge_me = left_base_ob.to_mesh(context.scene, apply_modifiers = True, settings = 'PREVIEW') left_bridge_ob = bpy.data.objects.new(odc_bridge.name, left_bridge_me) left_bridge_ob.matrix_world = left_base_ob.matrix_world context.scene.objects.link(left_bridge_ob) print(left_bridge_ob.name) for i in range(1, len(left_contours)): print('adding boolean modifier') mod = left_bridge_ob.modifiers.new(str(i), 'BOOLEAN') mod.operation = 'INTERSECT' mod.object = left_contours[i] print(left_contours[i].name) left_final_me = left_bridge_ob.to_mesh(context.scene, apply_modifiers = True, settings = 'PREVIEW') mods = [mod for mod in left_bridge_ob.modifiers] for mod in mods: left_bridge_ob.modifiers.remove(mod) left_bridge_ob.data = left_final_me odc_bridge.bridge = left_bridge_ob.name if len(right_teeth): right_teeth_sorted = [tooth for tooth in sorted(right_teeth, key = get_key, reverse = True)] right_contours = [bpy.data.objects.get(tooth.contour) for tooth in right_teeth_sorted] right_base_ob = right_contours[0] right_bridge_me = right_base_ob.to_mesh(context.scene, apply_modifiers = True, settings = 'PREVIEW') right_bridge_ob = bpy.data.objects.new(odc_bridge.name, right_bridge_me) right_bridge_ob.matrix_world = right_base_ob.matrix_world context.scene.objects.link(right_bridge_ob) for i in range(1, len(right_contours)): mod = right_bridge_ob.modifiers.new(str(i), 'BOOLEAN') mod.operation = 'UNION' mod.object = right_contours[i] right_final_me = right_bridge_ob.to_mesh(context.scene, apply_modifiers = True, settings = 'PREVIEW') mods = [mod for mod in right_bridge_ob.modifiers] for mod in mods: right_bridge_ob.modifiers.remove(mod) right_bridge_ob.data = right_final_me odc_bridge.bridge = right_bridge_ob.name if len(left_teeth) and len(right_teeth): mod = left_bridge_ob.modifiers.new('Midline', 'BOOLEAN') mod.operation = 'DIFFERENCE' mod.object = right_bridge_ob left_bridge_ob.update_tag() context.scene.update() final_me = left_bridge_ob.to_mesh(context.scene, apply_modifiers = True, settings = 'PREVIEW') mods = [mod for mod in left_bridge_ob.modifiers] for mod in mods: left_bridge_ob.modifiers.remove(mod) left_bridge_ob.data = final_me context.scene.objects.unlink(right_bridge_ob) bpy.data.objects.remove(right_bridge_ob) bpy.data.meshes.remove(right_bridge_me) odc_bridge.bridge = left_bridge_ob.name return {'FINISHED'}
def execute(self, context): settings = get_settings() dbg = settings.debug #if bpy.context.mode != 'OBJECT': # bpy.ops.object.mode_set(mode = 'OBJECT') sce = context.scene n = sce.odc_implant_index implant_space = sce.odc_implants[n] implants = odcutils.implant_selection(context) layers_copy = [layer for layer in context.scene.layers] context.scene.layers[0] if implants != []: for implant_space in implants: #check if space already has an implant object. #if so, delete, replace, print warning if implant_space.implant and implant_space.implant in bpy.data.objects: self.report({ 'WARNING' }, "replacing the existing implant with the one you chose") Implant = bpy.data.objects[implant_space.implant] #the origin/location of the implant is it's apex L = Implant.location.copy() world_mx = Implant.matrix_world.copy() #the platorm is the length of the implant above the apex, in the local Z direction #local Z positive is out the apex, soit's negative. #Put the cursor there sce.cursor_location = L - Implant.dimensions[ 2] * world_mx.to_3x3() * Vector((0, 0, 1)) #first get rid of children...so we can use the #parent to find out who the children are if Implant.children: for child in Implant.children: sce.objects.unlink(child) child.user_clear() bpy.data.objects.remove(child) #unlink it from the scene, clear it's users, remove it. sce.objects.unlink(Implant) Implant.user_clear() #remove the object bpy.data.objects.remove(Implant) #TDOD what about the children/hardwares? else: world_mx = Matrix.Identity(4) world_mx[0][3] = sce.cursor_location[0] world_mx[1][3] = sce.cursor_location[1] world_mx[2][3] = sce.cursor_location[2] #is this more memory friendly than listing all objects? current_obs = [ob.name for ob in bpy.data.objects] #link the new implant from the library odcutils.obj_from_lib(settings.imp_lib, self.imp) #this is slightly more robust than trusting we don't have duplicate names. for ob in bpy.data.objects: if ob.name not in current_obs: Implant = ob sce.objects.link(Implant) #this relies on the associated hardware objects having the parent implant #name inside them if self.hardware: current_obs = [ob.name for ob in bpy.data.objects] inc = self.imp + '_' hardware_list = odcutils.obj_list_from_lib( settings.imp_lib, include=inc) print(hardware_list) for ob in hardware_list: odcutils.obj_from_lib(settings.imp_lib, ob) for ob in bpy.data.objects: if ob.name not in current_obs: sce.objects.link(ob) ob.parent = Implant ob.layers[11] = True delta = Implant.dimensions[2] * world_mx.to_3x3() * Vector( (0, 0, 1)) print(delta.length) world_mx[0][3] += delta[0] world_mx[1][3] += delta[1] world_mx[2][3] += delta[2] Implant.matrix_world = world_mx if sce.odc_props.master: Master = bpy.data.objects[sce.odc_props.master] odcutils.parent_in_place(Implant, Master) else: self.report({ 'WARNING' }, 'No Master Model, placing implant anyway, moving objects may not preserve spatial relationships' ) #looks a little redundant, but it ensure if any #duplicates exist our referencing stays accurate Implant.name = implant_space.name + '_' + Implant.name implant_space.implant = Implant.name odcutils.layer_management(sce.odc_implants, debug=dbg) for i, layer in enumerate(layers_copy): context.scene.layers[i] = layer context.scene.layers[11] = True return {'FINISHED'}
def draw(self, context): if not context.scene.odc_props.show_ortho: return sce = bpy.context.scene layout = self.layout addon_prefs = get_settings() row = layout.row() row.label(text="Orthodontics") row.operator( "wm.url_open", text="", icon="INFO").url = "https://github.com/patmo141/odc_public/wiki" layout.label(text='Brackets') row = layout.row() row.prop(addon_prefs, "ortho_lib", text="") row = layout.row() row.prop(addon_prefs, "bracket", text="Bracket") row = layout.row() row.prop(addon_prefs, "bgauge_override", text="") row.prop(addon_prefs, "bracket_gauge", text="") row = layout.row() row.operator("opendental.place_ortho_bracket", text="Place Bracket Guide") row = layout.row() row.operator("opendental.place_static_bracket", text="Place Bracket at Cursor") layout.label(text="Treatment Animation/Setup") row = layout.row() row.operator("opendental.show_max_teeth", text="Upper") row.operator("opendental.show_man_teeth", text="Lower") row = layout.row() row.operator("opendental.show_left_teeth", text="Left") row.operator("opendental.show_right_teeth", text="Right") row = layout.row() col = row.column(align=True) col.operator("opendental.add_bone_roots", "Add roots") if context.mode == "OBJECT": col.operator("opendental.adjust_bone_roots", "Adjust Roots") elif context.mode == 'EDIT_ARMATURE' and context.object.type == 'ARMATURE': col.operator("object.mode_set", 'Finish Roots').mode = 'OBJECT' col.operator("opendental.set_roots_parents", "Set Root Parents") if context.scene.frame_current != 0 and not any( [ob.animation_data for ob in context.scene.objects]): row = layout.row() row.label("Initial position not captured!", icon='ERROR') row = layout.row() row.label('Set Frame to 0 and record initial position') else: row = layout.row() row.operator("opendental.set_treatment_keyframe", "Capture Positions") row = layout.row() row.prop(context.scene, "frame_current", text='') layout.label(text="Physics Simulation Tools") row = layout.row() col = row.column(align=True) col.operator("opendental.add_physics_scene", "Add Physics Scene") col.operator("opendental.physics_sim_setup", "Setup Physics Simulation") col.operator("opendental.add_forcefields", "Add Forcefields") col.operator("opendental.limit_physics_movements", "Limit Movement") col.operator("opendental.unlimit_physics_movements", "Unlimit Movement") col.operator("opendental.lock_physics_movements", "Lock Tooth") col.operator("opendental.unlock_physics_movements", "Unlock Tooth") layout.label(text="Simulation Timeline") row = layout.row() row.operator("screen.animation_play", icon='PLAY') row.prop(context.scene, "frame_current") row.operator("screen.frame_jump", icon='FILE_REFRESH').end = False # Big render button row = layout.row() row.scale_y = 1.5 row.operator("opendental.keep_simulation_results", "Keep Simulation")
def execute(self,context): settings = get_settings() dbg = settings.debug bridge_methods.bridge_from_selection(context, debug=dbg) return {'FINISHED'}
def execute(self, context): settings = get_settings() dbg = settings.debug #if bpy.context.mode != 'OBJECT': # bpy.ops.object.mode_set(mode = 'OBJECT') sce = context.scene implants = odcutils.implant_selection(context) layers_copy = [layer for layer in context.scene.layers] context.scene.layers[0] = True if implants != []: for implant_space in implants: #check if space already has an implant object. #if so, delete, replace, print warning Implant = bpy.data.objects[implant_space.implant] if Implant.rotation_mode != 'QUATERNION': Implant.rotation_mode = 'QUATERNION' Implant.update_tag() sce.update() if bpy.data.objects.get(implant_space.drill): self.report({'WARNING'}, "replacing the existing drill with the one you chose") Sleeve = bpy.data.objects[implant_space.drill] #unlink it from the scene, clear it's users, remove it. sce.objects.unlink(Sleeve) Implant.user_clear() #remove the object bpy.data.objects.remove(Sleeve) current_obs = [ob.name for ob in bpy.data.objects] #link the new implant from the library settings = get_settings() odcutils.obj_from_lib(settings.drill_lib,self.drill) #this is slightly more robust than trusting we don't have duplicate names. for ob in bpy.data.objects: if ob.name not in current_obs: Sleeve = ob sce.objects.link(Sleeve) Sleeve.layers[19] = True mx_w = Implant.matrix_world.copy() #point the right direction Sleeve.rotation_mode = 'QUATERNION' Sleeve.rotation_quaternion = mx_w.to_quaternion() Sleeve.update_tag() context.scene.update() Trans = Sleeve.rotation_quaternion * Vector((0,0,-self.depth)) Sleeve.matrix_world[0][3] = mx_w[0][3] + Trans[0] Sleeve.matrix_world[1][3] = mx_w[1][3] + Trans[1] Sleeve.matrix_world[2][3] = mx_w[2][3] + Trans[2] Sleeve.name = implant_space.name + '_' + Sleeve.name implant_space.drill = Sleeve.name Sleeve.update_tag() context.scene.update() odcutils.parent_in_place(Sleeve, Implant) odcutils.layer_management(sce.odc_implants, debug = dbg) for i, layer in enumerate(layers_copy): context.scene.layers[i] = layer context.scene.layers[19] = True return {'FINISHED'}
def execute(self,context): settings = get_settings() dbg = settings.debug odc_bridge = bridge_methods.active_spanning_restoration(context)[0] sce = context.scene Bridge = bpy.data.objects.get(odc_bridge.bridge) if not Bridge: self.report({'ERROR'}, 'Use "Boolean Bridge" to join individual units to an outer shell first') go_local = False if context.space_data.local_view: go_local = True bpy.ops.view3d.localview() if len(Bridge.modifiers): me = Bridge.to_mesh(context.scene, True, 'PREVIEW') mods = [mod for mod in Bridge.modifiers] for mod in mods: Bridge.modifiers.remove(mod) Bridge.data = me ### Remove the bottom 3 edge loops bridge_bme = bmesh.new() bridge_bme.from_object(Bridge, context.scene) bridge_bme.edges.ensure_lookup_table() bridge_bme.verts.ensure_lookup_table() bridge_bme.faces.ensure_lookup_table() for i in range(0,3): non_man_eds = [ed for ed in bridge_bme.edges if not ed.is_manifold] bmesh.ops.delete(bridge_bme, geom = non_man_eds, context = 2) non_man_vs = [v for v in bridge_bme.verts if not v.is_manifold] bmesh.ops.delete(bridge_bme, geom = non_man_vs, context = 1) bridge_bme.edges.ensure_lookup_table() bridge_bme.verts.ensure_lookup_table() bridge_bme.faces.ensure_lookup_table() bridge_bme.to_mesh(Bridge.data) ### DONE Removing bottom 3 edge loops ### bridge_teeth = [context.scene.odc_teeth[name] for name in odc_bridge.tooth_string.split(sep=":")] intag_objects = [bpy.data.objects.get(tooth.intaglio) for tooth in bridge_teeth if tooth.rest_type != '1'] if None in intag_objects: self.report({'ERROR'}, 'Missing Intaglio for some abutments') bpy.ops.object.select_all(action = 'DESELECT') join_obs = [] for ob in intag_objects: new_me = ob.to_mesh(context.scene, True, 'PREVIEW') new_ob = bpy.data.objects.new(ob.name + ' dupli', new_me) new_ob.matrix_world = ob.matrix_world context.scene.objects.link(new_ob) join_obs.append(new_ob) print(join_obs) bpy.ops.object.select_all(action = 'DESELECT') for ob in join_obs: ob.select = True Bridge.select = True context.scene.objects.active = Bridge Bridge.name += '_solid' bpy.ops.object.join() bridge_bme.free() bridge_bme = bmesh.new() bridge_bme.from_mesh(Bridge.data, True) bridge_bme.edges.ensure_lookup_table() bridge_bme.verts.ensure_lookup_table() bridge_bme.faces.ensure_lookup_table() non_man = [ed for ed in bridge_bme.edges if not ed.is_manifold] bmesh.ops.bridge_loops(bridge_bme, edges = non_man, use_pairs = True) #non_man = [ed.index for ed in bridge_bme.edges if not ed.is_manifold] #loops = mesh_cut.edge_loops_from_bmedges(bridge_bme, non_man) #for loop in loops: #for i in loop: #bridge_bme.verts[i].select_set(True) bmesh.ops.recalc_face_normals(bridge_bme, faces = bridge_bme.faces[:]) bridge_bme.to_mesh(Bridge.data) #bridge_bme.transform(Bridge.matrix_world) #new_me = bpy.data.meshes.new(odc_bridge.name + '_solid') #bridge_bme.to_mesh(new_me) bridge_bme.free() #new_ob = bpy.data.objects.new(odc_bridge.name + '_solid', new_me) #context.scene.objects.link(new_ob) if go_local: bpy.ops.view3d.localview() return {'FINISHED'}