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

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