source: GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/vmi/src/mesh.cpp @ 983

Revision 983, 20.0 KB checked in by gumbau, 18 years ago (diff)
Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <memory.h>
4#include <string.h>
5#include <math.h>
6
7#include "../include/mesh.h"
8#include "../include/area.h"
9#include "../include/global.h"
10
11using namespace VMI;
12
13#define MAX_NUM_TRI 450
14
15void VMI::printItemList(int *list, int n) {
16    int i;
17   
18    for (i=0; i<n; i++)
19        printf("%d ",list[i]);
20
21    printf("\n");
22}
23
24int VMI::findItem(int *list, int n, int item) {
25    int i;
26
27    for (i=0; i<n; i++)
28        if (list[i] == item) return TRUE;
29        return FALSE;
30}
31
32void VMI::addItem(int *list, int *n, int item) {
33
34    if (!findItem(list, *n, item))
35        list[(*n)++] = item;
36}
37
38int VMI::findEdge(Edge *e, GLuint num, GLuint _u, GLuint _v) {
39    GLuint i, u, v;
40    int found = -1;
41
42    for (i=0; i<num; i++) {
43
44        if (e[i].enable == TRUE) {
45
46            u = e[i].u;
47            v = e[i].v;
48
49            if (((u == _u) && (v == _v)) ||
50                ((u == _v) && (v == _u))) {
51                found = i;
52                break;
53            }
54        }
55    }
56
57    return found;
58}
59
60GLdouble VMI::computeTriangleArea(Vertex *vertices, Triangle *t) {
61    GLuint i;
62    GLdouble v0[3], v1[3], v2[3], a;
63   
64    // Compute triangle area
65    i = t->indices[0];
66    v0[0] = vertices[i].x;
67    v0[1] = vertices[i].y;
68    v0[2] = vertices[i].z;
69
70    i = t->indices[1];
71    v1[0] = vertices[i].x;
72    v1[1] = vertices[i].y;
73    v1[2] = vertices[i].z;
74
75    i = t->indices[2];
76    v2[0] = vertices[i].x;
77    v2[1] = vertices[i].y;
78    v2[2] = vertices[i].z;
79
80    a = triangleArea(v0, v1, v2);
81   
82    //printf("Triangle area: %f\n", a)
83    return a; 
84}
85
86void VMI::computeTriangleNormal(Vertex *vertices, Triangle *t) {
87    GLuint i;
88    GLfloat x0, y0, z0,
89            x1, y1, z1,
90            x2, y2, z2;
91    GLfloat x10, y10, z10,
92            x12, y12, z12,
93            cpx, cpy, cpz, r;
94
95    i = t->indices[0];
96    x0 = vertices[i].x;
97    y0 = vertices[i].y;
98    z0 = vertices[i].z;
99
100    i = t->indices[1];
101    x1 = vertices[i].x;
102    y1 = vertices[i].y;
103    z1 = vertices[i].z;
104
105    i = t->indices[2];
106    x2 = vertices[i].x;
107    y2 = vertices[i].y;
108    z2 = vertices[i].z;
109
110    /* Compute edge vectors */
111    x10 = x1 - x0;
112    y10 = y1 - y0;
113    z10 = z1 - z0;
114    x12 = x1 - x2;
115    y12 = y1 - y2;
116    z12 = z1 - z2;
117
118    /* Compute the cross product */
119    cpx = (z10 * y12) - (y10 * z12);
120    cpy = (x10 * z12) - (z10 * x12);
121    cpz = (y10 * x12) - (x10 * y12);
122
123    /* Normalize the result to get the unit-length facet normal */
124    r = sqrt(cpx * cpx + cpy * cpy + cpz * cpz);
125
126    t->normal[0] = cpx / r;
127    t->normal[1] = cpy / r;
128    t->normal[2] = cpz / r;
129}
130
131Mesh *VMI::initMesh(GLMmodel* pmodel) {
132
133    GLuint i, j, v1, v2, v3, n, e, t;
134    Mesh *mesh;
135
136    mesh = (Mesh *)malloc (sizeof(Mesh));
137   
138    if (mesh == NULL) {
139        fprintf(stderr, "Error allocating memory\n");
140        exit(1);
141    }
142
143    mesh->vertices = (Vertex *)malloc (sizeof(Vertex) * pmodel->numvertices);
144   
145    if (mesh->vertices == NULL) {
146        fprintf(stderr, "Error allocating memory\n");
147        exit(1);
148    }
149
150    mesh->triangles = (Triangle *)malloc (sizeof(Triangle) * pmodel->numtriangles);
151   
152    if (mesh->triangles == NULL) {
153        fprintf(stderr, "Error allocating memory\n");
154        exit(1);
155    }
156   
157    printf("Adding vertices...");
158    for (i=1; i<=pmodel->numvertices; i++) { // Vertices start at 1
159
160        mesh->vertices[i - 1].x = pmodel->vertices[3 * i + 0];
161        mesh->vertices[i - 1].y = pmodel->vertices[3 * i + 1];
162        mesh->vertices[i - 1].z = pmodel->vertices[3 * i + 2];
163        mesh->vertices[i - 1].numTriangles = 0;
164        mesh->vertices[i - 1].triangles = NULL;
165        mesh->vertices[i - 1].enable = GL_TRUE;
166    }
167    printf("Ok\n");
168    mesh->numVertices = pmodel->numvertices;
169    mesh->currentNumVertices = pmodel->numvertices;
170
171    printf("Adding triangles...");
172    for (i=0; i<pmodel->numtriangles; i++) {
173        mesh->triangles[i].id = i;
174        mesh->triangles[i].indices[0] = pmodel->triangles[i].vindices[0] - 1;
175        mesh->triangles[i].indices[1] = pmodel->triangles[i].vindices[1] - 1;
176        mesh->triangles[i].indices[2] = pmodel->triangles[i].vindices[2] - 1;
177        mesh->triangles[i].area = computeTriangleArea(mesh->vertices, &mesh->triangles[i]);
178        //printf("\n%d a: %f",i , mesh->triangles[i].area);
179        computeTriangleNormal(mesh->vertices, &mesh->triangles[i]);
180
181        mesh->triangles[i].saliency = 0.0;
182
183        mesh->triangles[i].enable = GL_TRUE;
184       
185        for (j=0; j<3; j++) {
186            // Adding triangle i adjacent to 3 vertices
187            v1 = mesh->triangles[i].indices[j];
188   
189            // Reallocate memory for the new adjacent triangle
190            mesh->vertices[v1].triangles = (GLuint *)realloc(mesh->vertices[v1].triangles, (mesh->vertices[v1].numTriangles + 1) * sizeof(GLuint));
191            addItem((int *)mesh->vertices[v1].triangles, (int *)&mesh->vertices[v1].numTriangles, i);
192        }
193    }
194    //printf("\n");
195    printf("Ok\n");
196
197    mesh->numTriangles = pmodel->numtriangles;
198    mesh->currentNumTriangles = pmodel->numtriangles;
199
200    mesh->edges = (Edge *)malloc (sizeof(Edge) * mesh->numTriangles * 3);  // E = 3 T / 2
201   
202    if (mesh->edges == NULL) {
203        fprintf(stderr, "Error allocating memory\n");
204        exit(1);
205    }
206   
207    // Init edges
208    for (i=0; i<mesh->numTriangles * 3; i++) {
209       
210        mesh->edges[i].triangles    = NULL;
211        mesh->edges[i].numTriangles = 0;
212    }
213
214    printf("Adding edges...");
215    n = 0;
216
217    for (i=0; i<mesh->numTriangles; i++) {
218        t = 0;
219        v1 = mesh->triangles[i].indices[0];
220        v2 = mesh->triangles[i].indices[1];
221        v3 = mesh->triangles[i].indices[2];
222       
223        if ((e = findEdge(mesh->edges, n, v1, v2)) == -1) {
224            mesh->edges[n].u = v1;
225            mesh->edges[n].v = v2;
226            mesh->edges[n].enable = GL_TRUE;
227           
228            // Reallocate memory for the new adjacent triangle
229            mesh->edges[n].triangles = (GLuint *)realloc(mesh->edges[n].triangles, (mesh->edges[n].numTriangles + 1) * sizeof(GLuint));
230            // Adding triangle i adjacent to edge n
231            addItem((int *)mesh->edges[n].triangles, (int *)&mesh->edges[n].numTriangles, i);
232            //printf("n:%d i:%d\n", n, i);
233           
234            // Adding edge n adjacent to triangle i
235            addItem((int *)mesh->triangles[i].edges, (int *)&t, n);
236            n++;
237        } else {
238            // Reallocate memory for the new adjacent triangle
239            mesh->edges[e].triangles = (GLuint *)realloc(mesh->edges[e].triangles, (mesh->edges[e].numTriangles + 1) * sizeof(GLuint));
240            // Adding triangle i adjacent to edge e
241            addItem((int *)mesh->edges[e].triangles, (int *)&mesh->edges[e].numTriangles, i);
242            //printf("n:%d i:%d\n", e, i);
243           
244            // Adding edge e adjacent to triangle i
245            addItem((int *)mesh->triangles[i].edges, (int *)&t, e);
246        }
247        if (( e = findEdge(mesh->edges, n, v2, v3)) == -1) {
248            mesh->edges[n].u = v2;
249            mesh->edges[n].v = v3;
250            mesh->edges[n].enable = GL_TRUE;
251           
252            // Reallocate memory for the new adjacent triangle
253            mesh->edges[n].triangles = (GLuint *)realloc(mesh->edges[n].triangles, (mesh->edges[n].numTriangles + 1) * sizeof(GLuint));
254            // Adding triangle i adjacent to edge n
255            addItem((int *)mesh->edges[n].triangles, (int *)&mesh->edges[n].numTriangles, i);
256            //printf("n:%d i:%d\n", n, i);
257           
258            // Adding edge n adjacent to triangle i
259            addItem((int *)mesh->triangles[i].edges, (int *)&t, n);
260            n++;
261        } else {
262            // Reallocate memory for the new adjacent triangle
263            mesh->edges[e].triangles = (GLuint *)realloc(mesh->edges[e].triangles, (mesh->edges[e].numTriangles + 1) * sizeof(GLuint));
264            // Adding triangle i adjacent to edge e
265            addItem((int *)mesh->edges[e].triangles, (int *)&mesh->edges[e].numTriangles, i);
266            //printf("n:%d i:%d\n", e, i);
267           
268            // Adding edge e adjacent to triangle i
269            addItem((int *)mesh->triangles[i].edges, (int *)&t, e);
270        }
271        if ((e = findEdge(mesh->edges, n, v3, v1)) == -1) {
272            mesh->edges[n].u = v3;
273            mesh->edges[n].v = v1;
274            mesh->edges[n].enable = GL_TRUE;
275           
276            // Reallocate memory for the new adjacent triangle
277            mesh->edges[n].triangles = (GLuint *)realloc(mesh->edges[n].triangles, (mesh->edges[n].numTriangles + 1) * sizeof(GLuint));
278            // Adding triangle i adjacent to edge n
279            addItem((int *)mesh->edges[n].triangles, (int *)&mesh->edges[n].numTriangles, i);
280            //printf("n:%d i:%d\n", n, i);
281           
282            // Adding edge n adjacent to triangle i
283            addItem((int *)mesh->triangles[i].edges, (int *)&t, n);
284            n++;
285        } else  {
286            // Reallocate memory for the new adjacent triangle
287            mesh->edges[e].triangles = (GLuint *)realloc(mesh->edges[e].triangles, (mesh->edges[e].numTriangles + 1) * sizeof(GLuint));
288            // Adding triangle i adjacent to edge e
289            addItem((int *)mesh->edges[e].triangles, (int *)&mesh->edges[e].numTriangles, i);
290            //printf("n:%d i:%d\n", e, i);
291           
292            // Adding edge e adjacent to triangle i
293            addItem((int *)mesh->triangles[i].edges, (int *)&t, e);
294        }
295    }
296    printf("Ok\n");
297    mesh->numEdges = n;
298
299    return mesh;
300}
301
302void VMI::printMesh(Mesh *mesh) {
303    GLuint i, j;
304
305    printf("Vertices (%d)\n", mesh->numVertices);
306    printf("------------------------\n");
307   
308    for (i=0; i<mesh->numVertices; i++) {
309        printf("v%d (%f,%f,%f)\n", i, mesh->vertices[i].x, mesh->vertices[i].y,
310                                     mesh->vertices[i].z);
311        printf("  t(%d)[", mesh->vertices[i].numTriangles);
312        if (mesh->vertices[i].triangles != NULL) {
313            printf("%d", mesh->vertices[i].triangles[0]);
314            for (j=1; j<mesh->vertices[i].numTriangles; j++) {
315                printf(",%d", mesh->vertices[i].triangles[j]);
316            }
317        }
318        printf("]\n");
319    }
320
321    printf("Edges (%d)\n", mesh->numEdges);
322    printf("------------------------\n");
323    for (i=0; i<mesh->numEdges; i++) {
324        printf("e%d (%d,%d)\n", i, mesh->edges[i].u, mesh->edges[i].v);
325        printf("  t(%d)[", mesh->edges[i].numTriangles);
326        if (mesh->edges[i].triangles != NULL) {
327            printf("%d", mesh->edges[i].triangles[0]);
328            for (j=1; j<mesh->edges[i].numTriangles; j++) {
329                printf(",%d", mesh->edges[i].triangles[j]);
330            }
331        }
332        printf("]\n");
333    }
334
335    printf("Triangles (%d)\n", mesh->numTriangles);
336    printf("------------------------\n");
337    for (i=0; i<mesh->numTriangles; i++) {
338        printf("t%d (%d,%d,%d)\n", i, mesh->triangles[i].indices[0], mesh->triangles[i].indices[1],
339                                     mesh->triangles[i].indices[2]);
340        printf("  e(3)[");
341        printf("%d", mesh->triangles[i].edges[0]);
342        for (j=1; j<3; j++) {
343            printf(",%d", mesh->triangles[i].edges[j]);
344        }
345        printf("]\n");
346
347        printf("  n(3)[");
348        printf("%f", mesh->triangles[i].normal[0]);
349        for (j=1; j<3; j++) {
350            printf(",%f", mesh->triangles[i].normal[j]);
351        }
352        printf("]\n");
353       
354        printf("  area: %f\n", mesh->triangles[i].area);
355    }
356}
357
358void VMI::deleteMesh(Mesh *mesh) {
359        GLuint i;
360
361        if (NULL != mesh) {
362                for (i=0; i<mesh->numVertices; i++) {
363                        if (mesh->vertices[i].triangles != NULL)
364                                free(mesh->vertices[i].triangles);
365
366                }
367                if (mesh->vertices != NULL) free(mesh->vertices);
368                mesh->numVertices = 0;
369
370                for (i=0; i<mesh->numEdges; i++) {
371                        if (mesh->edges[i].triangles != NULL)
372                                free(mesh->edges[i].triangles);
373                }
374                if (mesh->edges != NULL) free(mesh->edges);
375                mesh->numEdges = 0;
376
377                if (mesh->triangles != NULL) free(mesh->triangles);
378                mesh->numTriangles = 0;
379
380                free(mesh);
381
382                mesh = NULL;
383        }
384}
385
386int *VMI::trianglesAdjToEdge(Mesh *mesh, int e, int *n) {
387    int triangles[MAX_NUM_TRI];
388    int i, n0, n1, n2,
389        u = mesh->edges[e].u,
390        v = mesh->edges[e].v;
391    int *list, num = 0;
392
393    for (i=0; i<(int)mesh->numTriangles; i++) {
394       
395        if (mesh->triangles[i].enable == TRUE) {
396           
397            n0 = mesh->triangles[i].indices[0];
398            n1 = mesh->triangles[i].indices[1];
399            n2 = mesh->triangles[i].indices[2];
400           
401            if ((n0 == v) || (n1 == v) || (n2 == v) ||
402                (n0 == u) || (n1 == u) || (n2 == u))
403               
404                triangles[num++] = i;
405        }
406    }
407
408    list = (int*) malloc (sizeof(int) * num);
409    if (NULL == list) {
410        fprintf (stderr, "no more memory for list");
411        exit(1);
412    }
413
414    memcpy(list, triangles, sizeof(int) * num);
415
416    *n = num;
417
418    return list;
419}
420
421int *VMI::trianglesAdjToVertex(Mesh *mesh, int v, int *n) {
422    int triangles[MAX_NUM_TRI];
423    int i, n0, n1, n2;
424    int *list, num = 0;
425
426    for (i=0; i<(int)mesh->numTriangles; i++) {
427       
428        if (mesh->triangles[i].enable == TRUE) {
429           
430            n0 = mesh->triangles[i].indices[0];
431            n1 = mesh->triangles[i].indices[1];
432            n2 = mesh->triangles[i].indices[2];
433           
434            if ((n0 == v) || (n1 == v) || (n2 == v))
435               
436                triangles[num++] = i;
437        }
438    }
439
440    list = (int*) malloc (sizeof(int) * num);
441    if (NULL == list) {
442        fprintf (stderr, "no more memory for list");
443        exit(1);
444    }
445
446    memcpy(list, triangles, sizeof(int) * num);
447
448    *n = num;
449
450    return list;
451}
452
453int *VMI::verticesAdjToVertex(Mesh *mesh, int v, int *n) {
454    int numTr;
455    int *triangles = trianglesAdjToVertex(mesh, v, &numTr);
456    int *vertices = (int*) malloc (sizeof(int) * numTr * 2);
457    int i, t, n0, n1, n2;
458    int num = 0;
459
460    for (i=0; i<numTr; i++) {
461        t = triangles[i];
462
463        n0 = mesh->triangles[t].indices[0];
464        n1 = mesh->triangles[t].indices[1];
465        n2 = mesh->triangles[t].indices[2];
466
467        if (n0 != v) addItem(vertices, &num, n0);
468        if (n1 != v) addItem(vertices, &num, n1);
469        if (n2 != v) addItem(vertices, &num, n2);
470    }
471
472    *n = num;
473
474    free(triangles);
475
476    return vertices;
477}
478
479int *VMI::edgesAdjToVertex(Mesh *mesh, int v, int *n) {
480    int numTr;
481    int *triangles = trianglesAdjToVertex(mesh, v, &numTr);
482    int *edges = (int*) malloc (sizeof(int) * numTr * 2);
483    int i, t, n0, n1, n2, e;
484    int num = 0;
485
486    for (i=0; i<numTr; i++) {
487        t = triangles[i];
488
489        n0 = mesh->triangles[t].indices[0];
490        n1 = mesh->triangles[t].indices[1];
491        n2 = mesh->triangles[t].indices[2];
492       
493        if (((n0 == v) || (n1 == v)) &&
494            ((e = findEdge(mesh->edges, mesh->numEdges, n0, n1)) != -1)) addItem(edges, &num, e);
495 
496        if (((n1 == v) || (n2 == v)) &&
497            ((e = findEdge(mesh->edges, mesh->numEdges, n1, n2)) != -1)) addItem(edges, &num, e);
498       
499        if (((n0 == v) || (n2 == v)) &&
500            ((e = findEdge(mesh->edges, mesh->numEdges, n0, n2)) != -1)) addItem(edges, &num, e); 
501    }
502
503    *n = num;
504
505    free(triangles);
506
507    return edges;
508}
509
510int *VMI::edgesAdjToVertices(Mesh *mesh, int *vertices, int numVertices, int *n) {
511    int edges[MAX_NUM_TRI*2];
512    int i, j, v, num = 0, e;
513    int *list, numEdges;
514
515    for (i=0; i<numVertices; i++) {
516        v = vertices[i];
517
518        list = edgesAdjToVertex(mesh, v, &numEdges);
519
520        for (j=0; j<numEdges; j++) {
521            e = list[j];
522           
523            addItem(edges, &num, e);
524        }
525
526        free(list);
527    }
528
529    list = (int*) malloc (sizeof(int) * num);
530    if (NULL == list) {
531        fprintf (stderr, "no more memory for list");
532        exit(1);
533    }
534
535    memcpy(list, edges, sizeof(int) * num);
536
537    *n = num;
538
539    return list;
540}
541
542GLboolean VMI::findVertex(GLfloat *vertices, GLuint num, GLfloat x, GLfloat y, GLfloat z, int *pos) {
543    GLuint i;
544    GLfloat _x, _y, _z;
545    GLboolean found = GL_FALSE;
546   
547    *pos = -1;
548
549    for (i=1; i<num; i++) { // i=0
550
551        _x = vertices[3 * i + 0];
552        _y = vertices[3 * i + 1];
553        _z = vertices[3 * i + 2];
554
555        if (((_x == x) && (_y == y) && (_z == z))) {
556            found = GL_TRUE;
557            *pos = (int)i;
558            break;
559        }
560    }
561
562    return found;
563}
564
565void VMI::updateModel(GLMmodel* pmodel, Mesh *mesh, GLuint numVertices, GLuint numTriangles) {
566    GLuint i , v1, v2 ,v3, numV = 1, numT = 0;
567    int pos;
568    GLfloat x, y, z;
569   
570    if (pmodel->vertices != NULL) free(pmodel->vertices);
571
572    pmodel->vertices = (GLfloat *)calloc ((numVertices + 1) * 3,  sizeof(GLfloat));
573   
574
575    if (pmodel->triangles != NULL) free(pmodel->triangles);
576
577    pmodel->triangles = (GLMtriangle *)malloc (numTriangles * sizeof(GLMtriangle));
578
579   
580    for (i=0; i<mesh->numTriangles; i++) {
581        if (mesh->triangles[i].enable) {
582            v1 = mesh->triangles[i].indices[0];
583            v2 = mesh->triangles[i].indices[1];
584            v3 = mesh->triangles[i].indices[2];
585           
586            x = mesh->vertices[v1].x;
587            y = mesh->vertices[v1].y;
588            z = mesh->vertices[v1].z;
589           
590            if (!findVertex(pmodel->vertices, numV, x, y ,z, &pos)) {
591                pmodel->triangles[numT].vindices[0] = numV;
592               
593                pmodel->vertices[3 * numV + 0] = x;
594                pmodel->vertices[3 * numV + 1] = y;
595                pmodel->vertices[3 * numV + 2] = z;
596                numV++;
597            } else pmodel->triangles[numT].vindices[0] = (GLuint)pos;
598           
599            x = mesh->vertices[v2].x;
600            y = mesh->vertices[v2].y;
601            z = mesh->vertices[v2].z;
602           
603            if (!findVertex(pmodel->vertices, numV, x, y ,z, &pos)) {
604                pmodel->triangles[numT].vindices[1] = numV;
605               
606                pmodel->vertices[3 * numV + 0] = x;
607                pmodel->vertices[3 * numV + 1] = y;
608                pmodel->vertices[3 * numV + 2] = z;
609                numV++;
610            } else pmodel->triangles[numT].vindices[1] = (GLuint)pos;
611           
612            x = mesh->vertices[v3].x;
613            y = mesh->vertices[v3].y;
614            z = mesh->vertices[v3].z;
615           
616            if (!findVertex(pmodel->vertices, numV, x, y ,z, &pos)) {
617                pmodel->triangles[numT].vindices[2] = numV;
618               
619                pmodel->vertices[3 * numV + 0] = x;
620                pmodel->vertices[3 * numV + 1] = y;
621                pmodel->vertices[3 * numV + 2] = z;
622                numV++;
623            } else pmodel->triangles[numT].vindices[2] = (GLuint)pos;
624            numT++;
625        }
626    }
627    pmodel->numvertices  = numV - 1;
628    pmodel->numtriangles = numT;
629}
630
631void VMI::saveModel(char *filename, GLMmodel* pmodel, Mesh *mesh) {
632    GLuint i;
633
634    // The output model contains only one group
635    pmodel->numgroups = 1;
636
637    if (pmodel->groups->name != NULL) free(pmodel->groups->name);
638    pmodel->groups->name = strdup("default");
639    pmodel->groups->material = 0;
640    pmodel->groups->next = NULL;
641    pmodel->groups->numtriangles = mesh->currentNumTriangles;
642
643    if (pmodel->groups->triangles != NULL) free(pmodel->groups->triangles);
644    pmodel->groups->triangles = (GLuint*)malloc(sizeof(GLuint) * mesh->currentNumTriangles);
645
646    for (i=0; i<mesh->currentNumTriangles; i++)
647        pmodel->groups->triangles[i] = i;
648
649    updateModel(pmodel, mesh, mesh->currentNumTriangles * 3, mesh->currentNumTriangles);
650
651    printf("glmWriteOBJ...");
652   
653    glmWriteOBJ(pmodel, filename, GLM_NONE);
654    printf("Ok\n");
655}
Note: See TracBrowser for help on using the repository browser.