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

Revision 1526, 10.5 KB checked in by gumbau, 18 years ago (diff)

Updated modules to the new interface and the new simplification algorithm improvements.

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