Mercurial > repos > mb2013 > nepenthes_3dpca
comparison Rotate.py @ 17:27af4a7b1e1d draft
Uploaded
author | mb2013 |
---|---|
date | Tue, 20 May 2014 03:29:26 -0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
16:fea55f4efcce | 17:27af4a7b1e1d |
---|---|
1 # Rotate ply file to normalized position | |
2 # based at points on symmetry axis | |
3 # MB | |
4 | |
5 import math | |
6 from math import * | |
7 import sys | |
8 import numpy | |
9 | |
10 # Main function | |
11 def main(): | |
12 # input user .ply file | |
13 name_file_ply = sys.argv[1] | |
14 # input user symmetry points file | |
15 sym_points_file = sys.argv[2] | |
16 | |
17 # to function 'extracting header', return header features | |
18 var_header,var_vertex_nm,var_face_nm, var_col = extracting_header(name_file_ply) | |
19 | |
20 # to function 'extracting symmetry points', return symmetry points and list with new vertex | |
21 listsym,listtotal_vertex = extracting_symmetry_points(sym_points_file) | |
22 | |
23 # to function 'extracting coordiantes', return list vertex and colors | |
24 listtotal_vertex, listtotal_colors = extracting_coordinates(name_file_ply, | |
25 var_header,var_vertex_nm,var_face_nm, | |
26 listtotal_vertex, var_col) | |
27 # to function 'shift to zero' | |
28 shift_to_zero(listsym,listtotal_vertex) | |
29 | |
30 # to function 'write ply file' | |
31 write_ply_file(name_file_ply, var_header,var_vertex_nm,var_face_nm, | |
32 listtotal_colors, listtotal_vertex) | |
33 | |
34 | |
35 # Function to extract all the values of the header of the ply file | |
36 def extracting_header(name_file_ply): | |
37 file_ply = open(name_file_ply) # open ply file | |
38 var_col = 0 # color variable | |
39 count = 0 # counter | |
40 | |
41 # for the first lines of the ply file | |
42 for line in range(0, 40): | |
43 readheader = file_ply.readline().strip().split() | |
44 if len(readheader) != 0: | |
45 if readheader[0] == 'end_header': | |
46 var_header = count | |
47 | |
48 # If there are colors in the ply file | |
49 if 'red' in readheader: | |
50 var_col += 1 | |
51 if 'blue' in readheader: | |
52 var_col += 1 | |
53 if 'green' in readheader: | |
54 var_col += 1 | |
55 | |
56 # extracting number of vertexen | |
57 if readheader[0] == "element" and readheader[1] == "vertex": | |
58 var_vertex_nm = readheader[2] | |
59 | |
60 # extracting number of faces | |
61 if readheader[0] == "element" and readheader[1] == "face": | |
62 var_face_nm = readheader[2] | |
63 count += 1 | |
64 else: | |
65 continue | |
66 | |
67 file_ply.close() # closing ply file | |
68 return var_header, var_vertex_nm,var_face_nm, var_col # return values to main | |
69 | |
70 # Function for extracting the values of the symmetry points file | |
71 def extracting_symmetry_points(sym_points_file): | |
72 sympoints = open(sym_points_file) # open symmetry file | |
73 symlines = sympoints.readlines() # read all the lines of file | |
74 listsym = [] # symmetry points | |
75 listtotal_vertex = [] # vertexen | |
76 # every line in the sym file | |
77 for sym in range(0,len(symlines)): | |
78 symline_1 = symlines[sym].strip().split() | |
79 listsym.append(symlines[sym].strip().split()) #add symmetry points | |
80 listtotal_vertex.append(symlines[sym].strip().split()) # add symmetry points | |
81 | |
82 sympoints.close() # close symmetry file | |
83 return listsym,listtotal_vertex # return symmetry points list and vertex list | |
84 | |
85 | |
86 # Function to extract the coordinates of the ply file | |
87 def extracting_coordinates(name_file_ply, var_header,var_vertex_nm,var_face_nm, listtotal_vertex, var_col): | |
88 file1 = open(name_file_ply) # open ply file | |
89 | |
90 sub_list = [] #sublist coordinates | |
91 listtotal_colors = [] # color list | |
92 sub_colors = [] # sublist color | |
93 | |
94 # coordinates of ply file to list | |
95 for coordinates_ln in range(0, (int(var_header) + int(var_vertex_nm) + int(var_face_nm) + 1)): | |
96 line = file1.readline().strip().split() | |
97 if (int(var_header) < coordinates_ln < (int(var_vertex_nm)+ int(var_header)+1)): | |
98 rayx = sub_list.append(line[0]) | |
99 rayy = sub_list.append(line[1]) | |
100 rayz = sub_list.append(line[2]) | |
101 listtotal_vertex.append(sub_list) #x y z coordinates to list | |
102 sub_list = [] | |
103 if var_col != 0: #if color code is not 0 | |
104 color_x = sub_colors.append(line[3]) | |
105 color_y = sub_colors.append(line[4]) | |
106 color_z = sub_colors.append(line[5]) | |
107 listtotal_colors.append(sub_colors) #colors to list | |
108 sub_colors = [] | |
109 | |
110 return listtotal_vertex, listtotal_colors # return coordinates (vertexen) and color lists | |
111 | |
112 | |
113 # Function to calculate the values in the Z rotation matrix | |
114 def Rz_matrix(z_angle): # Rz rotation matrix | |
115 return [[cos(math.radians(z_angle)), -sin(math.radians(z_angle)), 0.0],[sin(math.radians(z_angle)),cos(math.radians(z_angle)),0.0],[0.0, 0.0, 1.0]] | |
116 | |
117 # Function to calculate the new coordinates rotated with Z rotation matrix | |
118 def Z_rotation(point2, z_angle): # multiplication rotation matrix and coordinates | |
119 r_z = Rz_matrix(z_angle) | |
120 rotated_z = [] | |
121 for i in range(3): | |
122 rotated_z.append((sum([r_z[i][j] * point2[j] for j in range(3)]))) | |
123 return rotated_z | |
124 | |
125 # Function to calculate the values in the X rotation matrix | |
126 def Rx_matrix(x_angle): #rotation matrix x-axis | |
127 return [[1, 0, 0],[0,cos(math.radians(x_angle)),-sin(math.radians(x_angle))],[0,sin(math.radians(x_angle)),cos(math.radians(x_angle))]] | |
128 | |
129 # Function to calculate the new coordinates rotated with X rotation matrix | |
130 def X_rotation(point3, x_angle): #multiplication rotation matrix and coordinates | |
131 r_x = Rx_matrix(x_angle) | |
132 rotated_x = [] | |
133 for i in range(3): | |
134 rotated_x.append((sum([r_x[i][j] * point3[j] for j in range(3)]))) | |
135 return rotated_x | |
136 | |
137 # Function to calculate the values in the Y rotation matrix | |
138 def Ry_matrix(y_angle): # Ry rotation matrix | |
139 return [[cos(math.radians(y_angle)), 0.0, sin(math.radians(y_angle))],[0.0, 1.0, 0.0],[-sin(math.radians(y_angle)),0.0, cos(math.radians(y_angle))]] | |
140 | |
141 # Function to calculate the new coordinates rotated with Y rotation matrix | |
142 def Y_rotation(point4, y_angle): #multiplication rotation matrix and coordinates | |
143 r_y = Ry_matrix(y_angle) | |
144 rotated_y = [] | |
145 for i in range(3): | |
146 rotated_y.append((sum([r_y[i][j] * point4[j] for j in range(3)]))) | |
147 return rotated_y | |
148 | |
149 #Function to shift the object to the zeropoint | |
150 def shift_to_zero(listsym, listtotal_vertex): | |
151 sym3 = listsym[2] | |
152 zeropoint = sym3 | |
153 list2 = [] # sublist coordinates | |
154 listdata3 = [] # new coordinates | |
155 # every coordinate minus the sym3 coordinates | |
156 for vertex in range(0,len(listtotal_vertex)): | |
157 list2.append(float(listtotal_vertex[vertex][0]) - float(zeropoint[0])) | |
158 list2.append(float(listtotal_vertex[vertex][1]) - float(zeropoint[1])) | |
159 list2.append(float(listtotal_vertex[vertex][2]) - float(zeropoint[2])) | |
160 listdata3.append(list2) # add new coordinates to list | |
161 list2 = [] | |
162 | |
163 # to function 'rotate z axis' | |
164 rotate_z_axis(listdata3) | |
165 | |
166 # Function for rotating the object around z axis | |
167 def rotate_z_axis(listdata3): | |
168 # If object is upside down, 180 degrees rotation around the Z axis is needed. | |
169 listdatatemp = [] | |
170 # check if object is upside down | |
171 if listdata3[0][1] < listdata3[2][1]: | |
172 angle = 180 | |
173 # rotate 180 degrees. | |
174 for coordinates in range(0,len(listdata3)): | |
175 listdatatemp.append(Z_rotation(listdata3[coordinates], angle)) | |
176 listdata3 = listdatatemp # new coordinates | |
177 | |
178 | |
179 # calculate angle rotation z | |
180 len_z_a = listdata3[0][0] - listdata3[2][0] | |
181 len_z_b = listdata3[0][1] - listdata3[2][1] | |
182 z_angle = (math.degrees(math.atan(len_z_a/len_z_b))) | |
183 | |
184 # calculate new coordinates with rotation matrix of Z | |
185 listdata4 = [] | |
186 for coordinates in range(0, len(listdata3)): | |
187 listdata4.append(Z_rotation(listdata3[coordinates], z_angle)) # add new coordinates to list | |
188 listdata3 = [] | |
189 | |
190 # to function 'rotate x axis' | |
191 rotate_x_axis(listdata4) | |
192 | |
193 # Function for rotating the object around x axis | |
194 def rotate_x_axis(listdata4): | |
195 #calculate angle rotation x | |
196 len_x_a = listdata4[0][2] - listdata4[2][0] | |
197 len_x_b = listdata4[0][1] - listdata4[2][0] | |
198 x_angle = -(math.degrees(math.atan(len_x_a/len_x_b))) | |
199 | |
200 # calculate new coordinates with rotation matrix of X | |
201 listdata5 = [] | |
202 for coordinates in range(0, len(listdata4)): | |
203 listdata5.append(X_rotation(listdata4[coordinates], x_angle)) # add new coordinates to list | |
204 listdata4 = [] | |
205 | |
206 # to function 'rotate y axis' | |
207 rotate_y_axis(listdata5) | |
208 | |
209 # Function for rotating the object around y axis | |
210 def rotate_y_axis(listdata5): | |
211 #calculate angle rotation y | |
212 len_y_a = (listdata5[1][0] - listdata5[2][0]) | |
213 len_y_b = (listdata5[1][2] - listdata5[2][2]) | |
214 y_angle = -(math.degrees(math.atan(len_y_a/len_y_b))) | |
215 | |
216 # calculate new coordinates with rotation matrix of Y | |
217 listdata6 = [] | |
218 for coordinates in range(0, len(listdata5)): | |
219 listdata6.append(Y_rotation(listdata5[coordinates], y_angle)) | |
220 | |
221 listdata5 = [] | |
222 #Rotate 180 degrees around y axis when object is backwards.# | |
223 listdatatemp = [] | |
224 if listdata6[1][0] < listdata6[3][0]: #point sym2_x < point sym 3 | |
225 angle = 180 | |
226 for coordinates in range(0,len(listdata6)): | |
227 listdatatemp.append(Y_rotation(listdata6[coordinates], angle)) # add new coordinates to list | |
228 listdata6 = listdatatemp | |
229 | |
230 # to function 'write new coordinates' | |
231 write_new_coordinates(listdata6) | |
232 | |
233 # Function write the new coordinates to outputfile. | |
234 def write_new_coordinates(listdata6): | |
235 file_outputname4 = 'outputrotate_points.ply' # sub outputfile | |
236 output4 = open(file_outputname4, 'w') | |
237 | |
238 # write every coordinate to output file | |
239 for line in range(0,len(listdata6)): | |
240 output4.write("%.7f %.7f %.7f\n"%(listdata6[line][0], listdata6[line][1], listdata6[line][2])) | |
241 | |
242 # Function to write the new ply file with | |
243 def write_ply_file(name_file_ply, var_header,var_vertex_nm,var_face_nm, listtotal_colors, listtotal_vertex): | |
244 outfile_rotating2 = open(sys.argv[3], 'w') #create new file | |
245 pointsfile = open('outputrotate_points.ply', 'r') #new points | |
246 file2= open(name_file_ply) #original ply file | |
247 counter = 0 # counter for color | |
248 | |
249 # writing all the parts of the new ply file | |
250 for line in range(0,(int(var_header) + int(var_vertex_nm) + int(var_face_nm) + 1)): | |
251 line2 = file2.readline() | |
252 readline2 = line2.strip().split() | |
253 if line <= (int(var_header)): #header writing | |
254 outfile_rotating2.write('%s'%(line2)) | |
255 if line == int(var_header): #new coordinates writing | |
256 line2 = file2.readline() | |
257 readline2 = line2.strip().split() | |
258 for vertex in range(0,len(listtotal_vertex)): | |
259 line3 = pointsfile.readline().strip() | |
260 if vertex >= 4: #from point 4, because they were extra edit to the list in the beginning | |
261 outfile_rotating2.write('%s %s %s %s\n'% | |
262 (line3, listtotal_colors[counter][0], | |
263 listtotal_colors[counter][1], listtotal_colors[counter][2])) | |
264 counter += 1 | |
265 if line == (int(var_vertex_nm) + int(var_header)-1): #write the faces | |
266 for face in range(0, int(var_face_nm)): | |
267 line2 = file2.readline() | |
268 outfile_rotating2.write('%s'%(line2)) | |
269 counter = 0 | |
270 | |
271 outfile_rotating2.close() # outputfile close | |
272 | |
273 main() |