source: GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/vmi/src/change.cpp @ 2090

Revision 2090, 13.2 KB checked in by gumbau, 17 years ago (diff)
Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <memory.h>
4
5#include "../include/global.h"
6#include "../include/change.h"
7
8using namespace VMI;
9using namespace std;
10
11Geometry::MeshSimplificationSequence *VMI::mSequence    =       NULL;
12
13Change *VMI::createChange(Mesh *mesh, int e) {
14        Change *c;
15
16        c = (Change*) malloc (sizeof(Change));
17        if (NULL == c) {
18                fprintf (stderr, "no more memory for a mesh change\n");
19                exit(1);
20        }
21        c->e = e;
22        c->u = mesh->edges[e].u;
23        c->v = mesh->edges[e].v;
24        c->modified = NULL;
25        c->deleted = NULL;
26        c->numDel = 0;
27        c->numMod = 0;
28
29        computeChange(mesh, c);
30
31        return c;
32}
33
34Change *VMI::newChange(Mesh *mesh, int u, int v) {
35        Change *c;
36
37        c = (Change*) malloc (sizeof(Change));
38        if (NULL == c) {
39                fprintf (stderr, "no more memory for a mesh change\n");
40                exit(1);
41        }
42        c->e = -1; // Default edge, not used
43        c->u = u;
44        c->v = v;
45        c->modified = NULL;
46        c->deleted = NULL;
47        c->numDel = 0;
48        c->numMod = 0;
49
50        computeChange(mesh, c);
51
52        return c;
53}
54
55void VMI::deleteChange(Change *c)
56{
57
58        if (NULL != c)
59        {
60                if (c->deleted != NULL)   free(c->deleted);
61                if (c->modified != NULL)  free(c->modified);
62                c->modified = NULL;
63                c->deleted = NULL;
64                c->numDel = 0;
65                c->numMod = 0;
66
67                free(c);
68                c = NULL;
69        }
70}
71
72void VMI::writeChange(FILE* file, Change *c)
73{
74        int i;
75
76        fputc('v',file);
77        fputc('%',file);
78        fprintf(file, " %d %d 0 0 0 ", c->v, c->u);
79
80        for (i=0; i<c->numDel; i++) {
81                fprintf(file, "%d ", c->deleted[i].id);
82        }
83
84        fputc('&',file);
85        for (i=0; i<c->numMod; i++) {
86                fprintf(file, " %d", c->modified[i].id);
87        }
88
89        fputc('\n',file);
90}
91
92void VMI::printChange(Change *c)
93{
94        int i;
95
96        if (NULL != c) {
97
98                printf("e%d(%d,%d)\n",c->e,c->u,c->v);
99
100                printf("d %d\n", c->numDel);
101                for (i=0;i<c->numDel;i++) {
102                        printf(" %d", c->deleted[i].id);
103                }
104                printf("\n");
105                printf("m %d\n", c->numMod);
106                for (i=0;i<c->numMod;i++) {
107                        printf(" %d", c->modified[i].id);
108                }
109                printf("\n");
110        }
111}
112
113void VMI::modifyTriangle(Triangle *t, int c, int p)
114{
115        if ((int)t->indices[0] == c)
116                t->indices[0]= p;
117        if ((int)t->indices[1] == c)
118                t->indices[1]= p;
119        if ((int)t->indices[2] == c)
120                t->indices[2]= p;
121}
122
123int VMI::isATriangleToModify(Triangle *t, int c)
124{
125        int u = t->indices[0],
126                        v = t->indices[1],
127                        w = t->indices[2];
128
129        if ((u == c) || (v == c) || (w == c)) return TRUE;
130
131        return FALSE;
132}
133
134int VMI::isATriangleToDelete(Triangle *t, int c, int p)
135{
136        int u = t->indices[0],
137                        v = t->indices[1],
138                        w = t->indices[2];
139
140        if (((u == c) && ( v == p)) ||
141                        ((u == c) && ( w == p)) ||
142                        ((v == c) && ( w == p)))
143                return TRUE;
144        if (((u == p) && ( v == c)) ||
145                        ((u == p) && ( w == c)) ||
146                        ((v == p) && ( w == c)))
147                return TRUE;
148
149        return FALSE;
150}
151
152void VMI::modifyTriangles(Mesh *mesh, Change *c)
153{
154        int i, t;
155
156        // Reallocate memory for new adjacent triangles from vertex v
157  if (c->numMod > 0) {
158      mesh->vertices[c->v].triangles =
159          (GLuint *)realloc(mesh->vertices[c->v].triangles,
160          (mesh->vertices[c->v].numTriangles + mesh->vertices[c->u].numTriangles) * sizeof(GLuint));
161  }
162
163        for (i=0; i<c->numMod; i++) {
164                t = c->modified[i].id;
165                modifyTriangle(&mesh->triangles[t], c->u, c->v);
166
167                //printf("New area of triangle %d:\n", t);
168                mesh->triangles[t].area = computeTriangleArea(mesh->vertices, &mesh->triangles[t]);
169
170                computeTriangleNormal(mesh->vertices, &mesh->triangles[t]);
171
172                // Update vertex adjacency c->v
173                addItem((int *)mesh->vertices[c->v].triangles, (int *)&mesh->vertices[c->v].numTriangles, t);
174        }
175}
176
177void VMI::unmodifyTriangles(Mesh *mesh, Change *c)
178{
179        int i, t;
180
181        for (i=0; i<c->numMod; i++) {
182                t = c->modified[i].id;
183
184                memcpy(&mesh->triangles[t], &c->modified[i], sizeof(Triangle));
185                /*printf("t(%d %d %d)\n", mesh->triangles[t].indices[0],
186                        mesh->triangles[t].indices[1],
187                        mesh->triangles[t].indices[2]);*/
188
189                // Update vertex adjacency c->v
190                delItem((int *)mesh->vertices[c->v].triangles, (int *)&mesh->vertices[c->v].numTriangles, t);
191        }
192
193}
194
195int VMI::hasEdge(Triangle *t, int e) {
196    int e0 = t->edges[0],
197        e1 = t->edges[1],
198        e2 = t->edges[2];
199   
200    if ((e == e0) || (e == e1) || (e == e2)) return TRUE;
201
202    return FALSE;
203}
204
205void VMI::getEdges(Triangle *t, Change *c, int *l, int *r) {
206
207    // Default edges
208    *l = -1;
209    *r = -1;
210
211    // Set edge l and r
212    if ((int)t->edges[0] == c->e) {
213        *l = t->edges[1];
214        *r = t->edges[2];
215        if ((int)mesh->edges[*l].u == c->v || (int)mesh->edges[*l].v == c->v)
216            swap(l, r);
217    } else if ((int)t->edges[1] == c->e) {
218        *l = t->edges[0];
219        *r = t->edges[2];
220        if ((int)mesh->edges[*l].u == c->v || (int)mesh->edges[*l].v == c->v)
221            swap(l, r);
222    } else if ((int)t->edges[2] == c->e) {
223        *l = t->edges[0];
224        *r = t->edges[1];
225        if ((int)mesh->edges[*l].u == c->v || (int)mesh->edges[*l].v == c->v)
226            swap(l, r);
227    }
228}
229
230void VMI::swap(int *i, int *j) {
231    int t;
232
233    t = *i;
234    *i = *j;
235    *j = t;
236}
237
238void VMI::deleteTriangles(Mesh *mesh, Change *c)
239{
240            int i, j, t, v;
241#ifdef USE_EDGE_ADJACENCY
242    int t1, l, r;
243#endif
244   
245    for (i=0; i<c->numDel; i++) {
246        t = c->deleted[i].id;
247
248        //printf("%d(%d,%d) Deleting triangle %d\n",c->e, c->u, c->v, t);
249
250        // Update vertex adjacency
251        for (j=0; j<3; j++) {
252            v = c->deleted[i].indices[j];
253           
254            delItem((int *)mesh->vertices[v].triangles,(int *)&mesh->vertices[v].numTriangles,t);
255        }
256
257#ifdef USE_EDGE_ADJACENCY
258        // Update triangle edge adjancency
259        // The modified triangles have to be calculated before
260        // Set edge l and r
261        getEdges(&c->deleted[i], c, &l, &r);
262        //printf("e%d(%d,%d): l:%d r:%d\n", c->e, c->u, c->v, l, r);
263        // Find triangle that contains edge l
264        for (j=0; j<c->numMod; j++)
265            if (hasEdge(&c->modified[j], l)) {
266                // Change edge l by r in the Mesh
267                t1 = c->modified[j].id;
268                //printf("t:%d %d %d %d\n", t1, mesh->triangles[t1].edges[0], mesh->triangles[t1].edges[1] ,mesh->triangles[t1].edges[2]);
269                if (mesh->triangles[t1].edges[0] == (GLuint)l) mesh->triangles[t1].edges[0] = r;
270                if (mesh->triangles[t1].edges[1] == (GLuint)l) mesh->triangles[t1].edges[1] = r;
271                if (mesh->triangles[t1].edges[2] == (GLuint)l) mesh->triangles[t1].edges[2] = r;
272                //printf("t:%d %d %d %d\n", t1, mesh->triangles[t1].edges[0], mesh->triangles[t1].edges[1] ,mesh->triangles[t1].edges[2]);
273                break;
274            }
275
276        // Delete edge l
277        if (l != -1) mesh->edges[l].enable = FALSE;
278#endif
279        mesh->triangles[t].enable = FALSE;
280        mesh->currentNumTriangles--;
281    }
282}
283
284void VMI::undeleteTriangles(Mesh *mesh, Change *c) {
285    int i, j, t, v;
286   
287    for (i=0; i<c->numDel; i++) {
288        t = c->deleted[i].id;
289       
290        //printf("Undeleting triangle %d\n",t);
291
292        memcpy(&mesh->triangles[t], &c->deleted[i], sizeof(Triangle));
293        /*printf("t(%d %d %d)\n", mesh->triangles[t].indices[0],
294                                  mesh->triangles[t].indices[1],
295                                  mesh->triangles[t].indices[2]);*/
296
297        // Update vertex adjacency
298        for (j=0; j<3; j++) {
299            v = c->deleted[i].indices[j];
300           
301            addItem((int *)mesh->vertices[v].triangles,(int *)&mesh->vertices[v].numTriangles,t);
302        }
303#ifdef USE_EDGE_ADJACENCY
304        // Enable adjacent edges
305        for (j=0; j<3; j++) {
306            mesh->edges[mesh->triangles[t].edges[j]].enable = TRUE;
307        }
308#endif
309        mesh->triangles[t].enable = TRUE;
310        mesh->currentNumTriangles++;
311    }
312}
313
314Triangle *VMI::getTrianglesToModify(Mesh *mesh, Change *c, GLuint *numMod) {
315  int i, t;
316  Triangle *modified = NULL;
317
318  // Allocating memory
319  modified = (Triangle *)malloc(mesh->vertices[c->u].numTriangles * sizeof(Triangle));
320  *numMod = 0;
321 
322  for (i=0; i<(int)mesh->vertices[c->u].numTriangles; i++) {
323     
324      t = mesh->vertices[c->u].triangles[i];
325     
326      if ((mesh->triangles[t].enable == TRUE) &&
327          !isATriangleToDelete(&mesh->triangles[t], c->u, c->v)) {
328         
329          //printf("Triangle to modify %d\n", t);
330          // Save the original values of the triangle
331          memcpy(&modified[*numMod], &mesh->triangles[t], sizeof(Triangle));
332          (*numMod)++;
333      }
334  }
335  return modified;
336}
337
338Triangle *VMI::getTrianglesToDelete(Mesh *mesh, Change *c, GLuint *numDel) {
339  int i, t;
340  Triangle *deleted = NULL;
341 
342  // Allocating memory
343  deleted = (Triangle *)malloc(mesh->vertices[c->u].numTriangles * sizeof(Triangle));
344  *numDel = 0;
345
346  for (i=0; i<(int)mesh->vertices[c->u].numTriangles; i++) {
347     
348      t = mesh->vertices[c->u].triangles[i];
349
350      if ((mesh->triangles[t].enable == TRUE) &&
351          isATriangleToDelete(&mesh->triangles[t], c->u, c->v)) {
352                                                   
353          //printf("Triangle to delete %d\n",t);                   
354          memcpy(&deleted[*numDel], &mesh->triangles[t], sizeof(Triangle));
355          (*numDel)++;
356      }
357  }
358  return deleted;
359}
360
361void VMI::deleteEdges(Mesh *mesh, Change *c) {
362    int i, e;
363#ifndef USE_EDGE_ADJACENCY
364    int n0, n1, n2;
365#else
366    int j, u, v;
367#endif
368
369#ifdef USE_EDGE_ADJACENCY
370    for (i=0; i<c->numDel; i++) {
371       
372        for (j=0; j<3; j++) {
373            e = c->deleted[i].edges[j];
374            if (e != c->e) {
375                u = mesh->edges[e].u;
376                v = mesh->edges[e].v;
377                if (u == c->u || v == c->u) {
378                    //printf("%d\n",j);
379                    mesh->edges[e].enable = FALSE;
380                }
381            }
382        }
383        //getchar();
384    }
385#else
386    for (i=0; i<c->numDel; i++) {
387
388        n0 = c->deleted[i].indices[0];
389        n1 = c->deleted[i].indices[1];
390        n2 = c->deleted[i].indices[2];
391
392        if ((n0 == c->u && n1 != c->v) || (n1 == c->u && n0 != c->v)) {
393            e = findEdge(mesh->edges, mesh->numEdges, n0, n1);
394
395            //printf("a\n");
396            if (e != -1)
397                mesh->edges[e].enable = FALSE;
398        }
399
400        if ((n1 == c->u && n2 != c->v) || (n2 == c->u && n1 != c->v)) {
401            e = findEdge(mesh->edges, mesh->numEdges, n1, n2);
402           
403            //printf("b\n");
404            if (e != -1)
405                mesh->edges[e].enable = FALSE;
406        }
407
408        if ((n0 == c->u && n2 != c->v) || (n2 == c->u && n0 != c->v)) {
409            e = findEdge(mesh->edges, mesh->numEdges, n0, n2);
410           
411            //printf("c\n");
412            if (e != -1)
413                mesh->edges[e].enable = FALSE;
414        }
415        //getchar();
416    }
417#endif
418}
419
420void VMI::modifyEdges(Mesh *mesh, Change *c) {
421    int e, u, v;
422   
423    // Update mesh and heap
424    for(e = 0; e < (int)mesh->numEdges; e++) {
425       
426        if (mesh->edges[e].enable == TRUE) {
427           
428            // Modify edge
429            if ((int)mesh->edges[e].u == c->u)
430                mesh->edges[e].u = c->v;
431           
432            if ((int)mesh->edges[e].v == c->u)
433                mesh->edges[e].v = c->v;
434           
435            // Check edge
436            u = mesh->edges[e].u;
437            v = mesh->edges[e].v;
438           
439            // if the edge is not valid, we simply delete it
440            if ((u == v) ||
441                (u == c->u) || (v == c->u))
442               
443                mesh->edges[e].enable = FALSE;
444        }
445    }
446}
447
448///////////////////////////////////////////////////////////////////////////////
449
450// Compute the triangle mesh changes due to a heap node simplification
451void VMI::computeChange(Mesh *mesh, Change *c) {
452  GLuint numMod, numDel;
453  Triangle *m = getTrianglesToModify(mesh, c, &numMod),
454            *d = getTrianglesToDelete(mesh, c, &numDel);
455 
456  c->numDel   = numDel;
457  c->deleted  = d;
458 
459  c->numMod   = numMod;
460  c->modified = m;
461
462  //printChange(c);
463  //getchar();
464}
465
466// Update the triangle mesh due to a heap node simplification
467void VMI::doChange(Mesh *mesh, Change *c)
468{
469        modifyTriangles(mesh, c);
470
471        // This function must be called after modifyTriangles()
472        deleteTriangles(mesh, c);
473
474        // Delete vertex u
475        mesh->vertices[c->u].enable = FALSE;
476        mesh->currentNumVertices--;
477
478        //printMesh(mesh);
479        //getchar();
480}
481
482void VMI::undoChange(Mesh *mesh, Change *c)
483{
484        unmodifyTriangles(mesh, c);
485
486        undeleteTriangles(mesh, c);
487
488        mesh->vertices[c->u].enable = TRUE;
489        mesh->currentNumVertices++;
490
491        //printMesh(mesh);
492        //getchar();
493}
494
495/*
496namespace VMI{
497std::map<int, INTVECTOR> inversemap;
498}
499*/
500
501//      Save simplification sequence in Geometry Game Tools format.
502extern void     VMI::saveSimplificationSequence(Change  *c,int obligatory)
503{
504        Geometry::MeshSimplificationSequence::Step      step;
505
506        if (mSequence == NULL)
507        {
508                mSequence       =       new Geometry::MeshSimplificationSequence();
509        }
510
511        step.mV0        =       c->v;
512        step.mV1        =       c->u;
513
514        //      Debug.
515        cout    <<      "----> V0: "
516                                <<      step.mV0
517                                <<      " V1: "
518                                <<      step.mV1
519                                <<      endl;
520
521        //      If only one triangle has been deleted.
522        if (c->numDel == 1)
523        {
524                step.mT0        =       c->deleted[0].id;
525                step.mT1        =       c->deleted[0].id;
526        }
527        //      If two triangles have been deleted.
528        else
529        {
530                step.mT0        =       c->deleted[0].id;
531                step.mT1        =       c->deleted[1].id;
532        }
533
534        step.x  =       0.0;
535        step.y  =       0.0;
536        step.z  =       0.0;
537
538        //      Write obligatory field.
539        step.obligatory =       obligatory;
540
541        //      List of new triangles.
542        //      For each modified triangle.
543        for (int        i = 0;  i < c->numMod;  i++)
544        {
545                step.mModfaces.push_back(c->modified[i].id);
546        }
547
548        //      Add step to list of changes.
549        mSequence->mSteps.push_back(step);
550}
551
Note: See TracBrowser for help on using the repository browser.