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

Revision 2127, 10.0 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          (int *)realloc(mesh->vertices[c->v].triangles,
160          (mesh->vertices[c->v].numTriangles + mesh->vertices[c->u].numTriangles) * sizeof(int));
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
195void VMI::swap(int *i, int *j) {
196    int t;
197
198    t = *i;
199    *i = *j;
200    *j = t;
201}
202
203void VMI::deleteTriangles(Mesh *mesh, Change *c)
204{
205          int i, j, t, v;
206   
207    for (i=0; i<c->numDel; i++) {
208        t = c->deleted[i].id;
209
210        //printf("%d(%d,%d) Deleting triangle %d\n",c->e, c->u, c->v, t);
211
212        // Update vertex adjacency
213        for (j=0; j<3; j++) {
214            v = c->deleted[i].indices[j];
215           
216            delItem((int *)mesh->vertices[v].triangles,(int *)&mesh->vertices[v].numTriangles,t);
217        }
218
219        mesh->triangles[t].enable = FALSE;
220        mesh->currentNumTriangles--;
221    }
222}
223
224void VMI::undeleteTriangles(Mesh *mesh, Change *c) {
225    int i, j, t, v;
226   
227    for (i=0; i<c->numDel; i++) {
228        t = c->deleted[i].id;
229       
230        //printf("Undeleting triangle %d\n",t);
231
232        memcpy(&mesh->triangles[t], &c->deleted[i], sizeof(Triangle));
233        /*printf("t(%d %d %d)\n", mesh->triangles[t].indices[0],
234                                  mesh->triangles[t].indices[1],
235                                  mesh->triangles[t].indices[2]);*/
236
237        // Update vertex adjacency
238        for (j=0; j<3; j++) {
239            v = c->deleted[i].indices[j];
240           
241            addItem((int *)mesh->vertices[v].triangles,(int *)&mesh->vertices[v].numTriangles,t);
242        }
243
244        mesh->triangles[t].enable = TRUE;
245        mesh->currentNumTriangles++;
246    }
247}
248
249Triangle *VMI::getTrianglesToModify(Mesh *mesh, Change *c, int *numMod) {
250  int i, t;
251  Triangle *modified = NULL;
252
253  // Allocating memory
254  modified = (Triangle *)malloc(mesh->vertices[c->u].numTriangles * sizeof(Triangle));
255  *numMod = 0;
256 
257  for (i=0; i<(int)mesh->vertices[c->u].numTriangles; i++) {
258     
259      t = mesh->vertices[c->u].triangles[i];
260     
261      if ((mesh->triangles[t].enable == TRUE) &&
262          !isATriangleToDelete(&mesh->triangles[t], c->u, c->v)) {
263         
264          //printf("Triangle to modify %d\n", t);
265          // Save the original values of the triangle
266          memcpy(&modified[*numMod], &mesh->triangles[t], sizeof(Triangle));
267          (*numMod)++;
268      }
269  }
270  return modified;
271}
272
273Triangle *VMI::getTrianglesToDelete(Mesh *mesh, Change *c, int *numDel) {
274  int i, t;
275  Triangle *deleted = NULL;
276 
277  // Allocating memory
278  deleted = (Triangle *)malloc(mesh->vertices[c->u].numTriangles * sizeof(Triangle));
279  *numDel = 0;
280
281  for (i=0; i<(int)mesh->vertices[c->u].numTriangles; i++) {
282     
283      t = mesh->vertices[c->u].triangles[i];
284
285      if ((mesh->triangles[t].enable == TRUE) &&
286          isATriangleToDelete(&mesh->triangles[t], c->u, c->v)) {
287                                                   
288          //printf("Triangle to delete %d\n",t);                   
289          memcpy(&deleted[*numDel], &mesh->triangles[t], sizeof(Triangle));
290          (*numDel)++;
291      }
292  }
293  return deleted;
294}
295
296void VMI::modifyEdges(Mesh *mesh, Change *c) {
297    int i, e;
298
299        for(i = 0; i < mesh->vertices[c->v].numEdges; i++) {
300       
301                e = mesh->vertices[c->v].edges[i];
302
303        if (mesh->edges[e].enable == TRUE) {
304           
305            // Modify edge
306            if (mesh->edges[e].u == c->u)
307                mesh->edges[e].u = c->v;
308           
309            if (mesh->edges[e].v == c->u)
310                mesh->edges[e].v = c->v;
311        }
312    }
313}
314
315int VMI::find(int *edges, int num, int v_) {
316        int i;
317
318        int u, v;
319
320
321        for(i=0; i<num; i++) {
322
323                u = mesh->edges[edges[i]].u;
324
325                v = mesh->edges[edges[i]].v;
326
327                if (u == v_ || v == v_) return TRUE;
328
329        }
330
331        return FALSE;
332}
333void VMI::updateEdgeAdj(Mesh *mesh, Change *c) {
334        int i;
335
336        int v, e;
337
338        mesh->vertices[c->v].edges =
339            (int *)realloc(mesh->vertices[c->v].edges,
340            (mesh->vertices[c->v].numEdges + mesh->vertices[c->u].numEdges) * sizeof(int));
341
342        for (i=0; i<mesh->vertices[c->u].numEdges; i++) {
343       
344                e = mesh->vertices[c->u].edges[i];
345                if (mesh->edges[e].u == c->u) v =mesh->edges[e].v;
346                else v = mesh->edges[e].u;
347               
348                if (!find(mesh->vertices[c->v].edges, mesh->vertices[c->v].numEdges, v))
349                        addItem(mesh->vertices[c->v].edges, &mesh->vertices[c->v].numEdges, e);
350                else mesh->edges[e].enable = FALSE;
351        }
352
353        delItem(mesh->vertices[c->v].edges, &mesh->vertices[c->v].numEdges, c->e);
354}
355
356///////////////////////////////////////////////////////////////////////////////
357
358// Compute the triangle mesh changes due to a heap node simplification
359void VMI::computeChange(Mesh *mesh, Change *c) {
360  int numMod, numDel;
361  Triangle *m = getTrianglesToModify(mesh, c, &numMod),
362            *d = getTrianglesToDelete(mesh, c, &numDel);
363 
364  c->numDel   = numDel;
365  c->deleted  = d;
366 
367  c->numMod   = numMod;
368  c->modified = m;
369
370  //printChange(c);
371  //getchar();
372}
373
374// Update the triangle mesh due to a heap node simplification
375void VMI::doChange(Mesh *mesh, Change *c)
376{
377        modifyTriangles(mesh, c);
378
379        // This function must be called after modifyTriangles()
380        deleteTriangles(mesh, c);
381
382        // Delete vertex u
383        mesh->vertices[c->u].enable = FALSE;
384        mesh->currentNumVertices--;
385
386        //printMesh(mesh);
387        //getchar();
388}
389
390void VMI::undoChange(Mesh *mesh, Change *c)
391{
392        unmodifyTriangles(mesh, c);
393
394        undeleteTriangles(mesh, c);
395
396        mesh->vertices[c->u].enable = TRUE;
397        mesh->currentNumVertices++;
398
399        //printMesh(mesh);
400        //getchar();
401}
402
403/*
404namespace VMI{
405std::map<int, INTVECTOR> inversemap;
406}
407*/
408
409//      Save simplification sequence in Geometry Game Tools format.
410extern void     VMI::saveSimplificationSequence(Change  *c,int obligatory)
411{
412        Geometry::MeshSimplificationSequence::Step      step;
413
414        if (mSequence == NULL)
415        {
416                mSequence       =       new Geometry::MeshSimplificationSequence();
417        }
418
419        step.mV0        =       c->v;
420        step.mV1        =       c->u;
421
422        //      Debug.
423        cout    <<      "----> V0: "
424                                <<      step.mV0
425                                <<      " V1: "
426                                <<      step.mV1
427                                <<      endl;
428
429        //      If only one triangle has been deleted.
430        if (c->numDel == 1)
431        {
432                step.mT0        =       c->deleted[0].id;
433                step.mT1        =       c->deleted[0].id;
434        }
435        //      If two triangles have been deleted.
436        else
437        {
438                step.mT0        =       c->deleted[0].id;
439                step.mT1        =       c->deleted[1].id;
440        }
441
442        step.x  =       0.0;
443        step.y  =       0.0;
444        step.z  =       0.0;
445
446        //      Write obligatory field.
447        step.obligatory =       obligatory;
448
449        //      List of new triangles.
450        //      For each modified triangle.
451        for (int        i = 0;  i < c->numMod;  i++)
452        {
453                step.mModfaces.push_back(c->modified[i].id);
454        }
455
456        //      Add step to list of changes.
457        mSequence->mSteps.push_back(step);
458}
459
Note: See TracBrowser for help on using the repository browser.