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

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

Added original make3d

File size: 14.7 KB
Line 
1/*
2
3Brian Curless
4
5Computer Graphics Laboratory
6Stanford University
7
8---------------------------------------------------------------------
9
10Copyright (1997) The Board of Trustees of the Leland Stanford Junior
11University. Except for commercial resale, lease, license or other
12commercial transactions, permission is hereby given to use, copy,
13modify this software for academic purposes only.  No part of this
14software or any derivatives thereof may be used in the production of
15computer models for resale or for use in a commercial
16product. STANFORD MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND
17CONCERNING THIS SOFTWARE.  No support is implied or provided.
18
19*/
20
21
22#include <stdio.h>
23#include <ply.h>
24#include <stdlib.h>
25#include <strings.h>
26#include <iostream>
27#include <limits.h>
28
29#define MAX_VERT_PROPS 20
30
31#include "plyio.h"
32#include "vripGlobals.h"
33#include "rangePly.h"
34
35void keepUsedVerts(Mesh *mesh, int &numVertsUsed, 
36                   uchar *vertUsed, Triangle *tris);
37
38
39struct PlyVertex {
40    float x, y, z;
41    float nx, ny, nz;
42    uchar diff_r, diff_g, diff_b;
43    float intensity;
44    float std_dev;
45    float confidence;
46};
47
48
49struct PlyFace {
50    uchar nverts;
51    int *verts;
52};
53
54
55
56static PlyProperty vert_prop_x = 
57   {"x", PLY_FLOAT, PLY_FLOAT, 0, 0, PLY_START_TYPE, PLY_START_TYPE, 0};
58static PlyProperty vert_prop_y = 
59  {"y", PLY_FLOAT, PLY_FLOAT, 0, 0, PLY_START_TYPE, PLY_START_TYPE, 0};
60static PlyProperty vert_prop_z = 
61  {"z", PLY_FLOAT, PLY_FLOAT, 0, 0, PLY_START_TYPE, PLY_START_TYPE, 0};
62static PlyProperty vert_prop_nx = 
63   {"nx", PLY_FLOAT, PLY_FLOAT, 0, 0, PLY_START_TYPE, PLY_START_TYPE, 0};
64static PlyProperty vert_prop_ny = 
65  {"ny", PLY_FLOAT, PLY_FLOAT, 0, 0, PLY_START_TYPE, PLY_START_TYPE, 0};
66static PlyProperty vert_prop_nz = 
67  {"nz", PLY_FLOAT, PLY_FLOAT, 0, 0, PLY_START_TYPE, PLY_START_TYPE, 0};
68static PlyProperty vert_prop_intens = 
69  {"intensity", PLY_FLOAT, PLY_FLOAT, 0, 0, PLY_START_TYPE, PLY_START_TYPE, 0};
70static PlyProperty vert_prop_std_dev = 
71  {"std_dev", PLY_FLOAT, PLY_FLOAT, 0, 0, PLY_START_TYPE, PLY_START_TYPE, 0};
72static PlyProperty vert_prop_confidence = 
73  {"confidence", PLY_FLOAT, PLY_FLOAT, 0, 0, PLY_START_TYPE, PLY_START_TYPE, 0};
74static PlyProperty vert_prop_diff_r = 
75  {"diffuse_red", PLY_UCHAR, PLY_UCHAR, 0, 0, PLY_START_TYPE, PLY_START_TYPE, 0};
76static PlyProperty vert_prop_diff_g = 
77  {"diffuse_green", PLY_UCHAR, PLY_UCHAR, 0, 0, PLY_START_TYPE, PLY_START_TYPE, 0};
78static PlyProperty vert_prop_diff_b = 
79  {"diffuse_blue", PLY_UCHAR, PLY_UCHAR, 0, 0, PLY_START_TYPE, PLY_START_TYPE, 0};
80
81static PlyProperty vert_prop_r = 
82  {"red", PLY_UCHAR, PLY_UCHAR, 0, 0, PLY_START_TYPE, PLY_START_TYPE, 0};
83static PlyProperty vert_prop_g = 
84  {"green", PLY_UCHAR, PLY_UCHAR, 0, 0, PLY_START_TYPE, PLY_START_TYPE, 0};
85static PlyProperty vert_prop_b = 
86  {"blue", PLY_UCHAR, PLY_UCHAR, 0, 0, PLY_START_TYPE, PLY_START_TYPE, 0};
87
88static PlyProperty vert_props[MAX_VERT_PROPS];
89
90
91static PlyProperty face_props[] = { 
92  {"vertex_indices", PLY_INT, PLY_INT, 0, 1, PLY_UCHAR, PLY_UCHAR, 0},
93};
94
95
96/* dummy variables and associated macros for computing field offsets */
97
98static PlyVertex *vert_dummy;
99#define voffset(field) ((char *) (&vert_dummy->field) - (char *) vert_dummy)
100static PlyFace *face_dummy;
101#define foffset(field) ((char *) (&face_dummy->field) - (char *) face_dummy)
102
103
104
105
106//
107// Read in data from the ply file
108//
109
110Mesh *
111readPlyFile(const char *filename)
112{
113    int i, j;
114    int nelems;
115    char **elist;
116    int file_type;
117    float version;
118    char *elem_name;
119    int nprops, num_vert_props;
120    int num_elems;
121    PlyProperty **plist;
122
123    face_props[0].offset = foffset(verts);
124    face_props[0].count_offset = foffset(nverts);  /* count offset */
125   
126    PlyFile *ply = 
127        ply_open_for_reading(filename, &nelems, &elist, &file_type, &version);
128
129    if (!ply)
130        exit(1);
131
132    int nvp = 0;
133
134    if (ply_is_valid_property(ply, "vertex", vert_prop_x.name)) {
135        vert_props[nvp] = vert_prop_x;
136        vert_props[nvp].offset = voffset(x); nvp++;
137    }
138   
139    if (ply_is_valid_property(ply, "vertex", vert_prop_y.name)) {
140        vert_props[nvp] = vert_prop_y;
141        vert_props[nvp].offset = voffset(y); nvp++;
142    }
143   
144    if (ply_is_valid_property(ply, "vertex", vert_prop_z.name)) {
145        vert_props[nvp] = vert_prop_z;
146        vert_props[nvp].offset = voffset(z); nvp++;
147    }
148   
149    if (ply_is_valid_property(ply, "vertex", vert_prop_nx.name)) {
150        vert_props[nvp] = vert_prop_nx;
151        vert_props[nvp].offset = voffset(nx); nvp++;
152    }
153   
154    if (ply_is_valid_property(ply, "vertex", vert_prop_ny.name)) {
155        vert_props[nvp] = vert_prop_ny;
156        vert_props[nvp].offset = voffset(ny); nvp++;
157    }
158   
159    if (ply_is_valid_property(ply, "vertex", vert_prop_nz.name)) {
160        vert_props[nvp] = vert_prop_nz;
161        vert_props[nvp].offset = voffset(nz); nvp++;
162    }
163   
164    if (ply_is_valid_property(ply, "vertex", vert_prop_intens.name)) {
165        vert_props[nvp] = vert_prop_intens;
166        vert_props[nvp].offset = voffset(intensity); nvp++;
167    }
168   
169    if (ply_is_valid_property(ply, "vertex", vert_prop_std_dev.name)) {
170        vert_props[nvp] = vert_prop_std_dev;
171        vert_props[nvp].offset = voffset(std_dev); nvp++;
172    }
173   
174    int hasConfidence = 0;
175    if (ply_is_valid_property(ply, "vertex", vert_prop_confidence.name)) {
176        vert_props[nvp] = vert_prop_confidence;
177        vert_props[nvp].offset = voffset(confidence); nvp++;
178        hasConfidence = 1;
179    }
180   
181    int hasDiffColor = 0;
182    if (ply_is_valid_property(ply, "vertex", "diffuse_red") &&
183        ply_is_valid_property(ply, "vertex", "diffuse_green") &&
184        ply_is_valid_property(ply, "vertex", "diffuse_blue")) 
185    {
186        vert_props[nvp] = vert_prop_diff_r;
187        vert_props[nvp].offset = voffset(diff_r); nvp++;
188        vert_props[nvp] = vert_prop_diff_g;
189        vert_props[nvp].offset = voffset(diff_g); nvp++;
190        vert_props[nvp] = vert_prop_diff_b;
191        vert_props[nvp].offset = voffset(diff_b); nvp++;
192        hasDiffColor = 1;
193    }
194   
195    int hasColor = 0;
196    if (ply_is_valid_property(ply, "vertex", "red") &&
197        ply_is_valid_property(ply, "vertex", "green") &&
198        ply_is_valid_property(ply, "vertex", "blue")) 
199    {
200        vert_props[nvp] = vert_prop_r;
201        vert_props[nvp].offset = voffset(diff_r); nvp++;
202        vert_props[nvp] = vert_prop_g;
203        vert_props[nvp].offset = voffset(diff_g); nvp++;
204        vert_props[nvp] = vert_prop_b;
205        vert_props[nvp].offset = voffset(diff_b); nvp++;
206        hasColor = 1;
207    }
208   
209    num_vert_props = nvp;
210
211    Mesh *mesh = new Mesh;
212    mesh->hasConfidence = hasConfidence;
213    mesh->hasColor = hasColor || hasDiffColor;
214    Vertex *vert;
215    Triangle *tri;
216    PlyVertex plyVert;
217    PlyFace plyFace;
218
219    for (i = 0; i < nelems; i++) {
220
221        /* get the description of the first element */
222        elem_name = elist[i];
223        plist = ply_get_element_description
224            (ply, elem_name, &num_elems, &nprops);
225       
226        /* if we're on vertex elements, read them in */
227        if (equal_strings ("vertex", elem_name)) {
228           
229            mesh->numVerts = num_elems;
230            mesh->verts = new Vertex[mesh->numVerts];
231           
232            /* set up for getting vertex elements */
233            ply_get_element_setup (ply, elem_name, num_vert_props, vert_props);
234           
235            if (Verbose)
236                printf("Reading vertices...\n");
237
238            /* grab all the vertex elements */
239            for (j = 0; j < mesh->numVerts; j++) {
240                ply_get_element (ply, (void *) &plyVert);
241                vert = &mesh->verts[j];
242                vert->coord.x = plyVert.x;
243                vert->coord.y = plyVert.y;
244                vert->coord.z = plyVert.z;
245                if (hasConfidence)
246                    vert->confidence = plyVert.confidence;
247                else 
248                    vert->confidence = 1.0;
249                if (hasDiffColor ||  hasColor) {
250                   vert->red = plyVert.diff_r;
251                   vert->green = plyVert.diff_g;
252                   vert->blue = plyVert.diff_b;
253                }
254            }
255            fflush(stdout);
256
257            if (Verbose)
258                printf("Done.\n");
259
260        }
261
262        if (equal_strings ("face", elem_name)) {
263
264            ply_get_element_setup (ply, elem_name, 1, face_props);
265
266            mesh->numTris = num_elems;
267
268            if (mesh->numTris == 0)
269                continue;
270
271            mesh->tris = new Triangle[mesh->numTris];
272
273            if (Verbose)
274                printf("Reading Faces...\n");
275
276            for (j = 0; j < mesh->numTris; j++) {               
277                ply_get_element (ply, (void *) &plyFace);
278                tri = &mesh->tris[j];
279                tri->vindex1 = plyFace.verts[0];
280                tri->vindex2 = plyFace.verts[1];
281                tri->vindex3 = plyFace.verts[2];
282                free(plyFace.verts);
283            }
284
285            if (Verbose)
286                printf("Done.\n");
287        }
288    }
289
290    int num_obj_info, found_mirror;
291    char **obj_info = ply_get_obj_info (ply, &num_obj_info);
292
293    char temp[PATH_MAX];
294    found_mirror = FALSE;
295    mesh->isWarped = FALSE;
296    mesh->isRightMirrorOpen = TRUE;
297    for (i = 0; i < num_obj_info; i++) {
298        if (strstr(obj_info[i], "is_right_mirror_open")) {
299            found_mirror = TRUE;
300            sscanf(obj_info[i], "%s%d", temp, &mesh->isRightMirrorOpen);
301        }
302        else if (strstr(obj_info[i], "is_warped")) {
303            sscanf(obj_info[i], "%s%d", temp, &mesh->isWarped);
304        }
305    }
306
307    if (mesh->isWarped && !found_mirror)
308        printf("Couldn't tell which mirror was open.  Right mirror assumed.\n");
309
310    ply_close(ply);
311    return mesh;
312}
313
314
315int
316writePlyFile(const char *filename, Mesh *mesh)
317{
318    int i, j;
319    int nelems;
320    char **elist;
321    int file_type;
322    float version;
323    char *elem_name;
324    int nprops, num_vert_props;
325    int num_elems;
326    PlyProperty **plist;
327    int hasIntensity;
328    int hasColor;
329    int hasConfidence;
330    int nvp;
331    char *elem_names[] = {"vertex", "face"};
332    PlyFile *ply;
333
334   if (filename == NULL) {
335       ply = ply_write(stdout, 2, elem_names, PLY_BINARY_BE);
336    } else {
337       ply = ply_open_for_writing(filename, 2, elem_names, 
338                            PLY_BINARY_BE, &version);
339    }
340
341    if (ply == NULL)
342        return 0;
343
344    int numVertsUsed;
345    uchar *vertUsed = new uchar[mesh->numVerts];
346    Triangle *tris = new Triangle[mesh->numTris];
347    keepUsedVerts(mesh, numVertsUsed, vertUsed, tris);
348
349    nvp = 0;
350
351    vert_props[nvp] = vert_prop_x;
352    vert_props[nvp].offset = offsetof(PlyVertex,x); nvp++;
353    vert_props[nvp] = vert_prop_y;
354    vert_props[nvp].offset = offsetof(PlyVertex,y); nvp++;
355    vert_props[nvp] = vert_prop_z;
356    vert_props[nvp].offset = offsetof(PlyVertex,z); nvp++;
357
358    if (mesh->hasConfidence) {
359       vert_props[nvp] = vert_prop_confidence;
360       vert_props[nvp].offset = offsetof(PlyVertex, confidence); nvp++;
361    }
362
363    if (mesh->hasColor) {
364        vert_props[nvp] = vert_prop_diff_r;
365        vert_props[nvp].offset = voffset(diff_r); nvp++;
366        vert_props[nvp] = vert_prop_diff_g;
367        vert_props[nvp].offset = voffset(diff_g); nvp++;
368        vert_props[nvp] = vert_prop_diff_b;
369        vert_props[nvp].offset = voffset(diff_b); nvp++;
370    }
371
372    num_vert_props = nvp;
373
374    face_props[0].offset = offsetof(PlyFace, verts);
375    face_props[0].count_offset = offsetof(PlyFace, nverts);  /* count offset */
376   
377    ply_describe_element (ply, "vertex", numVertsUsed, 
378                          num_vert_props, vert_props);
379
380    ply_describe_element (ply, "face", mesh->numTris, 1, face_props);
381
382    ply_header_complete (ply);
383   
384
385
386    /* set up and write the vertex elements */
387    PlyVertex plyVert;
388    Vertex *vert;
389
390    ply_put_element_setup (ply, "vertex");
391
392     for (i = 0; i < mesh->numVerts; i++) {
393       if (!vertUsed[i])
394         continue;
395
396        vert = &mesh->verts[i];
397        plyVert.x = vert->coord.x;
398        plyVert.y = vert->coord.y;
399        plyVert.z = vert->coord.z;
400
401        if (mesh->hasConfidence)
402           plyVert.confidence = vert->confidence;
403
404
405        if (mesh->hasColor) {
406           plyVert.diff_r = vert->red;
407           plyVert.diff_g = vert->green;
408           plyVert.diff_b = vert->blue;
409        }
410           
411        ply_put_element (ply, (void *) &plyVert);
412    }
413
414    PlyFace plyFace;
415    Triangle *tri;
416    int vertIndices[3];
417
418    ply_put_element_setup (ply, "face");
419
420    for (i = 0; i < mesh->numTris; i++) {
421        tri = &tris[i];
422        plyFace.nverts = 3;
423        vertIndices[0] = tri->vindex1;
424        vertIndices[1] = tri->vindex2;
425        vertIndices[2] = tri->vindex3;
426        plyFace.verts = (int *)vertIndices;
427
428        ply_put_element (ply, (void *) &plyFace);
429    }
430   
431    /* close the PLY file */
432    ply_close (ply);   
433
434    delete [] vertUsed;
435    delete [] tris;
436
437    return 1;
438}
439
440
441
442
443Mesh *
444readMeshFromPly(const char *filename, int fillGaps, int extendEdges)
445{
446    int i;
447    Mesh *mesh;
448
449    if (is_range_grid_file(filename)) {
450        RangeGrid *rangeGrid;
451        if (fillGaps) {
452            rangeGrid = readRangeGridFillGaps(filename);
453            if (rangeGrid == NULL) {
454                return NULL;
455            }
456            mesh = meshFromGrid(rangeGrid, MeshResolution, TRUE);
457        } else if (extendEdges) {
458            rangeGrid = readRangeGridExtendEdges(filename);
459            if (rangeGrid == NULL) {
460                return NULL;
461            }
462            mesh = meshFromGrid(rangeGrid, MeshResolution, FALSE);
463        } else {
464            rangeGrid = readRangeGrid(filename);
465            if (rangeGrid == NULL) {
466                return NULL;
467            }
468            mesh = meshFromGrid(rangeGrid, MeshResolution, FALSE);
469        }
470        delete rangeGrid;
471    }
472    else {
473        mesh = readPlyFile(filename);
474        if (mesh == NULL)
475            return NULL;
476        else
477           prepareMesh(mesh);
478   }   
479
480    return mesh;
481}
482
483void
484prepareMesh(Mesh *mesh) 
485{
486   int i;
487   for (i = 0; i < mesh->numVerts; i++) {
488      mesh->verts[i].stepsToEdge = 0;   
489      mesh->verts[i].holeFill = FALSE;   
490      mesh->verts[i].numVerts = 0;   
491      mesh->verts[i].numTris = 0;   
492      mesh->verts[i].maxVerts = 8;
493      mesh->verts[i].verts = new Vertex*[8];
494      mesh->verts[i].edgeLengths = new float[8];
495      mesh->verts[i].maxTris = 8;
496      mesh->verts[i].tris = new Triangle*[8];
497   }
498   
499   for (i = 0; i < mesh->numTris; i++) {
500      Triangle *tri = &mesh->tris[i];
501     
502      Vertex *vert1 = &mesh->verts[tri->vindex1];
503      Vertex *vert2 = &mesh->verts[tri->vindex2];
504      Vertex *vert3 = &mesh->verts[tri->vindex3];
505     
506      if (vert1->numTris == vert1->maxTris)
507         reallocTris(vert1);
508     
509      if (vert2->numTris == vert2->maxTris)
510         reallocTris(vert2);
511     
512      if (vert3->numTris == vert3->maxTris)
513         reallocTris(vert3);
514     
515      vert1->tris[vert1->numTris++] = tri;
516      vert2->tris[vert2->numTris++] = tri;
517      vert3->tris[vert3->numTris++] = tri;
518     
519      addNeighbors(vert1,vert2);
520      addNeighbors(vert1,vert3);
521      addNeighbors(vert2,vert3);
522     
523   }
524   
525   mesh->initNormals(); 
526   find_mesh_edges(mesh);
527}
528
529
530void
531keepUsedVerts(Mesh *mesh, int &numVertsUsed, 
532              uchar *vertUsed, Triangle *tris) 
533{
534   int i;
535
536   // Figure out which ones got used
537   for (i = 0; i < mesh->numVerts; i++) {
538      vertUsed[i] = 0;
539   }
540   
541   for (i = 0; i < mesh->numTris; i++) {
542      vertUsed[mesh->tris[i].vindex1] = 1;
543      vertUsed[mesh->tris[i].vindex2] = 1;
544      vertUsed[mesh->tris[i].vindex3] = 1;
545   }
546   
547   // Count the number used and build new vertex array
548   //  and re-indexing array and delete allocations
549   //  from unused verts
550   int count = 0;
551   int *reIndex = new int[mesh->numVerts];
552   for (i = 0; i < mesh->numVerts; i++) {
553      if (vertUsed[i]) {
554         reIndex[i] = count;
555         count++;
556      }
557   }
558   
559   numVertsUsed = count;
560 
561   // Now re-index triangles
562   for (i = 0; i < mesh->numTris; i++) {
563      tris[i].vindex1 = reIndex[mesh->tris[i].vindex1];
564      tris[i].vindex2 = reIndex[mesh->tris[i].vindex2];
565      tris[i].vindex3 = reIndex[mesh->tris[i].vindex3];
566   } 
567
568   delete [] reIndex;   
569}
Note: See TracBrowser for help on using the repository browser.