source: GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/SimplificationMethod.cpp @ 2291

Revision 2291, 45.3 KB checked in by gumbau, 17 years ago (diff)
RevLine 
[983]1#include <stdlib.h>
2#include "SimplificationMethod.h"
3#include <iostream>
4#include <fstream>
[2088]5#include <gfx/geom/ProxGrid.h>
6#include "quadrics.h"
[983]7
8using namespace std;
9using namespace Geometry;
[1526]10using   namespace       simplif;
[983]11
[2088]12//-------------------------------------------------------------------------
[983]13//      Constructor
[2088]14//-------------------------------------------------------------------------
[1526]15SimplificationMethod::SimplificationMethod(const Mesh *m)
[983]16{
[2088]17        mInitialMesh                            =       new Mesh();
18        *mInitialMesh                           =       *m;
[983]19        mGeoMesh                                                =       NULL;
[2088]20        first_index_submesh     =       new unsigned int[mInitialMesh->mSubMeshCount];
[983]21        indexMeshLeaves                 =       -1;
[1526]22
23        //      Create simplification sequence.
24        msimpseq        =       new MeshSimplificationSequence();
[983]25}
26
[2088]27//-------------------------------------------------------------------------
[983]28//      Destructor
[2088]29//-------------------------------------------------------------------------
[983]30SimplificationMethod::~SimplificationMethod()
31{
[2088]32        delete  heap;
33        delete  [] first_index_submesh;
34
35        delete  mInitialMesh;
[983]36}
37
[2088]38//-------------------------------------------------------------------------
[983]39//      Recalculate the cost of the vertices of an edge
[2088]40//-------------------------------------------------------------------------
[1025]41void SimplificationMethod::compute_pair_info(simplif::pair_info *auxpair)
[983]42{
[1025]43        simplif::Vertex *v0 = auxpair->v0;
44        simplif::Vertex *v1 = auxpair->v1;
[983]45
[2291]46        simplif::vert_info      *v0_info = vertex_info(v0);
47        simplif::vert_info      *v1_info = vertex_info(v1);
[983]48
[2291]49        simplif::Mat4 Q                 =       v0_info->Q + v1_info->Q;
50        simplif::real norm      =       v0_info->norm + v1_info->norm;
[983]51
[2088]52        auxpair->cost = simplif::quadrix_pair_target(   Q,
53                                                                                                                                                                                                v0,
54                                                                                                                                                                                                v1,
55                                                                                                                                                                                                auxpair->candidate);
[983]56
[1526]57        if ( simplif::will_weight_by_area )
58        {
[983]59                auxpair->cost /= norm;
[1526]60        }
[983]61
[1526]62        if ( simplif::will_preserve_mesh_quality )
63        {
[983]64                auxpair->cost += pair_mesh_penalty(M0, v0, v1, auxpair->candidate);
[1526]65        }
[983]66
67        //
68        // NOTICE:  In the heap we use the negative cost.  That's because
69        //          the heap is implemented as a MAX heap.
70        //
[1526]71        if ( auxpair->isInHeap() )
[983]72        {
73                heap->update(auxpair, (float)-auxpair->cost);
74        }
75        else
76        {
77                heap->insert(auxpair, (float)-auxpair->cost);
78        }
79}
80
[2088]81//-------------------------------------------------------------------------
[983]82//      Reasign the new vertex to the adequate face
[2088]83//-------------------------------------------------------------------------
[1526]84int SimplificationMethod::predict_face( simplif::Face& F,
85                                                                                                                                                                simplif::Vertex *v1,
86                                                                                                                                                                simplif::Vertex *v2,
87                                                                                                                                                                simplif::Vec3& vnew,
88                                                                                                                                                                simplif::Vec3& f1,
89                                                                                                                                                                simplif::Vec3& f2,
90                                                                                                                                                                simplif::Vec3& f3)
[983]91{
92        int nmapped = 0;
93
[2088]94        if ( F.vertex(0) == v1 || F.vertex(0) == v2 )
[1526]95        {
96                f1 = vnew;  nmapped++;
97        }
98        else
99        {
100                f1 = *F.vertex(0);
101        }
[983]102
[2088]103        if ( F.vertex(1) == v1 || F.vertex(1) == v2 )
[1526]104        {
105                f2 = vnew;  nmapped++;
106        }
107        else
108        {
109                f2 = *F.vertex(1);
110        }
[983]111
[2088]112        if ( F.vertex(2) == v1 || F.vertex(2) == v2 )
[1526]113        {
114                f3 = vnew;  nmapped++;
115        }
116        else
117        {
118                f3 = *F.vertex(2);
119        }
[983]120
121        return nmapped;
122}
123
124#define MESH_INVERSION_PENALTY 1e9
125
[2088]126//-------------------------------------------------------------------------
127//-------------------------------------------------------------------------
128simplif::real SimplificationMethod::pair_mesh_penalty(simplif::Model& M,
129                                                                                                                                                                                                                        simplif::Vertex *v1,
130                                                                                                                                                                                                                        simplif::Vertex *v2,
131                                                                                                                                                                                                                        simplif::Vec3& vnew)
[983]132{
[1025]133        static simplif::face_buffer changed;
[1526]134
[983]135        changed.reset();
136
137        M.contractionRegion(v1, v2, changed);
138
139        // real Nsum = 0;
[1025]140        simplif::real Nmin = 0;
[983]141
[1526]142        for (int i      =       0; i < changed.length(); i++)
[983]143        {
[1025]144                simplif::Face& F = *changed(i);
145                simplif::Vec3 f1, f2, f3;
[983]146
147                int nmapped = predict_face(F, v1, v2, vnew, f1, f2, f3);
148
149                // Only consider non-degenerate faces
150                if( nmapped < 2 )
151                {
[1025]152                        simplif::Plane Pnew(f1, f2, f3);
[1526]153
[1025]154                        simplif::real delta =  Pnew.normal() * F.plane().normal();
[983]155
[1526]156                        if( Nmin > delta )
157                        {
158                                Nmin = delta;
159                        }
[983]160                }
161        }
162
163        //return (-Nmin) * MESH_INVERSION_PENALTY;
164        if( Nmin < 0.0 )
[1526]165        {
[983]166                return MESH_INVERSION_PENALTY;
[1526]167        }
[983]168        else
[1526]169        {
[983]170                return 0.0;
[1526]171        }
[983]172}
173
[2088]174//-------------------------------------------------------------------------
[983]175//      Returns true if the givens vertices are a valid pair
[2088]176//-------------------------------------------------------------------------
[1526]177bool SimplificationMethod::check_for_pair(simplif::Vertex *v0,
178                                                                                                                                                                        simplif::Vertex *v1)
[983]179{
[2291]180        const simplif::pair_buffer& pairs = vertex_info(v0)->pairs;
[983]181
182        for(int i=0; i<pairs.length(); i++)
183        {
184                if( pairs(i)->v0==v1 || pairs(i)->v1==v1 )
[1526]185                {
[983]186                        return true;
[1526]187                }
[983]188        }
189
190        return false;
191}
192
[2088]193//-------------------------------------------------------------------------
[983]194//      Create a new pair with two given vertices
[2088]195//-------------------------------------------------------------------------
[1526]196simplif::pair_info *SimplificationMethod::new_pair(     simplif::Vertex *v0,
197                                                                                                                                                                                                                simplif::Vertex *v1)
[983]198{
[1025]199        simplif::pair_info *pair = new simplif::pair_info(v0,v1);
[1526]200
[2291]201        simplif::vert_info              *v0_info = vertex_info(v0);
202        v0_info->pairs.add(pair);
[983]203
[2291]204        simplif::vert_info              *v1_info = vertex_info(v1);
205        v1_info->pairs.add(pair);
206
[983]207        return pair;
208}
209
[2088]210//-------------------------------------------------------------------------
[983]211//      Remove a given pair
[2088]212//-------------------------------------------------------------------------
[1025]213void SimplificationMethod::delete_pair(simplif::pair_info *auxpair)
[983]214{
[2291]215        simplif::vert_info      *v0_info = vertex_info(auxpair->v0);
216        simplif::vert_info      *v1_info = vertex_info(auxpair->v1);
[983]217
[2291]218        v0_info->pairs.remove(v0_info->pairs.find(auxpair));
219        v1_info->pairs.remove(v1_info->pairs.find(auxpair));
[983]220
[2291]221        if (auxpair->isInHeap())
[1526]222        {
[983]223                heap->kill(auxpair->getHeapPos());
[1526]224        }
[983]225
226        delete auxpair;
227}
228
[2088]229//-------------------------------------------------------------------------
[983]230//      Contract a given pair
[2088]231//-------------------------------------------------------------------------
[2194]232void SimplificationMethod::do_contract( simplif::Model                  &m,
233                                                                                                                                                                simplif::pair_info      *auxpair,
234                                                                                                                                                                int                                                                     obligatory)
[983]235{
[2088]236        simplif::Vertex                 *v0                     = auxpair->v0;
237        simplif::Vertex                 *v1                     = auxpair->v1;
238        simplif::Vec3                   vnew            = auxpair->candidate;
239        float                                                           x,y,z;
240        simplif::Vertex                 *aux_vert;
[1526]241
[2088]242        _float3_                                                removed_vert;
243        int                                                                     i;
244        vertex_map_str                  lb;
245        vertex_map_str                  ub;
[2194]246
247        //      Stores the simplification step.
248        MeshSimplificationSequence::Step simplifstep;
[1526]249       
250        // V0 must be always the alive vertex
251        // V1 must be always the removed vertex
252        if (vnew == (*v0))
253        {
[2088]254                //      Coords of the removed vertex.
255                x       =       (*v1)[X];
256                y       =       (*v1)[Y];
257                z       =       (*v1)[Z];
258
259                aux_vert        =       v1;
[1526]260        }
261        else
262        {
[2088]263                //      Coords of the removed vertex.
264                x       =       (*v0)[X];
265                y       =       (*v0)[Y];
266                z       =       (*v0)[Z];
267
[1526]268                //      Simplification step.
[2088]269                aux_vert        =       v0;
270                v0      =       v1;
271                v1      =       aux_vert;
[1526]272        }
[983]273
[2291]274        simplif::vert_info      *v0_info = vertex_info(v0);
275        simplif::vert_info      *v1_info = vertex_info(v1);
[2088]276
277        //      Simplification step.
278        simplifstep.mV0 = v0->vID;
279        simplifstep.mV1 = v1->vID;
280
281        //      Position of the vertex removed.
282        removed_vert    =       _float3_(x,y,z);
283
284        //      If position of the removed vertex is found.
285        if (vertexMultimap.end() != vertexMultimap.find(removed_vert))
286        {
287                lb      =       vertexMultimap.lower_bound(removed_vert);
288                ub      =       vertexMultimap.upper_bound(removed_vert);
289
290                //      For each vertex.
291                while   (lb != ub)
292                {
293                        //      If removed vertex is found.
294                        if ((*lb).second == aux_vert->vID)
295                        {
296                                //      Debug.
297                                cout    <<      "to remove: "
298                                                        <<      (*lb).second
299                                                        <<      endl;
300
301                                //      Delete vertex that disappears.
302                                vertexMultimap.erase(lb);
303                               
304                                //      Break while.
305                                lb      =       ub;
306                        }
307                        else
308                        {
309                                //      Next iteration.
310                                lb++;
311                        }
312                }
313        }
314
315        //      Make v0 be the new vertex
[2291]316        v0_info->Q              += v1_info->Q;
317        v0_info->norm   += v1_info->norm;
[983]318
[1025]319        simplif::Vec3 p(vnew);
[983]320
[1526]321        //      Perform the actual contraction.
322        static simplif::face_buffer changed;
[983]323
324        changed.reset();
325        m.contract(v0, v1, vnew, changed);
326
[1526]327        //      Stores the displacement in the simplification step.
328        simplifstep.x = (float)0.0f;
329        simplifstep.y = (float)0.0f;
330        simplifstep.z = (float)0.0f;
331
[1007]332        //      Number of triangles that are removed in this simplification step.
333        int _numDelTris = 0; // 1 or 2 triangles can be removed.
334
335        for (i = 0;     i < changed.length();   i++)
[983]336        {
[1007]337                if (!changed(i)->isValid())
338                {
[983]339                        _numDelTris++;
[1007]340                }
[983]341        }
342
[1007]343        int del_index   =       0;
344
[2194]345        //      Initialize deleted triangles.
346        simplifstep.mT0 =       -1;
347        simplifstep.mT1 =       -1;
348
349        //      Sets obligatory flag.
350        simplifstep.obligatory  =       obligatory;
351
[1526]352        //      Clears faces list.
353        simplifstep.mModfaces.clear();
354
355        //      mModfaces y mT0, mT1 of simplifstep stores
356        //      the triangles id's -> geomesh has not triangles id's.
357        for (i  =       0;      i < changed.length();   i++)
[983]358        {
[1526]359                simplif::Face *auxface  =       changed(i);
[1007]360
361                if (auxface->isValid())
[983]362                {
[1526]363                        //      Modified triangles.
[983]364                        simplifstep.mModfaces.push_back(auxface->validID());
365                }
[1007]366                else
[983]367                {
[1526]368                        //      Removed triangles.
369                        if (_numDelTris == 1)
[983]370                        {
[1526]371                                simplifstep.mT0 =       auxface->validID();
372                                simplifstep.mT1 =       auxface->validID();
[983]373                        }
[1007]374                        else
[983]375                        {
[1526]376                                if(del_index == 0)
[983]377                                {
[1526]378                                        simplifstep.mT0 =       auxface->validID();
[983]379                                        del_index++;
380                                }
[1007]381                                else
[983]382                                {
[1526]383                                        simplifstep.mT1 =       auxface->validID();
[983]384                                }
385                        }
386                }
387        }
388
[1526]389        //      Simplification sequence that make reference to the
390        //      simplification method sequence.
391        //decim_data.push_back(simplifstep);
[983]392
[1526]393        //      Adds new simplification step.
394        msimpseq->mSteps.push_back(simplifstep);
395
[983]396#ifdef SUPPORT_VCOLOR
[1526]397        //      If the vertices are colored, color the new vertex
398        //      using the average of the old colors.
[983]399        v0->props->color += v1->props->color;
400        v0->props->color /= 2;
401#endif
402
[1526]403        //      Remove the pair that we just contracted.
[983]404        delete_pair(auxpair);
405
[1526]406        //      Recalculate pairs associated with v0.
[2291]407        for (i  =       0;      i < v0_info->pairs.length();    i++)
[983]408        {
[2291]409                simplif::pair_info *p = v0_info->pairs(i);
[983]410                compute_pair_info(p);
411        }
412
[1526]413        //      Process pairs associated with now dead vertex.
414        //      Collect condemned pairs for execution.
415        static simplif::pair_buffer condemned(6);
416
[983]417        condemned.reset();
418
[2088]419        //      Recalculate pairs associated with v1.
[2291]420        for (i  =       0;      i < v1_info->pairs.length(); i++)
[983]421        {
[2291]422                simplif::pair_info *p = v1_info->pairs(i);
[983]423
[1025]424                simplif::Vertex *u;
[1526]425
[2088]426                if ( p->v0 == v1 )
[1526]427                {
[983]428                        u = p->v1;
[1526]429                }
430                else
431                {
[2088]432                        if ( p->v1 == v1)
[1526]433                        {
[983]434                                u = p->v0;
[1526]435                        }
[983]436                        else
[1526]437                        {
[983]438                                std::cerr << "YOW!  This is a bogus pair." << endl;
[1526]439                        }
440                }
[983]441
[1526]442                if ( !check_for_pair(u, v0) )
[983]443                {
[1526]444                        p->v0   =       v0;
445                        p->v1   =       u;
446
[2291]447                        v0_info->pairs.add(p);
[983]448                        compute_pair_info(p);
449                }
450                else
[1526]451                {
[983]452                        condemned.add(p);
[1526]453                }
[983]454        }
455
[1526]456        for (i  =       0;      i < condemned.length(); i++)
457        {
[983]458                // Do you have any last requests?
459                delete_pair(condemned(i));
[1526]460        }
[983]461
[1526]462        //      Safety precaution.
[2291]463        v1_info->pairs.reset();
[983]464}
465
[2088]466//-------------------------------------------------------------------------
467//-------------------------------------------------------------------------
[1526]468bool SimplificationMethod::decimate_quadric(simplif::Vertex *v,
469                                                                                                                                                                                simplif::Mat4& Q)
[983]470{
471        if( vinfo.length() > 0 )
472        {
[2291]473                Q = vinfo(v->uniqID)->Q;
[983]474                return true;
475        }
476        else
[1526]477        {
[983]478                return false;
[1526]479        }
[983]480}
481
[2088]482//-------------------------------------------------------------------------
483//      Extract a pair from the heap, concract it and remove it from the heap.
484//-------------------------------------------------------------------------
[1025]485void SimplificationMethod::decimate_contract(simplif::Model& m)
[983]486{
[1526]487        simplif::heap_node      *top;
488        simplif::pair_info      *pair;
[2088]489        simplif::Vertex                 *v0;
490        simplif::Vertex                 *v1;
491        simplif::Vec3                           candidate;
492        _float3_                                                f0;
493        _float3_                                                f1;
[983]494
[1526]495        for (;;)
[983]496        {
[1526]497                top     =       heap->extract();
498               
499                if (!top)
500                {
501                        return;
502                }
503               
504                pair    =       (simplif::pair_info *)top->obj;
[983]505
[1526]506                //      Remove all the vertices of the removed edges.
507                bool    sharededge      =       false;
508               
509                for (int        i       =       0;      i < pair->v0->edgeUses().length();      i++)
510                {
511                        simplif::Edge   *econ   =       pair->v0->edgeUses()(i);
512                       
513                        if (pair->v1->vID == econ->org()->vID
514                                        ||
515                                        pair->v1->vID == econ->dest()->vID)
[983]516                        {
[1526]517                                sharededge      =       true;
[983]518                                break;
519                        }
520                }
521
[2088]522                //      Coordinates of the pair.
523                f0      =       _float3_((*pair->v0)[X],(*pair->v0)[Y],(*pair->v0)[Z]);
524                f1      =       _float3_((*pair->v1)[X],(*pair->v1)[Y],(*pair->v1)[Z]);
525
526                if (pair->isValid()
527                                &&
528                                sharededge
529                                &&
530                                (vertexMultimap.find(f0) != vertexMultimap.end())
531                                &&
[2194]532                                (vertexMultimap.find(f1) != vertexMultimap.end())
533                                &&
534                                ((*pair->v0) != (*pair->v1)))
[1526]535                {
[983]536                        break;
[1526]537                }
[983]538
[2088]539                //      Debug.
540                cout    <<      "Deleting pair ("
541                                        <<      pair->v0->vID
542                                        <<      "--"
543                                        <<      pair->v1->vID
544                                        <<      ")"
545                                        <<      endl;
546
[1526]547                //      Deletes repetitions of pair in heap.
[983]548                delete_pair(pair);
549        }
550
[1526]551        //      Copy pair.
[2088]552        v0      =       new Vertex(     (*pair->v0)[X],
553                                                                                (*pair->v0)[Y],
554                                                                                (*pair->v0)[Z]);
555
556        v0->vID = pair->v0->vID;
[1526]557       
[2088]558        v1      =       new Vertex(     (*pair->v1)[X],
559                                                                                (*pair->v1)[Y],
560                                                                                (*pair->v1)[Z]);
[2089]561
[1599]562        v1->vID = pair->v1->vID;
[1526]563
564        candidate       =       pair->candidate;
565
566        //      Debug.
[2088]567        cout    <<      "Contracting... "
568                                <<      endl;
[1526]569
570        //      Contract main pair.
[2194]571        do_contract(m, pair, 0);
[983]572
[1526]573        //      Attempt to maintain valid vertex information.
574        M0.validVertCount--;
575
[2088]576        //      Find twin vertices to the contracted one and contract them.
577        removeTwinVertices(m,v0,v1,candidate);
[1526]578
579        //      Free Memory.
580        delete  v0;
581        delete  v1;
[983]582}
583
[2088]584//-------------------------------------------------------------------------
585//      Find twin vertices to the contracted one and contract them.
586//-------------------------------------------------------------------------
587void SimplificationMethod::removeTwinVertices(simplif::Model    &m,
588                                                                                                                                                                                        simplif::Vertex *v0,
589                                                                                                                                                                                        simplif::Vertex *v1,
590                                                                                                                                                                                        simplif::Vec3           candidate)
[1526]591{
[2088]592        bool                                                            twin_found;
593        simplif::Edge                           *edge;
[1526]594        simplif::pair_info      *pair;
[2088]595        simplif::Vertex                 *vert;
596        simplif::Vertex                 *lonely_vert;
597        simplif::Vertex                 *new_vert;
598        vertex_map_str                  lb;
599        vertex_map_str                  ub;
600        vertex_map_str                  it;
601        _float3_                                                f0;
602        _float3_                                                f1;
603        simplif::Edge                           *econ;
[1526]604        simplif::vert_info      new_vert_info;
605        Geometry::GeoVertex     vertex_added;
[2088]606        simplif::Vertex                 *take_bone_from_vert;
607        float                                                           x,y,z;
[1526]608
[2291]609        //      Gets the vertex that is not the candidate.
610        if ((*v1) == candidate)
[1526]611        {
[2291]612                vert                                                            = v0;
613                v0                                                                      =       v1;
614                v1                                                                      =       vert;
615        }
[2088]616
[2291]617        take_bone_from_vert = v0;
[1526]618
[2291]619        f0      =       _float3_((*v0)[X],(*v0)[Y],(*v0)[Z]);
620        f1      =       _float3_((*v1)[X],(*v1)[Y],(*v1)[Z]);
[1526]621
[2291]622        while ((it = vertexMultimap.find(f1)) != vertexMultimap.end())
623        {
624                twin_found      =       false;
625
626                lonely_vert     =       m.vertex((*it).second);
627
628                //      Debug.
629                if ((*it).second == 10988)
[1526]630                {
[2291]631                        cout    <<      "Lonely: "
632                                <<      lonely_vert->vID
633                                <<      endl;
634                }
[1526]635
[2291]636                for (int        i       =       0;      i < lonely_vert->edgeUses().length();   i++)
637                {
638                        econ    =       lonely_vert->edgeUses()(i);
[1526]639
[2291]640                        if (((*econ->org()) == (*v0))
641                                        ||
642                                        ((*econ->dest()) == (*v0)))
[2194]643                        {
[2291]644                                lb      =       vertexMultimap.lower_bound(f0);
645                                ub      =       vertexMultimap.upper_bound(f0);
[1526]646
[2291]647                                //      For each vertex.
648                                while   (lb != ub)
[2088]649                                {
[2291]650                                        //      If removed vertex is found.
651                                        if (((*lb).second == econ->org()->vID)
652                                                        ||
653                                                        ((*lb).second == econ->dest()->vID))
[2088]654                                        {
[2291]655                                                twin_found      =       true;
[1526]656
[2291]657                                                //      Break while.
658                                                lb      =       ub;
[2088]659                                        }
[2291]660                                        else
661                                        {
662                                                //      Next iteration.
663                                                lb++;
664                                        }
[2088]665                                }
[2291]666
667                                break;
[2088]668                        }
[2291]669                }
[1526]670
[2291]671                //      If a twin edge has been found.
672                if (twin_found)
673                {
674                        //      Debug.
675                        cout    <<      "Twin Contracted..."    <<      endl;
[1526]676
[2291]677                        //      Extract twin edge from heap.
678                        pair    =       new_pair(econ->org(),econ->dest());
[1526]679
[2291]680                        //      Copy candidate.
681                        pair->candidate =       candidate;
[1526]682
[2291]683                        pair->notInHeap();
[1526]684
[2291]685                        //      Contract twin pair.
686                        do_contract(m, pair, 1);
687                        M0.validVertCount--;
688                }
689                else
690                {
691                        //      Debug.
692                        cout    <<      "Contracting new pair..."       <<      endl;
[1526]693
[2291]694                        new_vert        =       m.newVertex(candidate[X],candidate[Y],candidate[Z]);
[1526]695
[2291]696                        //      Add new vert to multimap.
697                        x       =       (*new_vert)[X];
698                        y       =       (*new_vert)[Y];
699                        z       =       (*new_vert)[Z];
[1526]700
[2291]701                        //      Adds new vertex to multimap.
702                        vertexMultimap.insert(vertex_pair(_float3_(x,y,z),new_vert->vID));
[2194]703
[2291]704                        //      Creates new edge.
705                        edge    =       m.newEdge(new_vert,lonely_vert);
[2194]706
[2291]707                        //      We assume here there are the same number of vertices
708                        //      and texture coordinates and normals.
[2194]709
[2291]710                        // Assign a texture coordinate for the vertex.
711                        simplif::Vec2 newtexcoord = m.texcoord(lonely_vert->vID);
712                        m.in_TexCoord(newtexcoord);
[1526]713
[2291]714                        //      Assign a normal coordinate for the vbertex.
715                        simplif::Vec3 newnormal = m.normal(lonely_vert->vID);
716                        m.in_Normal(newnormal);
[1526]717
[2291]718                        //      Adds new vertex information to simplification sequence.
719                        vertex_added.id                         =       new_vert->vID;
[1526]720
[2291]721                        vertex_added.bonefrom   =       take_bone_from_vert->vID;
[1526]722
[2291]723                        vertex_added.position   =       Vector3(candidate[X],
724                                                                                                                                                        candidate[Y],
725                                                                                                                                                        candidate[Z]);
[1526]726
[2291]727                        simplif::Vec2 tc                        = m.texcoord(new_vert->vID);
728                        vertex_added.texcoord   =       Vector2(tc[X],tc[Y]);
[1526]729
[2291]730                        simplif::Vec3 vn                = m.normal(new_vert->vID);
731                        vertex_added.normal     =       Vector3(vn[X],vn[Y],vn[Z]);
[1526]732
[2291]733                        msimpseq->mNewVertices.push_back(vertex_added);
[1526]734
[2291]735                        //      Debug.
736                        vert_info               *new_vert_info;
737                        new_vert_info   =       new vert_info();
[1526]738
[2291]739                        vinfo.add(new_vert_info);
740                        //------------------------------
[2088]741
[2291]742                        pair                                            =       new_pair(new_vert,lonely_vert);
743                        pair->candidate =       candidate;
744                        pair->notInHeap();
[2088]745
[2291]746                        //      Debug.
747                        cout    <<      "new: "
748                                <<      new_vert->vID
749                                <<      "("
750                                <<      (*new_vert)[X]
751                                <<      ","
752                                <<      (*new_vert)[Y]
753                                <<      ","
754                                <<      (*new_vert)[Z]
755                                <<      ") lonely: "
756                                <<      lonely_vert->vID
757                                <<      "("
758                                <<      (*lonely_vert)[X]
759                                <<      ","
760                                <<      (*lonely_vert)[Y]
761                                <<      ","
762                                <<      (*lonely_vert)[Z]
763                                <<      ")"
764                                <<      endl;
[2088]765
[2291]766                        //      Contract new pair.
767                        do_contract(m, pair, 1);
768                        M0.validVertCount--;
[1526]769                }
770        }
771}
772
[2088]773//-------------------------------------------------------------------------
774//-------------------------------------------------------------------------
[1025]775simplif::real SimplificationMethod::decimate_error(simplif::Vertex *v)
[983]776{
[2291]777        simplif::vert_info      *info = vertex_info(v);
[983]778
[2291]779        simplif::real err = simplif::quadrix_evaluate_vertex(*v, info->Q);
[983]780
[2291]781        if ( simplif::will_weight_by_area )
782        {
783                err /= info->norm;
784        }
[983]785
[2291]786        return err;
[983]787}
788
[2088]789//-------------------------------------------------------------------------
[983]790//      Extract the minimum cost of the the valid nodes (not simplified)
[2088]791//-------------------------------------------------------------------------
[1025]792simplif::real SimplificationMethod::decimate_min_error()
[983]793{
[1025]794        simplif::heap_node *top;
795        simplif::pair_info *pair;
[983]796
797        for(;;)
798        {
799                top = heap->top();
[1526]800               
[2291]801                if(!top)
[1526]802                {
803                        return -1.0;
804                }
805
[1025]806                pair = (simplif::pair_info *)top->obj;
[983]807
[2291]808                if(pair->isValid())
[1526]809                {
[983]810                        break;
[1526]811                }
[983]812
813                top = heap->extract();
814                delete_pair(pair);
815        }
816
817        return pair->cost;
818}
819
[2088]820//-------------------------------------------------------------------------
[983]821//      Returns the maximum error by vertex
[2088]822//-------------------------------------------------------------------------
[1025]823simplif::real SimplificationMethod::decimate_max_error(simplif::Model& m)
[983]824{
[1025]825        simplif::real max_err = 0;
[983]826
827        for(int i=0; i<m.vertCount(); i++)
[2291]828                if(m.vertex(i)->isValid())
[983]829                {
830                        max_err = MAX(max_err, decimate_error(m.vertex(i)));
831                }
832
833        return max_err;
834}
835
[2088]836//-------------------------------------------------------------------------
[983]837//      Initializations
[2088]838//-------------------------------------------------------------------------
839void SimplificationMethod::decimate_init(       simplif::Model  &m,
840                                                                                                                                                                        simplif::real   limit)
[983]841{
842        int i,j;
843
[1526]844        //      Reserve memory for vert_info array.
[983]845
[2291]846        for (i  =       0; i < m.vertCount(); i++)
847        {
848                vert_info                       *new_vert_info;
849                new_vert_info   =       new vert_info();
850
851                vinfo.add(new_vert_info);
852        }
853
[1526]854        if (simplif::will_use_vertex_constraint)
855        {
856                //      For each vertex, calculate contraints.
857                for     (i      =       0;      i < m.vertCount();      i++)
[983]858                {
[1526]859                        simplif::Vertex *v      =       m.vertex(i);
860                       
861                        if (v->isValid())
862                        {
[2291]863                                vertex_info(v)->Q = simplif::quadrix_vertex_constraint(*v);
[1526]864                        }
[983]865                }
[1526]866        }
[983]867
[1526]868        //      For each face, recalculate constraints.
869        for (i  =       0;      i < m.faceCount();      i++)
870        {
871                if (m.face(i)->isValid())
[983]872                {
[1526]873                        if (simplif::will_use_plane_constraint)
[983]874                        {
[1025]875                                simplif::Mat4 Q = simplif::quadrix_plane_constraint(*m.face(i));
876                                simplif::real norm = 0.0;
[983]877
[1526]878                                if (simplif::will_weight_by_area)
[983]879                                {
[1526]880                                        norm    =               m.face(i)->area();
881                                        Q                       *=      norm;
[983]882                                }
883
[1526]884                                for (j  =       0;      j < 3;  j++)
[983]885                                {
[2291]886                                        vertex_info(m.face(i)->vertex(j))->Q            +=      Q;
887                                        vertex_info(m.face(i)->vertex(j))->norm +=      norm;
[983]888                                }
889                        }
890                }
[1526]891        }
[983]892
[1526]893        if (simplif::will_constrain_boundaries)
[983]894        {
[1526]895                //      For each edge, recalculate constraints.
896                for (i  =       0;      i < m.edgeCount();      i++)
897                {
898                        if (m.edge(i)->isValid() && simplif::check_for_discontinuity(m.edge(i)))
[983]899                        {
[1025]900                                simplif::Mat4 B = simplif::quadrix_discontinuity_constraint(m.edge(i));
901                                simplif::real norm = 0.0;
[983]902
[1526]903                                if (simplif::will_weight_by_area)
[983]904                                {
[1526]905                                        norm    =               simplif::norm2(*m.edge(i)->org() - *m.edge(i)->dest());
906                                        B                       *=      norm;
[983]907                                }
908
[1025]909                                B *= simplif::boundary_constraint_weight;
[2291]910
911                                vertex_info(m.edge(i)->org())->Q                        += B;
912                                vertex_info(m.edge(i)->org())->norm             += norm;
913                                vertex_info(m.edge(i)->dest())->Q                       += B;
914                                vertex_info(m.edge(i)->dest())->norm    += norm;
[983]915                        }
[1526]916                }
[983]917        }
918
[1526]919        //      Create heap.
[1025]920        heap = new simplif::Heap(m.validEdgeCount);
[983]921
922        int pair_count = 0;
923
[1526]924        //      For each edge, add pairs to heap.
925        for (i  =       0;      i < m.edgeCount();      i++)
926        {
927                if (m.edge(i)->isValid())
[983]928                {
[2291]929                        simplif::pair_info *pair = new_pair(m.edge(i)->org(),
930                                                                                                                                                                        m.edge(i)->dest());
931
[983]932                        //pointers_to_remove.push_back(pair);
[2088]933
[983]934                        compute_pair_info(pair);
935                        pair_count++;
936                }
[1526]937        }
[983]938
[1526]939        if (limit < 0)
[983]940        {
[1526]941                limit   =       m.bounds.radius * 0.05;
[983]942        }
[1526]943       
944        proximity_limit =       limit * limit;
945       
946        if (proximity_limit > 0)
[983]947        {
[1025]948                simplif::ProxGrid grid(m.bounds.min, m.bounds.max, limit);
[1526]949               
950                //      Add points to grid.
951                for (i  =       0;      i < m.vertCount();      i++)
952                {
[983]953                        grid.addPoint(m.vertex(i));
[1526]954                }
[983]955
[1025]956                simplif::buffer<simplif::Vec3 *> nearby(32);
[1526]957               
958                //      For each vertex.
959                for (i  =       0;      i < m.vertCount();      i++)
[983]960                {
961                        nearby.reset();
962                        grid.proximalPoints(m.vertex(i), nearby);
963
[1526]964                        for (j  =       0;      j < nearby.length();    j++)
[983]965                        {
[1025]966                                simplif::Vertex *v1 = m.vertex(i);
967                                simplif::Vertex *v2 = (simplif::Vertex *)nearby(j);
[983]968
[1526]969                                if (v1->isValid() && v2->isValid())
[983]970                                {
971#ifdef SAFETY
972                                        assert(pair_is_valid(v1,v2));
973#endif
[1526]974                                        if (!check_for_pair(v1,v2))
[983]975                                        {
[1025]976                                                simplif::pair_info *pair = new_pair(v1,v2);
[983]977                                                compute_pair_info(pair);
978                                                pair_count++;
979                                        }
980                                }
981                        }
982                }
983        }
984}
985
[2088]986//-------------------------------------------------------------------------
[983]987//      Initilizations
[2088]988//-------------------------------------------------------------------------
[984]989void SimplificationMethod::simplifmethod_init(void)
[983]990{
[984]991        // Change mesh structure.
[1526]992        generateSimplifModel();
993               
[983]994        M0.bounds.complete();
995
996        initialVertCount = M0.vertCount();
997        initialEdgeCount = M0.edgeCount();
998        initialFaceCount = M0.faceCount();
999
[1526]1000        // Get rid of degenerate faces.
1001        for (int        i       =       0;      i < M0.faceCount();     i++)
1002        {
1003                if (!M0.face(i)->plane().isValid())
1004                {
[983]1005                        M0.killFace(M0.face(i));
[1526]1006                }
1007        }
[983]1008
1009        M0.removeDegeneracy(M0.allFaces());
1010
[1526]1011        // Get rid of unused vertices.
1012        for (int        i       =       0;      i < M0.vertCount();     i++)
[983]1013        {
[1526]1014                if (M0.vertex(i)->edgeUses().length() == 0)
1015                {
[983]1016                        M0.vertex(i)->kill();
[1526]1017                }
[983]1018        }
1019}
1020
[2088]1021//-------------------------------------------------------------------------
[983]1022//      Do the contractions till the required LOD (percentage option)
[2088]1023//-------------------------------------------------------------------------
[984]1024void SimplificationMethod::simplifmethod_run(int finalfaces,TIPOFUNC upb)
[983]1025{
[1025]1026        decimate_init(M0, simplif::pair_selection_tolerance);
[983]1027        unsigned        int     contador        =       0;
1028        float                                   percent; // simplification percentage.
1029
1030        percent =       (float)(2.0 * 100.0) / (M0.validFaceCount - finalfaces);
1031
1032        //      Update progress bar.
1033        if (upb)
1034        {
1035                upb(0.0);
1036        }
1037
[1526]1038        /*
1039        for (   std::vector<MeshSimplificationSequence::Step>::iterator
1040                                it      =       decim_data.begin();
1041                                it != decim_data.end();
1042                                it++)
[983]1043        {
1044                it->mModfaces.clear();
1045        }
[1526]1046       
[983]1047        decim_data.clear();
[1526]1048        */
[983]1049
[1526]1050        //      Debug.
1051        cout    <<      "M0.validFaceCount: "   <<      M0.validFaceCount       <<      endl;
1052        cout    <<      "finalfaces: "                          <<      finalfaces                              <<      endl;
1053       
1054        while ( M0.validFaceCount > finalfaces/*simplif::face_target*/
1055                                        && M0.validFaceCount > 1
1056                                        && decimate_min_error() < simplif::error_tolerance )
[983]1057        {
1058                decimate_contract(M0);
1059
1060                //      Update progress bar.
1061                if (upb)
1062                {
1063                        upb(percent);
1064                }
1065        }
1066
1067        //      Update progress bar.
1068        if (upb)
1069        {
1070                upb(100.0);
1071        }
1072}
1073
[2088]1074//-------------------------------------------------------------------------
[983]1075//      Do the contractions till the required LOD (number of vertices option)
[2088]1076//-------------------------------------------------------------------------
[984]1077void SimplificationMethod::simplifmethod_runv(int numvertices,TIPOFUNC upb)
[983]1078{
[1025]1079        decimate_init(M0, simplif::pair_selection_tolerance);
[983]1080        unsigned        int     contador        =       0;
1081        int                                             previousValidVertCount;
1082        float                                   percent; // Simplification percentage.
1083
1084        previousValidVertCount  =       0;
1085
[1526]1086        percent =       (float)(2.0 * 100.0)
1087                                                /
1088                                                (float)((M0.validFaceCount - numvertices / 3.0));
[983]1089
1090        //      Update progress bar.
1091        if (upb)
1092        {
1093                upb(0.0);
1094        }
1095
[1526]1096        /*
1097        for (   std::vector<MeshSimplificationSequence::Step>::iterator
1098                                it      =       decim_data.begin();
1099                                it != decim_data.end();
1100                                it++)
[983]1101        {
1102                it->mModfaces.clear();
1103        }
[1526]1104       
[983]1105        decim_data.clear();
[1526]1106        */
[983]1107
[1526]1108        //      Debug.
1109        cout    <<      "M0.validVertCount:     "       <<      M0.validVertCount       <<      endl;
1110        cout    <<      "numvertices:   "       <<      numvertices     <<      endl;
1111
[1025]1112        while(  M0.validVertCount > numvertices /*simplif::face_target*/
[983]1113                        &&
[1025]1114                        decimate_min_error() < simplif::error_tolerance
[983]1115                        &&
1116                        previousValidVertCount  !=      M0.validVertCount)
1117        {
1118                previousValidVertCount  =       M0.validVertCount;
1119
1120                decimate_contract(M0);
1121
1122                //      Update progress bar.
1123                if (upb)
1124                {
1125                        upb(percent);
1126                }
1127        }
1128
1129        //      Update progress bar.
1130        if (upb)
1131        {
1132                upb(100.0);
1133        }
1134}
1135
[2088]1136//-------------------------------------------------------------------------
[1526]1137//      Generate simplification model.
[2088]1138//-------------------------------------------------------------------------
[1526]1139void    SimplificationMethod::generateSimplifModel(void)
[983]1140{
[2088]1141        int             face_index      =       0;
1142        int             vertID;
1143        float   x,y,z;
[983]1144
[1526]1145        //      For each submesh.
1146        bool added_vertices = false;
[2088]1147        for (size_t     i =     0;      i       <       mInitialMesh->mSubMeshCount;    i++)
[983]1148        {
[1526]1149                //      If is not a tree leaves submesh.
1150                if (i != indexMeshLeaves)
[983]1151                {
[1526]1152                        //      For all the vertices of each submesh.
1153                        for (   size_t  j       =       0;
[2088]1154                                        j < mInitialMesh->mSubMesh[i].mVertexBuffer->mVertexCount;
[1526]1155                                        j++)
[983]1156                        {
[2088]1157                                x       =       mInitialMesh->mSubMesh[i].mVertexBuffer->mPosition[j].x;
1158                                y       =       mInitialMesh->mSubMesh[i].mVertexBuffer->mPosition[j].y;
1159                                z       =       mInitialMesh->mSubMesh[i].mVertexBuffer->mPosition[j].z;
1160
[1526]1161                                //      If the vertex is not in vertices_map, then is added.
[2088]1162                                vertID  =       M0.in_Vertex(simplif::Vec3(
1163                                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mPosition[j].x,
1164                                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mPosition[j].y,
1165                                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mPosition[j].z));
[983]1166
[1526]1167                                M0.in_Normal(simplif::Vec3(
[2088]1168                                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mNormal[j].x,
1169                                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mNormal[j].y,
1170                                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mNormal[j].z));
[983]1171
[1526]1172                                M0.in_TexCoord(simplif::Vec2(
[2088]1173                                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mTexCoords[j].x,
1174                                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mTexCoords[j].y));
[983]1175
[1526]1176                                added_vertices = true;
[2088]1177
1178                                //      Add vertex to multimap.
1179                                vertexMultimap.insert(vertex_pair(_float3_(x,y,z),vertID));
[983]1180                        }
[2088]1181                }
1182
[1526]1183                //      If is shared vertex buffer object.
[2088]1184                if (mInitialMesh->mSubMesh[i].mSharedVertexBuffer && added_vertices)
[983]1185                {
[1526]1186                        printf("Shared break");
1187                        break;
[983]1188                }
1189        }
1190
[1526]1191        //      For each submesh.
[2088]1192        for (size_t     i = 0;  i < mInitialMesh->mSubMeshCount;        i++)
[983]1193        {
[1526]1194                if (i != indexMeshLeaves)
[983]1195                {
[2088]1196                        for (   Geometry::Index j       =       0;
1197                                                j < mInitialMesh->mSubMesh[i].mIndexCount;
1198                                                j       +=      3)
[983]1199                        {
[1526]1200                                //      +1 is required because the first index in the
1201                                //      simplification method is 1
1202                                //      Index of the vertex in vertices_map.
[2088]1203                                Geometry::Index index0  =               mInitialMesh->mSubMesh[i].mIndex[j];
[1526]1204                               
[2088]1205                                Geometry::Index index1  =               mInitialMesh->mSubMesh[i].mIndex[j + 1];
[1526]1206                               
[2088]1207                                Geometry::Index index2  =               mInitialMesh->mSubMesh[i].mIndex[j + 2];
[1526]1208                               
1209                                //      Create a triangle with its indices in vertices_map.
1210                                face_index      =       M0.miin_Face(
1211                                                index0,
1212                                                index1,
1213                                                index2);
1214
1215                                //      igeo allows to identify the submesh that contains the triangle.
1216                                M0.face(face_index)->igeo       =       (int)i;
[983]1217                        }
1218                }
1219        }
[1526]1220        number_of_triangles     =       face_index;
[983]1221}
1222
[2088]1223//-------------------------------------------------------------------------
[1526]1224//      simplifmethod_init is executed to do some initalizations
1225//      simplifmethod_run is executed to do the decimation
1226//      Then, the simpified model is created and the decimation
1227//      information is returned.
[2088]1228//-------------------------------------------------------------------------
[983]1229MeshSimplificationSequence *SimplificationMethod::Decimate(     float lod,
1230                                                                                                                                                                                                                                                int simpliftype,
1231                                                                                                                                                                                                                                                TIPOFUNC upb)
1232{
[2088]1233        bool                                                                                            shared_vertex;
1234        unsigned        int                                                             vertex_count;
1235        std::map<int,int>::iterator     findit;
1236        //      Initialize      vertex count.
1237        vertex_count    =       0;
1238
1239        //      Initialize shared vertex buffer flag.
1240        shared_vertex   =       false;
1241
1242        //      Determines if the mesh have shared vertex buffer.
1243        for (int i = 0; i < mInitialMesh->mSubMeshCount;        i++)
1244        {
1245                if (mInitialMesh->mSubMesh[i].mSharedVertexBuffer)
1246                {
1247                        shared_vertex   =       true;
1248                        break;
1249                }
1250        }
1251
[984]1252        simplifmethod_init();
[983]1253
1254        if (simpliftype == 0)
1255        {
[1526]1256                //      Percentage option.
[984]1257                simplifmethod_run((int)(number_of_triangles*lod),upb);
[983]1258        }
1259        else
1260        {
[1526]1261                //      Number of vertices option.
[984]1262                simplifmethod_runv((int)lod,upb);
[983]1263        }
1264
[2088]1265        MAPAINDIND *unique_verts_inds_by_geo =
1266                new MAPAINDIND[mInitialMesh->mSubMeshCount];
[983]1267
[2088]1268        MAPAINDIND      shared_vertex_map;
[983]1269
[2088]1270        REPINDLIST *ver_inds_rep_by_geo = new REPINDLIST[mInitialMesh->mSubMeshCount];
[983]1271
1272        //      Index counter by submesh.
[2088]1273        int *inextvert = new int[mInitialMesh->mSubMeshCount];
[983]1274
[2088]1275        for (unsigned int       i = 0;  i < mInitialMesh->mSubMeshCount;        i++)
[983]1276        {
1277                inextvert[i] = 0;
1278        }
1279
1280        //      Construct the model.
[1526]1281        std::cout << "M0.faceCount(): " << M0.faceCount() << std::endl;
[2088]1282
1283        //      For each face.
[983]1284        for (int        i = 0;  i < M0.faceCount();     i++)
1285        {
1286                if (M0.face(i)->isValid())
1287                {
[1025]1288                        simplif::Face *auxface  =       M0.face(i);
[983]1289
1290                        //      Determine to which submesh pertains the triangle.
1291                        int igeo = auxface->igeo;
1292
[2088]1293                        //      For each index of the face.
1294                        for (size_t     j = 0; j < 3; j++)
[983]1295                        {
[2088]1296                                if (shared_vertex)
1297                                {
1298                                        //      Insert to each submesh its triangles.
1299                                        findit =        shared_vertex_map.find(auxface->vertex(j)->vID);
[1526]1300
[2088]1301                                        if (findit == shared_vertex_map.end())
1302                                        {
1303                                                //      If it is not added... add and map it.
1304                                                shared_vertex_map[auxface->vertex(j)->vID] =    vertex_count;
1305
1306                                                vertex_count++;
1307                                        }
1308                                }
1309                                else
1310                                {
1311                                        //      Insert to each submesh its triangles.
1312                                        findit =        unique_verts_inds_by_geo[igeo].
1313                                                find(auxface->vertex(j)->vID);
1314
1315                                        if (findit == unique_verts_inds_by_geo[igeo].end())
1316                                        {
1317                                                //      If it is not added... add and map it.
1318                                                unique_verts_inds_by_geo[igeo][auxface->vertex(j)->vID] =
1319                                                        inextvert[igeo];
1320
1321                                                inextvert[igeo]++;
1322                                        }
1323                                }
1324
1325                                //      Total number of indices by submesh.
1326                                ver_inds_rep_by_geo[igeo].push_back(auxface->vertex(j)->vID);
[1526]1327                        }
[983]1328                }
1329        }
1330
1331        //      Output simplified mesh.
1332        mGeoMesh                                                                =       new Mesh();
1333        mGeoMesh->mVertexBuffer =       new     VertexBuffer();
1334
[2088]1335        mGeoMesh->mSubMeshCount = mInitialMesh->mSubMeshCount;
[986]1336
[983]1337        //      Memory allocation for the submeshes.
[2088]1338        mGeoMesh->mSubMesh = new SubMesh[mInitialMesh->mSubMeshCount];
[983]1339
1340        //      Fill up bounding box settings.
[2088]1341        mGeoMesh->mMeshBounds.maxX                                      =       mInitialMesh->mMeshBounds.maxX;
1342        mGeoMesh->mMeshBounds.maxY                                      =       mInitialMesh->mMeshBounds.maxY;
1343        mGeoMesh->mMeshBounds.maxZ                                      =       mInitialMesh->mMeshBounds.maxZ;
1344        mGeoMesh->mMeshBounds.minX                                      =       mInitialMesh->mMeshBounds.minX;
1345        mGeoMesh->mMeshBounds.minY                                      =       mInitialMesh->mMeshBounds.minY;
1346        mGeoMesh->mMeshBounds.minZ                                      =       mInitialMesh->mMeshBounds.minZ;
1347        mGeoMesh->mMeshBounds.radius                            =       mInitialMesh->mMeshBounds.radius;
1348        mGeoMesh->mMeshBounds.scaleFactor               =       mInitialMesh->mMeshBounds.scaleFactor;
[983]1349
1350        //      Copy skeleton name.
[2088]1351        if (mInitialMesh->hasSkeleton)
[983]1352        {
1353                mGeoMesh->hasSkeleton   =       true;
[986]1354
[2088]1355                strcpy(mGeoMesh->mSkeletonName,mInitialMesh->mSkeletonName);
[983]1356        }
1357
[2088]1358        //      If the mesh has shared vertex.
1359        if (shared_vertex)
[983]1360        {
[2088]1361                fillUpSharedVertices(shared_vertex_map,ver_inds_rep_by_geo);
1362        }
1363        else
1364        {
1365                fillUpVertices(unique_verts_inds_by_geo,ver_inds_rep_by_geo);
1366        }
1367
1368        //------------------------//
1369        //      Bones reassignment.             //
1370        //------------------------//
1371        VertexBoneAssignment    bone;
1372        bool                                                                    vertex_found;
1373        MAPAINDIND::iterator    it;
1374
1375        addNewBoneAssignments();
1376
1377        //      For each bone assignment.
1378        for (unsigned int i = 0; i < mInitialMesh->mBones.size(); i++)
1379        {
1380                bone.vertexIndex        =       mInitialMesh->mBones[i].vertexIndex;
1381                bone.boneIndex          =       mInitialMesh->mBones[i].boneIndex;
1382                bone.weight                             =       mInitialMesh->mBones[i].weight;
1383
1384                vertex_found    =       false;
1385
1386                //      If the vertex is found in the simplification model.
1387                if ((it = shared_vertex_map.find(bone.vertexIndex))
1388                                !=
1389                                shared_vertex_map.end())
[983]1390                {
[2088]1391                        bone.vertexIndex        =       (*it).second;
1392
1393                        mGeoMesh->mBones.push_back(bone);
1394                        vertex_found    =       true;
[983]1395                }
1396        }
[2088]1397        //------------------------------------------------------------//
[983]1398
[2088]1399        delete[] unique_verts_inds_by_geo;
1400        delete[] ver_inds_rep_by_geo;
1401        delete[] inextvert;
1402
1403        //      Store the simplification steps in MeshSimplificationSequence.
1404        int     acum    =       0;
1405
1406        for (size_t i   =       0; i < mInitialMesh->mSubMeshCount; i++)
1407        {
1408                if (mInitialMesh->mSubMesh[i].mSharedVertexBuffer)
1409                {
1410                        first_index_submesh[i]  =       0;
1411                }
1412                else
1413                {
1414                        first_index_submesh[i]  =       acum;
1415                }
1416
1417                acum    +=      (int)mInitialMesh->mSubMesh[i].mVertexBuffer->mVertexCount;
1418        }
1419
1420        vector<int>     v0;
1421        vector<int>     v1;
1422        vector<int>     submesh0;
1423        vector<int>     submesh1;
1424
1425        return msimpseq;
1426}
1427
1428//-------------------------------------------------------------------------
1429//      Add bone assignments for new bones.
1430//-------------------------------------------------------------------------
1431void    SimplificationMethod::addNewBoneAssignments()
1432{
1433        size_t  vertex_id;
1434        size_t  bones_count;
1435        VertexBoneAssignment bone;
1436        vector<VertexBoneAssignment>::iterator  it;
1437
1438        //      Copy new vertices.
1439        for (unsigned   int     i       =       0;      i < msimpseq->mNewVertices.size();      i++)
1440        {
1441                vertex_id       =       msimpseq->mNewVertices[i].id;
1442
1443                //      Initialize number of bones.
1444                bones_count     =       mInitialMesh->mBones.size();
1445
1446                // check if my twin-vertex-bone has a bone assignment
1447                // we check only the GeoMesh bones because the lodstrips
1448                // only works for sharedvertex bones.
1449                for (int  j = 0; j < bones_count; j++)
1450                {
1451                        it      =       mInitialMesh->mBones.begin() + j;
1452
1453                        if (it->vertexIndex == msimpseq->mNewVertices[i].bonefrom)
1454                        {
1455                                bone.vertexIndex        = vertex_id;
1456                                bone.boneIndex          = it->boneIndex;
1457                                bone.weight                             = it->weight;
1458
1459                                mInitialMesh->mBones.push_back(bone);
1460                                bones_count++;
1461                        }
1462                }
1463        }
1464}
1465
1466//-------------------------------------------------------------------------
1467//      Erase submeshes that have not indices.
1468//-------------------------------------------------------------------------
1469void    SimplificationMethod::eraseVoidSubMeshes(Mesh   *geoMesh)
1470{
1471        SubMesh *geosubmesh;
1472        size_t  valid_submesh_count;
1473        size_t  submesh;
1474
1475        valid_submesh_count     =       0;
1476
1477        //      For each submesh.
1478        for     (size_t i       =       0; i < geoMesh->mSubMeshCount;  i++)
1479        {
1480                //      Debug.
1481                cout    <<      "Indices of submesh "
1482                                        <<      i
1483                                        <<      ": "
1484                                        <<      geoMesh->mSubMesh[i].mIndexCount
1485                                        <<      endl;
1486
1487                if ((geoMesh->mSubMesh[i].mIndexCount > 0)
1488                                ||
1489                                (indexMeshLeaves == i))
1490                {
1491                        valid_submesh_count++;
1492                }
1493        }
1494
1495        //      Reassign submesh count.
1496        geoMesh->mSubMeshCount  =       valid_submesh_count;
1497
1498        //      Reserve memory for valid submeshes.
1499        geosubmesh      =       new     SubMesh[valid_submesh_count];
1500
1501        submesh =       0;
1502       
1503        //      For each submesh.
1504        for (size_t i = 0; i < geoMesh->mSubMeshCount; i++)
1505        {
1506                //      If leaves submesh is found.
1507                if (indexMeshLeaves == i)
1508                {
1509                        geosubmesh[i].mStripCount       =       0;
1510                        geosubmesh[i].mStrip                    =       NULL;
1511
1512                        geosubmesh[i].mSharedVertexBuffer       =       false;
1513
1514                        strcpy( geosubmesh[i].mMaterialName,
1515                                        mInitialMesh->mSubMesh[i].mMaterialName);
1516
1517                        //      Copy submesh bones.
1518                        if (!mInitialMesh->mSubMesh[i].mBones.empty())
1519                        {
1520                                for (   size_t j = 0;
1521                                                j < mInitialMesh->mSubMesh[i].mBones.size();
1522                                                j++)
1523                                {
1524                                        geosubmesh[i].mBones.push_back(mInitialMesh->
1525                                                        mSubMesh[i].mBones[j]);
1526                                }
1527                        }
1528
1529                        //      Leaves mesh.
1530                        geosubmesh[i].mIndexCount       =       
1531                                mInitialMesh->mSubMesh[i].mIndexCount;
1532
1533                        geosubmesh[i].mIndex    =
1534                                new Geometry::Index[geosubmesh[i].mIndexCount];
1535
1536                        memcpy( geosubmesh[i].mIndex,
1537                                        mInitialMesh->mSubMesh[i].mIndex,
1538                                        mInitialMesh->mSubMesh[i].mIndexCount * sizeof(Index));
1539
1540                        //      Copy the leaves submesh vertices.
1541                        geosubmesh[i].mVertexBuffer     =
1542                                mInitialMesh->mSubMesh[i].mVertexBuffer->Clone();
1543
1544                        //      Next valid submesh.
1545                        submesh++;
1546                }
1547                else if (geoMesh->mSubMesh[i].mIndexCount > 0)
1548                {
1549                        geosubmesh[submesh].mSharedVertexBuffer =
1550                                                                        geoMesh->mSubMesh[i].mSharedVertexBuffer;
1551
1552                        geosubmesh[submesh].mVertexBuffer       =       geoMesh->mVertexBuffer;
1553
1554                        geosubmesh[submesh].mType                               =       geoMesh->mSubMesh[i].mType;
1555
1556                        geosubmesh[submesh].mStripCount =       geoMesh->mSubMesh[i].mStripCount;
1557
1558                        geosubmesh[submesh].mIndexCount =       geoMesh->mSubMesh[i].mIndexCount;
1559
1560                        //      Reserve memory for indices.
1561                        geosubmesh[submesh].mIndex      =
1562                                                                                                        new Index[geosubmesh[submesh].mIndexCount];
1563
1564                        //      Copy indices.
1565                        memcpy( geosubmesh[submesh].mIndex,
1566                                        geoMesh->mSubMesh[i].mIndex,
1567                                        geoMesh->mSubMesh[i].mIndexCount * sizeof(Index));
1568
1569                        //      Reserve memory for array of strips.
1570                        geosubmesh[submesh].mStrip      =
1571                                new Index*[geoMesh->mSubMesh[submesh].mStripCount];
1572
1573                        //      Copy strip list of the submesh.
1574                        for (size_t j = 0; j < geoMesh->mSubMesh[i].mStripCount; j++)
1575                        {
1576                                geosubmesh[submesh].mStrip[j]   =       geoMesh->mSubMesh[i].mStrip[j];
1577                        }
1578
1579                        strcpy( geosubmesh[submesh].mMaterialName,
1580                                        geoMesh->mSubMesh[i].mMaterialName);
1581
1582                        for (size_t     j       =       0;      j < geoMesh->mSubMesh[i].mBones.size(); j++)
1583                        {
1584                                geosubmesh[submesh].mBones
1585                                        .push_back(geoMesh->mSubMesh[i].mBones[j]);
1586                        }
1587
1588                        //      Next valid submesh.
1589                        submesh++;
1590                }
1591        }
1592
1593        //      Delete submeshes.
1594        delete  []geoMesh->mSubMesh;
1595
1596        geoMesh->mSubMesh       =       geosubmesh;
1597}
1598
1599//-------------------------------------------------------------------------
1600//      Fill up vertices.
1601//-------------------------------------------------------------------------
1602void    SimplificationMethod::fillUpVertices(
1603                                                                                                                        MAPAINDIND      *unique_verts_inds_by_geo,
1604                                                                                                                        REPINDLIST      *ver_inds_rep_by_geo)
1605{
[983]1606        bool copiedShared = false;
1607
[1526]1608        //      For each submesh.
[2088]1609        for (size_t     i = 0;  i < mInitialMesh->mSubMeshCount;        i++)
[983]1610        {
[1526]1611                mGeoMesh->mSubMesh[i].mStripCount       =       0;
1612                mGeoMesh->mSubMesh[i].mStrip                    =       NULL;
[983]1613
[986]1614                mGeoMesh->
1615                        mSubMesh[i].mSharedVertexBuffer =       false;
1616
[983]1617                strcpy( mGeoMesh->mSubMesh[i].mMaterialName,
[2088]1618                                mInitialMesh->mSubMesh[i].mMaterialName);
[983]1619
1620                //      Copy submesh bones.
[2088]1621                if (!mInitialMesh->mSubMesh[i].mBones.empty())
[983]1622                {
[2088]1623                        for (   unsigned int j = 0;
1624                                                j < mInitialMesh->mSubMesh[i].mBones.size();
1625                                                j++)
[983]1626                        {
[2088]1627                                mGeoMesh->mSubMesh[i].mBones.push_back(mInitialMesh->
1628                                                mSubMesh[i].mBones[j]);
[983]1629                        }
1630                }
1631
1632                if (i != indexMeshLeaves)
1633                {
1634                        //      Indices vectors.
[984]1635                        mGeoMesh->mSubMesh[i].mIndexCount       =       ver_inds_rep_by_geo[i].size();
[983]1636
[2088]1637                        mGeoMesh->mSubMesh[i].mIndex                    =       new Geometry::Index[mGeoMesh->
1638                                mSubMesh[i].mIndexCount];
1639
[983]1640                        //      Store the indices.
1641                        for (unsigned int       j = 0;  j < mGeoMesh->mSubMesh[i].mIndexCount;  j++)
1642                        {
1643                                //      Obtain the indices that point at VertexBuffer.
[1526]1644                                mGeoMesh->mSubMesh[i].mIndex[j] =
[2088]1645                                        unique_verts_inds_by_geo[i][ver_inds_rep_by_geo[i][j]];
[983]1646                        }
1647
1648                        //      Copy the vertices.
1649                        if (mGeoMesh->mSubMesh[i].mSharedVertexBuffer)
1650                        {
1651                                //      Shared vertices.
1652                                if (!copiedShared)
1653                                {
1654                                        mGeoMesh->mVertexBuffer = new VertexBuffer();
1655                                        copiedShared                                            = true;
1656                                }
1657
1658                                mGeoMesh->mSubMesh[i].mVertexBuffer = mGeoMesh->mVertexBuffer;
1659                        }
1660                        else
1661                        {
1662                                //      There's no shared vertices.
1663                                mGeoMesh->mSubMesh[i].mVertexBuffer     =       new VertexBuffer();
1664                        }
1665
[1526]1666                        mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount       =
[2088]1667                                unique_verts_inds_by_geo[i].size();
1668
[1526]1669                        mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexInfo        =
[2088]1670                                mInitialMesh->mSubMesh[i].mVertexBuffer->mVertexInfo;
[983]1671
1672                        //      Allocate memory for position, normal and texutre coordinates.
[1526]1673                        mGeoMesh->mSubMesh[i].mVertexBuffer->mPosition  =
[2088]1674                                new Vector3[mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount];
1675
[1526]1676                        mGeoMesh->mSubMesh[i].mVertexBuffer->mNormal            =
[2088]1677                                new Vector3[mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount];
1678
[1526]1679                        mGeoMesh->mSubMesh[i].mVertexBuffer->mTexCoords =
[2088]1680                                new Vector2[mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount];
[983]1681
[2088]1682                        for (MAPAINDIND::iterator mapit = unique_verts_inds_by_geo[i].begin();
[986]1683                                                mapit != unique_verts_inds_by_geo[i].end();
1684                                                mapit++)
[983]1685                        {
1686                                //      Key and value.
1687                                int isrc = mapit->first;
1688                                int idst = mapit->second;
1689
1690                                //      Vertex coordinate.
1691                                //      Construction of the submeshes.
[1526]1692                                Vector3 v3(     (Real)M0.vertex(isrc)->operator [](0),
[2088]1693                                                (Real)M0.vertex(isrc)->operator [](1),
1694                                                (Real)M0.vertex(isrc)->operator [](2));
1695
[1526]1696                                mGeoMesh->mSubMesh[i].mVertexBuffer->mPosition[idst]    =       v3;
[983]1697
1698                                //      Normal coordinates.
[1526]1699                                Vector3 v3n(    (Real)M0.normal(isrc)(0),
[2088]1700                                                (Real)M0.normal(isrc)(1),
1701                                                (Real)M0.normal(isrc)(2));
1702
[1526]1703                                mGeoMesh->mSubMesh[i].mVertexBuffer->mNormal[idst]      =       v3n;
[983]1704
1705                                //      Texture coordinates.
[1526]1706                                Vector2 v2(     (Real)M0.texcoord(isrc)(0),
[2088]1707                                                (Real)M0.texcoord(isrc)(1));
1708
[1526]1709                                mGeoMesh->mSubMesh[i].mVertexBuffer->mTexCoords[idst]   =       v2;
[983]1710                        }
1711                }
[2088]1712                //      Leaves mesh.
[983]1713                else
1714                {
[2088]1715                        mGeoMesh->mSubMesh[i].mIndexCount       =       
1716                                                                                                                mInitialMesh->mSubMesh[i].mIndexCount;
[983]1717
[2088]1718                        mGeoMesh->mSubMesh[i].mIndex    =               
1719                                                new Geometry::Index[mGeoMesh->mSubMesh[i].mIndexCount];
1720
[983]1721                        //      Copy the leaves submesh indexes.
[2088]1722                        for (   unsigned int    j       =       0;
1723                                                j < mGeoMesh->mSubMesh[i].mIndexCount;
1724                                                j++)
1725                        {
1726                                mGeoMesh->mSubMesh[i].mIndex[j] =       mInitialMesh->mSubMesh[i].mIndex[j];
[983]1727                        }
1728
1729                        //      Copy the leaves submesh vertices.
[1526]1730                        mGeoMesh->mSubMesh[i].mVertexBuffer     =       new VertexBuffer();
[2088]1731
[1526]1732                        mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount       =
[2088]1733                                mInitialMesh->mSubMesh[i].mVertexBuffer->mVertexCount;
1734
[1526]1735                        mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexInfo        =
[2088]1736                                mInitialMesh->mSubMesh[i].mVertexBuffer->mVertexInfo;
[983]1737
1738                        //      Allocate memory for position, normal and texture coordinates.
[1526]1739                        mGeoMesh->mSubMesh[i].mVertexBuffer->mPosition  =
[2088]1740                                new Vector3[mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount];
1741
[1526]1742                        mGeoMesh->mSubMesh[i].mVertexBuffer->mNormal    =
[2088]1743                                new Vector3[mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount];
1744
[1526]1745                        mGeoMesh->mSubMesh[i].mVertexBuffer->mTexCoords =
[2088]1746                                new Vector2[mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount];
[986]1747
[983]1748                        for (   unsigned int j = 0;
[986]1749                                        j < mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount;
1750                                        j++)
[983]1751                        {
1752                                //      Position.
[1526]1753                                mGeoMesh->mSubMesh[i].mVertexBuffer->mPosition[j].x     =
[2088]1754                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mPosition[j].x;
1755
[1526]1756                                mGeoMesh->mSubMesh[i].mVertexBuffer->mPosition[j].y     =
[2088]1757                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mPosition[j].y;
1758
[1526]1759                                mGeoMesh->mSubMesh[i].mVertexBuffer->mPosition[j].z     =
[2088]1760                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mPosition[j].z;
[983]1761
1762                                //      Normals.
[1526]1763                                mGeoMesh->mSubMesh[i].mVertexBuffer->mNormal[j].x       =
[2088]1764                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mNormal[j].x;
1765
[1526]1766                                mGeoMesh->mSubMesh[i].mVertexBuffer->mNormal[j].y       =
[2088]1767                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mNormal[j].y;
1768
[1526]1769                                mGeoMesh->mSubMesh[i].mVertexBuffer->mNormal[j].z       =
[2088]1770                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mNormal[j].z;
[983]1771
1772                                //      Textures.
[1526]1773                                mGeoMesh->mSubMesh[i].mVertexBuffer->mTexCoords[j].x    =
[2088]1774                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mTexCoords[j].x;
1775
[1526]1776                                mGeoMesh->mSubMesh[i].mVertexBuffer->mTexCoords[j].y    =
[2088]1777                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mTexCoords[j].y;
[983]1778                        }
1779                }
1780        }
[2088]1781}
[983]1782
[2088]1783//-------------------------------------------------------------------------
1784//      Fill up shared vertices.
1785//-------------------------------------------------------------------------
1786void    SimplificationMethod::fillUpSharedVertices(
1787                                                                                                                MAPAINDIND      &shared_vertex_map,
1788                                                                                                                REPINDLIST      *ver_inds_rep_by_geo)
1789{
1790        mGeoMesh->mVertexBuffer = new VertexBuffer();
[983]1791
[2088]1792        //      For each submesh.
1793        for (size_t     i = 0;  i < mInitialMesh->mSubMeshCount;        i++)
1794        {
1795                mGeoMesh->
1796                        mSubMesh[i].mSharedVertexBuffer =       mInitialMesh->
1797                                                                                                                                                                        mSubMesh[i].mSharedVertexBuffer;
[986]1798
[2088]1799                //      Reassign submesh vertex buffers.
1800                mGeoMesh->mSubMesh[i].mVertexBuffer = mGeoMesh->mVertexBuffer;
1801
1802                mGeoMesh->mSubMesh[i].mStripCount       =       0;
1803                mGeoMesh->mSubMesh[i].mStrip                    =       NULL;
1804
1805                strcpy( mGeoMesh->mSubMesh[i].mMaterialName,
1806                                mInitialMesh->mSubMesh[i].mMaterialName);
1807
1808                //      Indices vectors.
1809                mGeoMesh->mSubMesh[i].mIndexCount       =       ver_inds_rep_by_geo[i].size();
1810
1811                mGeoMesh->mSubMesh[i].mIndex                    =       new Geometry::Index[mGeoMesh->
1812                                                                                                                                                                                                mSubMesh[i].mIndexCount];
1813
1814                //      Store the indices.
1815                for (unsigned int       j = 0;  j < mGeoMesh->mSubMesh[i].mIndexCount;  j++)
[983]1816                {
[2088]1817                        //      Obtain the indices that point at VertexBuffer.
1818                        mGeoMesh->mSubMesh[i].mIndex[j] =
1819                                shared_vertex_map[ver_inds_rep_by_geo[i][j]];
[983]1820                }
1821        }
[986]1822
[2088]1823        mGeoMesh->mVertexBuffer->mVertexCount   =       shared_vertex_map.size();
[986]1824
[2088]1825        mGeoMesh->mVertexBuffer->mVertexInfo    =       
1826                                                                                                                        mInitialMesh->mVertexBuffer->mVertexInfo;
1827
1828        //      Allocate memory for position, normal and texutre coordinates.
1829        mGeoMesh->mVertexBuffer->mPosition      =
1830                new Vector3[mGeoMesh->mVertexBuffer->mVertexCount];
1831
1832        mGeoMesh->mVertexBuffer->mNormal                =
1833                new Vector3[mGeoMesh->mVertexBuffer->mVertexCount];
1834
1835        mGeoMesh->mVertexBuffer->mTexCoords     =
1836                new Vector2[mGeoMesh->mVertexBuffer->mVertexCount];
1837
1838        for (MAPAINDIND::iterator mapit = shared_vertex_map.begin();
1839                        mapit != shared_vertex_map.end();
1840                        mapit++)
1841        {
1842                //      Key and value.
1843                int isrc = mapit->first;
1844                int idst = mapit->second;
1845
1846                //      Vertex coordinate.
1847                //      Construction of the submeshes.
1848                Vector3 v3(     (Real)M0.vertex(isrc)->operator [](0),
1849                                                                (Real)M0.vertex(isrc)->operator [](1),
1850                                                                (Real)M0.vertex(isrc)->operator [](2));
1851
1852                mGeoMesh->mVertexBuffer->mPosition[idst]        =       v3;
1853
1854                //      Normal coordinates.
1855                Vector3 v3n((Real)M0.normal(isrc)(0),
1856                                                                (Real)M0.normal(isrc)(1),
1857                                                                (Real)M0.normal(isrc)(2));
1858
1859                mGeoMesh->mVertexBuffer->mNormal[idst]  =       v3n;
1860
1861                //      Texture coordinates.
1862                Vector2 v2(     (Real)M0.texcoord(isrc)(0),
1863                                                                (Real)M0.texcoord(isrc)(1));
1864
1865                mGeoMesh->mVertexBuffer->mTexCoords[idst]       =       v2;
1866        }
[983]1867}
1868
[2088]1869//-------------------------------------------------------------------------
[983]1870//      Set submesh leaves.
[2088]1871//-------------------------------------------------------------------------
[983]1872void SimplificationMethod::setMeshLeaves(int meshLeaves)
1873{
1874        indexMeshLeaves =       meshLeaves;
1875}
1876
1877//      Gets mesh simplified.
1878Mesh    *       SimplificationMethod::GetMesh()
1879{
[2088]1880        //      Delete void submeshes.
1881        eraseVoidSubMeshes(mGeoMesh);
1882
[983]1883        return  mGeoMesh;
1884}
1885
Note: See TracBrowser for help on using the repository browser.