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

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