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

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

Added original make3d

File size: 22.9 KB
Line 
1/*
2
3Turn a PLY object with un-shared vertices into one with faces that
4share their vertices.
5
6Greg Turk, August 1994
7
8Modified to handle multiple input files,
9Lucas Pereira, 1/99
10*/
11
12
13#include <stdio.h>
14#include <stdlib.h>
15#include <math.h>
16#include <strings.h>
17#include <ply.h>
18
19#ifdef LINUX
20#include <string.h>
21#endif
22
23
24/* user's vertex and face definitions for a polygonal object */
25
26
27struct _Face;
28typedef struct _Flist {
29  struct _Face *f;
30  struct _Flist *next;
31} Flist;
32
33typedef struct _Vertex {
34  float x,y,z;
35  int index;
36  struct _Vertex *shared;
37  struct _Vertex *next;
38  void *other_props;       /* other properties */
39  int nfaces;
40  Flist *faces;            // linked list of faces, to detect repeats
41} Vertex;
42
43typedef struct _Face {
44  unsigned char nverts;    /* number of vertex indices in list */
45  int *verts;              /* vertex index list */
46  Vertex **vptrs;          /* vertex pointer list -- instead of recasting verts! */
47  void *other_props;       /* other properties */
48} Face;
49
50char *elem_names[] = { /* list of the kinds of elements in the user's object */
51  "vertex", "face"
52};
53
54PlyProperty vert_props[] = { /* list of property information for a vertex */
55  {"x", PLY_FLOAT, PLY_FLOAT, offsetof(Vertex,x), 0, 0, 0, 0},
56  {"y", PLY_FLOAT, PLY_FLOAT, offsetof(Vertex,y), 0, 0, 0, 0},
57  {"z", PLY_FLOAT, PLY_FLOAT, offsetof(Vertex,z), 0, 0, 0, 0},
58};
59
60PlyProperty face_props[] = { /* list of property information for a vertex */
61  {"vertex_indices", PLY_INT, PLY_INT, offsetof(Face,verts),
62   1, PLY_UCHAR, PLY_UCHAR, offsetof(Face,nverts)},
63};
64
65
66/*** the PLY object ***/
67
68typedef struct _PlyObject {
69  int nverts,nfaces;
70  Vertex **vlist;
71  Face **flist;
72  PlyOtherElems *other_elements;
73  PlyOtherProp *vert_other,*face_other;
74  int nelems;
75  char **elist;
76  int num_comments;
77  char **comments;
78  int num_obj_info;
79  char **obj_info;
80  int file_type;
81} PlyObject;
82
83static PlyObject *os;  // We will allocate when we know how many files...
84static int nFiles = 0;
85
86static float tolerance = 0.0001;   /* what constitutes "near" */
87
88
89/* hash table for near neighbor searches */
90/* A few randomly chosen prime numbers... */
91
92#define PR1  17
93#define PR2 101
94
95#define TABLE_SIZE1       5003
96#define TABLE_SIZE2      17011
97#define TABLE_SIZE3      53003
98#define TABLE_SIZE4     107021
99#define TABLE_SIZE5     233021
100#define TABLE_SIZE6     472019
101#define TABLE_SIZE7     600169
102#define TABLE_SIZE8    1111189
103#define TABLE_SIZE9    2222177
104#define TABLE_SIZE10   4444147
105#define TABLE_SIZE11   9374153
106#define TABLE_SIZE12  20123119
107#define TABLE_SIZE13  30123139
108#define TABLE_SIZE14  50123011
109#define TABLE_SIZE15  70123117
110#define TABLE_SIZE16 100123171
111#define TABLE_SIZE17 140123143
112#define TABLE_SIZE18 200123111
113#define TABLE_SIZE19 400123123
114#define TABLE_SIZE20 800123119
115
116
117
118
119typedef struct Hash_Table {     /* uniform spatial subdivision, with hash */
120  int npoints;                  /* number of points placed in table */
121  Vertex **verts;               /* array of hash cells */
122  int num_entries;              /* number of array elements in verts */
123  float scale;                  /* size of cell */
124} Hash_Table;
125
126
127Hash_Table *init_table(int, float);
128void add_to_hash (Vertex *, Hash_Table *, float);
129void usage(char *progname);
130void write_file();
131void read_file(FILE *inFile, PlyObject &o);
132void set_vptrs(PlyObject &o);
133void set_flists(PlyObject &o);
134void share_vertices();
135void remove_duplicate_faces();
136
137
138/******************************************************************************
139Main program.
140******************************************************************************/
141
142int
143main(int argc, char *argv[])
144{
145  int i,j;
146  char *s;
147  char *progname;
148  FILE **inFiles;
149
150  progname = argv[0];
151
152  /* Parse -flags */
153  while (--argc > 0 && (*++argv)[0]=='-') {
154    for (s = argv[0]+1; *s; s++)
155      switch (*s) {
156        case 't':
157          if (argc < 2) {
158            usage(progname);
159          }
160          tolerance = atof (*++argv);
161          argc -= 1;
162          break;
163        default:
164          usage (progname);
165          exit (-1);
166          break;
167      }
168  }
169
170  // Ok. Tricky logic here.  Either a single file on stdin, or else
171  // one or more files on the command line.
172  if (argc == 0) {
173    // one file, on stdin...
174    fprintf(stderr, "%s: reading from stdin...\n", progname);
175    nFiles = 1;
176    inFiles = (FILE **) malloc(sizeof(FILE *));
177    inFiles[0] = stdin;
178  } else {
179    // allocate file handles for all input files
180    nFiles = argc;
181    inFiles = (FILE **) malloc(nFiles * sizeof(FILE *));
182    // open each of the files
183    for (i=0; i < argc; i++) {
184      if (argv[i][0] == '-') {
185        fprintf(stderr, "Error: unhandled arg %s. (in wrong order, maybe?)\n",
186                argv[i]);
187        usage(progname);
188        exit(-1);
189      } else {
190        if ((inFiles[i] = fopen(argv[i], "r")) == NULL) {
191          fprintf(stderr, "Error: Couldn't open input file %s\n", argv[i]);
192          usage(progname);
193          exit(-1);
194        }
195      }
196    }
197  }
198 
199  // Now allocate the ply objects, and read them
200  os = (PlyObject *) malloc(nFiles * sizeof(PlyObject));
201  for (i=0; i < nFiles; i++) {
202    read_file(inFiles[i], os[i]);
203    // Check if any extra elements
204    if (i > 0 && os[i].nelems > 2) {
205      fprintf(stderr, "Warning:  file %s has %d elements. Discarding extras...\n",
206              argv[i], os[i].nelems);
207    }
208
209    // Check to make sure Vertex's other_props are identical to file 0
210    if (i > 0 && os[i].vert_other->nprops != os[0].vert_other->nprops) {
211      fprintf(stderr, "Error: file %s has %d extra vertex properties, but %s has %d.\n",
212              argv[0], os[0].vert_other->nprops,
213              argv[i], os[i].vert_other->nprops);
214      fprintf(stderr, "Program terminated for unreconcilable differences.\n\n");
215      exit(-1);
216    }
217    if (i > 0 && os[i].vert_other->size != os[0].vert_other->size) {
218      fprintf(stderr, "Error: file %s extra vertex properties have size %d, "
219              "but %s has size %d.\n",
220              argv[0], os[0].vert_other->size,
221              argv[i], os[i].vert_other->size);
222      fprintf(stderr, "Program terminated for unreconcilable differences.\n\n");
223      exit(-1);
224    }
225    if (i > 0) {
226      for (j=0; j < os[i].vert_other->nprops; j++) {
227        if (strcmp(os[i].vert_other->props[j]->name,
228                   os[0].vert_other->props[j]->name)) {
229          fprintf(stderr, "Error: file %s extra vertex property %d is %s, "
230                  " but %s extra vertex property %d is %s\n", 
231                  argv[0], j, os[0].vert_other->props[j]->name,
232                  argv[i], j, os[i].vert_other->props[j]->name);
233          fprintf(stderr, "Program terminated for unreconcilable differences.\n\n");
234          exit(-1);
235        }
236      }
237    }
238   
239    // Check to make sure Face's other_props are identical to file 0
240    if (i > 0 && os[i].face_other->nprops != os[0].face_other->nprops) {
241      fprintf(stderr, "Error: file %s has %d extra face properties, but %s has %d.\n",
242              argv[0], os[0].face_other->nprops,
243              argv[i], os[i].face_other->nprops);
244      fprintf(stderr, "Program terminated for unreconcilable differences.\n\n");
245      exit(-1);
246    }
247    if (i > 0 && os[i].face_other->size != os[0].face_other->size) {
248      fprintf(stderr, "Error: file %s extra face properties have size %d, "
249              "but %s has size %d.\n",
250              argv[0], os[0].face_other->size,
251              argv[i], os[i].face_other->size);
252      fprintf(stderr, "Program terminated for unreconcilable differences.\n\n");
253      exit(-1);
254    }
255    if (i > 0) {
256      for (j=0; j < os[i].face_other->nprops; j++) {
257        if (strcmp(os[i].face_other->props[j]->name,
258                   os[0].face_other->props[j]->name)) {
259          fprintf(stderr, "Error: file %s extra face property %d is %s, "
260                  " but %s extra face property %d is %s\n", 
261                  argv[0], j, os[0].face_other->props[j]->name,
262                  argv[i], j, os[i].face_other->props[j]->name);
263          fprintf(stderr, "Program terminated for unreconcilable differences.\n\n");
264          exit(-1);
265        }
266      }
267    }
268   
269    set_vptrs(os[i]);
270    set_flists(os[i]);
271  }
272
273  share_vertices();
274
275  remove_duplicate_faces();
276
277  write_file();
278  return(0);
279}
280
281
282/******************************************************************************
283Print out usage information.
284******************************************************************************/
285
286void
287usage(char *progname)
288{
289  fprintf (stderr, "\n");
290  fprintf (stderr, "usage: %s [flags] < in.ply > out.ply\n", progname);
291  fprintf (stderr, "usage: %s [flags] [in1.ply [in2.ply] ...] > out.ply\n", progname);
292  fprintf (stderr, "flags:\n");
293  fprintf (stderr, "       -t tolerance (default = %g)\n", tolerance);
294  fprintf (stderr, "\n");
295  fprintf (stderr, "This program takes one or more ply files, and merges \n");
296  fprintf (stderr, "vertices that are within tolerance of each other.\n");
297  fprintf (stderr, "This is useful to combine multiple meshes into a single\n");
298  fprintf (stderr, "mesh, with smoothly continuous normals.\n");
299  fprintf (stderr, "\n");
300  fprintf (stderr, "If handling more than one file, the vertex and face elements\n");
301  fprintf (stderr, "must have exactly the same properties (in the same order)\n");
302  fprintf (stderr, "in all files or else it will print an error and exit.  If\n");
303  fprintf (stderr, "the files have extra elements, they will be ignored (except \n");
304  fprintf (stderr, "for the first file, which has all extra elements written out,\n");
305  fprintf (stderr, "to maintain backward-compatibility with old plyshared.  It will\n");
306  fprintf (stderr, "print a warning message if elements are ignored.\n");
307  fprintf (stderr, "\n");
308  exit(-1);
309}
310
311/******************************************************************************
312Make face vptrs point to the vertices...
313******************************************************************************/
314
315void
316set_vptrs(PlyObject &o) {
317  int i,j;
318  Face *f;
319  Vertex *v;
320
321  // Malloc vptrs array, set the pointers.
322  for (i=0; i < o.nfaces; i++) {
323    f = o.flist[i];
324    f->vptrs = (Vertex **) malloc(f->nverts * sizeof(Vertex *));
325    for (j=0; j < f->nverts; j++) {
326      v = o.vlist[f->verts[j]];
327      f->vptrs[j] = v;
328    }
329  }
330}
331
332
333/******************************************************************************
334Make vertices point to the faces...
335******************************************************************************/
336
337void
338set_flists(PlyObject &o) {
339  int i,j;
340  Face *f;
341  Vertex *v;
342  Flist *fl;
343
344  // First set all vert facecounters to 0
345  for (i=0; i < o.nverts; i++) {
346    v = o.vlist[i];
347    v->nfaces = 0;
348  }
349
350  for (i=0; i < o.nfaces; i++) {
351    f = o.flist[i];
352    for (j=0; j < f->nverts; j++) {
353      v = o.vlist[f->verts[j]];
354      if ((fl = (Flist *) malloc(sizeof(Flist))) == NULL) {
355        fprintf(stderr, "Error, out of memory.\n");
356        exit(-1);
357      }
358      // Make fl point to the face, and add it to head of linked list
359      // so that the vertex knows about this face.
360      fl->f = f;
361      fl->next = v->faces;
362      v->faces = fl;
363      v->nfaces++;
364    }
365  }
366}
367
368
369/******************************************************************************
370Remove faces that are identical.
371******************************************************************************/
372
373void
374remove_duplicate_faces()
375{
376  int f;
377  int i,j;
378  Vertex *v;
379  Flist *f1, *f2;
380
381  for (f=0; f<nFiles; f++) {
382    for (i=0; i < os[f].nverts; i++) {
383      v = os[f].vlist[i];
384      // For each face in vertex list, nuke it if it's a duplicate
385      for (f1 = v->faces; f1 != NULL; f1 = f1->next) {
386        if (f1->f->nverts == 0) continue;
387        for (f2 = f1->next; f2 != NULL; f2 = f2->next) {
388          if (f2->f->nverts == 0) continue;
389          if (f1->f->nverts != f2->f->nverts) continue;
390          for (int offset=0; offset < f1->f->nverts; offset++) {
391            bool diffFound = false;
392            for (j=0; j < f1->f->nverts; j++) {
393              Vertex *v1 = f1->f->vptrs[j];
394              Vertex *v2 = f2->f->vptrs[(j+offset)%f1->f->nverts];
395              if (v1->shared != v2->shared) {
396                diffFound = true;
397                break;
398              }
399            }   
400            // If we get here, this particular offset gives a match
401            if (!diffFound) f2->f->nverts = 0;
402          }
403        }
404      }
405    }
406  }
407}
408
409
410/******************************************************************************
411Figure out which vertices are close enough to share.
412******************************************************************************/
413
414void
415share_vertices()
416{
417  int f;
418  int i,j,k;
419  int jj;
420  Hash_Table *table;
421  float squared_dist;
422  Vertex *vert;
423  Face *face;
424
425  int totalfaces = 0;
426  for (i=0; i < nFiles; i++) {
427    totalfaces += os[i].nverts;
428  }
429  table = init_table (totalfaces, tolerance);
430
431  squared_dist = tolerance * tolerance;
432
433  /* place all vertices in the hash table, and in the process */
434  /* learn which ones should be shared */
435
436  for (f=0; f < nFiles; f++) {
437    for (k = 0; k < os[f].nverts; k++) {
438      add_to_hash (os[f].vlist[k], table, squared_dist);
439    }
440  }
441
442  /* fix up the faces to point to the shared vertices */
443
444  for (f = 0; f < nFiles; f++) {
445    for (i = 0; i < os[i].nfaces; i++) {
446
447      face = os[f].flist[i];
448   
449      /* collapse adjacent vertices that are the same */
450      for (j = face->nverts-1; j >= 0; j--) {
451        jj = (j+1) % face->nverts;
452        if (face->vptrs[j] == face->vptrs[jj]) {
453          face->vptrs[j]->nfaces -=1;
454          for (k = j+1; k < face->nverts - 1; k++) {
455            face->verts[k] = face->verts[k+1];
456            face->vptrs[k] = face->vptrs[k+1];
457          }
458          face->nverts--;
459        }
460      }
461
462      /* remove any faces with less than three vertices by setting */
463      /* its vertex count to zero */
464
465      if (face->nverts < 3) {
466        for (j=0; j< face->nverts; j++) {
467          face->vptrs[j]->nfaces -=1;
468        }
469        face->nverts = 0;
470      }
471    }
472  }
473}
474
475
476/******************************************************************************
477Add a vertex to it's hash table.
478
479Entry:
480  vert    - vertex to add
481  table   - hash table to add to
482  sq_dist - squared value of distance tolerance
483******************************************************************************/
484
485void 
486add_to_hash(Vertex *vert, Hash_Table *table, float sq_dist)
487{
488  int index;
489  int a,b,c;
490  int aa,bb,cc;
491  float scale;
492  Vertex *ptr;
493  float dx,dy,dz;
494  float sq;
495  float min_dist;
496  Vertex *min_ptr;
497
498  /* determine which cell the position lies within */
499
500  scale = table->scale;
501  aa = (int) floor (vert->x * scale);
502  bb = (int) floor (vert->y * scale);
503  cc = (int) floor (vert->z * scale);
504
505  /* examine vertices in table to see if we're very close */
506
507  min_dist = 1e20;
508  min_ptr = NULL;
509
510  /* look at nine cells, centered at cell containing location */
511
512  for (a = aa-1; a <= aa+1; a++)
513  for (b = bb-1; b <= bb+1; b++)
514  for (c = cc-1; c <= cc+1; c++) {
515
516    /* compute position in hash table */
517    index = (a * PR1 + b * PR2 + c) % table->num_entries;
518    if (index < 0)
519      index += table->num_entries;
520
521    /* examine all points hashed to this cell */
522    for (ptr = table->verts[index]; ptr != NULL; ptr = ptr->next) {
523
524      /* distance (squared) to this point */
525      dx = ptr->x - vert->x;
526      dy = ptr->y - vert->y;
527      dz = ptr->z - vert->z;
528      sq = dx*dx + dy*dy + dz*dz;
529
530      /* maybe we've found new closest point */
531      if (sq <= min_dist) {
532        min_dist = sq;
533        min_ptr = ptr;
534      }
535    }
536  }
537
538  /* If we found a match, have new vertex point to the matching vertex. */
539  /* If we didn't find a match, add new vertex to the table. */
540
541  if (min_ptr && min_dist < sq_dist) {  /* match */
542    // set shared pointer
543    vert->shared = min_ptr;
544    // vert->shared gets all of the flist
545    while (vert->faces != NULL) {
546      // remove face node from vert
547      Flist *fl = vert->faces;
548      vert->faces = vert->faces->next;
549      // insert node in vert->shared
550      fl->next = vert->shared->faces;
551      vert->shared->faces = fl;
552    }
553  }
554  else {          /* no match */
555    index = (aa * PR1 + bb * PR2 + cc) % table->num_entries;
556    if (index < 0)
557      index += table->num_entries;
558    vert->next = table->verts[index];
559    table->verts[index] = vert;
560    vert->shared = vert;  /* self-reference as close match */
561  }
562}
563
564
565/******************************************************************************
566Initialize a uniform spatial subdivision table.  This structure divides
5673-space into cubical cells and deposits points into their appropriate
568cells.  It uses hashing to make the table a one-dimensional array.
569
570Entry:
571  nverts - number of vertices that will be placed in the table
572  size   - size of a cell
573
574Exit:
575  returns pointer to hash table
576******************************************************************************/
577
578Hash_Table *
579init_table(int nverts, float size)
580{
581  int i;
582  int index;
583  int a,b,c;
584  Hash_Table *table;
585  float scale;
586
587  /* allocate new hash table */
588
589  table = (Hash_Table *) malloc (sizeof (Hash_Table));
590
591  if (nverts < TABLE_SIZE1)
592    table->num_entries = TABLE_SIZE1;
593  else if (nverts < TABLE_SIZE2)
594    table->num_entries = TABLE_SIZE2;
595  else if (nverts < TABLE_SIZE3)
596    table->num_entries = TABLE_SIZE3;
597  else if (nverts < TABLE_SIZE4)
598    table->num_entries = TABLE_SIZE4;
599  else if (nverts < TABLE_SIZE5)
600    table->num_entries = TABLE_SIZE5;
601  else if (nverts < TABLE_SIZE6)
602    table->num_entries = TABLE_SIZE6;
603  else if (nverts < TABLE_SIZE7)
604    table->num_entries = TABLE_SIZE7;
605  else if (nverts < TABLE_SIZE8)
606    table->num_entries = TABLE_SIZE8;
607  else if (nverts < TABLE_SIZE9)
608    table->num_entries = TABLE_SIZE9;
609  else if (nverts < TABLE_SIZE10)
610    table->num_entries = TABLE_SIZE10;
611  else if (nverts < TABLE_SIZE11)
612    table->num_entries = TABLE_SIZE11;
613  else if (nverts < TABLE_SIZE12)
614    table->num_entries = TABLE_SIZE12;
615  else if (nverts < TABLE_SIZE13)
616    table->num_entries = TABLE_SIZE13;
617  else if (nverts < TABLE_SIZE14)
618    table->num_entries = TABLE_SIZE14;
619  else if (nverts < TABLE_SIZE15)
620    table->num_entries = TABLE_SIZE15;
621  else if (nverts < TABLE_SIZE16)
622    table->num_entries = TABLE_SIZE16;
623  else if (nverts < TABLE_SIZE17)
624    table->num_entries = TABLE_SIZE17;
625  else if (nverts < TABLE_SIZE18)
626    table->num_entries = TABLE_SIZE18;
627  else if (nverts < TABLE_SIZE19)
628    table->num_entries = TABLE_SIZE19;
629  else
630    table->num_entries = TABLE_SIZE20;
631
632  table->verts = (Vertex **) malloc (sizeof (Vertex *) * table->num_entries);
633
634  /* set all table elements to NULL */
635  for (i = 0; i < table->num_entries; i++)
636    table->verts[i] = NULL;
637
638  /* place each point in table */
639
640  scale = 1 / size;
641  table->scale = scale;
642
643  return (table);
644}
645
646
647/******************************************************************************
648Read in the PLY file from standard in.
649******************************************************************************/
650
651void
652read_file(FILE *inFile, PlyObject &o)
653{
654  int i,j,k;
655  PlyFile *ply;
656  int nprops;
657  int num_elems;
658  char *elem_name;
659  float version;
660  PlyProperty **plist;
661  o.other_elements = NULL;
662
663  /*** Read in the original PLY object ***/
664
665  ply  = ply_read (inFile, &(o.nelems), &(o.elist));
666  ply_get_info (ply, &(version), &(o.file_type));
667
668  for (i = 0; i < o.nelems; i++) {
669
670    /* get the description of the first element */
671    elem_name = o.elist[i];
672    plist = ply_get_element_description(ply, elem_name, &num_elems, &nprops);
673
674    if (equal_strings ("vertex", elem_name)) {
675
676      /* create a vertex list to hold all the vertices */
677      o.vlist = (Vertex **) malloc (sizeof (Vertex *) * num_elems);
678      o.nverts = num_elems;
679
680      /* set up for getting vertex elements */
681
682      ply_get_property (ply, elem_name, &vert_props[0]);
683      ply_get_property (ply, elem_name, &vert_props[1]);
684      ply_get_property (ply, elem_name, &vert_props[2]);
685      o.vert_other = ply_get_other_properties (ply, elem_name,
686                                                offsetof(Vertex,other_props));
687
688      /* grab all the vertex elements */
689      for (j = 0; j < num_elems; j++) {
690        o.vlist[j] = (Vertex *) malloc (sizeof (Vertex));
691        ply_get_element (ply, (void *) o.vlist[j]);
692        o.vlist[j]->index = j;
693        o.vlist[j]->faces = NULL;
694      }
695     
696
697
698    }
699    else if (equal_strings ("face", elem_name)) {
700
701      /* create a list to hold all the face elements */
702      o.flist = (Face **) malloc (sizeof (Face *) * num_elems);
703      o.nfaces = num_elems;
704
705      /* set up for getting face elements */
706
707      ply_get_property (ply, elem_name, &face_props[0]);
708      o.face_other = ply_get_other_properties (ply, elem_name,
709                     offsetof(Face,other_props));
710
711      /* grab all the face elements */
712      for (j = 0; j < num_elems; j++) {
713        o.flist[j] = (Face *) malloc (sizeof (Face));
714        ply_get_element (ply, (void *) o.flist[j]);
715      }
716    }
717    else
718      o.other_elements = ply_get_other_element (ply, elem_name, num_elems);
719  }
720
721  o.comments = ply_get_comments (ply, &(o.num_comments));
722  o.obj_info = ply_get_obj_info (ply, &(o.num_obj_info));
723
724  ply_close (ply);
725}
726
727
728/******************************************************************************
729Write out the PLY file to standard out.
730******************************************************************************/
731
732void
733write_file()
734{
735  int f;
736  int i,j,k;
737  PlyFile *ply;
738  int num_elems;
739  char *elem_name;
740  int vert_count;
741  int face_count;
742
743  /*** Write out the final PLY object ***/
744
745
746  ply = ply_write (stdout, os[0].nelems, os[0].elist, os[0].file_type);
747
748  /* count the vertices that are in the hash table */
749  vert_count = 0;
750  for (f=0; f < nFiles; f++) {
751    for (i = 0; i < os[f].nverts; i++) {
752      if (os[f].vlist[i]->shared == os[f].vlist[i]) {
753        // renumber vertices.
754        os[f].vlist[i]->index = vert_count;
755        vert_count++;
756      }
757    }
758  }
759
760  /* count the faces that do not have matches */
761  face_count = 0;
762  for (f=0; f < nFiles; f++) {
763    for (i = 0; i < os[f].nfaces; i++) {
764      if (os[f].flist[i]->nverts != 0) {
765        face_count++;
766      }
767    }
768  }
769
770  /* describe what properties go into the vertex and face elements */
771
772  ply_element_count (ply, "vertex", vert_count);
773  ply_describe_property (ply, "vertex", &vert_props[0]);
774  ply_describe_property (ply, "vertex", &vert_props[1]);
775  ply_describe_property (ply, "vertex", &vert_props[2]);
776  ply_describe_other_properties (ply, os[0].vert_other, 
777                                 offsetof(Vertex,other_props));
778
779  ply_element_count (ply, "face", face_count);
780  ply_describe_property (ply, "face", &face_props[0]);
781  ply_describe_other_properties (ply, os[0].face_other, offsetof(Face,other_props));
782
783  ply_describe_other_elements (ply, os[0].other_elements);
784
785  for (i = 0; i < os[0].num_comments; i++)
786    ply_put_comment (ply, os[0].comments[i]);
787
788  for (i = 0; i < os[0].num_obj_info; i++)
789    ply_put_obj_info (ply, os[0].obj_info[i]);
790
791  ply_header_complete (ply);
792
793  /* set up and write the vertex elements */
794
795  ply_put_element_setup (ply, "vertex");
796
797  for (f=0; f < nFiles; f++) {
798    for (i = 0; i < os[f].nverts; i++) {
799      if (os[f].vlist[i]->shared == os[f].vlist[i]) {
800        ply_put_element (ply, (void *) os[f].vlist[i]);
801        // fprintf(stderr, "Writing vertex %x\n", os[f].vlist[i]);
802      } else {
803        // fprintf(stderr, "Skipping vertex %x, shared %x\n",
804        //         os[f].vlist[i], os[f].vlist[i]->shared);
805      }
806    }
807  }
808  /* set up and write the face elements */
809
810  ply_put_element_setup (ply, "face");
811
812  for (f=0; f < nFiles; f++) {
813    for (i = 0; i < os[f].nfaces; i++) {
814      if (os[f].flist[i]->nverts == 0) {
815        continue;       
816      } 
817      // Reset the numbering scheme
818      for (j = 0; j < os[f].flist[i]->nverts; j++) {
819        os[f].flist[i]->verts[j] = os[f].flist[i]->vptrs[j]->shared->index;
820      }
821      // write out tri
822      ply_put_element (ply, (void *) os[f].flist[i]);
823    }
824  }
825
826  ply_put_other_elements (ply);
827
828  /* close the PLY file */
829  ply_close (ply);
830}
831
Note: See TracBrowser for help on using the repository browser.