1 | /* |
---|
2 | |
---|
3 | Apply a 3-D transformation to an object from a PLY file. |
---|
4 | Then figure out how it breaks into subvols, and write out the |
---|
5 | ply file in chunks, but going back to using the original |
---|
6 | vertices. |
---|
7 | |
---|
8 | It throws away all vertex properties except xyz and confidence |
---|
9 | (if confidence exists). |
---|
10 | |
---|
11 | Lucas Pereira, 2-28-99. |
---|
12 | |
---|
13 | Based somewhat on plyxform, |
---|
14 | Greg Turk, August 1994 |
---|
15 | */ |
---|
16 | |
---|
17 | #include <stdio.h> |
---|
18 | #include <stdlib.h> |
---|
19 | #include <math.h> |
---|
20 | #include <malloc.h> |
---|
21 | #include <ply.h> |
---|
22 | |
---|
23 | #include "Linear.h" |
---|
24 | |
---|
25 | /* user's vertex and face definitions for a polygonal object */ |
---|
26 | bool hasConfidence = 0; |
---|
27 | float subvolSize = 0; |
---|
28 | float epsilon = 0; |
---|
29 | bool writeDiced = 0; |
---|
30 | char *baseName = NULL; |
---|
31 | float minx = 1e30; |
---|
32 | float miny = 1e30; |
---|
33 | float minz = 1e30; |
---|
34 | float maxx = -1e30; |
---|
35 | float maxy = -1e30; |
---|
36 | float maxz = -1e30; |
---|
37 | float cropminx = -1e30; |
---|
38 | float cropminy = -1e30; |
---|
39 | float cropminz = -1e30; |
---|
40 | float cropmaxx = 1e30; |
---|
41 | float cropmaxy = 1e30; |
---|
42 | float cropmaxz = 1e30; |
---|
43 | char *outdir = NULL; |
---|
44 | |
---|
45 | typedef struct Vertex { |
---|
46 | float x,y,z; // xyz in mesh (non-transformed) coords |
---|
47 | float wx, wy, wz; // xyz in world coordinates (transformed) |
---|
48 | int index; // "true" index |
---|
49 | int svindex; // index for this particular subvol |
---|
50 | float confidence; |
---|
51 | } Vertex; |
---|
52 | |
---|
53 | typedef struct Face { |
---|
54 | unsigned char nverts; /* number of vertex indices in list */ |
---|
55 | int *verts; /* vertex index list */ |
---|
56 | } Face; |
---|
57 | |
---|
58 | |
---|
59 | |
---|
60 | char *elem_names[] = { /* list of the kinds of elements in the user's object */ |
---|
61 | "vertex", "face" |
---|
62 | }; |
---|
63 | |
---|
64 | PlyProperty vert_props[] = { /* list of property information for a vertex */ |
---|
65 | {"x", PLY_FLOAT, PLY_FLOAT, offsetof(Vertex,x), 0, 0, 0, 0}, |
---|
66 | {"y", PLY_FLOAT, PLY_FLOAT, offsetof(Vertex,y), 0, 0, 0, 0}, |
---|
67 | {"z", PLY_FLOAT, PLY_FLOAT, offsetof(Vertex,z), 0, 0, 0, 0}, |
---|
68 | {"confidence", PLY_FLOAT, PLY_FLOAT, offsetof(Vertex,confidence), 0, 0, 0, 0}, |
---|
69 | }; |
---|
70 | |
---|
71 | PlyProperty face_props[] = { /* list of property information for a vertex */ |
---|
72 | {"vertex_indices", PLY_INT, PLY_INT, offsetof(Face,verts), |
---|
73 | 1, PLY_UCHAR, PLY_UCHAR, offsetof(Face,nverts)}, |
---|
74 | }; |
---|
75 | |
---|
76 | /*** the PLY object ***/ |
---|
77 | |
---|
78 | int nverts, nfaces; |
---|
79 | int validverts, validfaces; |
---|
80 | Vertex **vlist; |
---|
81 | Vertex **validvlist; |
---|
82 | Face **flist; |
---|
83 | Face **validflist; |
---|
84 | int nelems; |
---|
85 | char **elist; |
---|
86 | int num_comments; |
---|
87 | char **comments; |
---|
88 | int num_obj_info; |
---|
89 | char **obj_info; |
---|
90 | int file_type; |
---|
91 | |
---|
92 | static float xtrans = 0; |
---|
93 | static float ytrans = 0; |
---|
94 | static float ztrans = 0; |
---|
95 | |
---|
96 | static float xscale = 1; |
---|
97 | static float yscale = 1; |
---|
98 | static float zscale = 1; |
---|
99 | |
---|
100 | static float rotx = 0; |
---|
101 | static float roty = 0; |
---|
102 | static float rotz = 0; |
---|
103 | |
---|
104 | static Quaternion quat; |
---|
105 | |
---|
106 | static Matrix4f xfmat; |
---|
107 | |
---|
108 | void usage(char *progname); |
---|
109 | void write_file(FILE *out); |
---|
110 | void clip_and_write_subvols(); |
---|
111 | void read_file(FILE *inFile); |
---|
112 | void transform(); |
---|
113 | int clip_to_bounds(float svminx, float svminy, float svminz, |
---|
114 | float svmaxx, float svmaxy, float svmaxz); |
---|
115 | |
---|
116 | /****************************************************************************** |
---|
117 | Transform a PLY file. |
---|
118 | ******************************************************************************/ |
---|
119 | |
---|
120 | int |
---|
121 | main(int argc, char *argv[]) |
---|
122 | { |
---|
123 | int i,j; |
---|
124 | char *s; |
---|
125 | char *progname; |
---|
126 | char *xfname = NULL; |
---|
127 | FILE *inFile = stdin; |
---|
128 | char *writebboxname = NULL; |
---|
129 | bool printbbox = FALSE; |
---|
130 | |
---|
131 | progname = argv[0]; |
---|
132 | |
---|
133 | quat.q[0] = 0; |
---|
134 | quat.q[1] = 0; |
---|
135 | quat.q[2] = 0; |
---|
136 | quat.q[3] = 1; |
---|
137 | |
---|
138 | xfmat.makeIdentity(); |
---|
139 | |
---|
140 | // With no args, this program does nothing, so print usage |
---|
141 | if (argc == 1) { |
---|
142 | usage(progname); |
---|
143 | exit(0); |
---|
144 | } |
---|
145 | |
---|
146 | /* Parse -flags */ |
---|
147 | while (--argc > 0 && (*++argv)[0]=='-') { |
---|
148 | s = argv[0]; |
---|
149 | if (equal_strings(s, "-h")) { |
---|
150 | usage(progname); |
---|
151 | exit(0); |
---|
152 | } else if (equal_strings(s, "-writebbox")) { |
---|
153 | if (argc < 2) usage(progname); |
---|
154 | writebboxname = (*++argv); |
---|
155 | argc -= 1; |
---|
156 | } else if (equal_strings(s, "-outdir")) { |
---|
157 | if (argc < 2) usage(progname); |
---|
158 | outdir = (*++argv); |
---|
159 | argc -= 1; |
---|
160 | } else if (equal_strings(s, "-printbbox")) { |
---|
161 | printbbox = TRUE; |
---|
162 | } else if (equal_strings(s, "-dice")) { |
---|
163 | if (argc < 4) usage(progname); |
---|
164 | subvolSize = atof(*++argv); |
---|
165 | epsilon = atof(*++argv); |
---|
166 | writeDiced = 1; |
---|
167 | baseName = (*++argv); |
---|
168 | if (subvolSize <= 0) { |
---|
169 | fprintf(stderr, "Error: subvolSize must be greater than zero.\n"); |
---|
170 | usage(progname); |
---|
171 | } |
---|
172 | argc -= 3; |
---|
173 | } else if (equal_strings(s, "-odice")) { |
---|
174 | if (argc < 4) usage(progname); |
---|
175 | subvolSize = atof(*++argv); |
---|
176 | epsilon = atof(*++argv); |
---|
177 | writeDiced = 0; |
---|
178 | baseName = (*++argv); |
---|
179 | if (subvolSize <= 0) { |
---|
180 | fprintf(stderr, "Error: subvolSize must be greater than zero.\n"); |
---|
181 | usage(progname); |
---|
182 | } |
---|
183 | argc -= 3; |
---|
184 | } else if (equal_strings(s, "-crop")) { |
---|
185 | if (argc < 7) usage(progname); |
---|
186 | cropminx = atof(*++argv); |
---|
187 | cropminy = atof(*++argv); |
---|
188 | cropminz = atof(*++argv); |
---|
189 | cropmaxx = atof(*++argv); |
---|
190 | cropmaxy = atof(*++argv); |
---|
191 | cropmaxz = atof(*++argv); |
---|
192 | argc -= 6; |
---|
193 | } else if (equal_strings(s, "-s")) { |
---|
194 | if (argc < 4) usage(progname); |
---|
195 | xscale = atof (*++argv); |
---|
196 | yscale = atof (*++argv); |
---|
197 | zscale = atof (*++argv); |
---|
198 | argc -= 3; |
---|
199 | } else if (equal_strings(s, "-f")) { |
---|
200 | if (argc < 2) usage(progname); |
---|
201 | xfname = (*++argv); |
---|
202 | argc-=1; |
---|
203 | } else if (equal_strings(s, "-t")) { |
---|
204 | if (argc < 4) usage(progname); |
---|
205 | xtrans = atof (*++argv); |
---|
206 | ytrans = atof (*++argv); |
---|
207 | ztrans = atof (*++argv); |
---|
208 | argc -= 3; |
---|
209 | } else if (equal_strings(s, "-r")) { |
---|
210 | if (argc < 4) usage(progname); |
---|
211 | rotx = atof (*++argv) * M_PI/180; |
---|
212 | roty = atof (*++argv) * M_PI/180; |
---|
213 | rotz = atof (*++argv) * M_PI/180; |
---|
214 | argc -= 3; |
---|
215 | } else if (equal_strings(s, "-q")) { |
---|
216 | if (argc < 5) usage(progname); |
---|
217 | quat.q[0] = atof (*++argv); |
---|
218 | quat.q[1] = atof (*++argv); |
---|
219 | quat.q[2] = atof (*++argv); |
---|
220 | quat.q[3] = atof (*++argv); |
---|
221 | argc -= 4; |
---|
222 | } else { |
---|
223 | fprintf(stderr, "Error: unrecognized arg: %s. Aborting...\n", |
---|
224 | argv[0]); |
---|
225 | usage(progname); |
---|
226 | exit(-1); |
---|
227 | break; |
---|
228 | } |
---|
229 | } |
---|
230 | |
---|
231 | /* optional input file (if not, read stdin ) */ |
---|
232 | if (argc > 0 && *argv[0] != '-') { |
---|
233 | inFile = fopen(argv[0], "r"); |
---|
234 | if (inFile == NULL) { |
---|
235 | fprintf(stderr, "Error: Couldn't open input file %s\n", argv[0]); |
---|
236 | usage(progname); |
---|
237 | exit(-1); |
---|
238 | } |
---|
239 | argc --; |
---|
240 | argv ++; |
---|
241 | } |
---|
242 | |
---|
243 | /* Check no extra args */ |
---|
244 | if (argc > 0) { |
---|
245 | fprintf(stderr, "Error: Unhandled arg: %s\n", argv[0]); |
---|
246 | usage(progname); |
---|
247 | exit(-1); |
---|
248 | } |
---|
249 | |
---|
250 | /* Read xf file if given... */ |
---|
251 | if (xfname) { |
---|
252 | FILE *xf = fopen(xfname, "r"); |
---|
253 | if (xf == NULL) { |
---|
254 | fprintf(stderr, "Error, couldn't open .xf file %s\n", xfname); |
---|
255 | usage(progname); |
---|
256 | exit(-1); |
---|
257 | } |
---|
258 | for (int i=0; i < 4; i++) { |
---|
259 | float a,b,c,d; |
---|
260 | fscanf(xf, "%f %f %f %f\n", &a, &b, &c, &d); |
---|
261 | xfmat.setElem(i,0,a); |
---|
262 | xfmat.setElem(i,1,b); |
---|
263 | xfmat.setElem(i,2,c); |
---|
264 | xfmat.setElem(i,3,d); |
---|
265 | } |
---|
266 | fclose(xf); |
---|
267 | } |
---|
268 | |
---|
269 | if (inFile == stdin) { |
---|
270 | fprintf(stderr, "Reading from stdin...\n"); |
---|
271 | } |
---|
272 | |
---|
273 | read_file(inFile); |
---|
274 | transform(); |
---|
275 | |
---|
276 | // Print bbox to stdout? |
---|
277 | if (printbbox) { |
---|
278 | fprintf(stdout, "%f %f %f\n%f %f %f\n", minx, miny, minz, |
---|
279 | maxx, maxy, maxz); |
---|
280 | } |
---|
281 | |
---|
282 | // Write bbox to file? |
---|
283 | if (writebboxname) { |
---|
284 | FILE *bbox = fopen(writebboxname, "w"); |
---|
285 | if (bbox == NULL) { |
---|
286 | fprintf(stderr, "Err, couldn't open %s for writing. Aborting...\n", |
---|
287 | writebboxname); |
---|
288 | exit(-1); |
---|
289 | } |
---|
290 | fprintf(bbox, "%f %f %f\n%f %f %f\n", minx, miny, minz, |
---|
291 | maxx, maxy, maxz); |
---|
292 | fclose(bbox); |
---|
293 | } |
---|
294 | |
---|
295 | if (subvolSize > 0) { |
---|
296 | clip_and_write_subvols(); |
---|
297 | } |
---|
298 | return(0); |
---|
299 | } |
---|
300 | |
---|
301 | /****************************************************************************** |
---|
302 | Write a ply file for each subvol that contains tris. |
---|
303 | Assumes that transform has been called, so that bboxes are set.... |
---|
304 | ******************************************************************************/ |
---|
305 | |
---|
306 | void |
---|
307 | clip_and_write_subvols() |
---|
308 | { |
---|
309 | int x, y, z; |
---|
310 | int minxi, minyi, minzi, maxxi, maxyi, maxzi; |
---|
311 | float svminx, svminy, svminz; |
---|
312 | float svmaxx, svmaxy, svmaxz; |
---|
313 | |
---|
314 | minxi = int(floor((minx - epsilon) / subvolSize)); |
---|
315 | minyi = int(floor((miny - epsilon) / subvolSize)); |
---|
316 | minzi = int(floor((minz - epsilon) / subvolSize)); |
---|
317 | maxxi = int(floor((maxx + epsilon) / subvolSize)); |
---|
318 | maxyi = int(floor((maxy + epsilon) / subvolSize)); |
---|
319 | maxzi = int(floor((maxz + epsilon) / subvolSize)); |
---|
320 | |
---|
321 | for (x = minxi; x <= maxxi; x++) { |
---|
322 | for (y = minyi; y <= maxyi; y++) { |
---|
323 | for (z = minzi; z <= maxzi; z++) { |
---|
324 | svminx = x*subvolSize-epsilon; |
---|
325 | svminy = y*subvolSize-epsilon; |
---|
326 | svminz = z*subvolSize-epsilon; |
---|
327 | svmaxx = (x+1)*subvolSize+epsilon; |
---|
328 | svmaxy = (y+1)*subvolSize+epsilon; |
---|
329 | svmaxz = (z+1)*subvolSize+epsilon; |
---|
330 | |
---|
331 | // Set bounds tighter if bounds exist? |
---|
332 | svminx = MAX(svminx, cropminx-epsilon); |
---|
333 | svminy = MAX(svminy, cropminy-epsilon); |
---|
334 | svminz = MAX(svminz, cropminz-epsilon); |
---|
335 | svmaxx = MIN(svmaxx, cropmaxx+epsilon); |
---|
336 | svmaxy = MIN(svmaxy, cropmaxy+epsilon); |
---|
337 | svmaxz = MIN(svmaxz, cropmaxz+epsilon); |
---|
338 | |
---|
339 | int numverts = clip_to_bounds(svminx, svminy, svminz, |
---|
340 | svmaxx, svmaxy, svmaxz); |
---|
341 | if (numverts > 0) { |
---|
342 | char fname[1000]; |
---|
343 | if (outdir != NULL) { |
---|
344 | sprintf(fname, "%s/%s_%d_%d_%d.ply", outdir, baseName, x, y, z); |
---|
345 | } else { |
---|
346 | sprintf(fname, "%s_%d_%d_%d.ply", baseName, x, y, z); |
---|
347 | } |
---|
348 | // Print name to stdout |
---|
349 | fprintf(stdout, "%s\n", fname); |
---|
350 | |
---|
351 | if (writeDiced) { |
---|
352 | FILE *out = fopen(fname, "w"); |
---|
353 | if (out == NULL) { |
---|
354 | fprintf(stderr, "Err: couldn't open fname... aborting.\n"); |
---|
355 | exit(-1); |
---|
356 | } |
---|
357 | write_file(out); |
---|
358 | fclose(out); |
---|
359 | } |
---|
360 | |
---|
361 | } |
---|
362 | } |
---|
363 | } |
---|
364 | } |
---|
365 | } |
---|
366 | |
---|
367 | /****************************************************************************** |
---|
368 | Figure out which vertices are in the bbox. Returns number of valid |
---|
369 | triangles... |
---|
370 | ******************************************************************************/ |
---|
371 | |
---|
372 | int |
---|
373 | clip_to_bounds(float svminx, float svminy, float svminz, |
---|
374 | float svmaxx, float svmaxy, float svmaxz) |
---|
375 | { |
---|
376 | int i, j; |
---|
377 | Vertex *v; |
---|
378 | Face *f; |
---|
379 | |
---|
380 | validverts = 0; |
---|
381 | validfaces = 0; |
---|
382 | |
---|
383 | // Set new id for all the vertices |
---|
384 | // -1 if outside volume... |
---|
385 | for (i=0; i < nverts; i++) { |
---|
386 | v = vlist[i]; |
---|
387 | if (v->wx >= svminx && |
---|
388 | v->wy >= svminy && |
---|
389 | v->wz >= svminz && |
---|
390 | v->wx <= svmaxx && |
---|
391 | v->wy <= svmaxy && |
---|
392 | v->wz <= svmaxz) { |
---|
393 | v->svindex = validverts; |
---|
394 | validvlist[validverts++] = v; |
---|
395 | } else { |
---|
396 | v->svindex = -1; |
---|
397 | } |
---|
398 | } |
---|
399 | |
---|
400 | // Abort right here if not at least 3 vertices... |
---|
401 | // fprintf(stderr, "valid verts: %d\n", validverts); |
---|
402 | if (validverts < 3) return 0; |
---|
403 | |
---|
404 | for (i=0; i < nfaces; i++) { |
---|
405 | f = flist[i]; |
---|
406 | bool good = TRUE; |
---|
407 | for (j=0; j < f->nverts; j++) { |
---|
408 | if (vlist[f->verts[j]]->svindex == -1) { |
---|
409 | good = FALSE; |
---|
410 | break; |
---|
411 | } |
---|
412 | } |
---|
413 | if (good) { |
---|
414 | validflist[validfaces++] = f; |
---|
415 | } |
---|
416 | } |
---|
417 | |
---|
418 | // fprintf(stdout, "valid faces: %d\n", validfaces); |
---|
419 | |
---|
420 | return(validfaces); |
---|
421 | } |
---|
422 | |
---|
423 | |
---|
424 | |
---|
425 | /****************************************************************************** |
---|
426 | Transform the PLY object. |
---|
427 | ******************************************************************************/ |
---|
428 | |
---|
429 | void |
---|
430 | transform() |
---|
431 | { |
---|
432 | int i; |
---|
433 | Vertex *vert; |
---|
434 | Vec3f vec1, vec2; |
---|
435 | Matrix4f mat, qmat; |
---|
436 | |
---|
437 | quat.toMatrix(qmat); |
---|
438 | mat.makeIdentity(); |
---|
439 | mat.scale(xscale, yscale, zscale); |
---|
440 | mat.rotateX(rotx); |
---|
441 | mat.rotateY(roty); |
---|
442 | mat.rotateZ(rotz); |
---|
443 | mat.multLeft(qmat); |
---|
444 | mat.setTranslate(xtrans, ytrans, ztrans); |
---|
445 | mat.multLeft(xfmat); |
---|
446 | |
---|
447 | for (i = 0; i < nverts; i++) { |
---|
448 | vert = vlist[i]; |
---|
449 | vec1.setValue(vert->x, vert->y, vert->z); |
---|
450 | mat.multVec(vec1, vec2); |
---|
451 | vert->wx = vec2.x; |
---|
452 | vert->wy = vec2.y; |
---|
453 | vert->wz = vec2.z; |
---|
454 | |
---|
455 | // Also compute bbox |
---|
456 | minx = MIN(minx, vert->wx); |
---|
457 | miny = MIN(miny, vert->wy); |
---|
458 | minz = MIN(minz, vert->wz); |
---|
459 | maxx = MAX(maxx, vert->wx); |
---|
460 | maxy = MAX(maxy, vert->wy); |
---|
461 | maxz = MAX(maxz, vert->wz); |
---|
462 | } |
---|
463 | |
---|
464 | // fprintf(stderr, "BBOX: (%.2f %.2f %.2f) to (%.2f %.2f %2.f)\n", |
---|
465 | // minx, miny, minz, maxx, maxy, maxz); |
---|
466 | } |
---|
467 | |
---|
468 | |
---|
469 | /****************************************************************************** |
---|
470 | Read in the PLY file from file / standard in. |
---|
471 | ******************************************************************************/ |
---|
472 | |
---|
473 | void |
---|
474 | read_file(FILE *inFile) |
---|
475 | { |
---|
476 | int i,j,k; |
---|
477 | PlyFile *ply; |
---|
478 | int nprops; |
---|
479 | int num_elems; |
---|
480 | char *elem_name; |
---|
481 | float version; |
---|
482 | |
---|
483 | |
---|
484 | /*** Read in the original PLY object ***/ |
---|
485 | |
---|
486 | |
---|
487 | ply = ply_read (inFile, &nelems, &elist); |
---|
488 | ply_get_info (ply, &version, &file_type); |
---|
489 | |
---|
490 | for (i = 0; i < nelems; i++) { |
---|
491 | |
---|
492 | /* get the description of the first element */ |
---|
493 | elem_name = elist[i]; |
---|
494 | ply_get_element_description (ply, elem_name, &num_elems, &nprops); |
---|
495 | |
---|
496 | if (equal_strings ("vertex", elem_name)) { |
---|
497 | |
---|
498 | // Check to see if it has confidences... |
---|
499 | for (int m=0; m < nprops; m++) { |
---|
500 | char *this_prop = ply->elems[i]->props[m]->name; |
---|
501 | if (equal_strings(this_prop, "confidence")) { |
---|
502 | hasConfidence = TRUE; |
---|
503 | break; |
---|
504 | } |
---|
505 | } |
---|
506 | |
---|
507 | /* create a vertex list to hold all the vertices */ |
---|
508 | vlist = (Vertex **) malloc (sizeof (Vertex *) * num_elems); |
---|
509 | validvlist = (Vertex **) malloc (sizeof (Vertex *) * num_elems); |
---|
510 | nverts = num_elems; |
---|
511 | |
---|
512 | // Allocate all the memory in one chunk, instead of piecewise later |
---|
513 | Vertex *varray = (Vertex *) malloc(sizeof(Vertex) * nverts); |
---|
514 | for (int k=0; k < nverts; k++) vlist[k] = &(varray[k]); |
---|
515 | |
---|
516 | |
---|
517 | /* set up for getting vertex elements */ |
---|
518 | |
---|
519 | ply_get_property (ply, elem_name, &vert_props[0]); |
---|
520 | ply_get_property (ply, elem_name, &vert_props[1]); |
---|
521 | ply_get_property (ply, elem_name, &vert_props[2]); |
---|
522 | if (hasConfidence) { |
---|
523 | ply_get_property (ply, elem_name, &vert_props[3]); |
---|
524 | } |
---|
525 | |
---|
526 | /* grab all the vertex elements */ |
---|
527 | for (j = 0; j < num_elems; j++) { |
---|
528 | ply_get_element (ply, (void *) vlist[j]); |
---|
529 | vlist[j]->index = j; |
---|
530 | } |
---|
531 | } |
---|
532 | else if (equal_strings ("face", elem_name)) { |
---|
533 | |
---|
534 | /* create a list to hold all the face elements */ |
---|
535 | flist = (Face **) malloc (sizeof (Face *) * num_elems); |
---|
536 | validflist = (Face **) malloc (sizeof (Face *) * num_elems); |
---|
537 | nfaces = num_elems; |
---|
538 | |
---|
539 | // Allocate all the memory in one chunk, instead of piecewise later |
---|
540 | Face *farray = (Face *) malloc(sizeof(Face) * nfaces); |
---|
541 | for (k=0; k < nfaces; k++) flist[k] = &(farray[k]); |
---|
542 | |
---|
543 | /* set up for getting face elements */ |
---|
544 | ply_get_property (ply, elem_name, &face_props[0]); |
---|
545 | |
---|
546 | /* grab all the face elements */ |
---|
547 | for (j = 0; j < num_elems; j++) { |
---|
548 | ply_get_element (ply, (void *) flist[j]); |
---|
549 | } |
---|
550 | } |
---|
551 | } |
---|
552 | comments = ply_get_comments (ply, &num_comments); |
---|
553 | obj_info = ply_get_obj_info (ply, &num_obj_info); |
---|
554 | |
---|
555 | ply_close (ply); |
---|
556 | } |
---|
557 | |
---|
558 | |
---|
559 | /****************************************************************************** |
---|
560 | Write out the PLY file to standard out. |
---|
561 | ******************************************************************************/ |
---|
562 | |
---|
563 | void |
---|
564 | write_file(FILE *out) |
---|
565 | { |
---|
566 | int i,j,k; |
---|
567 | PlyFile *ply; |
---|
568 | int num_elems; |
---|
569 | char *elem_name; |
---|
570 | |
---|
571 | /*** Write out the transformed PLY object ***/ |
---|
572 | |
---|
573 | |
---|
574 | ply = ply_write (out, nelems, elist, file_type); |
---|
575 | |
---|
576 | |
---|
577 | /* describe what properties go into the vertex and face elements */ |
---|
578 | |
---|
579 | ply_element_count (ply, "vertex", validverts); |
---|
580 | ply_describe_property (ply, "vertex", &vert_props[0]); |
---|
581 | ply_describe_property (ply, "vertex", &vert_props[1]); |
---|
582 | ply_describe_property (ply, "vertex", &vert_props[2]); |
---|
583 | if (hasConfidence) { |
---|
584 | ply_describe_property (ply, "vertex", &vert_props[3]); |
---|
585 | } |
---|
586 | |
---|
587 | ply_element_count (ply, "face", validfaces); |
---|
588 | ply_describe_property (ply, "face", &face_props[0]); |
---|
589 | |
---|
590 | for (i = 0; i < num_comments; i++) |
---|
591 | ply_put_comment (ply, comments[i]); |
---|
592 | |
---|
593 | for (i = 0; i < num_obj_info; i++) |
---|
594 | ply_put_obj_info (ply, obj_info[i]); |
---|
595 | |
---|
596 | ply_header_complete (ply); |
---|
597 | |
---|
598 | /* set up and write the vertex elements */ |
---|
599 | ply_put_element_setup (ply, "vertex"); |
---|
600 | for (i = 0; i < validverts; i++) { |
---|
601 | ply_put_element (ply, (void *) validvlist[i]); |
---|
602 | // fprintf(stderr, "%d ", validvlist[i]->svindex); |
---|
603 | } |
---|
604 | /* set up and write the face elements */ |
---|
605 | ply_put_element_setup (ply, "face"); |
---|
606 | Face tempface; |
---|
607 | tempface.verts = (int *) malloc(sizeof(int) * 256); |
---|
608 | for (i = 0; i < validfaces; i++) { |
---|
609 | if (validflist[i]->nverts < 3) { |
---|
610 | fprintf(stderr, "Error! less than 3 faces. we're hozed!\n"); |
---|
611 | continue; |
---|
612 | } |
---|
613 | // Put the new vertex indices into tempface |
---|
614 | tempface.nverts = validflist[i]->nverts; |
---|
615 | for (j = 0; j < validflist[i]->nverts; j++) { |
---|
616 | tempface.verts[j] = (vlist[validflist[i]->verts[j]])->svindex; |
---|
617 | } |
---|
618 | ply_put_element (ply, (void *) &tempface); |
---|
619 | } |
---|
620 | |
---|
621 | |
---|
622 | ply_close (ply); |
---|
623 | } |
---|
624 | |
---|
625 | |
---|
626 | /****************************************************************************** |
---|
627 | Print out usage information. |
---|
628 | ******************************************************************************/ |
---|
629 | |
---|
630 | void |
---|
631 | usage(char *progname) |
---|
632 | { |
---|
633 | fprintf (stderr, "\n"); |
---|
634 | fprintf (stderr, "usage: %s [options] subvol_size epsilon [in.ply]\n", progname); |
---|
635 | fprintf (stderr, " or: %s [options] subvol_size epsilon < in.ply\n", progname); |
---|
636 | fprintf (stderr, "\n"); |
---|
637 | fprintf (stderr, "Options:\n"); |
---|
638 | fprintf (stderr, " -writebbox bboxname (writes mesh bbox to file)\n"); |
---|
639 | fprintf (stderr, " -printbbox (prints bbox to stdout)\n"); |
---|
640 | fprintf (stderr, " -outdir dir (directory for storing output files..)\n"); |
---|
641 | fprintf (stderr, " -dice subvolsize epsilon basename\n"); |
---|
642 | fprintf (stderr, " Will write out subvols of the form:\n"); |
---|
643 | fprintf (stderr, " basename_-2_3_0.ply\n"); |
---|
644 | fprintf (stderr, " (and write the names of the files to stdout.)\n"); |
---|
645 | fprintf (stderr, " -odice subvolsize epsilon basename\n"); |
---|
646 | fprintf (stderr, " Other dice option. Will not actually generate\n"); |
---|
647 | fprintf (stderr, " any ply files, but will write their names to\n"); |
---|
648 | fprintf (stderr, " stdout (useful to find which subvols have tris.\n"); |
---|
649 | fprintf (stderr, " -crop minx miny minz maxx maxy maxz (crops output)\n"); |
---|
650 | fprintf (stderr, "\n"); |
---|
651 | fprintf (stderr, "As well as plyxform options:\n"); |
---|
652 | fprintf (stderr, " -f m.xf (a transform matrix file)\n"); |
---|
653 | fprintf (stderr, " -t xtrans ytrans ztrans (translation)\n"); |
---|
654 | fprintf (stderr, " -s xscale yscale zscale (scale)\n"); |
---|
655 | fprintf (stderr, " -r xangle yangle zangle (rotation, all in degrees)\n"); |
---|
656 | fprintf (stderr, " -q qi qj qk ql (rotation, quaternion)\n"); |
---|
657 | fprintf (stderr, " (point = m.xf * (ftrans_factor + rotz * roty * rotx * scale_factor * point))\n"); |
---|
658 | fprintf (stderr, "\n"); |
---|
659 | exit (-1); |
---|
660 | } |
---|