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

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