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

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

Added original make3d

File size: 10.2 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 "Mesh.h"
23#include <limits.h>
24#include "rangePly.h"
25#include "plyio.h"
26#include "vripGlobals.h"
27
28#ifdef linux
29#include <float.h>
30#endif
31
32static void lower_edge_confidence(Mesh *mesh);
33static void lower_edge_confidence_2(Mesh *mesh);
34
35
36Mesh::Mesh()
37{
38    numVerts = 0;
39    verts = NULL;
40   
41    numTris = 0;
42    tris = NULL;
43
44    hasConfidence = 0;
45    hasColor = 0;
46}
47
48
49Mesh::~Mesh()
50{
51    if (verts != NULL) {
52        for (int i = 0; i < numVerts; i++) {
53            delete [] verts[i].verts;
54            delete [] verts[i].edgeLengths;
55            delete [] verts[i].tris;
56        }
57
58        delete [] verts;
59    }
60
61    if (tris != NULL) {
62        delete [] tris;
63    }
64}
65
66 
67
68void
69Mesh::computeBBox()
70{
71    bbox.init();
72
73    Vertex *buf = this->verts;
74    for (int i = 0; i < this->numVerts; i++, buf++) {
75        bbox.update(buf->coord);
76    }
77}
78
79
80void
81Mesh::initNormals()
82{
83    computeTriNormals();
84    computeVertNormals();
85}
86
87
88void
89Mesh::computeTriNormals()
90{
91    Vec3f v1, v2, v3, norm;
92    Triangle *tri;
93    int i;
94
95    for (i = 0; i < numTris; i++) {
96        tri = &tris[i];
97        v1.setValue(verts[tri->vindex1].coord);
98        v2.setValue(verts[tri->vindex2].coord);
99        v3.setValue(verts[tri->vindex3].coord);
100        v2 = v1 - v2;
101        v3 = v1 - v3;
102        tri->norm = v2.cross(v3);
103        tri->norm.normalize();
104    }
105}
106
107void
108Mesh::computeVertNormals()
109{
110    Vec3f norm;
111    int i, index;
112
113    for (i = 0; i < numVerts; i++) {
114        verts[i].norm.setValue(0, 0, 0);
115    }
116
117    for (i = 0; i < numTris; i++) {
118        index = tris[i].vindex1;
119        verts[index].norm += tris[i].norm;
120       
121        index = tris[i].vindex2;
122        verts[index].norm += tris[i].norm;
123       
124        index = tris[i].vindex3;
125        verts[index].norm += tris[i].norm;
126    }
127
128    for (i = 0; i < numVerts; i++) {
129        verts[i].norm.normalize();
130    }
131}
132
133
134void
135doConfidence(Mesh *mesh, int perspective)
136{
137    float dotLaser, angleLaser, radAngleLaser;
138    float dotCCD, angleCCD, radAngleCCD;
139    float weight;
140    Vec3f dirLaser, dirCCD;
141
142    if (mesh->isWarped) {
143        if (mesh->isRightMirrorOpen) {
144            angleCCD = 30;
145        } else {
146            angleCCD = -30;
147        }
148        radAngleCCD = angleCCD*M_PI/180;
149        dirCCD.setValue(sin(radAngleCCD), 0, cos(radAngleCCD));
150
151        angleLaser = 0;
152        radAngleLaser = angleLaser*M_PI/180;
153        dirLaser.setValue(sin(radAngleLaser), 0, cos(radAngleLaser));
154
155        for (int i = 0; i < mesh->numVerts; i++) {
156
157            // No confidence for "phony" polygons and their vertices
158            if (mesh->verts[i].holeFill) {
159                mesh->verts[i].confidence = 0;
160            } else {
161                dotCCD = dirCCD.dot(mesh->verts[i].norm);
162                dotCCD = MAX(dotCCD,0);
163                dotLaser = dirLaser.dot(mesh->verts[i].norm);
164                dotLaser = MAX(dotLaser,0);
165
166               
167                weight = dotLaser*dotCCD;
168               
169                // Dividing by 0.9 scales it back up some.  Min is about 0.8
170                //weight = pow(weight, ConfidenceExponent)/0.9;
171                //if (weight < 0.001)
172                //   weight = 0;
173
174                weight = dotCCD;
175                weight = pow(weight, ConfidenceExponent);
176
177                mesh->verts[i].confidence *= weight;
178            }
179        }
180    }
181    else if (!perspective) {
182        angleLaser = 0;
183        radAngleLaser = angleLaser*M_PI/180;
184        dirLaser.setValue(sin(radAngleLaser), 0, cos(radAngleLaser));
185
186        for (int i = 0; i < mesh->numVerts; i++) {
187            if (mesh->verts[i].holeFill) {
188                mesh->verts[i].confidence = 0;
189            } else {
190                dotLaser = dirLaser.dot(mesh->verts[i].norm);
191                dotLaser = MAX(dotLaser,0);
192                weight = pow(dotLaser, ConfidenceExponent);
193                mesh->verts[i].confidence *= weight;
194            }
195        }
196    } else {
197        angleLaser = 0;
198        radAngleLaser = angleLaser*M_PI/180;
199        dirLaser.setValue(sin(radAngleLaser), 0, cos(radAngleLaser));
200
201        for (int i = 0; i < mesh->numVerts; i++) {
202            if (mesh->verts[i].holeFill) {
203                mesh->verts[i].confidence = 0;
204            } else {
205                dirLaser = PerspectiveCOP - mesh->verts[i].coord;
206                dirLaser.normalize();
207                dotLaser = dirLaser.dot(mesh->verts[i].norm);
208                dotLaser = MAX(dotLaser,0);
209                weight = pow(dotLaser, ConfidenceExponent);
210                mesh->verts[i].confidence *= weight;
211            }
212        }
213    }
214
215    lower_edge_confidence(mesh);
216
217    mesh->hasConfidence = 1;
218
219}
220
221
222/******************************************************************************
223Lower the confidence value on edges.
224
225Entry:
226  mesh  - mesh on which to lower the edge confidence
227  level - level of mesh detail
228******************************************************************************/
229
230static void
231lower_edge_confidence(Mesh *mesh)
232{
233  int i,j,k;
234  int pass;
235  int val;
236  float recip, weight;
237  Vertex *v;
238  int chew_count;
239
240  switch (MeshResolution) {
241    case 1:
242      chew_count = EdgeConfSteps;
243      break;
244    case 2:
245      chew_count = EdgeConfSteps/2;
246      break;
247    case 3:
248      chew_count = EdgeConfSteps/4;
249      break;
250    case 4:
251      chew_count = EdgeConfSteps/8;
252      break;
253  }
254
255  if (chew_count == 0) {
256     return;
257  }
258
259  MaxStepsToEdge = chew_count;
260
261  for (i = 0; i < mesh->numVerts; i++) {
262     
263      v = &mesh->verts[i];
264      if (v->stepsToEdge >= 0) {
265          if (v->on_edge) {
266              v->stepsToEdge = 0;
267          } else {
268              v->stepsToEdge = chew_count;
269          }
270      }
271  }
272
273  /* make several passes through the vertices */
274  for (pass = 1; pass < chew_count; pass++) {
275
276    /* propagate higher on-edge values away from edges */
277    for (i = 0; i < mesh->numVerts; i++) {
278
279      v = &mesh->verts[i];
280      if (v->on_edge != 0)
281        continue;
282
283      for (j = 0; j < v->numVerts; j++) {
284        if (v->verts[j]->on_edge == pass) {
285          v->on_edge = pass+1;
286          v->stepsToEdge = pass;
287          break;
288        }
289      }
290    }
291  }
292
293
294  /* lower the confidences on the edge */
295
296  recip = 1.0 / (chew_count);
297
298  for (i = 0; i < mesh->numVerts; i++) {
299      v = &mesh->verts[i];
300      val = v->on_edge;
301      if (val) {
302          weight = (val-1) * recip;
303          weight = pow(weight, EdgeConfExponent);
304          v->confidence *= weight;
305          v->confidence += ConfidenceBias/255.0;
306          v->confidence = MIN(v->confidence, 1.0);
307          if (val > 1)
308              v->on_edge = 0;
309      }
310  }
311}
312
313
314
315static void
316lower_edge_confidence_2(Mesh *mesh)
317{
318  int i,j,k;
319  int pass;
320  int val;
321  float recip, max_dist, newDist;
322  Vertex *v;
323  int chew_count;
324
325#if 0
326  switch (level) {
327    case 0:
328      chew_count = (int)(8*CONF_EDGE_COUNT_FACTOR+0.5);
329      break;
330    case 1:
331      chew_count = (int)(4*CONF_EDGE_COUNT_FACTOR+0.5);
332      break;
333    case 2:
334      chew_count = (int)(2*CONF_EDGE_COUNT_FACTOR+0.5);
335      break;
336    case 3:
337      chew_count = (int)(1*CONF_EDGE_COUNT_FACTOR+0.5);
338      break;
339    default:
340      fprintf (stderr, "lower_edge_confidence: bad switch %d\n", level);
341      exit (-1);
342  }
343#endif
344
345
346    for (i = 0; i < mesh->numVerts; i++) {
347      v = &mesh->verts[i];
348      if (v->on_edge) {
349          v->distToBoundary = 0;
350      } else {
351          v->distToBoundary = FLT_MAX;
352      }
353    }
354
355  chew_count = 16;
356
357  max_dist = chew_count * 0.0005;
358  printf("Arbitrary scale factor in edge confidence!\n");
359
360  /* make several passes through the vertices */
361  for (pass = 1; pass < chew_count; pass++) {
362
363    /* propagate higher on-edge values away from edges */
364    for (i = 0; i < mesh->numVerts; i++) {
365
366      v = &mesh->verts[i];
367      if (v->on_edge)
368        continue;
369
370      for (j = 0; j < v->numVerts; j++) {
371        if (v->verts[j]->distToBoundary != FLT_MAX) {
372            newDist = v->verts[j]->distToBoundary + v->edgeLengths[j];
373            v->distToBoundary = MIN(v->distToBoundary, newDist);
374        }
375      }
376    }
377  }
378
379  /* lower the confidences on the edge */
380
381  for (i = 0; i < mesh->numVerts; i++) {
382      v = &mesh->verts[i];
383      if (v->distToBoundary < max_dist) {
384          v->confidence *= v->distToBoundary/max_dist;
385      }
386  }
387}
388
389
390void
391reallocVerts(Vertex *v)
392{
393    int i;
394    Vertex **newVerts;
395    float *newLengths;
396
397    v->maxVerts *= 2;
398    newVerts = new Vertex*[v->maxVerts];
399    newLengths = new float[v->maxVerts];
400    for (i = 0; i < v->numVerts; i++) {
401        newVerts[i] = v->verts[i];
402        newLengths[i] = v->edgeLengths[i];
403    }
404    delete [] v->verts;
405    delete [] v->edgeLengths;
406
407    v->verts = newVerts;
408    v->edgeLengths = newLengths;
409}
410
411
412void
413reallocTris(Vertex *v)
414{
415    int i;
416    Triangle **newTris;
417
418    v->maxTris *= 2;
419    newTris = new Triangle*[v->maxTris];
420    for (i = 0; i < v->numTris; i++) {
421        newTris[i] = v->tris[i];
422    }
423    delete [] v->tris;
424
425    v->tris = newTris;
426}
427
428
429Mesh *
430cleanMesh(Mesh *inMesh)
431{
432  int i;
433
434  Mesh *outMesh = new Mesh;
435
436  outMesh->numVerts = 0;
437  int max_verts = inMesh->numVerts;
438  outMesh->verts = new Vertex[max_verts];
439
440  outMesh->numTris = 0;
441  int max_tris = inMesh->numTris;
442  outMesh->tris = new Triangle[max_tris];
443
444  outMesh->hasConfidence = inMesh->hasConfidence;
445  outMesh->hasColor = inMesh->hasColor;
446
447  int *vertRemap = new int[inMesh->numVerts];
448  int outIndex = 0;
449  for (i = 0; i < inMesh->numVerts; i++) {
450     if (inMesh->verts[i].confidence < MinVertexConfidence) {
451        vertRemap[i] = -1;
452     } else {
453        outMesh->verts[outIndex].coord = inMesh->verts[i].coord;
454        vertRemap[i] = outIndex;
455        if (inMesh->hasConfidence)
456           outMesh->verts[outIndex].confidence = inMesh->verts[i].confidence;
457        else 
458           outMesh->verts[outMesh->numVerts].confidence = 1;
459
460        if (inMesh->hasColor) {
461           outMesh->verts[outMesh->numVerts].red = inMesh->verts[i].red;
462           outMesh->verts[outMesh->numVerts].green = inMesh->verts[i].green;
463           outMesh->verts[outMesh->numVerts].blue = inMesh->verts[i].blue;
464        }       
465        outIndex++;
466     }
467  }
468 
469  outMesh->numVerts = outIndex;
470
471  /* create the triangles */
472  outIndex = 0;
473  for (i = 0; i < inMesh->numTris; i++) {
474     if (vertRemap[inMesh->tris[i].vindex1] == -1 ||
475         vertRemap[inMesh->tris[i].vindex2] == -1 ||
476         vertRemap[inMesh->tris[i].vindex3] == -1 ) {
477           continue;
478        }
479 
480     outMesh->tris[outIndex].vindex1 = vertRemap[inMesh->tris[i].vindex1];
481     outMesh->tris[outIndex].vindex2 = vertRemap[inMesh->tris[i].vindex2];
482     outMesh->tris[outIndex].vindex3 = vertRemap[inMesh->tris[i].vindex3];
483     outIndex++;
484  }
485
486  outMesh->numTris = outIndex;
487
488  outMesh->initNormals(); 
489
490  find_mesh_edges(outMesh);
491
492  prepareMesh(outMesh);
493
494  return (outMesh);
495}
Note: See TracBrowser for help on using the repository browser.