source: GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/AdjModel.cxx @ 774

Revision 774, 10.8 KB checked in by gumbau, 18 years ago (diff)

GTGeometry and GeoTool? initial imports

Line 
1/************************************************************************
2
3  Adjacency model representation.
4  $Id: AdjModel.cxx,v 1.1 1997/06/25 15:24:52 garland Exp $
5
6  Adapted from:
7     mlab: (Id: polymodel.cc,v 1.21 1997/02/06 16:34:14 garland Exp)
8  via
9     QSlim: (Id: polymodel.cc,v 1.5 1997/02/25 20:36:36 garland Exp)
10
11 ************************************************************************/
12
13#include "AdjModel.h"
14
15using namespace qslim;
16
17int Model::in_Vertex(const Vec3& p)
18{
19    Vertex *v = newVertex(p[X], p[Y], p[Z]);
20    bounds.addPoint(p);
21    return vertCount() - 1;
22}
23
24int Model::in_Normal(const Vec3& n)
25{
26        normals.add(n);
27        return normCount()-1;
28}
29
30int Model::in_TexCoord(const Vec2& t)
31{
32        texcoords.add(t);
33        return texcoordCount()-1;
34}
35
36int Model::in_Face(int a, int b, int c, int n1, int n2, int n3, int t1, int t2, int t3)
37{
38    Vertex *v1 = vertices(a-1);
39    Vertex *v2 = vertices(b-1);
40    Vertex *v3 = vertices(c-1);
41       
42    Face *t = newFace(v1, v2, v3);
43
44        t->normals[0] = n1;
45        t->normals[1] = n2;
46        t->normals[2] = n3;
47
48        t->texcoords[0] = t1;
49        t->texcoords[1] = t2;   
50        t->texcoords[2] = t3;
51
52        return faceCount() - 1;
53}
54
55int Model::miin_Face(int a, int b, int c)
56{
57    Vertex *v1 = vertices(a-1);
58    Vertex *v2 = vertices(b-1);
59    Vertex *v3 = vertices(c-1);
60       
61    Face *t = newFace(v1, v2, v3);
62
63        t->normals[0] = a;
64        t->normals[1] = b;
65        t->normals[2] = c;
66
67        t->texcoords[0] = a;
68        t->texcoords[1] = b;   
69        t->texcoords[2] = c;
70
71        return faceCount() - 1;
72}
73
74#ifdef SUPPORT_FCOLOR
75int Model::in_FColor(const Vec3& c)
76{
77    Face *f = faces(faces.length()-1);
78
79    if( !f->props )
80        f->props = new FProp;
81
82    f->props->color = c;
83    return 0;
84}
85#endif
86
87#ifdef SUPPORT_VCOLOR
88int Model::in_VColor(const Vec3& c)
89{
90    Vertex *v = vertices(vertices.length()-1);
91
92    if( !v->props )
93        v->props = new VProp;
94
95    v->props->color = c;
96    return 0;
97}
98#endif
99
100Vec3 Model::synthesizeNormal(Vertex *v)
101{
102    Vec3 n(0,0,0);
103    int n_count = 0;
104
105    edge_buffer& edges = v->edgeUses();
106    for(int i=0; i<edges.length(); i++)
107    {
108        face_buffer& faces = edges(i)->faceUses();
109
110        for(int j=0; j<faces.length(); j++)
111        {
112            n += faces(j)->plane().normal();
113            n_count++;
114        }
115    }
116
117    if( n_count )
118        n /= (real)n_count;
119    else
120    {
121                std::cerr << "Vertex with no normals!!: " << v->uniqID;
122                std::cerr << " / " << v->tempID << std::endl;
123    }
124    return n;
125}
126
127
128////////////////////////////////////////////////////////////////////////
129//
130// Model Transmogrification:
131//
132// These routines are the basic model munging procedures.
133// All model simplification is implemented in terms of these
134// transmogrification primitives.
135////////////////////////////////////////////////////////////////////////
136
137
138Vertex *Model::newVertex(real x, real y, real z)
139{
140    Vertex *v = new Vertex(x, y, z);
141
142    v->vID = v->uniqID = vertices.add(v);
143
144/*    if( logfile && selected_output&OUTPUT_MODEL_DEFN )
145                *logfile << "v " << x << " " << y << " " << z << std::endl;
146*/
147    validVertCount++;
148
149    return v;
150}
151
152Edge *Model::newEdge(Vertex *a, Vertex *b)
153{
154    Edge *e = new Edge(a, b);
155
156    e->uniqID = edges.add(e);
157    e->sym()->uniqID = e->uniqID;
158
159    validEdgeCount++;
160
161    return e;
162}
163
164static Edge *get_edge(Model *m, Vertex *org, Vertex *v)
165{
166    edge_buffer& edge_uses = org->edgeUses();
167
168    for(int i=0; i<edge_uses.length(); i++)
169        if( edge_uses(i)->dest() == v )
170            return edge_uses(i);
171
172    Edge *e = m->newEdge(org, v);
173
174    return e;
175}
176
177
178Face *Model::newFace(Vertex *v1, Vertex *v2, Vertex *v3)
179{
180    Edge *e0 = get_edge(this, v1, v2);   // v1->edgeTo(m, v2);
181    Edge *e1 = get_edge(this, v2, v3);   // v2->edgeTo(m, v3);
182    Edge *e2 = get_edge(this, v3, v1);   // v3->edgeTo(m, v1);
183 
184    Face *t = new Face(e0, e1, e2);
185
186    t->uniqID = faces.add(t);
187
188/*    if( logfile && selected_output&OUTPUT_MODEL_DEFN )
189        *logfile << "f " << v1->uniqID+1 << " "
190        << v2->uniqID+1 << " " << v3->uniqID+1 << std::endl;
191*/
192    validFaceCount++;
193
194    return t;
195}
196
197
198void Model::killVertex(Vertex *v)
199{
200    if( v->isValid() )
201    {
202/*      if( logfile && selected_output&OUTPUT_CONTRACTIONS )
203                *logfile << "v- " << v->uniqID+1 << std::endl;
204*/
205        v->kill();
206        validVertCount--;
207    }
208}
209
210void Model::killEdge(Edge *e)
211{
212    if( e->isValid() )
213    {
214        e->kill();
215        validEdgeCount--;
216    }
217}
218
219void Model::killFace(Face *f)
220{
221    if( f->isValid() )
222    {
223/*      if( logfile && selected_output&OUTPUT_CONTRACTIONS )
224                *logfile << "f- " << f->uniqID+1 << std::endl;
225*/
226        f->kill();
227        validFaceCount--;
228    }
229}
230
231void Model::reshapeVertex(Vertex *v, real x, real y, real z)
232{
233    v->set(x, y, z);
234
235#ifdef LOG_LOWLEVEL_OPS
236    if( logfile )
237        *logfile << "v! " << v->uniqID+1 << " "
238                 << x << " " << y << " " << z << endl;
239#endif
240}
241
242void Model::remapVertex(Vertex *from, Vertex *to)
243{
244    from->remapTo(to);
245
246#ifdef LOG_LOWLEVEL_OPS
247    if( logfile )
248        *logfile << "v> " << from->uniqID+1 << " " << to->uniqID+1 << endl;
249#endif
250}
251
252
253
254void Model::contract(Vertex *v1,
255                     const vert_buffer& rest,
256                     const Vec3& to,
257                     face_buffer& changed)
258{
259    int i;
260
261/*    if( logfile && selected_output&OUTPUT_CONTRACTIONS )
262    {
263        *logfile << "v% (" << v1->uniqID+1;
264        for(i=0; i<rest.length(); i++)
265            *logfile << " " << rest(i)->uniqID+1;
266       
267        *logfile << ") " << to[X] << " " << to[Y] << " " << to[Z] << std::endl;
268    }
269*/
270
271    //
272    // Collect all the faces that are going to be changed
273    //
274    contractionRegion(v1, rest, changed);
275
276    reshapeVertex(v1, to[X], to[Y], to[Z]);
277
278    for(i=0; i<rest.length(); i++)
279                rest(i)->remapTo(v1);
280
281    removeDegeneracy(changed);
282}
283
284void Model::maybeFixFace(Face *F)
285{
286    //
287    // Invalid faces do not need to be fixed.
288#ifdef SAFETY
289    assert( F->isValid() );
290#endif
291
292    Vertex *v0=F->vertex(0); Vertex *v1=F->vertex(1); Vertex *v2=F->vertex(2);
293    Edge *e0 = F->edge(0); Edge *e1 = F->edge(1); Edge *e2 = F->edge(2);
294
295    bool a=(v0 == v1),  b=(v0 == v2),  c=(v1 == v2);
296
297    if( a && c )
298    {
299        // This triangle has been reduced to a point
300        killEdge(e0);
301        killEdge(e1);
302        killEdge(e2);
303
304        killFace(F);
305    }
306    //
307    // In the following 3 cases, the triangle has become an edge
308    else if( a )
309    {
310        killEdge(e0);
311        e1->remapTo(e2->sym());
312        killFace(F);
313    }
314    else if( b )
315    {
316        killEdge(e2);
317        e0->remapTo(e1->sym());
318        killFace(F);
319    }
320    else if( c )
321    {
322        killEdge(e1);
323        e0->remapTo(e2->sym());
324        killFace(F);
325    }
326    else
327    {
328        // This triangle remains non-degenerate
329/*              // SUS: recalcular la normal en los triangulos cambiados no degenerados
330
331                qslim::Vertex * auxv0 = F->vertex(0);
332                qslim::Vertex * auxv1 = F->vertex(1);
333                qslim::Vertex * auxv2 = F->vertex(2);
334                qslim::Vec3 vd1(auxv1->operator[](qslim::X) - auxv0->operator[](qslim::X),
335                                                auxv1->operator[](qslim::Y) - auxv0->operator[](qslim::Y),
336                                                auxv1->operator[](qslim::Z) - auxv0->operator[](qslim::Z));
337                qslim::Vec3 vd2(auxv2->operator[](qslim::X) - auxv0->operator[](qslim::X),
338                                                auxv2->operator[](qslim::Y) - auxv0->operator[](qslim::Y),
339                                                auxv2->operator[](qslim::Z) - auxv0->operator[](qslim::Z));
340
341                qslim::unitize(vd1);
342                qslim::unitize(vd2);
343
344                qslim::Vec3 vn = vd1 ^ vd2;
345                qslim::unitize(vn);
346               
347                //auxf->vertex_normals[0] = vn;
348                //auxf->vertex_normals[1] = vn;
349                //auxf->vertex_normals[2] = vn;
350                F->vertex_normals[0][qslim::X] = vn[qslim::X];
351                F->vertex_normals[0][qslim::Y] = vn[qslim::Y];
352                F->vertex_normals[0][qslim::Z] = vn[qslim::Z];
353                F->vertex_normals[1][qslim::X] = vn[qslim::X];
354                F->vertex_normals[1][qslim::Y] = vn[qslim::Y];
355                F->vertex_normals[1][qslim::Z] = vn[qslim::Z];
356                F->vertex_normals[2][qslim::X] = vn[qslim::X];
357                F->vertex_normals[2][qslim::Y] = vn[qslim::Y];
358                F->vertex_normals[2][qslim::Z] = vn[qslim::Z];*/
359
360    }
361}
362
363void Model::removeDegeneracy(face_buffer& changed)
364{
365    for(int i=0; i<changed.length(); i++)
366                maybeFixFace(changed(i));
367}
368
369void Model::contractionRegion(Vertex *v1,
370                              const vert_buffer& vertices,
371                              face_buffer& changed)
372{
373    changed.reset();
374
375    //
376    // First, reset the marks on all reachable vertices
377    int i;
378
379    untagFaceLoop(v1);
380    for(i=0; i<vertices.length(); i++)
381                untagFaceLoop(vertices(i));
382
383    //
384    // Now, pick out all the unique reachable faces
385    collectFaceLoop(v1, changed);
386    for(i=0; i<vertices.length(); i++)
387                collectFaceLoop(vertices(i), changed);
388}
389
390
391void Model::contractionRegion(Vertex *v1, Vertex *v2, face_buffer& changed)
392{
393    changed.reset();
394
395    //
396    // Clear marks on all reachable faces
397    untagFaceLoop(v1);
398    untagFaceLoop(v2);
399
400    //
401    // Collect all the unique reachable faces
402    collectFaceLoop(v1, changed);
403    collectFaceLoop(v2, changed);
404}
405
406void Model::contract(Vertex *v1, Vertex *v2, const Vec3& to,
407                     face_buffer& changed)
408{
409#ifdef SAFETY
410    assert( v1 != v2);
411#endif
412
413/*    if( logfile && selected_output&OUTPUT_CONTRACTIONS )
414        *logfile << "v% (" << v1->uniqID+1 << " " << v2->uniqID+1 << ") "
415                 << to[X] << " "
416                 << to[Y] << " "
417                 << to[Z] << std::endl;
418*/
419    //
420    // Collect all the faces that are going to be changed
421    //
422    contractionRegion(v1, v2, changed);
423
424    reshapeVertex(v1, to[X], to[Y], to[Z]);
425
426    //
427    // Map v2 ---> v1.  This accomplishes the topological change that we want.
428    v2->remapTo(v1);
429
430    removeDegeneracy(changed);
431}
432
433
434/*
435ostream& operator<<(ostream& out, Model& M)
436{
437    int i;
438    int uniqVerts = 0;
439
440    out << "#$SMF 1.0" << endl;
441
442    out_annotate(out, M);
443
444    for(i=0; i<M.vertCount(); i++)
445    {
446        if( M.vertex(i)->isValid() )
447        {
448            M.vertex(i)->tempID = ++uniqVerts;
449
450            out_annotate(out, M.vertex(i));
451            const Vertex& v = *M.vertex(i);
452            out << "v " << v[X] << " " << v[Y] << " " << v[Z] << endl;
453
454#ifdef SUPPORT_VCOLOR
455            if( v.props )
456                out << ":vc "
457                    << v.props->color[X] << " "
458                    << v.props->color[Y] << " "
459                    << v.props->color[Z] << endl;
460#endif
461        }
462        else
463            M.vertex(i)->tempID = -1;
464
465    }
466
467    for(i=0; i<M.faceCount(); i++)
468    {
469        if( M.face(i)->isValid() )
470        {
471            Face *f = M.face(i);
472            out_annotate(out, f);
473            out << "f ";
474            Vertex *v0 = (Vertex *)f->vertex(0);
475            Vertex *v1 = (Vertex *)f->vertex(1);
476            Vertex *v2 = (Vertex *)f->vertex(2);
477#ifdef SAFETY
478            assert( v0->tempID >= 0 );
479            assert( v1->tempID >= 0 );
480            assert( v2->tempID >= 0 );
481#endif
482            out<<v0->tempID << " " <<v1->tempID<< " " <<v2->tempID<< endl;
483#ifdef SUPPORT_FCOLOR
484            if( f->props )
485                out << ":fc "
486                    << f->props->color[X] << " "
487                    << f->props->color[Y] << " "
488                    << f->props->color[Z] << endl;
489#endif
490        }
491    }
492
493    return out;
494}
495*/
Note: See TracBrowser for help on using the repository browser.