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

Revision 1007, 7.1 KB checked in by gumbau, 18 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
8#define MAX_NUM_TRI 250
9
10using namespace VMI;
11
12std::vector<VMI::vmiStep> VMI::mVMISteps;
13
14Change *VMI::createChange (Mesh *mesh, int e) {
15    Change *c;
16   
17    c = (Change*) malloc (sizeof(Change));
18    if (NULL == c) {
19        fprintf (stderr, "no more memory for mesh changes");
20        exit(1);
21    }
22    c->e = e;
23    c->u = mesh->edges[e].u;
24    c->v = mesh->edges[e].v;
25    c->modified = NULL;
26    c->deleted = NULL;
27    c->numDel = 0;
28    c->numMod = 0;
29   
30    return c;
31}
32
33void VMI::deleteChange(Change *c)
34{
35
36        if (NULL != c)
37        {
38                if (c->deleted != NULL)   free(c->deleted);
39                if (c->modified != NULL)  free(c->modified);
40                c->modified = NULL;
41                c->deleted = NULL;
42                c->numDel = 0;
43                c->numMod = 0;
44
45                free(c);
46                c = NULL;
47        }
48}
49
50void VMI::writeChange(FILE* file, Change *c)
51{
52        int i;
53
54        fputc('v',file);
55        fputc('%',file);
56        fprintf(file, " %d %d 0 0 0 ", c->v, c->u);
57
58        for (i=0; i<c->numDel; i++) {
59                fprintf(file, "%d ", c->deleted[i].id);
60        }
61
62        fputc('&',file);
63        for (i=0; i<c->numMod; i++) {
64                fprintf(file, " %d", c->modified[i].id);
65        }
66
67        fputc('\n',file);
68}
69
70void VMI::printChange(Change *c)
71{
72        int i;
73
74        if (NULL != c) {
75
76                printf("e%d(%d,%d)\n",c->e,c->u,c->v);
77
78                printf("d %d\n", c->numDel);
79                for (i=0;i<c->numDel;i++) {
80                        printf(" %d", c->deleted[i].id);
81                }
82                printf("\n");
83                printf("m %d\n", c->numMod);
84                for (i=0;i<c->numMod;i++) {
85                        printf(" %d", c->modified[i].id);
86                }
87                printf("\n");
88        }
89}
90
91void VMI::modifyTriangle(Triangle *t, int c, int p)
92{
93
94        if ((int)t->indices[0] == c)
95                t->indices[0]= p;
96        if ((int)t->indices[1] == c)
97                t->indices[1]= p;
98        if ((int)t->indices[2] == c)
99                t->indices[2]= p;
100}
101
102int VMI::isATriangleToModify(Triangle *t, int c, int p)
103{
104        int u = t->indices[0],
105                        v = t->indices[1],
106                        w = t->indices[2];
107
108        if ((u == c) || (v == c) || (w == c)) return TRUE;
109
110        return FALSE;
111}
112
113void VMI::modifyTriangles(Mesh *mesh, Change *c)
114{
115        int i, t;
116
117        for (i=0; i<c->numMod; i++)
118        {
119                t = c->modified[i].id;
120                modifyTriangle(&mesh->triangles[t], c->u, c->v);
121
122                //printf("New area of triangle %d:\n", t);
123                mesh->triangles[t].area = computeTriangleArea(mesh->vertices, &mesh->triangles[t]);
124
125                computeTriangleNormal(mesh->vertices, &mesh->triangles[t]);
126        }
127}
128
129void VMI::unmodifyTriangles(Mesh *mesh, Change *c)
130{
131        int i, t;
132
133        for (i=0; i<c->numMod; i++) {
134                t = c->modified[i].id;
135
136                memcpy(&mesh->triangles[t], &c->modified[i], sizeof(Triangle));
137                /*printf("t(%d %d %d)\n", mesh->triangles[t].indices[0],
138                        mesh->triangles[t].indices[1],
139                        mesh->triangles[t].indices[2]);*/
140        }
141}
142
143void VMI::deleteTriangles(Mesh *mesh, Change *c)
144{
145        int i, t;
146
147        for (i=0; i<c->numDel; i++)
148        {
149                t = c->deleted[i].id;
150
151                //printf("Deleting triangle %d\n",t);
152                mesh->triangles[t].enable = FALSE;
153                mesh->currentNumTriangles--;
154        }
155}
156
157void VMI::undeleteTriangles(Mesh *mesh, Change *c)
158{
159        int i, t;
160
161        for (i=0; i<c->numDel; i++)
162        {
163                t = c->deleted[i].id;
164
165                memcpy(&mesh->triangles[t], &c->deleted[i], sizeof(Triangle));
166                /*printf("t(%d %d %d)\n", mesh->triangles[t].indices[0],
167                        mesh->triangles[t].indices[1],
168                        mesh->triangles[t].indices[2]);*/
169
170                mesh->triangles[t].enable = TRUE;
171                mesh->currentNumTriangles++;
172        }
173}
174
175int VMI::getTrianglesToModify(Mesh *mesh, int c, int p, Triangle *modified)
176{
177        GLuint i, num = 0;
178
179        for (i=0; i<mesh->numTriangles; i++)
180        {
181                if ((mesh->triangles[i].enable == TRUE) &&
182                                isATriangleToModify(&mesh->triangles[i], c, p))
183                {
184
185                        //printf("Triangle to modify %d\n", i);
186                        // Save the original values of the triangle
187                        memcpy(&modified[num], &mesh->triangles[i], sizeof(Triangle));
188                        num++;
189                }
190        }
191
192        return num;
193}
194
195int VMI::isATriangleToDelete(Triangle *t, int c, int p)
196{
197        int u = t->indices[0],
198                        v = t->indices[1],
199                        w = t->indices[2];
200
201        if (((u == c) && ( v == p)) ||
202                        ((u == c) && ( w == p)) ||
203                        ((v == c) && ( w == p)))
204                return TRUE;
205        if (((u == p) && ( v == c)) ||
206                        ((u == p) && ( w == c)) ||
207                        ((v == p) && ( w == c)))
208                return TRUE;
209
210        return FALSE;
211}
212
213int VMI::getTrianglesToDelete(Mesh *mesh, int numMod, Triangle *modified, Triangle *deleted, int c, int p)
214{
215        int i, num = 0;
216        GLuint t;
217
218        for (i=0; i<numMod; i++)
219        {
220                t = modified[i].id;
221
222                if (isATriangleToDelete(&mesh->triangles[t], c, p))
223                {                                             
224                        //printf("Triangle to delete %d\n",t);                   
225                        memcpy(&deleted[num], &modified[i], sizeof(Triangle));
226                        num++;
227                }
228        }
229        return num;
230}
231
232void VMI::printList(Triangle *list, int n)
233{
234        int i;
235
236        for (i=0; i<n; i++)
237                printf("%d ",list[i].id);
238
239        printf("\n");
240}
241
242void VMI::deleteItem(Triangle *list, int *n, int item)
243{
244        int i, j;
245
246        for (i=0; i<*n; i++)
247        {
248                if (list[i].id == (GLuint)item)
249                {
250                        // delete it
251                        for (j =i + 1 ; j<*n; j++)
252                                list[j - 1] = list[j];
253                        (*n)--;
254                        i--; // Delete all ocurrencies of an item
255                }
256        }
257}
258
259///////////////////////////////////////////////////////////////////////////////
260
261// Compute the triangle mesh changes due to a heap node simplification
262void VMI::computeChanges(Mesh *mesh, Change *c)
263{
264        Triangle m[MAX_NUM_TRI], d[MAX_NUM_TRI/2];
265        int numMod = getTrianglesToModify(mesh, c->u, c->v, m);
266        int numDel = getTrianglesToDelete(mesh, numMod, m, d, c->u, c->v);
267        int i;
268
269        //printf("d %d\n",numDel);
270        //printList(d, numDel);
271
272        for (i=0; i<numDel; i++)
273                deleteItem(m, &numMod, d[i].id);
274
275        //printf("m %d\n",numMod);
276        //printList(m, numMod);
277        //getchar();
278
279        c->numDel = numDel;
280        // Free memory
281        if (c->deleted != NULL) free(c->deleted);
282        // Allocate memory
283        c->deleted = (Triangle *)malloc(sizeof(Triangle) * numDel);
284       
285        if (c->deleted == NULL)
286        {
287                fprintf(stderr, "Error allocating memory\n");
288                exit(1);
289        }
290       
291        memcpy(c->deleted, d, sizeof(Triangle) * numDel);
292
293        c->numMod = numMod;
294       
295        // Free memory
296        if (c->modified != NULL) free(c->modified);
297       
298        // Allocate memory
299        c->modified = (Triangle *)malloc(sizeof(Triangle) * numMod);
300       
301        if (c->modified == NULL)
302        {
303                fprintf(stderr, "Error allocating memory\n");
304                exit(1);
305        }
306       
307        memcpy(c->modified, m, sizeof(Triangle) * numMod);
308
309        //printChange(c);
310        //getchar();
311}
312
313// Update the triangle mesh due to a heap node simplification
314void VMI::doChange(Mesh *mesh, Change *c)
315{
316        modifyTriangles(mesh, c);
317
318        deleteTriangles(mesh, c);
319
320        mesh->vertices[c->u].enable = FALSE;
321        mesh->currentNumVertices--;
322}
323
324void VMI::undoChange(Mesh *mesh, Change *c)
325{   
326        unmodifyTriangles(mesh, c);
327
328        undeleteTriangles(mesh, c);
329
330        mesh->vertices[c->u].enable = TRUE;
331        mesh->currentNumVertices++;
332}
333
334//      Save simplification sequence in Geometry Game Tools format.
335extern void     VMI::saveSimplificationSequence(Change  *c)
336{
337        vmiStep step;
338        step.mV0        =       c->u;
339        step.mV1        =       c->v;
340
341        //      If only one triangle has been deleted.
342        if (c->numDel == 1)
343        {
344                step.mT0        =       c->deleted[0].id;
345                step.mT1        =       c->deleted[0].id;
346        }
347        //      If two triangles have been deleted.
348        else
349        {
350                step.mT0        =       c->deleted[0].id;
351                step.mT1        =       c->deleted[1].id;
352        }
353
354        step.x  =       0.0;
355        step.y  =       0.0;
356        step.z  =       0.0;
357
358        //      Write obligatory field.
359        step.obligatory =       0;
360
361        //      List of new triangles.
362        //      For each modified triangle.
363        for (int        i = 0;  i < c->numMod;  i++)
364        {
365                step.mModfaces.push_back(c->modified[i].id);
366        }
367
368        //      Add step to list of changes.
369        mVMISteps.push_back(step);
370}
Note: See TracBrowser for help on using the repository browser.