def update_spline(self, segment_number=50, fine_flag=False): spline_points_tem = [] for i in self.tooth_list: if i in self.existing_tooth_list: idx = np.where(self.existing_tooth_list == i)[0][0] points_tem = self.existing_tooth[idx].centroid elif i in self.missing_tooth_list: idx = np.where(self.missing_tooth_list == i)[0][0] points_tem = self.missing_tooth[idx].centroid spline_points_tem.append(points_tem) self.spline_points = np.asarray(spline_points_tem) #self.spline_points = spline_points_tem cylindrical_center = (spline_points_tem[0] + spline_points_tem[-1]) / 2 self.spline_points_cylindrical = coordinates.convert_cylindrical( spline_points_tem, cylindrical_center) self.spline_points_cylindrical_center = cylindrical_center missing_spline_points_tem = [] for tooth in self.missing_tooth: missing_spline_points_tem.append(tooth.centroid) self.missing_spline_points = np.asarray(missing_spline_points_tem) del missing_spline_points_tem if fine_flag is True: self.spline_points_fine = fit_spline_and_split_fxt( self.spline_points, self.missing_spline_points, segment_number) self.spline_points_fine_cylindrical = coordinates.convert_cylindrical( self.spline_points_fine, self.spline_points_cylindrical_center) self.spline_points_fine_cylindrical_mid_points = check_boundary( self.spline_points_fine_cylindrical[:, 1]) del spline_points_tem, cylindrical_center
def __init__(self, stl_raw_points, defined_targets, defined_center=[0, 0, 0]): self.all_points_cartesian = np.asarray(stl_raw_points) self.coordinate_center = defined_center # convert to cylindrical coordinates [r, theta, z] self.all_points_cylindrical = coordinates.convert_cylindrical( self.all_points_cartesian, defined_center) self.angle_range = [ np.min(self.all_points_cylindrical[:, 1] * 180 / np.pi), np.max(self.all_points_cylindrical[:, 1] * 180 / np.pi) ] self.radius_range = [ np.min(self.all_points_cylindrical[:, 0]), np.max(self.all_points_cylindrical[:, 0]) ] self.height_range = [ np.min(self.all_points_cylindrical[:, 2]), np.max(self.all_points_cylindrical[:, 2]) ] # define targets self.target_origins_cartesian = np.asarray(defined_targets) self.target_origins_cylindrical = coordinates.convert_cylindrical( self.target_origins_cartesian, defined_center) # define multiple regions based on cylindrical coordinate angles (theta) if np.ndim(self.target_origins_cylindrical) == 1: self.target_angle_range = self.angle_range else: self.target_angle_range = [] self.target_angle_range.append(self.angle_range[0]) for i in range(len(self.target_origins_cylindrical[:, 1]) - 1): self.target_angle_range.append( (self.target_origins_cylindrical[i, 1] + self.target_origins_cylindrical[i + 1, 1]) / 2 * 180 / np.pi) self.target_angle_range.append(self.angle_range[1]) self.target_radius_range = self.radius_range self.target_height_range = self.height_range self.all_regions_cartesion = [] self.all_regions_cylindrical = [] self.check_angle_range = [] self.check_radius_range = [] self.check_height_range = [] self.n_fiducial = 0 self.n_target = len(self.target_origins_cartesian) self.default_fiducial = [] self.surface_points = []
def update_spline(self, segment_number=50, fine_flag = False): spline_points_tem = [] for tooth in self.existing_tooth: spline_points_tem.append(tooth.centroid) self.spline_points = np.asarray(spline_points_tem) cylindrical_center = (spline_points_tem[0] + spline_points_tem[-1])/2 self.spline_points_cylindrical = coordinates.convert_cylindrical(spline_points_tem, cylindrical_center) self.spline_points_cylindrical_center = cylindrical_center if fine_flag is True: self.spline_points_fine = fit_spline_and_split(self.spline_points, segment_number) self.spline_points_fine_cylindrical = coordinates.convert_cylindrical(self.spline_points_fine, self.spline_points_cylindrical_center) self.spline_points_fine_cylindrical_mid_points = check_boundary(self.spline_points_fine_cylindrical[:,1]) del spline_points_tem, cylindrical_center
def update_spline(self, segment_number=50, fine_flag=False): spline_points_tem = self.pyramid_fiducial_points self.spline_points = np.asarray(spline_points_tem) cylindrical_center = (spline_points_tem[0] + spline_points_tem[-1]) / 2 #cylindrical_center = np.array([5, -16, 233]) self.spline_points_cylindrical = coordinates.convert_cylindrical(spline_points_tem, cylindrical_center) self.spline_points_cylindrical_center = cylindrical_center if fine_flag is True: self.spline_points_fine = fit_spline_and_split_splint(self.spline_points, segment_number, self.spline_fitting_base_axis) self.spline_points_fine_cylindrical = coordinates.convert_cylindrical(self.spline_points_fine, self.spline_points_cylindrical_center) self.spline_points_fine_cylindrical_mid_points = check_boundary(self.spline_points_fine_cylindrical[:, 1]) del spline_points_tem, cylindrical_center
def update_guided_spline(self, segment_number=50, fine_flag=False): for i in self.tooth_list: if i in self.existing_tooth_list: idx = np.where(self.existing_tooth_list == i)[0][0] idx2 = np.where(self.tooth_list == i)[0][0] #print('i is', i) #print('idx is',idx) #print('idx2 is', idx2) #print('tooth list is', self.existing_tooth_list) #print('number of spline points is', np.shape(self.spline_points)) #print('spline points are', self.spline_points) #print('shape of missing spline points is', np.shape(self.missing_spline_points)) #print('missing spline points are', self.missing_spline_points) #print('soline_points[idx] is', self.spline_points[idx]) self.spline_guided_points[idx2] = self.spline_points[idx] elif i in self.missing_tooth_list: idx = np.where(self.missing_tooth_list == i)[0][0] idx2 = np.where(self.tooth_list == i)[0][0] self.spline_guided_points[idx2] = self.missing_spline_points[ idx] if fine_flag is True: points_tem = np.asarray(self.spline_guided_points) self.spline_guided_points_fine = fit_spline_and_split( points_tem, segment_number) self.spline_guided_points_fine_cylindrical = coordinates.convert_cylindrical( self.spline_guided_points_fine, self.spline_points_cylindrical_center) self.spline_guided_points_fine_cylindrical_mid_points = check_boundary( self.spline_guided_points_fine_cylindrical[:, 1]) del points_tem
def update_ignore_boundary(self, ignore_tooth_list): min_theta = [] max_theta = [] for i in ignore_tooth_list: points_tem = self.get_tooth(i).points points_tem_cylindrical = coordinates.convert_cylindrical(points_tem, self.spline_points_cylindrical_center) min_theta.append(np.min(points_tem_cylindrical[:,1])) max_theta.append(np.max(points_tem_cylindrical[:,1])) self.ignore_boundary[0] = np.min(np.asarray(min_theta)) self.ignore_boundary[1] = np.max(np.asarray(max_theta))
def update_virtual_guided_spline(self, segment_number=50, fine_flag = False): for i in self.tooth_list: if i in self.existing_tooth_list: idx = np.where(self.existing_tooth_list == i)[0][0] idx2 = np.where(self.tooth_list == i)[0][0] self.spline_virtual_guided_points[idx2] = self.spline_points[idx] elif i in self.missing_tooth_list: idx = np.where(self.missing_tooth_list == i)[0][0] idx2 = np.where(self.tooth_list == i)[0][0] self.spline_virtual_guided_points[idx2] = self.spline_virtual_points[idx] if fine_flag is True: points_tem = np.asarray(self.spline_virtual_guided_points) fig=plt.figure() plt.scatter(points_tem[:,0],points_tem[:,1]) plt.show() self.spline_virtual_guided_points_fine = fit_spline_and_split(points_tem, segment_number) self.spline_virtual_guided_points_fine_cylindrical = coordinates.convert_cylindrical(self.spline_virtual_guided_points_fine, self.spline_points_cylindrical_center) self.spline_virtual_guided_points_fine_cylindrical_mid_points = check_boundary(self.spline_virtual_guided_points_fine_cylindrical[:,1])
splint_ground.update_spline(fine_flag=True) splint_ios.update_spline(fine_flag=True) #fig = plt.figure() #plt.scatter(splint_ground.spline_points_fine[:, 0], splint_ground.spline_points_fine[:, 1], label='ground') #plt.scatter(splint_ios.spline_points_fine[:, 0], splint_ios.spline_points_fine[:, 1], label='ios') #plt.legend() #plt.show() # perform splint correction displacement_splint = np.asarray(splint_ground.spline_points_fine) - np.asarray(splint_ios.spline_points_fine) for i in arch_ios.existing_tooth_list: points_tem = arch_ios.get_tooth(i).points points_tem_transformed = transpose_pc(points_tem, modify_matrix) points_tem_transformed_cylindrical = coordinates.convert_cylindrical(points_tem_transformed, splint_ground.spline_points_fine_cylindrical_mid_points) points_tem_corrected_transformed = sc.displacement(points_tem_transformed, points_tem_transformed_cylindrical, splint_ground.spline_points_fine_cylindrical_mid_points, displacement_splint) #points_tem_corrected = transpose_pc(points_tem_corrected_transformed, np.linalg.inv(modify_matrix)) points_tem_corrected = transpose_pc(points_tem_corrected_transformed, modify_matrix2) tooth_feature_splint_correction = fe.ToothFeature(points_tem_corrected, i, 'IOS', 'IOS') arch_ios_splint_correction.add_tooth(i, tooth_feature_splint_correction) #target_points_transfromed = transpose_pc(arch_ios.target_points, modify_matrix) target_points_transfromed = transpose_pc(splint_fiducial_ios[20:, :], modify_matrix) target_points_transfromed_cylindrical = coordinates.convert_cylindrical(target_points_transfromed, splint_ground.spline_points_fine_cylindrical_mid_points) target_points_corrected_transformed = sc.displacement(target_points_transfromed, target_points_transfromed_cylindrical, splint_ground.spline_points_fine_cylindrical_mid_points, displacement_splint) #target_points_corrected = transpose_pc(target_points_corrected_transformed, np.linalg.inv(modify_matrix)) target_points_corrected = transpose_pc(target_points_corrected_transformed, modify_matrix2) arch_ios_splint_correction.add_target(target_points_corrected) print('original target points are', splint_fiducial_ios[20:, :]) print('target_points corrected are', target_points_corrected)
del points_rigid_tem, tooth_feature_rigid_tem, points_virtual_tem, tooth_feature_virtual_tem # Update spline points arch_ct_in_ios.update_spline(fine_flag=True) arch_ct_to_ios.update_spline(fine_flag=True) print('displacement check', arch_ct_to_ios.spline_points - arch_ct_in_ios.spline_points) print('original spline is', arch_ct_in_ios.spline_points) print('target spline is', arch_ct_to_ios.spline_points) displacement = arch_ct_to_ios.spline_points_fine - arch_ct_in_ios.spline_points_fine corrected_spline = sc.displacement(arch_ct_in_ios.spline_points, arch_ct_in_ios.spline_points_cylindrical, arch_ct_in_ios.spline_points_fine_cylindrical_mid_points, displacement) print('corrected spline is', corrected_spline) for i in arch_ct_to_ios.tooth_list: candidate_tooth = arch_ct_in_ios.get_tooth(i).points candidate_tooth_cylindrical = coordinates.convert_cylindrical(candidate_tooth, arch_ct_in_ios.spline_points_cylindrical_center) corrected_tooth = sc.displacement(candidate_tooth, candidate_tooth_cylindrical,arch_ct_in_ios.spline_points_fine_cylindrical_mid_points, displacement) corrected_tooth_feature = fe.ToothFeature(corrected_tooth, i, 'CT', 'IOS') arch_ct_in_ios_curvilinear_correction.add_tooth(i, corrected_tooth_feature) candidate2_tooth = arch_ios.get_tooth(i).points candidate2_tooth_cylindrical = coordinates.convert_cylindrical(candidate2_tooth, arch_ct_in_ios.spline_points_cylindrical_center) corrected2_tooth = sc.displacement(candidate2_tooth, candidate2_tooth_cylindrical,arch_ct_in_ios.spline_points_fine_cylindrical_mid_points, displacement) corrected2_tooth_feature = fe.ToothFeature(corrected2_tooth, i, 'IOS', 'IOS') arch_ios_curvilinear_correction.add_tooth(i, corrected2_tooth_feature) del candidate_tooth, candidate2_tooth arch_ios_curvilinear_correction.update_spline() arch_ct_in_ios_curvilinear_correction.update_spline()
# points_tem_transformed_cylindrical = coordinates.convert_cylindrical(points_tem_transformed, splint_ground.spline_points_fine_cylindrical_mid_points) # points_tem_corrected = sc.displacement(points_tem_transformed, points_tem_transformed_cylindrical, splint_ground.spline_points_fine_cylindrical_mid_points, displacement_splint) # tooth_feature_splint_correction = fe.ToothFeature(points_tem_corrected, i, 'solidworks', 'IOS') # arch_ios_splint_correction.add_tooth(i, tooth_feature_splint_correction) # Deform stl image and save to new stl your_mesh = mesh.Mesh.from_file( "G:\\My Drive\\Project\\IntraOral Scanner Registration\\IOS_scan_raw_data\\IOS Splint\\demo_scan\\2nd_splint\\full_arch2\\5272021-demo_picture_full_arch-lowerjaw.stl" ) original_stl_points = np.copy(your_mesh.points) new_stl_points = np.copy(your_mesh.points) for j in range(3): points_tem = np.copy(original_stl_points[:, 3 * j:3 * (j + 1)]) points_tem_transformed = transpose_pc(points_tem, trans_rigid0) points_tem_transformed_cylindrical = coordinates.convert_cylindrical( points_tem_transformed, splint_ground.spline_points_fine_cylindrical_mid_points) points_tem_corrected = sc.displacement( points_tem_transformed, points_tem_transformed_cylindrical, splint_ground.spline_points_fine_cylindrical_mid_points, displacement_splint) new_stl_points[:, 3 * j:3 * (j + 1)] = points_tem_corrected for i in range(np.shape(new_stl_points)[0]): your_mesh.points[i, :] = new_stl_points[i, :] print('original_stl_points 0 are', original_stl_points[0, :]) print('new_stl_points 0 are', new_stl_points[0, :]) print('your_mesh points 0 are', your_mesh.points[0, :]) your_mesh.save( "G:\\My Drive\\Project\\IntraOral Scanner Registration\\IOS_scan_raw_data\\IOS Splint\\demo_scan\\2nd_splint\\full_arch2\\deformed.stl" )
if __name__ == "__main__": stl_base = "G:\\My Drive\\Project\\HW-9232 Registration method for edentulous\\Edentulous registration error analysis\\Typodont_scan\\Edentulous_scan\\" all_regions = [] file = stl_base + 'full_arch.txt' if os.path.isfile(file): print('read txt') full_region = Yomiread.read_csv(file, 3, -1) else: stl_file = 'full_arch.stl' print('read stl') full_region = region_points.read_regions(stl_base + stl_file, voxel_size=2.0) Yomiwrite.write_csv_matrix(stl_base + 'full_arch.txt', full_region) # convert to cylindrical coordinates [r, theta, z] full_region_cylinder = coordinates.convert_cylindrical( full_region, [0, 0, 0]) print('point are', full_region_cylinder) # generate target regions # angle [90:125:160] # radius 12~16 (inner) 16~23 (occlusal) 23~39 (outer) # z [10:19.6:24] ANGLE_RANGE = [90, 160] RADIUS_RANGE = [16, 23] HEIGHT_RANGE = [5, 34] D_ANGLE = 2 D_HEIGHT = 1 D_RADIUS = 1 N_REGION = 2 * D_ANGLE * D_HEIGHT + D_ANGLE
splint_geometry.update_spline(fine_flag=True) splint_ios.update_spline(fine_flag=True) #print('splint_fine points are', splint_geometry.spline_points_fine) #print('spline boundary is', splint_geometry.spline_points_fine_cylindrical_mid_points) print('ground transformed ') displacement = np.asarray(splint_geometry.spline_points_fine) - np.asarray( splint_ios.spline_points_fine) for i in splint_ios.pyramid_number_list: point = splint_ios.get_pyramid(i) print('i is', i) print('point is', point) point_cylindrical = coordinates.convert_cylindrical( point, splint_ios.spline_points_cylindrical_center) #point_cylindrical = coordinates.convert_cylindrical(point, center_2) point_moved = sc.displacement_single_point( point, point_cylindrical, splint_ios.spline_points_fine_cylindrical_mid_points, displacement) print('moved point is', point_moved) print('target point is', splint_geometry.get_pyramid(i)) splint_ios_corrected.add_pyramid(i, point_moved) diff_before = np.asarray(splint_geometry.pyramid_points) - np.asarray( splint_ios.pyramid_points) diff_after = np.asarray(splint_geometry.pyramid_points) - np.asarray( splint_ios_corrected.pyramid_points) diff_before_norm = np.linalg.norm(diff_before, axis=1) diff_after_norm = np.linalg.norm(diff_after, axis=1) diff_before_norm_2d = np.linalg.norm(diff_before[:, 0:2], axis=1)