source: GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoMeshSimplifier.cpp @ 1024

Revision 1024, 23.8 KB checked in by gumbau, 18 years ago (diff)
Line 
1#include "GeoMeshSimplifier.h"
2#include "GeoMeshSimpSequence.h"
3#include "SimplificationMethod.h"
4#include <iostream>
5#include <fstream>
6
7using namespace Geometry;
8using namespace std;
9
10////////////////////////////////////////////////////////////////////////////
11//                                                                                                                                                                                                                                                                                              //
12//                                                                                      MeshSimplifier class                                                                                                                    //
13//                                                                                                                                                                                                                                                                                              //
14////////////////////////////////////////////////////////////////////////////
15
16//---------------------------------------------------------------------------
17//      MeshSimplifier constructor.
18//---------------------------------------------------------------------------
19MeshSimplifier::MeshSimplifier( const Mesh      *m,
20                                                                                                                                TIPOFUNC                upb)
21{
22        objmesh                                 =       m;
23        mGeoMesh                                =       NULL;
24        msimpsequence           =       NULL;
25        indexMeshLeaves =       -1;
26
27        //      Sets the actual progress bar function.
28        mUPB    =       upb;
29}
30
31//---------------------------------------------------------------------------
32//      MeshSimplifier destroyer.
33//---------------------------------------------------------------------------
34MeshSimplifier::~MeshSimplifier()
35{
36        delete msimpsequence;
37}
38
39//---------------------------------------------------------------------------
40// Returns the simplified mesh.
41//---------------------------------------------------------------------------
42Mesh *  MeshSimplifier::GetMesh()
43{
44        return mGeoMesh;
45}
46
47//---------------------------------------------------------------------------
48//      Set submesh leaves
49//---------------------------------------------------------------------------
50void MeshSimplifier::setMeshLeaves(Index index)
51{
52        indexMeshLeaves =       index;
53}
54
55//---------------------------------------------------------------------------
56// Returns the simplification sequence for general meshes.
57//---------------------------------------------------------------------------
58MeshSimplificationSequence *MeshSimplifier::GetSimplificationSequence()
59{
60        return msimpsequence;
61}
62
63//---------------------------------------------------------------------------
64//      Sort mesh bones.
65//---------------------------------------------------------------------------
66void    MeshSimplifier::sortBones()
67{
68        Mesh                                                                    *mesh_copy;
69        int                                                                             n;
70        int                                                                     o;
71        int                                                                             p;
72        VertexBoneAssignment    assign;
73        VertexBuffer                                    *mesh_vb;
74        VertexBuffer                                    *undo_vb;
75        SubMesh                                                         *geosubmesh;
76        SubMesh                                                         *undosubmesh;
77       
78        //      Gets a copy of the mesh.
79        mesh_copy               =       new Mesh();
80        *mesh_copy      =       *mGeoMesh;
81       
82        //      For each submesh.
83        for (size_t     i       =       0; i < mGeoMesh->mSubMeshCount; i++)
84        {
85                geosubmesh      =       &mGeoMesh->mSubMesh[i];
86                undosubmesh     =       &mesh_copy->mSubMesh[i];
87               
88                //      If there is submesh bones.
89                if (!geosubmesh->mBones.empty())
90                {
91                        assign.boneIndex        =       0;
92                        assign.weight                   =       1;
93
94                        geosubmesh->mBones.clear();
95
96                        for (int        m       =       0;      m < geosubmesh->mVertexBuffer->mVertexCount;    m++)
97                        {
98                                assign.vertexIndex      =       m;
99                               
100                                geosubmesh->mBones.push_back(assign);
101                        }
102
103                        //      Change bones.
104                        for (int        m = 0;  m < geosubmesh->mBones.size();  m++)
105                        {
106                                n       =       geosubmesh->mBones[m].vertexIndex;
107
108                                //      Initialize o.
109                                o       =       0;
110
111                                mesh_vb =       geosubmesh->mVertexBuffer;
112                                undo_vb =       undosubmesh->mVertexBuffer;
113
114                                while (!(
115                                                        (mesh_vb->mPosition[n].x == undo_vb->mPosition[o].x)
116                                                        &&
117                                                        (mesh_vb->mPosition[n].y == undo_vb->mPosition[o].y)
118                                                        &&
119                                                        (mesh_vb->mPosition[n].z == undo_vb->mPosition[o].z)
120                                                        ))
121                                {
122                                        o++;
123                                }
124
125                                //      Initialize p.
126                                p       =       0;
127
128                                while (undosubmesh->mBones[p].vertexIndex != o)
129                                {
130                                        p++;
131                                }
132
133                                //      Same bone for 'm' and 'p'.
134                                geosubmesh->mBones[m].boneIndex =       undosubmesh->mBones[p].boneIndex;
135                        }
136                }
137        }
138
139        //      Delete copy of the mesh.
140        delete  mesh_copy;
141}
142
143////////////////////////////////////////////////////////////////////////////
144//                                                                                                                                                                                                                                                                                              //
145//                                                                      GeometryBasedSimplifier class                                                                                                   //
146//                                                                                                                                                                                                                                                                                              //
147////////////////////////////////////////////////////////////////////////////
148
149//---------------------------------------------------------------------------
150//      Constructor.
151//---------------------------------------------------------------------------
152GeometryBasedSimplifier::GeometryBasedSimplifier(       const Mesh      *m,
153                                                                                                                                                                                                        TIPOFUNC                upb)
154                                                                                                                                                                                                :MeshSimplifier(m,upb)
155{
156}
157
158//---------------------------------------------------------------------------
159//      Destroyer.
160//---------------------------------------------------------------------------
161GeometryBasedSimplifier::~GeometryBasedSimplifier()
162{
163}
164
165//---------------------------------------------------------------------------
166// Starts the simplification process. Receives as a parameter the LOD factor in a range of [0,1]. Implements the Simplifier::Simplify method to perform an image based simplification.
167//---------------------------------------------------------------------------
168void GeometryBasedSimplifier::Simplify(Real paramlod)
169{
170        SimplificationMethod *m_qslim   =       new SimplificationMethod(objmesh);
171       
172        m_qslim->setMeshLeaves(indexMeshLeaves);
173       
174        msimpsequence   =       m_qslim->Decimate(paramlod,0,mUPB);
175       
176        mGeoMesh        =       m_qslim->GetMesh();
177       
178        delete  m_qslim;
179}
180
181//---------------------------------------------------------------------------
182// Starts the simplification process. Receives as a parameter the number of vertices of the resulting mesh. Implements the Simplifier::Simplify method to perform an image based simplification.
183//---------------------------------------------------------------------------
184void GeometryBasedSimplifier::Simplify(uint32 numvertices)
185{
186        SimplificationMethod *m_qslim   =       new SimplificationMethod(objmesh);
187       
188        m_qslim->setMeshLeaves(indexMeshLeaves);
189       
190        msimpsequence   =       m_qslim->Decimate((float)numvertices,1,mUPB);
191
192        mGeoMesh        =       m_qslim->GetMesh();
193       
194        delete m_qslim;
195}
196
197////////////////////////////////////////////////////////////////////////////
198//                                                                                                                                                                                                                                                                                              //
199//                                                              ViewPointDrivenSimplifier class                                                                                                 //
200//                                                                                                                                                                                                                                                                                              //
201////////////////////////////////////////////////////////////////////////////
202
203//---------------------------------------------------------------------------
204/// Class constructor. Will call Simplifier class constructor.
205//---------------------------------------------------------------------------
206ViewPointDrivenSimplifier::ViewPointDrivenSimplifier(   const Mesh      *m,
207                                                                                                                                                                                                                        TIPOFUNC                upb)
208                                                                                                                                                                                                                :MeshSimplifier(m,upb)
209{
210        //      Set progress update function
211        VMI::mUPB       =       upb;
212       
213        VMI::width  = 256;
214        VMI::height = 256;
215
216        VMI::bEnableOffScreen     = GL_TRUE;
217        VMI::bBeQuiet             = GL_FALSE;
218        VMI::bSaveLog             = GL_FALSE;
219        VMI::bLoadCamerasFromFile = GL_FALSE;
220
221        VMI::cameraType = 2;
222        VMI::radius = 1.3;
223        VMI::fov = 60.0;
224
225        printf("w: %d h: %d\n", VMI::width, VMI::height);
226
227        printf( "t: %d c: %d o: %d r: %f\n",
228                        VMI::numDemandedTriangles,
229                        VMI::cameraType,
230                        VMI::bEnableOffScreen,
231                        VMI::radius);
232
233
234        mGeoMesh        =       new Mesh();
235       
236        *mGeoMesh       =       *m;
237       
238        //      Transform NoSV Mesh to a SV Mesh.
239        mGeoMesh        =       mGeoMesh->toSharedVertex();
240
241        //      Loads the vmi mesh structure for a geometry mesh given.
242        VMI::mesh = initMeshStructure(mGeoMesh);
243       
244        // RGB and Alpha.
245        glutInitDisplayMode(GLUT_DEPTH | GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA);
246        glutInitWindowSize(VMI::width, VMI::height);
247        glutInitWindowPosition(100, 100);
248
249        VMI::vmiWin     =       glutCreateWindow("VMI");
250
251        glewInit();
252
253        VMI::init();
254
255        if (VMI::bLoadCamerasFromFile == GL_FALSE)
256        {
257                switch (VMI::cameraType)
258                {
259                        case 0:
260                                VMI::cameras = VMI::setCameras(VMI::radius, OCTAHEDRON, &VMI::numCameras);
261                                printf("Number of cameras: %d\n", OCTAHEDRON);
262                                break;
263                        case 1:
264                                VMI:: cameras = VMI::setCameras(VMI::radius, ICOSAHEDRON, &VMI::numCameras);
265                                printf("Number of cameras: %d\n", ICOSAHEDRON);
266                                break;
267                        case 2:
268                                VMI::cameras = VMI::setCameras(VMI::radius, DODECAHEDRON, &VMI::numCameras);
269                                printf("Number of cameras: %d\n", DODECAHEDRON);
270                                break;
271                        default:
272                                break;
273                }
274        }
275
276        VMI::histogram  =       VMI::initHistogram(     VMI::mesh->currentNumTriangles,
277                                                                                                                                                                VMI::numCameras);
278
279        VMI::initialIs  =       VMI::initIs(VMI::numCameras);
280
281}
282
283//---------------------------------------------------------------------------
284/// Class destructor.
285//---------------------------------------------------------------------------
286ViewPointDrivenSimplifier::~ViewPointDrivenSimplifier(void)
287{
288        // Free memory
289         VMI::freeMemory();
290}
291
292/// Copy constructor
293//ViewPointDrivenSimplifier(const ViewPointDrivenSimplifier&);
294
295/// Assignment operator
296//ViewPointDrivenSimplifier& operator =(const ViewPointDrivenSimplifier&);
297
298/// Starts the simplification process. Receives as a parameter the LOD factor in a range of [0,1]. Implements the Simplifier::Simplify method to perform an image based simplification.
299void ViewPointDrivenSimplifier::Simplify(Real percent)
300{
301        VMI::numDemandedTriangles = (int)(VMI::mesh->numTriangles * percent);
302
303        if ((VMI::numDemandedTriangles == 0)
304                        ||
305                        (VMI::numDemandedTriangles >= VMI::mesh->currentNumTriangles))
306        {
307                printf("Illegal number of triangles.\n");
308        }
309
310        VMI::display();
311
312        //      Load a geometry mesh for vmi mesh.
313        loadMesh();
314
315        GetMeshSimpSequence();
316}
317
318//---------------------------------------------------------------------------
319/// Starts the simplification process. Receives as a parameter the number of vertices of the resulting mesh. Implements the Simplifier::Simplify method to perform an image based simplification.
320//---------------------------------------------------------------------------
321void ViewPointDrivenSimplifier::Simplify(uint32 numVertices)
322{
323        float   percent;
324
325        percent =       (numVertices    *       100.0) / VMI::mesh->numVertices;
326
327        VMI::numDemandedTriangles = (int)(VMI::mesh->numTriangles * (percent / 100));
328
329        if ((VMI::numDemandedTriangles == 0)
330                        ||
331                        (VMI::numDemandedTriangles >= VMI::mesh->currentNumTriangles))
332        {
333                printf("Illegal number of triangles.\n");
334        }
335
336        VMI::display();
337
338        //      Load a geometry mesh for vmi mesh.
339        loadMesh();
340
341        GetMeshSimpSequence();
342}
343
344// Returns the simplified mesh.
345//Mesh  *       ViewPointDrivenSimplifier::GetMesh()
346//{
347//      return mGeoMesh;
348//}
349
350//---------------------------------------------------------------------------
351//      Gets the VMI mesh simplification sequence.
352//---------------------------------------------------------------------------
353void    ViewPointDrivenSimplifier::GetMeshSimpSequence()
354{
355        unsigned        int j = 0;
356       
357        MeshSimplificationSequence::Step        current_step;
358       
359        msimpsequence   =       new MeshSimplificationSequence();
360       
361        //      For each simplification step.
362        for (unsigned   int i = 0;      i < VMI::mVMISteps.size();      i++)
363        {
364                current_step.mV0        =       VMI::mVMISteps[i].mV0;
365                current_step.mV1        =       VMI::mVMISteps[i].mV1;
366                current_step.mT0        =       VMI::mVMISteps[i].mT0;
367                current_step.mT1        =       VMI::mVMISteps[i].mT1;
368               
369                current_step.x  =       VMI::mVMISteps[i].x;
370                current_step.y  =       VMI::mVMISteps[i].y;
371                current_step.z  =       VMI::mVMISteps[i].z;
372
373                current_step.obligatorio        =       VMI::mVMISteps[i].obligatory;
374
375                //      For each face modificated.
376                while (j < VMI::mVMISteps[i].mModfaces.size())
377                {
378                        current_step.mModfaces.push_back(VMI::mVMISteps[i].mModfaces[j]);
379                       
380                        j++;
381                }
382               
383                msimpsequence->mSteps.push_back(current_step);
384        }
385}
386
387//---------------------------------------------------------------------------
388//      Class for join triangle holes.
389//---------------------------------------------------------------------------
390class _coord_
391{
392        public:
393                float x,y,z;
394                inline _coord_( float x =       0.0f,
395                                                                                float y =       0.0f,
396                                                                                float z =       0.0f)
397                { this->x = x; this->y = y; this->z = z; }
398               
399                inline _coord_(const _coord_ &f)
400                {
401                        x       =       f.x;
402                        y=f.y;
403                        z=f.z;
404                }
405               
406                inline _coord_ & operator=(const _coord_ &f)
407                {
408                        x       =       f.x;
409                        y       =       f.y;
410                        z       =       f.z;
411                       
412                        return *this;
413                }
414               
415                inline bool operator<(const _coord_ &f) const
416                {
417                        if (x<f.x-0.0001) return true;
418                        if (x>f.x+0.0001) return false;
419                        if (y<f.y-0.0001) return true;
420                        if (y>f.y+0.0001) return false;
421                        if (z<f.z-0.0001) return true;
422                        if (z>f.z+0.0001) return false;
423                       
424                        return  false;
425                }
426};
427
428//---------------------------------------------------------------------------
429//      Initialize the mesh of VMI module.
430//---------------------------------------------------------------------------
431VMI::Mesh *     ViewPointDrivenSimplifier::initMeshStructure(Mesh       *geoMesh)
432{
433        GLuint                          i, j, v1, v2, v3, n, e, t;
434        VMI::Mesh               *vmi_mesh;
435        SubMesh                         *geosubmesh;
436        VertexBuffer    *vertex_buffer;
437        int                                             mesh_index_count;
438        int                                             index;
439
440        //      Reallocate memory for vmi mesh object.
441        vmi_mesh = (VMI::Mesh *)malloc(sizeof(VMI::Mesh));
442
443        if (vmi_mesh == NULL)
444        {
445                fprintf(stderr, "Error allocating memory\n");
446                exit(1);
447        }
448
449        //      Shared vertex buffer.
450        vertex_buffer   =       geoMesh->mVertexBuffer;
451       
452        //      Reallocate memory for vertices of mesh.
453        vmi_mesh->vertices = (VMI::Vertex *)malloc(sizeof(VMI::Vertex)
454                                                                                                                                                                *
455                                                                                                                                                                vertex_buffer->mVertexCount);
456
457        if (vmi_mesh->vertices == NULL)
458        {
459                fprintf(stderr, "Error allocating memory\n");
460                exit(1);
461        }
462
463        //      Initialize mesh index count.
464        mesh_index_count        =       0;
465       
466        for (unsigned int submesh       =       0; submesh < mGeoMesh->mSubMeshCount; submesh++)
467        {
468                mesh_index_count        +=      int(mGeoMesh->mSubMesh[submesh].mIndexCount);
469        }
470       
471        //      Reallocate memory for indices.
472        vmi_mesh->triangles = (VMI::Triangle *)malloc(sizeof(VMI::Triangle)
473                                                                                                                                                                                *
474                                                                                                                                                                                (mesh_index_count / 3));
475
476        if (vmi_mesh->triangles == NULL)
477        {
478                fprintf(stderr, "Error allocating memory\n");
479                exit(1);
480        }
481
482        printf("Adding vertices...");
483        //      Fill up vertices.
484        std::map<_coord_, int> uniquevertices;
485        std::map<int, int> newindices;
486        for (i = 0; i < vertex_buffer->mVertexCount; i++)
487        {
488                _coord_ vertex_aux;
489                vertex_aux.x= vertex_buffer->mPosition[i].x;
490                vertex_aux.y= vertex_buffer->mPosition[i].y;
491                vertex_aux.z= vertex_buffer->mPosition[i].z;
492                //New index
493                if (uniquevertices.find(vertex_aux)==uniquevertices.end())
494                {
495                        uniquevertices[vertex_aux]= i;
496                        newindices[i]= i;
497
498                        VMI::INTVECTOR intvectoraux;
499                        intvectoraux.push_back(i);
500                        VMI::inversemap[i]= intvectoraux;
501
502                }else//The map of unique vertices already contains this vertex
503                {
504                        int newindex= uniquevertices[vertex_aux];
505                        newindices[i]= newindex;
506
507                        VMI::inversemap[newindex].push_back(i);;
508                }
509
510                // Vertices start at 0.
511                vmi_mesh->vertices[i].x = vertex_buffer->mPosition[i].x;
512                vmi_mesh->vertices[i].y = vertex_buffer->mPosition[i].y;
513                vmi_mesh->vertices[i].z = vertex_buffer->mPosition[i].z;
514               
515                vmi_mesh->vertices[i].numTriangles = 0;
516                vmi_mesh->vertices[i].triangles = NULL;
517                vmi_mesh->vertices[i].enable = GL_TRUE;
518        }
519       
520        printf("Ok\n");
521        vmi_mesh->numVertices = int(vertex_buffer->mVertexCount);
522        vmi_mesh->currentNumVertices = int(vertex_buffer->mVertexCount);
523
524        //      Fill up triangles.
525        printf("Adding triangles...");
526       
527        //      Initialize index of triangle.
528        index   =       0;
529       
530        //      For each submesh.
531        for (unsigned int submesh       =       0; submesh      <       mGeoMesh->mSubMeshCount; submesh++)
532        {
533                //      Gets actual submesh.
534                geosubmesh      =       &mGeoMesh->mSubMesh[submesh];
535               
536                for (i = 0; i < (geosubmesh->mIndexCount / 3); i++)
537                {
538                        vmi_mesh->triangles[index].id                           = index;
539                        vmi_mesh->triangles[index].submesh              = submesh;
540                        vmi_mesh->triangles[index].indices[0] = newindices[geosubmesh->mIndex[(3 * i)]];
541                        vmi_mesh->triangles[index].indices[1] = newindices[geosubmesh->mIndex[(3 * i) + 1]];
542                        vmi_mesh->triangles[index].indices[2] = newindices[geosubmesh->mIndex[(3 * i) + 2]];
543
544                        vmi_mesh->triangles[index].area = computeTriangleArea(vmi_mesh->vertices,
545                                        &vmi_mesh->triangles[index]);
546                        //printf("\n%d a: %f",index , vmi_mesh->triangles[index].area);
547                        computeTriangleNormal(vmi_mesh->vertices, &vmi_mesh->triangles[index]);
548
549                        vmi_mesh->triangles[index].saliency = 0.0;
550
551                        vmi_mesh->triangles[index].enable = GL_TRUE;
552
553                        for (j = 0; j < 3; j++)
554                        {
555                                // Adding triangle index adjacent to 3 vertices.
556                                v1 = vmi_mesh->triangles[index].indices[j];
557
558                                // Reallocate memory for the new adjacent triangle.
559                                vmi_mesh->vertices[v1].triangles = (GLuint *)realloc(vmi_mesh->vertices[v1].triangles, (vmi_mesh->vertices[v1].numTriangles + 1) * sizeof(GLuint));
560                                VMI::addItem((int *)vmi_mesh->vertices[v1].triangles, (int *)&vmi_mesh->vertices[v1].numTriangles, index);
561                        }
562
563                        //      Increments triangle count.
564                        index++;
565                }
566        }
567       
568        printf("Ok\n");
569
570        vmi_mesh->numTriangles                          = mesh_index_count / 3;
571        vmi_mesh->currentNumTriangles = mesh_index_count / 3;
572
573        printf("Num Triangles: %d\n",vmi_mesh->numTriangles);
574       
575        // E = 3 T / 2
576        vmi_mesh->edges = (VMI::Edge *)malloc(sizeof(VMI::Edge)
577                                                                                                                                                *
578                                                                                                                                                vmi_mesh->numTriangles * 3);
579
580        if (vmi_mesh->edges == NULL)
581        {
582                fprintf(stderr, "Error allocating memory\n");
583                exit(1);
584        }
585
586        // Init edges
587        for (i=0; i<vmi_mesh->numTriangles * 3; i++)
588        {
589                vmi_mesh->edges[i].triangles    = NULL;
590                vmi_mesh->edges[i].numTriangles = 0;
591        }
592
593        printf("Adding edges...");
594        n = 0;
595
596        for (i=0; i<vmi_mesh->numTriangles; i++)
597        {
598                t               =       0;
599                v1      =       vmi_mesh->triangles[i].indices[0];
600                v2      =       vmi_mesh->triangles[i].indices[1];
601                v3      =       vmi_mesh->triangles[i].indices[2];
602
603                if ((e = findEdge(vmi_mesh->edges, n, v1, v2)) == -1)
604                {
605                        vmi_mesh->edges[n].u                    =       v1;
606                        vmi_mesh->edges[n].v                    =       v2;
607                        vmi_mesh->edges[n].enable =     GL_TRUE;
608
609                        // Reallocate memory for the new adjacent triangle
610                        vmi_mesh->edges[n].triangles = (GLuint *)realloc(vmi_mesh->edges[n].triangles, (vmi_mesh->edges[n].numTriangles + 1) * sizeof(GLuint));
611                        // Adding triangle i adjacent to edge n
612                        VMI::addItem((int *)vmi_mesh->edges[n].triangles, (int *)&vmi_mesh->edges[n].numTriangles, i);
613                        //printf("n:%d i:%d\n", n, i);
614
615                        // Adding edge n adjacent to triangle i
616                        VMI::addItem((int *)vmi_mesh->triangles[i].edges, (int *)&t, n);
617                        n++;
618                }
619                else
620                {
621                        // Reallocate memory for the new adjacent triangle.
622                        vmi_mesh->edges[e].triangles = (GLuint *)realloc(vmi_mesh->edges[e].triangles, (vmi_mesh->edges[e].numTriangles + 1) * sizeof(GLuint));
623                        // Adding triangle i adjacent to edge e
624                        VMI::addItem((int *)vmi_mesh->edges[e].triangles, (int *)&vmi_mesh->edges[e].numTriangles, i);
625                        //printf("n:%d i:%d\n", e, i);
626
627                        // Adding edge e adjacent to triangle i
628                        VMI::addItem((int *)vmi_mesh->triangles[i].edges, (int *)&t, e);
629                }
630                if ((e = findEdge(vmi_mesh->edges, n, v2, v3)) == -1)
631                {
632                        vmi_mesh->edges[n].u = v2;
633                        vmi_mesh->edges[n].v = v3;
634                        vmi_mesh->edges[n].enable = GL_TRUE;
635
636                        // Reallocate memory for the new adjacent triangle
637                        vmi_mesh->edges[n].triangles = (GLuint *)realloc(vmi_mesh->edges[n].triangles, (vmi_mesh->edges[n].numTriangles + 1) * sizeof(GLuint));
638                        // Adding triangle i adjacent to edge n
639                        VMI::addItem((int *)vmi_mesh->edges[n].triangles, (int *)&vmi_mesh->edges[n].numTriangles, i);
640                        //printf("n:%d i:%d\n", n, i);
641
642                        // Adding edge n adjacent to triangle i
643                        VMI::addItem((int *)vmi_mesh->triangles[i].edges, (int *)&t, n);
644                        n++;
645                }
646                else
647                {
648                        // Reallocate memory for the new adjacent triangle
649                        vmi_mesh->edges[e].triangles = (GLuint *)realloc(vmi_mesh->edges[e].triangles, (vmi_mesh->edges[e].numTriangles + 1) * sizeof(GLuint));
650                        // Adding triangle i adjacent to edge e
651                        VMI::addItem((int *)vmi_mesh->edges[e].triangles, (int *)&vmi_mesh->edges[e].numTriangles, i);
652                        //printf("n:%d i:%d\n", e, i);
653
654                        // Adding edge e adjacent to triangle i
655                        VMI::addItem((int *)vmi_mesh->triangles[i].edges, (int *)&t, e);
656                }
657               
658                if ((e = findEdge(vmi_mesh->edges, n, v3, v1)) == -1)
659                {
660                        vmi_mesh->edges[n].u = v3;
661                        vmi_mesh->edges[n].v = v1;
662                        vmi_mesh->edges[n].enable = GL_TRUE;
663
664                        // Reallocate memory for the new adjacent triangle
665                        vmi_mesh->edges[n].triangles = (GLuint *)realloc(vmi_mesh->edges[n].triangles, (vmi_mesh->edges[n].numTriangles + 1) * sizeof(GLuint));
666                        // Adding triangle i adjacent to edge n
667                        VMI::addItem((int *)vmi_mesh->edges[n].triangles, (int *)&vmi_mesh->edges[n].numTriangles, i);
668                        //printf("n:%d i:%d\n", n, i);
669
670                        // Adding edge n adjacent to triangle i
671                        VMI::addItem((int *)vmi_mesh->triangles[i].edges, (int *)&t, n);
672                        n++;
673                }
674                else
675                {
676                        // Reallocate memory for the new adjacent triangle
677                        vmi_mesh->edges[e].triangles = (GLuint *)realloc(vmi_mesh->edges[e].triangles, (vmi_mesh->edges[e].numTriangles + 1) * sizeof(GLuint));
678                        // Adding triangle i adjacent to edge e
679                        VMI::addItem((int *)vmi_mesh->edges[e].triangles, (int *)&vmi_mesh->edges[e].numTriangles, i);
680                        //printf("n:%d i:%d\n", e, i);
681
682                        // Adding edge e adjacent to triangle i
683                        VMI::addItem((int *)vmi_mesh->triangles[i].edges, (int *)&t, e);
684                }
685        }
686       
687        printf("Ok\n");
688        vmi_mesh->numEdges = n;
689
690        return vmi_mesh;
691}
692
693//---------------------------------------------------------------------------
694//      Gets the geometry mesh of a  the vmi mesh given.
695//---------------------------------------------------------------------------
696void    ViewPointDrivenSimplifier::loadMesh()
697{
698        int                                             num_indices;
699        SubMesh                         *geosubmesh;
700        VertexBuffer    *vertex_buffer;
701       
702        //      Gets old vertex buffer.
703        vertex_buffer   =       mGeoMesh->mVertexBuffer;
704       
705        //      Initialize auxiliar vertex buffer.
706        mVB     =       new     VertexBuffer();
707       
708        mVB->mPosition          =       new     Vector3[VMI::mesh->currentNumVertices];
709        mVB->mNormal                    =       new     Vector3[VMI::mesh->currentNumVertices];
710        mVB->mTexCoords         =       new     Vector2[VMI::mesh->currentNumVertices];
711
712        mVB->mVertexInfo        =       vertex_buffer->mVertexInfo;
713
714        //      For each submesh.
715        for (unsigned int submesh       =       0; submesh < mGeoMesh->mSubMeshCount; submesh++)
716        {
717                geosubmesh      =       &mGeoMesh->mSubMesh[submesh];
718
719                delete  []geosubmesh->mIndex;
720
721                //      Initialize submesh index count;
722                num_indices     =       0;
723
724                //      For each triangle.
725                for (unsigned int i = 0; i < VMI::mesh->numTriangles; i++)
726                {
727                        //      If is enable and of the current submesh.
728                        if ((VMI::mesh->triangles[i].enable)
729                                        &&
730                                        (VMI::mesh->triangles[i].submesh == submesh))
731                        {
732                                //      Increments submesh index count.
733                                num_indices     +=      3;
734                        }
735                }
736
737                geosubmesh->mIndexCount =       num_indices;
738
739                geosubmesh->mIndex      =       new Index[geosubmesh->mIndexCount];
740
741                //      Initialize number of indices.
742                num_indices     =       0;
743
744                //      Fill up indices.
745                for (unsigned int i = 0; i < VMI::mesh->numTriangles; i++)
746                {
747                        if ((VMI::mesh->triangles[i].enable)
748                                        &&
749                                        (VMI::mesh->triangles[i].submesh == submesh))
750                        {
751                                geosubmesh->mIndex[num_indices++]       =       VMI::mesh->triangles[i].indices[0];
752                                geosubmesh->mIndex[num_indices++]       =       VMI::mesh->triangles[i].indices[1];
753                                geosubmesh->mIndex[num_indices++]       =       VMI::mesh->triangles[i].indices[2];
754                        }
755                }
756
757                //      For each index.
758                for (unsigned int i = 0; i < geosubmesh->mIndexCount; i++)
759                {
760                        findVertex(submesh,i);
761                }
762
763                geosubmesh->mVertexBuffer       =       mVB;
764        }
765
766        delete  vertex_buffer;
767       
768        mGeoMesh->mVertexBuffer =       mVB;
769
770}
771
772//---------------------------------------------------------------------------
773//      Find vertex in auxiliar vertex buffer.
774//---------------------------------------------------------------------------
775void    ViewPointDrivenSimplifier::findVertex(size_t    submesh, size_t elem)
776{
777        bool                                    found;
778        int                                             index;
779        unsigned int                    i;
780        int                                             new_elem;
781        VertexBuffer    *vertex_buffer;
782
783        found   =       false;
784
785        //      Shared vertex buffer.
786        vertex_buffer   =       mGeoMesh->mVertexBuffer;
787       
788        index   =       mGeoMesh->mSubMesh[submesh].mIndex[elem];
789       
790        i       =       0;
791       
792        while (!found && (i < mVB->mVertexCount))
793        {
794                if ((VMI::mesh->vertices[index].x == mVB->mPosition[i].x)
795                                &&
796                                (VMI::mesh->vertices[index].y == mVB->mPosition[i].y)
797                                &&
798                                (VMI::mesh->vertices[index].z == mVB->mPosition[i].z))
799                {
800                        found   =       true;
801
802                        //      Update index.
803                        mGeoMesh->mSubMesh[submesh].mIndex[elem]        =        i;
804                }
805
806                //      Increments index.
807                i++;
808        }
809
810        if (!found)
811        {
812                //      Last element.
813                new_elem        =       int(mVB->mVertexCount);
814               
815                //      Add to last.
816                mVB->mPosition[new_elem].x      =       VMI::mesh->vertices[index].x;
817                mVB->mPosition[new_elem].y      =       VMI::mesh->vertices[index].y;
818                mVB->mPosition[new_elem].z      =       VMI::mesh->vertices[index].z;
819
820                mVB->mNormal[new_elem].x        =       vertex_buffer->mNormal[index].x;
821                mVB->mNormal[new_elem].y        =       vertex_buffer->mNormal[index].y;
822                mVB->mNormal[new_elem].z        =       vertex_buffer->mNormal[index].z;
823
824                mVB->mTexCoords[new_elem].x     =       vertex_buffer->mTexCoords[index].x;
825                mVB->mTexCoords[new_elem].y     =       vertex_buffer->mTexCoords[index].y;
826
827                //      Update index.
828                mGeoMesh->mSubMesh[submesh].mIndex[elem]        =        new_elem;
829
830                //      Increments vertex count.
831                mVB->mVertexCount++;
832        }
833}
834
Note: See TracBrowser for help on using the repository browser.