Fracture plate (3-matic 14.0)

This tutorial shows how to semi-automatically design a patient specific finger plate. The workflow focuses on designing a plate based on the position of screws in 3D. This tutorial will help in understanding workflows that are part of a design process. The project hand_plate.mxp that is located in the 3-matic installation folder …\DemoFiles.

import os
import trimatic
from tkinter import *
import numpy

# Constants used for the script
ORIGINAL_FILES = ["screw","fingerbone"]
TEMP = "temp"
WRAPPED_TEMP = "wrapped_temp"
PLATE = "Hand plate"
FINAL_PLATE = "Final Hand plate"
SCREWS = ["Screw 1", "Screw 2", "Screw 3", "Screw 4"]
MESSAGE_1 = "Create the profile of the fracture plate and click OK. The script will continue..."
MESSAGE_2  = "Position the 4 screws of the plate. Click OK and start indicating the desired locations..."

# Open project and select the best view.
application_exe = trimatic.get_application_path()
application_path = os.path.dirname(application_exe)
project_filename = application_path + "/DemoFiles/hand_plate.mxp"
finger_bone = trimatic.find_part(ORIGINAL_FILES[1])
assert finger_bone

# Calculate the center of  gravity and inertia axes to ensure that create a plane.
finger_bone = trimatic.find_part(ORIGINAL_FILES[1])
inertia = trimatic.compute_inertia_axes(finger_bone)
finger_bone_zx_pl = trimatic.create_plane_normal_origin(normal=inertia[1],origin=inertia[0])
finger_bone_zx_pl.visible = False
sketch = trimatic.create_sketch(planes=finger_bone_zx_pl)

# Move the plane and the sketch above the bone
assembly = [finger_bone_zx_pl,sketch]
translation_vector = (0,inertia[2][1]+10,0)

# Importing the references of the surfaces onto the sketch.
for surf in finger_bone.get_surfaces():
	trimatic.import_outline(sketch,surf, construction=True)

# UI for the creation of the curve profile. 

trimatic.message_box(MESSAGE_1,'Sketch profile',False )

# Create a temporary part and hide the sketch
finger_bone.visible = False
temp_part = trimatic.copy_to_part(finger_bone.get_surfaces()) = TEMP
temp_part.visible = False
sketch.visible = False

# Wrap the temporary part
wrapped_temp = trimatic.wrap(entities=temp_part,gap_closing_distance=0.4,smallest_detail=0.2) = WRAPPED_TEMP

#project curve to part and split to surfaces
direc = (0,-translation_vector[1],0)

# Find and pick the smallest surface which is the plate
surfs = wrapped_temp.get_surfaces()
plate_surf = surfs[0]
if plate_surf.area > surfs[1].area:
	plate_surf = surfs[1]

#From surface to Part for the plate
plate_part = trimatic.copy_to_part(plate_surf)
plate_surf = plate_part.get_surfaces()[0]
trimatic.move_surface(plate_surf,direction=None,distance=0.5) = PLATE

#Delete temp parts
finger_bone.visible = True

# UI for the indicating scews
trimatic.message_box(MESSAGE_2,'Indicate screws',False )

points = [trimatic.indicate_coordinate() for i in range(len(SCREWS))]
planes = [0 for i in range(len(points))]
po = 0
for p in points:
	duplicatebone = trimatic.duplicate(plate_part)
	spherepoint = trimatic.create_sphere_part(p,1)
	inters = trimatic.boolean_intersection((duplicatebone,spherepoint))
	allsurfaces = inters.find_surfaces('Surface')
	areas = [0 for i in range(len(allsurfaces))]
	a = 0
	for s in allsurfaces:
		areas[a] = s.area
		a = a+1
	ms = numpy.argmax(areas)
	planes[po] = trimatic.create_plane_fit(allsurfaces[ms])
	# Check necessary whether Z-axis of plane points in right direction
	# by comparing direction from point to center of gravity with Z-axis direction
	gr = trimatic.compute_center_of_gravity(inters)
	sp = numpy.inner(numpy.subtract(p,gr),planes[po].object_coordinate_system.z_axis)
	if sp < 0:
	po = po + 1
# Place screws with plane to plane align
screws = [0 for i in range(len(points))]
screws2 = [0 for i in range(len(points))]
sc = 0
screw = trimatic.find_part(ORIGINAL_FILES[0])
screw.visible = False

for p in points:
	xyplanescrew = trimatic.create_plane_normal_origin(screw.object_coordinate_system.z_axis,screw.object_coordinate_system.origin)
	duplicatescrew = trimatic.duplicate(screw)
	screws[sc] = duplicatescrew
	screws2[sc] = trimatic.duplicate(screws[sc])
	planes[sc].visible = False
	screws[sc].visible = False
	sc = sc + 1

#Move a bit the screws to appear better
for sc in screws:
	trvector = sc.object_coordinate_system.z_axis #only 1 mm required
allscrews = trimatic.boolean_union(screws)
screws_4_subtraction = trimatic.boolean_union(screws2)

#create holes in the plate
final_plate = trimatic.boolean_subtraction(plate_part,screws_4_subtraction)  = FINAL_PLATE
wrapped_temp.visible = False