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

Revision 2103, 35.4 KB checked in by gumbau, 17 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        //      Saves initial state of mesh.
23        mInitialMesh    =       new Mesh();
24        *mInitialMesh   =       *m;
25       
26        objmesh                                 =       m;
27        mGeoMesh                                =       NULL;
28        msimpsequence           =       NULL;
29        indexMeshLeaves =       -1;
30
31        //      Sets the actual progress bar function.
32        mUPB    =       upb;
33}
34
35//-------------------------------------------------------------------------
36//      MeshSimplifier destroyer.
37//-------------------------------------------------------------------------
38MeshSimplifier::~MeshSimplifier()
39{
40        delete  mInitialMesh;
41        delete  msimpsequence;
42}
43
44//-------------------------------------------------------------------------
45// Returns the simplified mesh.
46//-------------------------------------------------------------------------
47Mesh *  MeshSimplifier::GetMesh()
48{
49        return mGeoMesh;
50}
51
52//-------------------------------------------------------------------------
53//      Set submesh leaves
54//-------------------------------------------------------------------------
55void MeshSimplifier::setMeshLeaves(Geometry::Index index)
56{
57        indexMeshLeaves =       index;
58}
59
60//-------------------------------------------------------------------------
61// Returns the simplification sequence for general meshes.
62//-------------------------------------------------------------------------
63MeshSimplificationSequence *MeshSimplifier::GetSimplificationSequence()
64{
65        return msimpsequence;
66}
67
68//-------------------------------------------------------------------------
69//    Sort mesh bones.
70//-------------------------------------------------------------------------
71void MeshSimplifier::sortBones()
72{
73        VertexBuffer    *simplified_vb;
74        VertexBuffer    *initial_vb;
75
76        std::vector<VertexBoneAssignment>       *simplified_bones;
77        std::vector<VertexBoneAssignment>       *initial_bones;
78
79        // After simplifying, the object always is shared vertex
80        // so, the bones must be placed in the GeoMesh
81        simplified_bones        =       &mGeoMesh->mBones;
82        simplified_vb                   =       mGeoMesh->mVertexBuffer;
83
84        // we assume the original mesh is shared vertex
85        // because before the simplification process
86        // the mesh becomes converted to shared vertex
87        // so, the original bones must be searched in the
88        // Mesh, not in every submesh
89
90        simplified_bones->clear();
91
92        //    Vertex buffers.
93        initial_vb      =       mInitialMesh->mVertexBuffer;
94
95        //    Bones.
96        initial_bones   =       &mInitialMesh->mBones;
97
98        //  For each bone assignment.
99        for (int b = 0; b < initial_bones->size(); b++)
100        {
101                VertexBoneAssignment    assign;
102
103                int n   =       (*initial_bones)[b].vertexIndex;
104
105                //      For each vertex.
106                for (int i      =       0;      i < simplified_vb->mVertexCount;        i++)
107                {
108                        if (simplified_vb->mPosition[i].x == initial_vb->mPosition[n].x &&
109                                        simplified_vb->mPosition[i].y == initial_vb->mPosition[n].y &&
110                                        simplified_vb->mPosition[i].z == initial_vb->mPosition[n].z)
111                        {
112                                assign.vertexIndex      =       i;
113                                assign.boneIndex                =       (*initial_bones)[b].boneIndex;
114                                assign.weight                           =       (*initial_bones)[b].weight;
115
116                                simplified_bones->push_back(assign);
117                        }
118                }
119        }
120}
121
122
123//////////////////////////////////////////////////////////////////////////
124//                                                                                                                                                                                                                                                                                      //
125//                                                                      GeometryBasedSimplifier class                                                                                           //
126//                                                                                                                                                                                                                                                                                      //
127//////////////////////////////////////////////////////////////////////////
128
129//-------------------------------------------------------------------------
130//      Constructor.
131//-------------------------------------------------------------------------
132GeometryBasedSimplifier::GeometryBasedSimplifier(       const Mesh      *m,
133                                                                                                                                                                                                        TIPOFUNC                upb)
134                                                                                                                                                                                                :MeshSimplifier(m,upb)
135{
136}
137
138//-------------------------------------------------------------------------
139//      Destructor.
140//-------------------------------------------------------------------------
141GeometryBasedSimplifier::~GeometryBasedSimplifier()
142{
143}
144
145//-------------------------------------------------------------------------
146// Starts the simplification process. Receives as a parameter
147// the LOD factor in a range of [0,1]. Implements the Simplifier::Simplify
148// method to perform an image based simplification.
149//-------------------------------------------------------------------------
150void GeometryBasedSimplifier::Simplify(Real paramlod)
151{
152        SimplificationMethod *m_qslim   =       new SimplificationMethod(objmesh);
153
154        m_qslim->setMeshLeaves(indexMeshLeaves);
155
156        msimpsequence   =       m_qslim->Decimate(paramlod,0,mUPB);
157
158        mGeoMesh        =       m_qslim->GetMesh();
159
160        //      Debug.
161        cout    <<      "Number of bone assignaments: "
162                                <<      mGeoMesh->mBones.size()
163                                <<      endl;
164
165        // if the initial mesh had shared vertex,
166        // convert the mesh to shared vertex
167        //Mesh *sharedMesh = mGeoMesh->toSharedVertex();
168        //delete mGeoMesh;
169        //mGeoMesh = sharedMesh;
170
171        //      Sort bones.
172        //sortBones();
173
174        delete  m_qslim;
175}
176
177//-------------------------------------------------------------------------
178// Starts the simplification process. Receives as a parameter the
179// number of vertices of the resulting mesh.
180// Implements the Simplifier::Simplify method to
181// perform an image based simplification.
182//-------------------------------------------------------------------------
183void GeometryBasedSimplifier::Simplify(uint32 numvertices)
184{
185        SimplificationMethod *m_qslim   =       new SimplificationMethod(objmesh);
186       
187        m_qslim->setMeshLeaves(indexMeshLeaves);
188       
189        msimpsequence   =       m_qslim->Decimate((float)numvertices,1,mUPB);
190
191        mGeoMesh        =       m_qslim->GetMesh();
192
193        // if the initial mesh had shared vertex,
194        // convert the mesh to shared vertex
195        //Mesh *sharedMesh = mGeoMesh->toSharedVertex();
196        //delete mGeoMesh;
197        //mGeoMesh = sharedMesh;
198       
199        //      Sort bones.
200        //sortBones();
201       
202        delete m_qslim;
203}
204
205//////////////////////////////////////////////////////////////////////////
206//                                                                                                                                                                                                                                                                                      //
207//                                                              ViewPointDrivenSimplifier class                                                                                         //
208//                                                                                                                                                                                                                                                                                      //
209//////////////////////////////////////////////////////////////////////////
210
211//------------------------------------------------------------------------
212// Class constructor. Will call Simplifier class constructor.
213//------------------------------------------------------------------------
214ViewPointDrivenSimplifier::ViewPointDrivenSimplifier(   const Mesh      *m,
215                                                                                                                                                                                                                        TIPOFUNC                upb)
216                                                                                                                                                                                                                :MeshSimplifier(m,upb)
217{
218        //      Set progress update function
219        VMI::mUPB       =       upb;
220
221        VMI::width  = 256;
222        VMI::height = 256;
223
224        VMI::bEnableOffScreen                   = GL_TRUE;
225        VMI::bBeQuiet                           = GL_FALSE;
226        VMI::bSaveLog                           = GL_FALSE;
227        VMI::bLoadCamerasFromFile               = GL_FALSE;
228        VMI::bRemoveRedundantVertices = GL_TRUE;
229
230        VMI::cameraType = 3; // 20 viewpoints
231        VMI::radius = 1.3;
232        VMI::fov = 60.0;
233
234        printf("w: %d h: %d\n", VMI::width, VMI::height);
235
236        printf( "t: %d c: %d o: %d r: %f\n",
237                        VMI::numDemandedTriangles,
238                        VMI::cameraType,
239                        VMI::bEnableOffScreen,
240                        VMI::radius);
241
242        //      Fill up attributes.
243        fillUpPosNorTC(mInitialMesh);
244
245        VMI::vPositions =       vPositions;
246        VMI::vNormals           =       vNormals;
247        VMI::vTexCoords =       vTexCoords;
248
249       
250
251        mGeoMesh        =       new Mesh();
252
253        *mGeoMesh       =       *m;
254
255        //      Transform NoSV Mesh to a SV Mesh.
256        //mGeoMesh      =       mGeoMesh->toSharedVertex();
257       
258        //      Join Vertices.
259        mTexConserver   =        new    TextureConserver();
260        mTexConserver->JoinVertices(mGeoMesh);
261
262        //      Loads the vmi mesh structure for a geometry mesh given.
263        VMI::mesh = initMeshStructure(mGeoMesh);
264
265        // RGB and Alpha.
266        glutInitDisplayMode(GLUT_DEPTH | GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA);
267        glutInitWindowSize(VMI::width, VMI::height);
268        glutInitWindowPosition(100, 100);
269
270        VMI::vmiWin     =       glutCreateWindow("VMI");
271
272        glewInit();
273
274        VMI::init();
275
276        if (VMI::bLoadCamerasFromFile == GL_FALSE)
277                VMI::cameras = VMI::setCameras(VMI::radius, VMI::cameraType, &VMI::numCameras);
278
279        VMI::histogram  =       VMI::initHistogram(     VMI::mesh->currentNumTriangles,
280                        VMI::numCameras);
281
282        VMI::initialIs  =       VMI::initIs(VMI::numCameras);
283}
284
285//-------------------------------------------------------------------------
286/// Class destructor.
287//-------------------------------------------------------------------------
288ViewPointDrivenSimplifier::~ViewPointDrivenSimplifier(void)
289{
290        // Free memory
291        VMI::freeMemory();
292
293        delete  VMI::mSequence;
294        VMI::mSequence  =       NULL;
295}
296
297/// Starts the simplification process. Receives as a parameter the
298///     LOD factor in a range of [0,1]. Implements the
299///     Simplifier::Simplify method to perform an image based simplification.
300void ViewPointDrivenSimplifier::Simplify(Real percent)
301{
302        VMI::numDemandedTriangles = (int)(VMI::mesh->numTriangles * percent);
303
304        if ((VMI::numDemandedTriangles == 0)
305                        ||
306                        (VMI::numDemandedTriangles >= VMI::mesh->currentNumTriangles))
307        {
308                printf("Illegal number of triangles.\n");
309        }
310
311        VMI::display();
312
313        //      Cleans firts simplification.
314        VMI::freeMemory();
315
316        VMI::mesh =     initMeshStructure(mInitialMesh);
317
318        VMI::contractInitialMesh(VMI::mesh);
319
320        //      Load a geometry mesh for vmi mesh.
321        loadMesh();
322       
323        GetMeshSimpSequence();
324
325        //      Sort bones.
326        bonesReassignament();
327}
328
329//-------------------------------------------------------------------------
330/// Starts the simplification process. Receives as a parameter
331///     the number of vertices of the resulting mesh.
332/// Implements the Simplifier::Simplify method to perform
333///     an image based simplification.
334//-------------------------------------------------------------------------
335void ViewPointDrivenSimplifier::Simplify(uint32 numVertices)
336{
337        float   percent;
338
339        percent =       (numVertices    *       100.0) / VMI::mesh->numVertices;
340
341        VMI::numDemandedTriangles = (int)(VMI::mesh->numTriangles * (percent / 100));
342
343        if ((VMI::numDemandedTriangles == 0)
344                        ||
345                        (VMI::numDemandedTriangles >= VMI::mesh->currentNumTriangles))
346        {
347                printf("Illegal number of triangles.\n");
348        }
349
350        VMI::display();
351
352        //      Cleans firts simplification.
353        VMI::freeMemory();
354
355        VMI::mesh =     initMeshStructure(mInitialMesh);
356
357        VMI::contractInitialMesh(VMI::mesh);
358
359        //      Load a geometry mesh for vmi mesh.
360        loadMesh();
361       
362        GetMeshSimpSequence();
363
364        //      Sort bones.
365        bonesReassignament();
366}
367
368//-------------------------------------------------------------------------
369//      Gets the VMI mesh simplification sequence.
370//-------------------------------------------------------------------------
371void    ViewPointDrivenSimplifier::GetMeshSimpSequence()
372{
373        size_t  j = 0;
374       
375        MeshSimplificationSequence::Step        current_step;
376       
377        msimpsequence   =       new MeshSimplificationSequence();
378
379        //      Copy the mesh simplification sequence.
380        msimpsequence->mSteps                           =       VMI::mSequence->mSteps;
381        msimpsequence->mNewVertices     =       VMI::mSequence->mNewVertices;
382
383        cout    <<      "Steps of simplification: "
384                                <<      msimpsequence->mSteps.size()
385                                <<      " Number of new vertices: "
386                                <<      msimpsequence->mNewVertices.size()
387                                <<      endl;
388}
389
390//-------------------------------------------------------------------------
391//      Initialize the mesh of VMI module.
392//-------------------------------------------------------------------------
393VMI::Mesh *     ViewPointDrivenSimplifier::initMeshStructure(Mesh       *geoMesh)
394{
395        GLuint                          i, j, v1, v2, v3, n, e, t;
396        VMI::Mesh               *vmi_mesh;
397        SubMesh                         *geosubmesh;
398        VertexBuffer    *vertex_buffer;
399        int                                             mesh_index_count;
400        int                                             index;
401
402        //      Reallocate memory for vmi mesh object.
403        vmi_mesh = (VMI::Mesh *)malloc(sizeof(VMI::Mesh));
404
405        if (vmi_mesh == NULL)
406        {
407                fprintf(stderr, "Error allocating memory\n");
408                exit(1);
409        }
410
411        //      Shared vertex buffer.
412        vertex_buffer   =       geoMesh->mVertexBuffer;
413       
414        //      Reallocate memory for vertices of mesh.
415        vmi_mesh->vertices = (VMI::Vertex *)malloc(sizeof(VMI::Vertex)
416                                                                                                                                                                *
417                                                                                                                                                                vertex_buffer->mVertexCount);
418
419        if (vmi_mesh->vertices == NULL)
420        {
421                fprintf(stderr, "Error allocating memory\n");
422                exit(1);
423        }
424
425        //      Initialize mesh index count.
426        mesh_index_count        =       0;
427       
428        for (   unsigned int submesh    =       0;
429                                submesh < geoMesh->mSubMeshCount;
430                                submesh++)
431        {
432                mesh_index_count        +=      int(geoMesh->mSubMesh[submesh].mIndexCount);
433        }
434       
435        //      Reallocate memory for indices.
436        vmi_mesh->triangles = (VMI::Triangle *)malloc(sizeof(VMI::Triangle)
437                                                                                                                                                                                *
438                                                                                                                                                                                (mesh_index_count / 3));
439
440        if (vmi_mesh->triangles == NULL)
441        {
442                fprintf(stderr, "Error allocating memory\n");
443                exit(1);
444        }
445
446        printf("Adding vertices...");
447
448        //      Fill up vertices.
449        for (i = 0; i < vertex_buffer->mVertexCount; i++)
450        {
451                // Vertices start at 0.
452                vmi_mesh->vertices[i].x = vertex_buffer->mPosition[i].x;
453                vmi_mesh->vertices[i].y = vertex_buffer->mPosition[i].y;
454                vmi_mesh->vertices[i].z = vertex_buffer->mPosition[i].z;
455               
456                vmi_mesh->vertices[i].numTriangles = 0;
457                vmi_mesh->vertices[i].triangles = NULL;
458                vmi_mesh->vertices[i].enable    = GL_TRUE;
459                vmi_mesh->vertices[i].movable = GL_TRUE;
460        }
461       
462        printf("Ok\n");
463        vmi_mesh->numVertices = int(vertex_buffer->mVertexCount);
464        vmi_mesh->currentNumVertices = int(vertex_buffer->mVertexCount);
465
466        printf("Vertices: %d\n",vmi_mesh->numVertices);
467
468        //      Fill up triangles.
469        printf("Adding triangles...");
470       
471        //      Initialize index of triangle.
472        index   =       0;
473       
474        //      For each submesh.
475        for (   unsigned int submesh    =       0;
476                                submesh <       geoMesh->mSubMeshCount;
477                                submesh++)
478        {
479                //      Gets actual submesh.
480                geosubmesh      =       &geoMesh->mSubMesh[submesh];
481               
482                //      For each three vertices.
483                for (i = 0; i < (geosubmesh->mIndexCount / 3); i++)
484                {
485                        vmi_mesh->triangles[index].id                           = index;
486                        vmi_mesh->triangles[index].submesh              = submesh;
487                        vmi_mesh->triangles[index].indices[0] = geosubmesh->mIndex[(3 * i)];
488                        vmi_mesh->triangles[index].indices[1] = geosubmesh->mIndex[(3 * i) + 1];
489                        vmi_mesh->triangles[index].indices[2] = geosubmesh->mIndex[(3 * i) + 2];
490
491                        vmi_mesh->triangles[index].area = computeTriangleArea(vmi_mesh->vertices,
492                                        &vmi_mesh->triangles[index]);
493                        computeTriangleNormal(vmi_mesh->vertices, &vmi_mesh->triangles[index]);
494
495                        vmi_mesh->triangles[index].saliency = 0.0;
496
497                        vmi_mesh->triangles[index].enable = GL_TRUE;
498
499                        for (j = 0; j < 3; j++)
500                        {
501                                // Adding triangle index adjacent to 3 vertices.
502                                v1 = vmi_mesh->triangles[index].indices[j];
503
504                                // Reallocate memory for the new adjacent triangle.
505                                vmi_mesh->vertices[v1].triangles = (GLuint *)realloc(vmi_mesh->vertices[v1].triangles, (vmi_mesh->vertices[v1].numTriangles + 1) * sizeof(GLuint));
506
507                                VMI::addItem(   (int *)vmi_mesh->vertices[v1].triangles,
508                                                                                        (int *)&vmi_mesh->vertices[v1].numTriangles,
509                                                                                        index);
510                        }
511
512                        //      Increments triangle count.
513                        index++;
514                }
515        }
516       
517        printf("Ok\n");
518
519        vmi_mesh->numTriangles                          = mesh_index_count / 3;
520        vmi_mesh->currentNumTriangles = mesh_index_count / 3;
521
522        printf("Num Triangles: %d\n",vmi_mesh->numTriangles);
523       
524        // E = 3 T / 2
525        vmi_mesh->edges = (VMI::Edge *)malloc(sizeof(VMI::Edge)
526                                                                                                                                                *
527                                                                                                                                                vmi_mesh->numTriangles * 3);
528
529        if (vmi_mesh->edges == NULL)
530        {
531                fprintf(stderr, "Error allocating memory\n");
532                exit(1);
533        }
534
535        printf("Adding edges...");
536        n = 0;
537
538        //      For each triangle adds three edges.
539        for (i  =       0; i < vmi_mesh->numTriangles; i++)
540        {
541                t               =       0;
542                v1      =       vmi_mesh->triangles[i].indices[0];
543                v2      =       vmi_mesh->triangles[i].indices[1];
544                v3      =       vmi_mesh->triangles[i].indices[2];
545
546                if ((e = findEdge(vmi_mesh->edges, n, v1, v2)) == -1)
547                {
548                        vmi_mesh->edges[n].u                                            =       v1;
549                        vmi_mesh->edges[n].v                                            =       v2;
550                        vmi_mesh->edges[n].triangles    = NULL;
551                        vmi_mesh->edges[n].numTriangles = 0;
552                        vmi_mesh->edges[n].enable                       =       GL_TRUE;
553
554                        // Reallocate memory for the new adjacent triangle
555                        vmi_mesh->edges[n].triangles = (GLuint *)realloc(vmi_mesh->edges[n].triangles, (vmi_mesh->edges[n].numTriangles + 1) * sizeof(GLuint));
556
557                        // Adding triangle i adjacent to edge n
558                        VMI::addItem(   (int *)vmi_mesh->edges[n].triangles,
559                                                                                (int *)&vmi_mesh->edges[n].numTriangles,
560                                                                                i);
561
562                        // Adding edge n adjacent to triangle i
563                        VMI::addItem((int *)vmi_mesh->triangles[i].edges, (int *)&t, n);
564                        n++;
565                }
566                else
567                {
568                        // Reallocate memory for the new adjacent triangle.
569                        vmi_mesh->edges[e].triangles = (GLuint *)realloc(vmi_mesh->edges[e].triangles, (vmi_mesh->edges[e].numTriangles + 1) * sizeof(GLuint));
570
571                        // Adding triangle i adjacent to edge e
572                        VMI::addItem(   (int *)vmi_mesh->edges[e].triangles,
573                                                                                (int *)&vmi_mesh->edges[e].numTriangles,
574                                                                                i);
575
576                        // Adding edge e adjacent to triangle i
577                        VMI::addItem((int *)vmi_mesh->triangles[i].edges, (int *)&t, e);
578                }
579
580                if ((e = findEdge(vmi_mesh->edges, n, v2, v3)) == -1)
581                {
582                        vmi_mesh->edges[n].u                                            = v2;
583                        vmi_mesh->edges[n].v                                            = v3;
584                        vmi_mesh->edges[n].triangles    = NULL;
585                        vmi_mesh->edges[n].numTriangles = 0;
586                        vmi_mesh->edges[n].enable                       = GL_TRUE;
587
588                        // Reallocate memory for the new adjacent triangle
589                        vmi_mesh->edges[n].triangles = (GLuint *)realloc(vmi_mesh->edges[n].triangles, (vmi_mesh->edges[n].numTriangles + 1) * sizeof(GLuint));
590
591                        // Adding triangle i adjacent to edge n
592                        VMI::addItem((int *)vmi_mesh->edges[n].triangles, (int *)&vmi_mesh->edges[n].numTriangles, i);
593                        vmi_mesh->edges[n].triangles    = NULL;
594                        vmi_mesh->edges[n].numTriangles = 0;
595
596                        // Adding edge n adjacent to triangle i
597                        VMI::addItem((int *)vmi_mesh->triangles[i].edges, (int *)&t, n);
598                        n++;
599                }
600                else
601                {
602                        // Reallocate memory for the new adjacent triangle
603                        vmi_mesh->edges[e].triangles = (GLuint *)realloc(vmi_mesh->edges[e].triangles, (vmi_mesh->edges[e].numTriangles + 1) * sizeof(GLuint));
604
605                        // Adding triangle i adjacent to edge e
606                        VMI::addItem(   (int *)vmi_mesh->edges[e].triangles,
607                                                                                (int *)&vmi_mesh->edges[e].numTriangles,
608                                                                                i);
609
610                        // Adding edge e adjacent to triangle i
611                        VMI::addItem((int *)vmi_mesh->triangles[i].edges, (int *)&t, e);
612                }
613               
614                if ((e = findEdge(vmi_mesh->edges, n, v3, v1)) == -1)
615                {
616                        vmi_mesh->edges[n].u                                            = v3;
617                        vmi_mesh->edges[n].v                                            = v1;
618                        vmi_mesh->edges[n].triangles    = NULL;
619                        vmi_mesh->edges[n].numTriangles = 0;
620                        vmi_mesh->edges[n].enable                       = GL_TRUE;
621
622                        // Reallocate memory for the new adjacent triangle.
623                        vmi_mesh->edges[n].triangles = (GLuint *)realloc(vmi_mesh->edges[n].triangles, (vmi_mesh->edges[n].numTriangles + 1) * sizeof(GLuint));
624
625                        // Adding triangle i adjacent to edge n
626                        VMI::addItem(   (int *)vmi_mesh->edges[n].triangles,
627                                                                                (int *)&vmi_mesh->edges[n].numTriangles,
628                                                                                i);
629
630                        // Adding edge n adjacent to triangle i
631                        VMI::addItem((int *)vmi_mesh->triangles[i].edges, (int *)&t, n);
632                        n++;
633                }
634                else
635                {
636                        // Reallocate memory for the new adjacent triangle
637                        vmi_mesh->edges[e].triangles = (GLuint *)realloc(vmi_mesh->edges[e].triangles, (vmi_mesh->edges[e].numTriangles + 1) * sizeof(GLuint));
638
639                        // Adding triangle i adjacent to edge e
640                        VMI::addItem((int *)vmi_mesh->edges[e].triangles, (int *)&vmi_mesh->edges[e].numTriangles, i);
641
642                        // Adding edge e adjacent to triangle i
643                        VMI::addItem((int *)vmi_mesh->triangles[i].edges, (int *)&t, e);
644                }
645        }
646       
647        printf("Ok\n");
648        vmi_mesh->numEdges = n;
649
650        //      Creates vertex multimap.
651        initVertexMultimap(vmi_mesh,mTexConserver->mVertices);
652
653        return vmi_mesh;
654}
655
656//-------------------------------------------------------------------------
657//      Gets the geometry mesh of a  the vmi mesh given.
658//-------------------------------------------------------------------------
659void    ViewPointDrivenSimplifier::loadMesh()
660{
661        int                                             num_indices;
662        SubMesh                         *geosubmesh;
663        VertexBuffer    *vertex_buffer;
664       
665        //      Gets old vertex buffer.
666        vertex_buffer   =       mGeoMesh->mVertexBuffer;
667       
668        //      Initialize auxiliar vertex buffer.
669        mVB     =       new     VertexBuffer();
670       
671        mVB->mPosition          =       new     Vector3[VMI::mesh->currentNumVertices];
672        mVB->mNormal                    =       new     Vector3[VMI::mesh->currentNumVertices];
673        mVB->mTexCoords         =       new     Vector2[VMI::mesh->currentNumVertices];
674
675        mVB->mVertexInfo        =       vertex_buffer->mVertexInfo;
676
677        //      For each submesh.
678        for (size_t     submesh =       0; submesh < mGeoMesh->mSubMeshCount; submesh++)
679        {
680                geosubmesh      =       &mGeoMesh->mSubMesh[submesh];
681
682                delete  []geosubmesh->mIndex;
683
684                //      Initialize submesh index count;
685                num_indices     =       0;
686
687                //      For each triangle.
688                for (size_t     i = 0; i < VMI::mesh->numTriangles; i++)
689                {
690                        //      If is enable and of the current submesh.
691                        if ((VMI::mesh->triangles[i].enable)
692                                        &&
693                                        (VMI::mesh->triangles[i].submesh == submesh))
694                        {
695                                //      Increments submesh index count.
696                                num_indices     +=      3;
697                        }
698                }
699
700                geosubmesh->mIndexCount =       num_indices;
701
702                geosubmesh->mIndex      =       new Geometry::Index[geosubmesh->mIndexCount];
703
704                //      Initialize number of indices.
705                num_indices     =       0;
706
707                //      Fill up indices.
708                for (size_t     i = 0; i < VMI::mesh->numTriangles; i++)
709                {
710                        if ((VMI::mesh->triangles[i].enable)
711                                        &&
712                                        (VMI::mesh->triangles[i].submesh == submesh))
713                        {
714                                geosubmesh->mIndex[num_indices++]       =
715                                                                                                                                        VMI::mesh->triangles[i].indices[0];
716
717                                geosubmesh->mIndex[num_indices++]       =
718                                                                                                                                        VMI::mesh->triangles[i].indices[1];
719
720                                geosubmesh->mIndex[num_indices++]       =
721                                                                                                                                        VMI::mesh->triangles[i].indices[2];
722                        }
723                }
724       
725                //      For each index.
726                for (size_t     i = 0; i < geosubmesh->mIndexCount; i++)
727                {
728                        findVertex(submesh,i);
729                }
730
731                geosubmesh->mVertexBuffer       =       mVB;
732        }
733
734        delete  vertex_buffer;
735       
736        mGeoMesh->mVertexBuffer =       mVB;
737}
738
739//-------------------------------------------------------------------------
740//      Find vertex in auxiliar vertex buffer.
741//-------------------------------------------------------------------------
742void    ViewPointDrivenSimplifier::findVertex(size_t    submesh, size_t elem)
743{
744        bool                                                                            found;
745        int                                                                                     index;
746        unsigned int                                            i;
747        int                                                                                     new_elem;
748        VertexBuffer                                            *vertex_buffer;
749        map<int,int>::iterator  it;
750
751        found   =       false;
752
753        //      Shared vertex buffer.
754        vertex_buffer   =       mInitialMesh->mVertexBuffer;
755
756        index   =       mGeoMesh->mSubMesh[submesh].mIndex[elem];
757
758        i       =       0;
759
760        if ((it =       mIndexMap.find(index)) != mIndexMap.end())
761        {
762                mGeoMesh->mSubMesh[submesh].mIndex[elem]        =       (*it).second;
763        }
764        else
765        {
766                mIndexMap[index]        =       int(mVB->mVertexCount);
767
768                //      Last element.
769                new_elem        =       int(mVB->mVertexCount);
770
771                mVB->mPosition[new_elem]        =       VMI::vPositions[index];
772                mVB->mNormal[new_elem]          =       VMI::vNormals[index];
773                mVB->mTexCoords[new_elem]       =       VMI::vTexCoords[index];
774
775                //      Update index.
776                mGeoMesh->mSubMesh[submesh].mIndex[elem]        =        new_elem;
777
778                //      Increments vertex count.
779                mVB->mVertexCount++;
780        }
781}
782
783//-------------------------------------------------------------------------
784//      Reassigns bones.
785//-------------------------------------------------------------------------
786void ViewPointDrivenSimplifier::bonesReassignament()
787{
788        size_t                                                                  vertex_id;
789        size_t                                                                  bones_count;
790        bool                                                                            vertex_found;
791        map<int,int>::iterator  im;
792        VertexBoneAssignment            bone;
793
794        vector<VertexBoneAssignment>::iterator  ib;
795
796        //      Copy new vertices.
797        for (unsigned   int     i       =       0;      i < msimpsequence->mNewVertices.size(); i++)
798        {
799                vertex_id       =       msimpsequence->mNewVertices[i].id;
800
801                //      Initialize number of bones.
802                bones_count     =       mInitialMesh->mBones.size();
803
804                // check if my twin-vertex-bone has a bone assignment
805                // we check only the GeoMesh bones because the lodstrips
806                // only works for sharedvertex bones.
807                for (int  j = 0; j < bones_count; j++)
808                {
809                        ib      =       mInitialMesh->mBones.begin() + j;
810
811                        if (ib->vertexIndex == msimpsequence->mNewVertices[i].bonefrom)
812                        {
813                                bone.vertexIndex        = vertex_id;
814                                bone.boneIndex          = ib->boneIndex;
815                                bone.weight                             = ib->weight;
816
817                                mInitialMesh->mBones.push_back(bone);
818                                bones_count++;
819                        }
820                }
821        }
822
823        //      Clears bones.
824        mGeoMesh->mBones.clear();
825
826        //      For each bone assignment.
827        for (unsigned int i = 0; i < mInitialMesh->mBones.size(); i++)
828        {
829                bone.vertexIndex        =       mInitialMesh->mBones[i].vertexIndex;
830                bone.boneIndex          =       mInitialMesh->mBones[i].boneIndex;
831                bone.weight                             =       mInitialMesh->mBones[i].weight;
832
833                vertex_found    =       false;
834
835                //      If the vertex is found in the simplification model.
836                if ((im = mIndexMap.find(bone.vertexIndex))
837                                !=
838                                mIndexMap.end())
839                {
840                        bone.vertexIndex        =       (*im).second;
841
842                        mGeoMesh->mBones.push_back(bone);
843                        vertex_found    =       true;
844                }
845        }
846}
847
848//-------------------------------------------------------------------------
849//      Fill up position, normal and texture coordinates.
850//-------------------------------------------------------------------------
851void    ViewPointDrivenSimplifier::fillUpPosNorTC(Mesh  *geoMesh)
852{
853        VertexBuffer    *vertex_buffer;
854        Vector3                         v3;
855        Vector2                         v2;
856
857        vertex_buffer   =       geoMesh->mVertexBuffer;
858
859        for (size_t     i = 0; i < vertex_buffer->mVertexCount; i++)
860        {
861                v3      =       vertex_buffer->mPosition[i];
862
863                vPositions.push_back(v3);
864
865                v3      =       vertex_buffer->mNormal[i];
866
867                vNormals.push_back(v3);
868
869                v2      =       vertex_buffer->mTexCoords[i];
870
871                vTexCoords.push_back(v2);
872        }
873}
874
875//-------------------------------------------------------------------------
876//      EdgesMultimap class
877//-------------------------------------------------------------------------
878
879//-------------------------------------------------------------------------
880//      Constructor.
881//-------------------------------------------------------------------------
882EdgesMultimap::EdgesMultimap()
883{
884}
885
886//-------------------------------------------------------------------------
887//      Destructor.
888//-------------------------------------------------------------------------
889EdgesMultimap::~EdgesMultimap()
890{
891        edges.clear();
892}
893
894//-------------------------------------------------------------------------
895//      Insert and edge.
896//-------------------------------------------------------------------------
897void    EdgesMultimap::insert(int v1,int v2)
898{
899        edges.insert(pair<int,int>(v1,v2));
900        edges.insert(pair<int,int>(v2,v1));
901}
902
903//-------------------------------------------------------------------------
904//      Remove edges with v1 and v2.
905//-------------------------------------------------------------------------
906void    EdgesMultimap::remove(int v1,int v2)
907{
908        multimap<int,int>::iterator     lb;
909        multimap<int,int>::iterator     ub;
910
911        if (edges.find(v1) != edges.end())
912        {
913                lb      =       edges.lower_bound(v1);
914                ub      =       edges.upper_bound(v1);
915
916                while (lb != ub)
917                {
918                        if ((*lb).second == v2)
919                        {
920                                //      Remove edge.
921                                edges.erase(lb);
922
923                                lb      =       ub;
924                        }
925                        else
926                        {
927                                lb++;
928                        }
929                }
930        }
931
932        if (edges.find(v2) != edges.end())
933        {
934                lb      =       edges.lower_bound(v2);
935                ub      =       edges.upper_bound(v2);
936
937                while (lb != ub)
938                {
939                        if ((*lb).second == v1)
940                        {
941                                //      Remove edge.
942                                edges.erase(lb);
943
944                                lb      =       ub;
945                        }
946                        else
947                        {
948                                lb++;
949                        }
950                }
951        }
952
953}
954
955//-------------------------------------------------------------------------
956//      Checks if the edge (v1,v2) exists.
957//-------------------------------------------------------------------------
958bool    EdgesMultimap::exists(int v1,int v2)
959{
960        bool                                                                                            found;
961        multimap<int,int>::iterator     lb;
962        multimap<int,int>::iterator     ub;
963
964        found   =       false;
965
966        //      Find range.
967        lb      =       edges.lower_bound(v1);
968        ub      =       edges.upper_bound(v1);
969
970        //      Search for all v1 edges.
971        while (lb != ub)
972        {
973                //      If edge is found.
974                if ((*lb).second = v2)
975                {
976                        found   =       true;
977                        lb              =       ub;
978                }
979                else
980                {
981                        //      Next iteration.
982                        lb++;
983                }
984        }
985
986        return  found;
987}
988
989//-------------------------------------------------------------------------
990//      Change vertex v1 to v2 in the map.
991//-------------------------------------------------------------------------
992void    EdgesMultimap::contract(int v1,int v2)
993{
994        multimap<int,int>::iterator     it;
995        int     v_aux;
996
997        //      Remove contracted edge.
998        remove(v1,v2);
999
1000        //      Modify all edges where appears v1 to v2.
1001        while ((it =    edges.find(v1)) != edges.end())
1002        {
1003                v_aux   =       (*it).second;
1004
1005                //      Remove current edge.
1006                remove(v1,v_aux);
1007
1008                //      Modify edge.
1009                insert(v2,v_aux);
1010        }
1011}
1012
1013//-------------------------------------------------------------------------
1014//      TextureConserver class
1015//-------------------------------------------------------------------------
1016TextureConserver::TextureConserver()
1017{
1018        mEdges          =       new     EdgesMultimap();
1019        mGeoMesh        =       new Mesh();
1020}
1021
1022TextureConserver::~TextureConserver()
1023{
1024        delete  mGeoMesh;
1025        delete  mEdges;
1026}
1027
1028//-------------------------------------------------------------------------
1029//      Join twin vertices into a unique vertex.
1030//-------------------------------------------------------------------------
1031void    TextureConserver::JoinVertices(Mesh *mesh)
1032{
1033        map<_coord_, int>                                                       uniquevertices;
1034        map<int, int>                                                                   newindices;
1035        multimap<int, int>::iterator    it;
1036        map<int, int>::iterator                         it_map;
1037        VertexBuffer                                                                    *vertex_buffer;
1038        VertexBuffer                                                                    *mGMVB;
1039        unsigned        int                                                                     vertex_count;
1040        unsigned        int                                                                     i;
1041        unsigned        int                                                                     aux_i;
1042        unsigned        int                                                                     submesh;
1043        SubMesh                                                                                         *geosubmesh;
1044        _coord_                                                                                         vertex_aux;
1045
1046        //      Copy actual mesh.
1047        *mGeoMesh               =       *mesh;
1048
1049        //      Gets the shared vertex buffer.
1050        vertex_buffer   =       mGeoMesh->mVertexBuffer;
1051
1052        //      Initialize unique vertices count.
1053        vertex_count    =       0;
1054
1055        //      Fill up vertices.
1056        for (i  =       0; i < vertex_buffer->mVertexCount; i++)
1057        {
1058                vertex_aux.x    = vertex_buffer->mPosition[i].x;
1059                vertex_aux.y    = vertex_buffer->mPosition[i].y;
1060                vertex_aux.z    = vertex_buffer->mPosition[i].z;
1061
1062                //      New index.
1063                if (uniquevertices.find(vertex_aux) == uniquevertices.end())
1064                {
1065                        uniquevertices[vertex_aux]      = vertex_count;
1066                        newindices[i]                                                           = vertex_count;
1067
1068                        mVertices.insert(pair<int,int>(vertex_count,i));
1069                       
1070                        //      Increments unique vertices count.
1071                        vertex_count++;
1072                }
1073                //      The map of unique vertices already contains this vertex.
1074                else
1075                {
1076                        int newindex    =       uniquevertices[vertex_aux];
1077                        newindices[i]   =       newindex;
1078
1079                        mVertices.insert(pair<int,int>(newindex,i));
1080                }
1081        }
1082
1083        //      Delete vertices.
1084        delete  mesh->mVertexBuffer;
1085
1086        mesh->mVertexBuffer     =       new VertexBuffer();
1087
1088        mesh->mVertexBuffer->mPosition          = new Vector3[vertex_count];
1089        mesh->mVertexBuffer->mNormal                    = new Vector3[vertex_count];
1090        mesh->mVertexBuffer->mTexCoords         = new Vector2[vertex_count];
1091
1092        mesh->mVertexBuffer->mVertexInfo        = vertex_buffer->mVertexInfo;
1093        mesh->mVertexBuffer->mVertexCount       = vertex_count;
1094
1095        mGMVB   =       mesh->mVertexBuffer;
1096
1097        //      Fill up unique vertices.
1098        for (i  =        0; i < vertex_count; i++)
1099        {
1100                //      Find first ocurrence of unique vertex.
1101                it      =       mVertices.find(i);
1102
1103                aux_i   =       (*it).second;
1104
1105                mGMVB->mPosition[i].x   =       vertex_buffer->mPosition[aux_i].x;
1106                mGMVB->mPosition[i].y   =       vertex_buffer->mPosition[aux_i].y;
1107                mGMVB->mPosition[i].z   =       vertex_buffer->mPosition[aux_i].z;
1108
1109                mGMVB->mNormal[i].x     =       vertex_buffer->mNormal[aux_i].x;
1110                mGMVB->mNormal[i].y     =       vertex_buffer->mNormal[aux_i].y;
1111                mGMVB->mNormal[i].z     =       vertex_buffer->mNormal[aux_i].z;
1112
1113                mGMVB->mTexCoords[i].x  =       vertex_buffer->mTexCoords[aux_i].x;
1114                mGMVB->mTexCoords[i].y  =       vertex_buffer->mTexCoords[aux_i].y;
1115        }
1116
1117        //      Fill up indices to unique vertices.
1118        //      For each submesh.
1119        for (submesh    =       0; submesh < mesh->mSubMeshCount; submesh++)
1120        {
1121                geosubmesh      =       &mesh->mSubMesh[submesh];
1122
1123                //      Change indices.
1124                for (i  =       0; i < geosubmesh->mIndexCount; i++)
1125                {
1126                        //      Unique index asociated to the given one.
1127                        it_map  =       newindices.find(geosubmesh->mIndex[i]);
1128
1129                        geosubmesh->mIndex[i]   =       (*it_map).second;
1130                }
1131        }
1132}
1133
1134//-------------------------------------------------------------------------
1135//      Modify the joined vertices sequento to an split.
1136//-------------------------------------------------------------------------
1137MeshSimplificationSequence *
1138TextureConserver::WriteRealSimpSeq(MeshSimplificationSequence *simpseq)
1139{
1140        bool    edge_found;
1141
1142        size_t  v0;
1143        size_t  v1;
1144        size_t  vertex_count;
1145        size_t  i,j;
1146
1147        VertexBuffer    *mVB;
1148        GeoVertex                       new_vertex;
1149
1150        multimap<int, int>::iterator    lb0;
1151        multimap<int, int>::iterator    ub0;
1152        multimap<int, int>::iterator    lb1;
1153        multimap<int, int>::iterator    ub1;
1154        multimap<int, int>::iterator    it0;
1155
1156        MeshSimplificationSequence                              *real_seq;
1157        MeshSimplificationSequence::Step        current_step;
1158
1159        //      Initialize vertex count.
1160        vertex_count    =       mGeoMesh->mVertexBuffer->mVertexCount;
1161
1162        //      Creates new simplification sequence.
1163        real_seq        =       new     MeshSimplificationSequence();
1164
1165        //      For each simplification step.
1166        for (i = 0; i < simpseq->mSteps.size(); i++)
1167        {
1168                lb0     =       mVertices.lower_bound(simpseq->mSteps[i].mV0);
1169                ub0     =       mVertices.upper_bound(simpseq->mSteps[i].mV0);
1170                lb1     =       mVertices.lower_bound(simpseq->mSteps[i].mV1);
1171                ub1     =       mVertices.upper_bound(simpseq->mSteps[i].mV1);
1172
1173                //      Removed vertex.
1174                while (lb1 != ub1)
1175                {
1176                        //      Real index.
1177                        v1      =       (*lb1).second;
1178
1179                        //      Begin of iteration v0.
1180                        it0     =       lb0;
1181
1182                        edge_found      =       false;
1183
1184                        //      Remaining vertex.
1185                        while (it0 != ub0)
1186                        {
1187                                //      Real index.
1188                                v0      =       (*it0).second;
1189
1190                                //      If edge exists.
1191                                if (mEdges->exists(v0,v1))
1192                                {
1193                                        mEdges->contract(v1,v0);
1194
1195                                        //      Simplification sequence.
1196                                        current_step.mV0        =       v0;
1197                                        current_step.mV1        =       v1;
1198
1199                                        real_seq->mSteps.push_back(current_step);
1200
1201                                        edge_found      =       true;
1202                                }
1203
1204                                it0++;
1205                        }
1206
1207                        //      If not found a valid edge.
1208                        if (!edge_found)
1209                        {
1210                                //      Id new vertex.
1211                                new_vertex.id                                   =       vertex_count;
1212                                new_vertex.bonefrom             =       v0;
1213
1214                                //      Simplification sequence.
1215                                current_step.mV0        =       new_vertex.id;
1216                                current_step.mV1        =       v1;
1217
1218                                real_seq->mSteps.push_back(current_step);
1219
1220                                //      Contracts lonely vertex.
1221                                mEdges->contract(v1,new_vertex.id);
1222
1223                                //      New vertex adquires position of v0.
1224                                new_vertex.position.x   =       mGeoMesh->mVertexBuffer->mPosition[v0].x;
1225                                new_vertex.position.y   =       mGeoMesh->mVertexBuffer->mPosition[v0].y;
1226                                new_vertex.position.z   =       mGeoMesh->mVertexBuffer->mPosition[v0].z;
1227
1228                                //      New vertex adquires normal of lonely one.
1229                                new_vertex.normal.x     =       mGeoMesh->mVertexBuffer->mNormal[v1].x;
1230                                new_vertex.normal.y     =       mGeoMesh->mVertexBuffer->mNormal[v1].y;
1231                                new_vertex.normal.z     =       mGeoMesh->mVertexBuffer->mNormal[v1].z;
1232
1233                                //      New vertex adquires the texture cood of the lonely one.
1234                                new_vertex.texcoord.x   =       mGeoMesh->mVertexBuffer->mTexCoords[v1].x;
1235                                new_vertex.texcoord.y   =       mGeoMesh->mVertexBuffer->mTexCoords[v1].y;
1236
1237                                //      New vertex stored.
1238                                real_seq->mNewVertices.push_back(new_vertex);
1239
1240                                //      New vertex added.
1241                                vertex_count++;
1242                        }
1243
1244                        lb1++;
1245                }
1246        }
1247
1248        //      Assigns new simplification sequence.
1249        delete  simpseq;
1250
1251        return  real_seq;
1252        /*
1253        //      New vertex buffer to add new vertices.
1254        mVB     =       new VertexBuffer();
1255
1256        mVB->mPosition  =       new Vector3[vertex_count];
1257        mVB->mNormal            =       new Vector3[vertex_count];
1258        mVB->mTexCoords =       new Vector2[vertex_count];
1259
1260        mVB->mVertexInfo        =       mGeoMesh->mVertexBuffer->mVertexInfo;
1261
1262        //      Copy original vertices.
1263        for (i = 0; i < mGeoMesh->mVertexBuffer->mVertexCount; i++)
1264        {
1265                mVB->mPosition[i].x     =       mGeoMesh->mVertexBuffer->mPosition[i].x;
1266                mVB->mPosition[i].y     =       mGeoMesh->mVertexBuffer->mPosition[i].y;
1267                mVB->mPosition[i].z     =       mGeoMesh->mVertexBuffer->mPosition[i].z;
1268
1269                mVB->mNormal[i].x       =       mGeoMesh->mVertexBuffer->mNormal[i].x;
1270                mVB->mNormal[i].y       =       mGeoMesh->mVertexBuffer->mNormal[i].y;
1271                mVB->mNormal[i].z       =       mGeoMesh->mVertexBuffer->mNormal[i].z;
1272
1273                mVB->mTexCoords[i].x    =       mGeoMesh->mVertexBuffer->mTexCoords[i].x;
1274                mVB->mTexCoords[i].y    =       mGeoMesh->mVertexBuffer->mTexCoords[i].y;
1275        }
1276
1277        //      Add new vertices.
1278        j       =       mGeoMesh->mVertexBuffer->mVertexCount;
1279
1280        for (i = 0; i < new_vertices.size(); i++)
1281        {
1282                mVB->mPosition[j].x     =       new_vertices[i].position.x;
1283                mVB->mPosition[j].y     =       new_vertices[i].position.y;
1284                mVB->mPosition[j].z     =       new_vertices[i].position.z;
1285
1286                mVB->mNormal[j].x       =       new_vertices[i].normal.x;
1287                mVB->mNormal[j].y       =       new_vertices[i].normal.y;
1288                mVB->mNormal[j].z       =       new_vertices[i].normal.z;
1289
1290                mVB->mTexCoords[j].x    =       new_vertices[i].texcoord.x;
1291                mVB->mTexCoords[j].y    =       new_vertices[i].texcoord.y;
1292        }
1293
1294        //      Free memory.
1295        delete  []mGeoMesh->mVertexBuffer;
1296
1297        //      Reassigns main vertex buffer with new vertices.
1298        mGeoMesh->mVertexBuffer = mVB;
1299
1300        //      Reassign submesh vertex buffers.
1301        for (i = 0; i < mGeoMesh->mSubMeshCount; i++)
1302        {
1303                mGeoMesh->mSubMesh[i].mVertexBuffer     =       mVB;
1304        }
1305        */
1306}
1307
1308//-------------------------------------------------------------------------
1309//      Return  mesh that may have repeated vertices for texture aparence.
1310//-------------------------------------------------------------------------
1311Mesh    *TextureConserver::GetMesh()
1312{
1313        return  mGeoMesh;
1314}
1315
Note: See TracBrowser for help on using the repository browser.