source: proiecte/pmake3d/make3d_original/Make3dSingleImageStanford_version0.1/third_party/vrippack-0.31/src/plytools/plydice.cc @ 37

Last change on this file since 37 was 37, checked in by (none), 14 years ago

Added original make3d

File size: 18.0 KB
Line 
1/*
2
3Apply a 3-D transformation to an object from a PLY file.
4Then figure out how it breaks into subvols, and write out the
5ply file in chunks, but going back to using the original
6vertices. 
7
8It throws away all vertex properties except xyz and confidence
9(if confidence exists).
10
11Lucas Pereira, 2-28-99.
12
13Based somewhat on plyxform,
14Greg 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 */
26bool hasConfidence = 0;
27float subvolSize = 0;
28float epsilon = 0;
29bool writeDiced = 0;
30char *baseName = NULL;
31float minx =  1e30;
32float miny =  1e30;
33float minz =  1e30;
34float maxx = -1e30;
35float maxy = -1e30;
36float maxz = -1e30;
37float cropminx = -1e30;
38float cropminy = -1e30;
39float cropminz = -1e30;
40float cropmaxx =  1e30;
41float cropmaxy =  1e30;
42float cropmaxz =  1e30;
43char *outdir = NULL;
44
45typedef 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
53typedef struct Face {
54  unsigned char nverts;    /* number of vertex indices in list */
55  int *verts;              /* vertex index list */
56} Face;
57
58
59
60char *elem_names[] = { /* list of the kinds of elements in the user's object */
61  "vertex", "face"
62};
63
64PlyProperty 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
71PlyProperty 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
78int nverts, nfaces;
79int validverts, validfaces;
80Vertex **vlist;
81Vertex **validvlist;
82Face **flist;
83Face **validflist;
84int nelems;
85char **elist;
86int num_comments;
87char **comments;
88int num_obj_info;
89char **obj_info;
90int file_type;
91
92static float xtrans = 0;
93static float ytrans = 0;
94static float ztrans = 0;
95
96static float xscale = 1;
97static float yscale = 1;
98static float zscale = 1;
99
100static float rotx = 0;
101static float roty = 0;
102static float rotz = 0;
103
104static Quaternion quat;
105
106static Matrix4f xfmat;
107
108void usage(char *progname);
109void write_file(FILE *out);
110void clip_and_write_subvols();
111void read_file(FILE *inFile);
112void transform();
113int  clip_to_bounds(float svminx, float svminy, float svminz, 
114                    float svmaxx, float svmaxy, float svmaxz);
115
116/******************************************************************************
117Transform a PLY file.
118******************************************************************************/
119
120int
121main(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/******************************************************************************
302Write a ply file for each subvol that contains tris.
303Assumes that transform has been called, so that bboxes are set....
304******************************************************************************/
305
306void
307clip_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/******************************************************************************
368Figure out which vertices are in the bbox. Returns number of valid
369triangles...
370******************************************************************************/
371
372int
373clip_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/******************************************************************************
426Transform the PLY object.
427******************************************************************************/
428
429void
430transform()
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/******************************************************************************
470Read in the PLY file from file / standard in.
471******************************************************************************/
472
473void
474read_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/******************************************************************************
560Write out the PLY file to standard out.
561******************************************************************************/
562
563void
564write_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/******************************************************************************
627Print out usage information.
628******************************************************************************/
629
630void
631usage(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}
Note: See TracBrowser for help on using the repository browser.