This script aligns a long bone to the world coordinate system based on 5 landmark points: an origin, proximal, distal, left and right point.
#This script aligns a long bone to the world coordinate system based on 5 landmark points: an origin, proximal, distal, left and right point. The distal-proximal direction defines the Z direction. The X direction is defined based on the right-left direction ( lateral-medial or medial-lateral, depending on whether it's the right or the left side). #Input: bone_name: string with name of bone part # orig_name: string with name of origin point # pt_prox_name: string with name of proximal point # pt_dist_name: string with name of distal point # pt_right_name: string with name of right point # pt_left_name: string with name of left point # Output: repositioned long bone along with input landmarks and calculated landmarks (x axis, # z axis, projected point, etc). # Author: Julien Deckx (Materialise) # Version: 1.0. (June 21 2018) import trimatic def AlignLongBone(bone_name, orig_name, pt_prox_name, pt_dist_name, pt_right_name, pt_left_name): # find all entities bone = trimatic.find_part(bone_name) orig = trimatic.find_point(orig_name) pt_prox = trimatic.find_point(pt_prox_name) pt_dist = trimatic.find_point(pt_dist_name) pt_left = trimatic.find_point(pt_left_name) pt_right = trimatic.find_point(pt_right_name) # the z direction is defined as distal to proximal z_line = trimatic.create_line(pt_dist, pt_prox) z_line.name = "z_line" # create a plane perpendicular to z, with pt_right as origin z_plane = trimatic.analyze.create_plane_normal_origin(origin=pt_right, normal=z_line.direction) z_plane.name = "z_plane" # extend z_plane and convert to part to allow projection of pt_left lr_distance = trimatic.measure.create_distance_measurement(pt_left, pt_right) z_plane.delta_x = lr_distance.value+1 z_plane.delta_y = lr_distance.value+1 z_plane_part = trimatic.convert_analytical_primitive_to_part(z_plane) # project pt_left in z_plane (try both +z and -z direction) plusZ_direction = z_line.direction minZ_direction = tuple([-x for x in plusZ_direction]) try: pt_left_proj = trimatic.project_point(direction = plusZ_direction, parts = z_plane_part, point_to_project = pt_left) except: pt_left_proj = trimatic.project_point(direction = minZ_direction, parts = z_plane_part, point_to_project = pt_left) pt_left_proj = trimatic.create_point(pt_left_proj) pt_left_proj.name = "pt_left_proj" # the direction is defined as the projection of the line from right to left x_line = trimatic.create_line(pt_right, pt_left_proj) # create planes for plane-to-plane align orig_x = trimatic.translate(entities = orig, translation_vector = x_line.direction, number_of_copies = 1) orig_z = trimatic.translate(entities = orig, translation_vector = z_line.direction, number_of_copies = 1) plane_moving = trimatic.create_plane_3_points(orig, orig_x, orig_z) plane_fixed = trimatic.create_plane_3_points((0,0,0), (1,0,0), (0,0,1)) trimatic.delete(orig_x) trimatic.delete(orig_z) # plane-to-plane align trimatic.plane_to_plane_align(plane_on_fixed_entity=plane_fixed,plane_on_moving_entity=plane_moving,move_along_entities=(bone, pt_prox, pt_dist, pt_left, pt_right, orig, z_line,z_plane,lr_distance, pt_left_proj, x_line),coincident=True)