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)
Line 
1#include <stdlib.h>
2#include "SimplificationMethod.h"
3#include <iostream>
4#include <fstream>
5#include <gfx/geom/ProxGrid.h>
6#include "quadrics.h"
7
8using namespace std;
9using namespace Geometry;
10using   namespace       simplif;
11
12//-------------------------------------------------------------------------
13//      Constructor
14//-------------------------------------------------------------------------
15SimplificationMethod::SimplificationMethod(const Mesh *m)
16{
17        mInitialMesh                            =       new Mesh();
18        *mInitialMesh                           =       *m;
19        mGeoMesh                                                =       NULL;
20        first_index_submesh     =       new unsigned int[mInitialMesh->mSubMeshCount];
21        indexMeshLeaves                 =       -1;
22
23        //      Create simplification sequence.
24        msimpseq        =       new MeshSimplificationSequence();
25}
26
27//-------------------------------------------------------------------------
28//      Destructor
29//-------------------------------------------------------------------------
30SimplificationMethod::~SimplificationMethod()
31{
32        delete  heap;
33        delete  [] first_index_submesh;
34
35        delete  mInitialMesh;
36}
37
38//-------------------------------------------------------------------------
39//      Recalculate the cost of the vertices of an edge
40//-------------------------------------------------------------------------
41void SimplificationMethod::compute_pair_info(simplif::pair_info *auxpair)
42{
43        simplif::Vertex *v0 = auxpair->v0;
44        simplif::Vertex *v1 = auxpair->v1;
45
46        simplif::vert_info      *v0_info = vertex_info(v0);
47        simplif::vert_info      *v1_info = vertex_info(v1);
48
49        simplif::Mat4 Q                 =       v0_info->Q + v1_info->Q;
50        simplif::real norm      =       v0_info->norm + v1_info->norm;
51
52        auxpair->cost = simplif::quadrix_pair_target(   Q,
53                                                                                                                                                                                                v0,
54                                                                                                                                                                                                v1,
55                                                                                                                                                                                                auxpair->candidate);
56
57        if ( simplif::will_weight_by_area )
58        {
59                auxpair->cost /= norm;
60        }
61
62        if ( simplif::will_preserve_mesh_quality )
63        {
64                auxpair->cost += pair_mesh_penalty(M0, v0, v1, auxpair->candidate);
65        }
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        //
71        if ( auxpair->isInHeap() )
72        {
73                heap->update(auxpair, (float)-auxpair->cost);
74        }
75        else
76        {
77                heap->insert(auxpair, (float)-auxpair->cost);
78        }
79}
80
81//-------------------------------------------------------------------------
82//      Reasign the new vertex to the adequate face
83//-------------------------------------------------------------------------
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)
91{
92        int nmapped = 0;
93
94        if ( F.vertex(0) == v1 || F.vertex(0) == v2 )
95        {
96                f1 = vnew;  nmapped++;
97        }
98        else
99        {
100                f1 = *F.vertex(0);
101        }
102
103        if ( F.vertex(1) == v1 || F.vertex(1) == v2 )
104        {
105                f2 = vnew;  nmapped++;
106        }
107        else
108        {
109                f2 = *F.vertex(1);
110        }
111
112        if ( F.vertex(2) == v1 || F.vertex(2) == v2 )
113        {
114                f3 = vnew;  nmapped++;
115        }
116        else
117        {
118                f3 = *F.vertex(2);
119        }
120
121        return nmapped;
122}
123
124#define MESH_INVERSION_PENALTY 1e9
125
126//-------------------------------------------------------------------------
127//-------------------------------------------------------------------------
128simplif::real SimplificationMethod::pair_mesh_penalty(simplif::Model& M,
129                                                                                                                                                                                                                        simplif::Vertex *v1,
130                                                                                                                                                                                                                        simplif::Vertex *v2,
131                                                                                                                                                                                                                        simplif::Vec3& vnew)
132{
133        static simplif::face_buffer changed;
134
135        changed.reset();
136
137        M.contractionRegion(v1, v2, changed);
138
139        // real Nsum = 0;
140        simplif::real Nmin = 0;
141
142        for (int i      =       0; i < changed.length(); i++)
143        {
144                simplif::Face& F = *changed(i);
145                simplif::Vec3 f1, f2, f3;
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                {
152                        simplif::Plane Pnew(f1, f2, f3);
153
154                        simplif::real delta =  Pnew.normal() * F.plane().normal();
155
156                        if( Nmin > delta )
157                        {
158                                Nmin = delta;
159                        }
160                }
161        }
162
163        //return (-Nmin) * MESH_INVERSION_PENALTY;
164        if( Nmin < 0.0 )
165        {
166                return MESH_INVERSION_PENALTY;
167        }
168        else
169        {
170                return 0.0;
171        }
172}
173
174//-------------------------------------------------------------------------
175//      Returns true if the givens vertices are a valid pair
176//-------------------------------------------------------------------------
177bool SimplificationMethod::check_for_pair(simplif::Vertex *v0,
178                                                                                                                                                                        simplif::Vertex *v1)
179{
180        const simplif::pair_buffer& pairs = vertex_info(v0)->pairs;
181
182        for(int i=0; i<pairs.length(); i++)
183        {
184                if( pairs(i)->v0==v1 || pairs(i)->v1==v1 )
185                {
186                        return true;
187                }
188        }
189
190        return false;
191}
192
193//-------------------------------------------------------------------------
194//      Create a new pair with two given vertices
195//-------------------------------------------------------------------------
196simplif::pair_info *SimplificationMethod::new_pair(     simplif::Vertex *v0,
197                                                                                                                                                                                                                simplif::Vertex *v1)
198{
199        simplif::pair_info *pair = new simplif::pair_info(v0,v1);
200
201        simplif::vert_info              *v0_info = vertex_info(v0);
202        v0_info->pairs.add(pair);
203
204        simplif::vert_info              *v1_info = vertex_info(v1);
205        v1_info->pairs.add(pair);
206
207        return pair;
208}
209
210//-------------------------------------------------------------------------
211//      Remove a given pair
212//-------------------------------------------------------------------------
213void SimplificationMethod::delete_pair(simplif::pair_info *auxpair)
214{
215        simplif::vert_info      *v0_info = vertex_info(auxpair->v0);
216        simplif::vert_info      *v1_info = vertex_info(auxpair->v1);
217
218        v0_info->pairs.remove(v0_info->pairs.find(auxpair));
219        v1_info->pairs.remove(v1_info->pairs.find(auxpair));
220
221        if (auxpair->isInHeap())
222        {
223                heap->kill(auxpair->getHeapPos());
224        }
225
226        delete auxpair;
227}
228
229//-------------------------------------------------------------------------
230//      Contract a given pair
231//-------------------------------------------------------------------------
232void SimplificationMethod::do_contract( simplif::Model                  &m,
233                                                                                                                                                                simplif::pair_info      *auxpair,
234                                                                                                                                                                int                                                                     obligatory)
235{
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;
241
242        _float3_                                                removed_vert;
243        int                                                                     i;
244        vertex_map_str                  lb;
245        vertex_map_str                  ub;
246
247        //      Stores the simplification step.
248        MeshSimplificationSequence::Step simplifstep;
249       
250        // V0 must be always the alive vertex
251        // V1 must be always the removed vertex
252        if (vnew == (*v0))
253        {
254                //      Coords of the removed vertex.
255                x       =       (*v1)[X];
256                y       =       (*v1)[Y];
257                z       =       (*v1)[Z];
258
259                aux_vert        =       v1;
260        }
261        else
262        {
263                //      Coords of the removed vertex.
264                x       =       (*v0)[X];
265                y       =       (*v0)[Y];
266                z       =       (*v0)[Z];
267
268                //      Simplification step.
269                aux_vert        =       v0;
270                v0      =       v1;
271                v1      =       aux_vert;
272        }
273
274        simplif::vert_info      *v0_info = vertex_info(v0);
275        simplif::vert_info      *v1_info = vertex_info(v1);
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
316        v0_info->Q              += v1_info->Q;
317        v0_info->norm   += v1_info->norm;
318
319        simplif::Vec3 p(vnew);
320
321        //      Perform the actual contraction.
322        static simplif::face_buffer changed;
323
324        changed.reset();
325        m.contract(v0, v1, vnew, changed);
326
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
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++)
336        {
337                if (!changed(i)->isValid())
338                {
339                        _numDelTris++;
340                }
341        }
342
343        int del_index   =       0;
344
345        //      Initialize deleted triangles.
346        simplifstep.mT0 =       -1;
347        simplifstep.mT1 =       -1;
348
349        //      Sets obligatory flag.
350        simplifstep.obligatory  =       obligatory;
351
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++)
358        {
359                simplif::Face *auxface  =       changed(i);
360
361                if (auxface->isValid())
362                {
363                        //      Modified triangles.
364                        simplifstep.mModfaces.push_back(auxface->validID());
365                }
366                else
367                {
368                        //      Removed triangles.
369                        if (_numDelTris == 1)
370                        {
371                                simplifstep.mT0 =       auxface->validID();
372                                simplifstep.mT1 =       auxface->validID();
373                        }
374                        else
375                        {
376                                if(del_index == 0)
377                                {
378                                        simplifstep.mT0 =       auxface->validID();
379                                        del_index++;
380                                }
381                                else
382                                {
383                                        simplifstep.mT1 =       auxface->validID();
384                                }
385                        }
386                }
387        }
388
389        //      Simplification sequence that make reference to the
390        //      simplification method sequence.
391        //decim_data.push_back(simplifstep);
392
393        //      Adds new simplification step.
394        msimpseq->mSteps.push_back(simplifstep);
395
396#ifdef SUPPORT_VCOLOR
397        //      If the vertices are colored, color the new vertex
398        //      using the average of the old colors.
399        v0->props->color += v1->props->color;
400        v0->props->color /= 2;
401#endif
402
403        //      Remove the pair that we just contracted.
404        delete_pair(auxpair);
405
406        //      Recalculate pairs associated with v0.
407        for (i  =       0;      i < v0_info->pairs.length();    i++)
408        {
409                simplif::pair_info *p = v0_info->pairs(i);
410                compute_pair_info(p);
411        }
412
413        //      Process pairs associated with now dead vertex.
414        //      Collect condemned pairs for execution.
415        static simplif::pair_buffer condemned(6);
416
417        condemned.reset();
418
419        //      Recalculate pairs associated with v1.
420        for (i  =       0;      i < v1_info->pairs.length(); i++)
421        {
422                simplif::pair_info *p = v1_info->pairs(i);
423
424                simplif::Vertex *u;
425
426                if ( p->v0 == v1 )
427                {
428                        u = p->v1;
429                }
430                else
431                {
432                        if ( p->v1 == v1)
433                        {
434                                u = p->v0;
435                        }
436                        else
437                        {
438                                std::cerr << "YOW!  This is a bogus pair." << endl;
439                        }
440                }
441
442                if ( !check_for_pair(u, v0) )
443                {
444                        p->v0   =       v0;
445                        p->v1   =       u;
446
447                        v0_info->pairs.add(p);
448                        compute_pair_info(p);
449                }
450                else
451                {
452                        condemned.add(p);
453                }
454        }
455
456        for (i  =       0;      i < condemned.length(); i++)
457        {
458                // Do you have any last requests?
459                delete_pair(condemned(i));
460        }
461
462        //      Safety precaution.
463        v1_info->pairs.reset();
464}
465
466//-------------------------------------------------------------------------
467//-------------------------------------------------------------------------
468bool SimplificationMethod::decimate_quadric(simplif::Vertex *v,
469                                                                                                                                                                                simplif::Mat4& Q)
470{
471        if( vinfo.length() > 0 )
472        {
473                Q = vinfo(v->uniqID)->Q;
474                return true;
475        }
476        else
477        {
478                return false;
479        }
480}
481
482//-------------------------------------------------------------------------
483//      Extract a pair from the heap, concract it and remove it from the heap.
484//-------------------------------------------------------------------------
485void SimplificationMethod::decimate_contract(simplif::Model& m)
486{
487        simplif::heap_node      *top;
488        simplif::pair_info      *pair;
489        simplif::Vertex                 *v0;
490        simplif::Vertex                 *v1;
491        simplif::Vec3                           candidate;
492        _float3_                                                f0;
493        _float3_                                                f1;
494
495        for (;;)
496        {
497                top     =       heap->extract();
498               
499                if (!top)
500                {
501                        return;
502                }
503               
504                pair    =       (simplif::pair_info *)top->obj;
505
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)
516                        {
517                                sharededge      =       true;
518                                break;
519                        }
520                }
521
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                                &&
532                                (vertexMultimap.find(f1) != vertexMultimap.end())
533                                &&
534                                ((*pair->v0) != (*pair->v1)))
535                {
536                        break;
537                }
538
539                //      Debug.
540                cout    <<      "Deleting pair ("
541                                        <<      pair->v0->vID
542                                        <<      "--"
543                                        <<      pair->v1->vID
544                                        <<      ")"
545                                        <<      endl;
546
547                //      Deletes repetitions of pair in heap.
548                delete_pair(pair);
549        }
550
551        //      Copy pair.
552        v0      =       new Vertex(     (*pair->v0)[X],
553                                                                                (*pair->v0)[Y],
554                                                                                (*pair->v0)[Z]);
555
556        v0->vID = pair->v0->vID;
557       
558        v1      =       new Vertex(     (*pair->v1)[X],
559                                                                                (*pair->v1)[Y],
560                                                                                (*pair->v1)[Z]);
561
562        v1->vID = pair->v1->vID;
563
564        candidate       =       pair->candidate;
565
566        //      Debug.
567        cout    <<      "Contracting... "
568                                <<      endl;
569
570        //      Contract main pair.
571        do_contract(m, pair, 0);
572
573        //      Attempt to maintain valid vertex information.
574        M0.validVertCount--;
575
576        //      Find twin vertices to the contracted one and contract them.
577        removeTwinVertices(m,v0,v1,candidate);
578
579        //      Free Memory.
580        delete  v0;
581        delete  v1;
582}
583
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)
591{
592        bool                                                            twin_found;
593        simplif::Edge                           *edge;
594        simplif::pair_info      *pair;
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;
604        simplif::vert_info      new_vert_info;
605        Geometry::GeoVertex     vertex_added;
606        simplif::Vertex                 *take_bone_from_vert;
607        float                                                           x,y,z;
608
609        //      Gets the vertex that is not the candidate.
610        if ((*v1) == candidate)
611        {
612                vert                                                            = v0;
613                v0                                                                      =       v1;
614                v1                                                                      =       vert;
615        }
616
617        take_bone_from_vert = v0;
618
619        f0      =       _float3_((*v0)[X],(*v0)[Y],(*v0)[Z]);
620        f1      =       _float3_((*v1)[X],(*v1)[Y],(*v1)[Z]);
621
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)
630                {
631                        cout    <<      "Lonely: "
632                                <<      lonely_vert->vID
633                                <<      endl;
634                }
635
636                for (int        i       =       0;      i < lonely_vert->edgeUses().length();   i++)
637                {
638                        econ    =       lonely_vert->edgeUses()(i);
639
640                        if (((*econ->org()) == (*v0))
641                                        ||
642                                        ((*econ->dest()) == (*v0)))
643                        {
644                                lb      =       vertexMultimap.lower_bound(f0);
645                                ub      =       vertexMultimap.upper_bound(f0);
646
647                                //      For each vertex.
648                                while   (lb != ub)
649                                {
650                                        //      If removed vertex is found.
651                                        if (((*lb).second == econ->org()->vID)
652                                                        ||
653                                                        ((*lb).second == econ->dest()->vID))
654                                        {
655                                                twin_found      =       true;
656
657                                                //      Break while.
658                                                lb      =       ub;
659                                        }
660                                        else
661                                        {
662                                                //      Next iteration.
663                                                lb++;
664                                        }
665                                }
666
667                                break;
668                        }
669                }
670
671                //      If a twin edge has been found.
672                if (twin_found)
673                {
674                        //      Debug.
675                        cout    <<      "Twin Contracted..."    <<      endl;
676
677                        //      Extract twin edge from heap.
678                        pair    =       new_pair(econ->org(),econ->dest());
679
680                        //      Copy candidate.
681                        pair->candidate =       candidate;
682
683                        pair->notInHeap();
684
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;
693
694                        new_vert        =       m.newVertex(candidate[X],candidate[Y],candidate[Z]);
695
696                        //      Add new vert to multimap.
697                        x       =       (*new_vert)[X];
698                        y       =       (*new_vert)[Y];
699                        z       =       (*new_vert)[Z];
700
701                        //      Adds new vertex to multimap.
702                        vertexMultimap.insert(vertex_pair(_float3_(x,y,z),new_vert->vID));
703
704                        //      Creates new edge.
705                        edge    =       m.newEdge(new_vert,lonely_vert);
706
707                        //      We assume here there are the same number of vertices
708                        //      and texture coordinates and normals.
709
710                        // Assign a texture coordinate for the vertex.
711                        simplif::Vec2 newtexcoord = m.texcoord(lonely_vert->vID);
712                        m.in_TexCoord(newtexcoord);
713
714                        //      Assign a normal coordinate for the vbertex.
715                        simplif::Vec3 newnormal = m.normal(lonely_vert->vID);
716                        m.in_Normal(newnormal);
717
718                        //      Adds new vertex information to simplification sequence.
719                        vertex_added.id                         =       new_vert->vID;
720
721                        vertex_added.bonefrom   =       take_bone_from_vert->vID;
722
723                        vertex_added.position   =       Vector3(candidate[X],
724                                                                                                                                                        candidate[Y],
725                                                                                                                                                        candidate[Z]);
726
727                        simplif::Vec2 tc                        = m.texcoord(new_vert->vID);
728                        vertex_added.texcoord   =       Vector2(tc[X],tc[Y]);
729
730                        simplif::Vec3 vn                = m.normal(new_vert->vID);
731                        vertex_added.normal     =       Vector3(vn[X],vn[Y],vn[Z]);
732
733                        msimpseq->mNewVertices.push_back(vertex_added);
734
735                        //      Debug.
736                        vert_info               *new_vert_info;
737                        new_vert_info   =       new vert_info();
738
739                        vinfo.add(new_vert_info);
740                        //------------------------------
741
742                        pair                                            =       new_pair(new_vert,lonely_vert);
743                        pair->candidate =       candidate;
744                        pair->notInHeap();
745
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;
765
766                        //      Contract new pair.
767                        do_contract(m, pair, 1);
768                        M0.validVertCount--;
769                }
770        }
771}
772
773//-------------------------------------------------------------------------
774//-------------------------------------------------------------------------
775simplif::real SimplificationMethod::decimate_error(simplif::Vertex *v)
776{
777        simplif::vert_info      *info = vertex_info(v);
778
779        simplif::real err = simplif::quadrix_evaluate_vertex(*v, info->Q);
780
781        if ( simplif::will_weight_by_area )
782        {
783                err /= info->norm;
784        }
785
786        return err;
787}
788
789//-------------------------------------------------------------------------
790//      Extract the minimum cost of the the valid nodes (not simplified)
791//-------------------------------------------------------------------------
792simplif::real SimplificationMethod::decimate_min_error()
793{
794        simplif::heap_node *top;
795        simplif::pair_info *pair;
796
797        for(;;)
798        {
799                top = heap->top();
800               
801                if(!top)
802                {
803                        return -1.0;
804                }
805
806                pair = (simplif::pair_info *)top->obj;
807
808                if(pair->isValid())
809                {
810                        break;
811                }
812
813                top = heap->extract();
814                delete_pair(pair);
815        }
816
817        return pair->cost;
818}
819
820//-------------------------------------------------------------------------
821//      Returns the maximum error by vertex
822//-------------------------------------------------------------------------
823simplif::real SimplificationMethod::decimate_max_error(simplif::Model& m)
824{
825        simplif::real max_err = 0;
826
827        for(int i=0; i<m.vertCount(); i++)
828                if(m.vertex(i)->isValid())
829                {
830                        max_err = MAX(max_err, decimate_error(m.vertex(i)));
831                }
832
833        return max_err;
834}
835
836//-------------------------------------------------------------------------
837//      Initializations
838//-------------------------------------------------------------------------
839void SimplificationMethod::decimate_init(       simplif::Model  &m,
840                                                                                                                                                                        simplif::real   limit)
841{
842        int i,j;
843
844        //      Reserve memory for vert_info array.
845
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
854        if (simplif::will_use_vertex_constraint)
855        {
856                //      For each vertex, calculate contraints.
857                for     (i      =       0;      i < m.vertCount();      i++)
858                {
859                        simplif::Vertex *v      =       m.vertex(i);
860                       
861                        if (v->isValid())
862                        {
863                                vertex_info(v)->Q = simplif::quadrix_vertex_constraint(*v);
864                        }
865                }
866        }
867
868        //      For each face, recalculate constraints.
869        for (i  =       0;      i < m.faceCount();      i++)
870        {
871                if (m.face(i)->isValid())
872                {
873                        if (simplif::will_use_plane_constraint)
874                        {
875                                simplif::Mat4 Q = simplif::quadrix_plane_constraint(*m.face(i));
876                                simplif::real norm = 0.0;
877
878                                if (simplif::will_weight_by_area)
879                                {
880                                        norm    =               m.face(i)->area();
881                                        Q                       *=      norm;
882                                }
883
884                                for (j  =       0;      j < 3;  j++)
885                                {
886                                        vertex_info(m.face(i)->vertex(j))->Q            +=      Q;
887                                        vertex_info(m.face(i)->vertex(j))->norm +=      norm;
888                                }
889                        }
890                }
891        }
892
893        if (simplif::will_constrain_boundaries)
894        {
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)))
899                        {
900                                simplif::Mat4 B = simplif::quadrix_discontinuity_constraint(m.edge(i));
901                                simplif::real norm = 0.0;
902
903                                if (simplif::will_weight_by_area)
904                                {
905                                        norm    =               simplif::norm2(*m.edge(i)->org() - *m.edge(i)->dest());
906                                        B                       *=      norm;
907                                }
908
909                                B *= simplif::boundary_constraint_weight;
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;
915                        }
916                }
917        }
918
919        //      Create heap.
920        heap = new simplif::Heap(m.validEdgeCount);
921
922        int pair_count = 0;
923
924        //      For each edge, add pairs to heap.
925        for (i  =       0;      i < m.edgeCount();      i++)
926        {
927                if (m.edge(i)->isValid())
928                {
929                        simplif::pair_info *pair = new_pair(m.edge(i)->org(),
930                                                                                                                                                                        m.edge(i)->dest());
931
932                        //pointers_to_remove.push_back(pair);
933
934                        compute_pair_info(pair);
935                        pair_count++;
936                }
937        }
938
939        if (limit < 0)
940        {
941                limit   =       m.bounds.radius * 0.05;
942        }
943       
944        proximity_limit =       limit * limit;
945       
946        if (proximity_limit > 0)
947        {
948                simplif::ProxGrid grid(m.bounds.min, m.bounds.max, limit);
949               
950                //      Add points to grid.
951                for (i  =       0;      i < m.vertCount();      i++)
952                {
953                        grid.addPoint(m.vertex(i));
954                }
955
956                simplif::buffer<simplif::Vec3 *> nearby(32);
957               
958                //      For each vertex.
959                for (i  =       0;      i < m.vertCount();      i++)
960                {
961                        nearby.reset();
962                        grid.proximalPoints(m.vertex(i), nearby);
963
964                        for (j  =       0;      j < nearby.length();    j++)
965                        {
966                                simplif::Vertex *v1 = m.vertex(i);
967                                simplif::Vertex *v2 = (simplif::Vertex *)nearby(j);
968
969                                if (v1->isValid() && v2->isValid())
970                                {
971#ifdef SAFETY
972                                        assert(pair_is_valid(v1,v2));
973#endif
974                                        if (!check_for_pair(v1,v2))
975                                        {
976                                                simplif::pair_info *pair = new_pair(v1,v2);
977                                                compute_pair_info(pair);
978                                                pair_count++;
979                                        }
980                                }
981                        }
982                }
983        }
984}
985
986//-------------------------------------------------------------------------
987//      Initilizations
988//-------------------------------------------------------------------------
989void SimplificationMethod::simplifmethod_init(void)
990{
991        // Change mesh structure.
992        generateSimplifModel();
993               
994        M0.bounds.complete();
995
996        initialVertCount = M0.vertCount();
997        initialEdgeCount = M0.edgeCount();
998        initialFaceCount = M0.faceCount();
999
1000        // Get rid of degenerate faces.
1001        for (int        i       =       0;      i < M0.faceCount();     i++)
1002        {
1003                if (!M0.face(i)->plane().isValid())
1004                {
1005                        M0.killFace(M0.face(i));
1006                }
1007        }
1008
1009        M0.removeDegeneracy(M0.allFaces());
1010
1011        // Get rid of unused vertices.
1012        for (int        i       =       0;      i < M0.vertCount();     i++)
1013        {
1014                if (M0.vertex(i)->edgeUses().length() == 0)
1015                {
1016                        M0.vertex(i)->kill();
1017                }
1018        }
1019}
1020
1021//-------------------------------------------------------------------------
1022//      Do the contractions till the required LOD (percentage option)
1023//-------------------------------------------------------------------------
1024void SimplificationMethod::simplifmethod_run(int finalfaces,TIPOFUNC upb)
1025{
1026        decimate_init(M0, simplif::pair_selection_tolerance);
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
1038        /*
1039        for (   std::vector<MeshSimplificationSequence::Step>::iterator
1040                                it      =       decim_data.begin();
1041                                it != decim_data.end();
1042                                it++)
1043        {
1044                it->mModfaces.clear();
1045        }
1046       
1047        decim_data.clear();
1048        */
1049
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 )
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
1074//-------------------------------------------------------------------------
1075//      Do the contractions till the required LOD (number of vertices option)
1076//-------------------------------------------------------------------------
1077void SimplificationMethod::simplifmethod_runv(int numvertices,TIPOFUNC upb)
1078{
1079        decimate_init(M0, simplif::pair_selection_tolerance);
1080        unsigned        int     contador        =       0;
1081        int                                             previousValidVertCount;
1082        float                                   percent; // Simplification percentage.
1083
1084        previousValidVertCount  =       0;
1085
1086        percent =       (float)(2.0 * 100.0)
1087                                                /
1088                                                (float)((M0.validFaceCount - numvertices / 3.0));
1089
1090        //      Update progress bar.
1091        if (upb)
1092        {
1093                upb(0.0);
1094        }
1095
1096        /*
1097        for (   std::vector<MeshSimplificationSequence::Step>::iterator
1098                                it      =       decim_data.begin();
1099                                it != decim_data.end();
1100                                it++)
1101        {
1102                it->mModfaces.clear();
1103        }
1104       
1105        decim_data.clear();
1106        */
1107
1108        //      Debug.
1109        cout    <<      "M0.validVertCount:     "       <<      M0.validVertCount       <<      endl;
1110        cout    <<      "numvertices:   "       <<      numvertices     <<      endl;
1111
1112        while(  M0.validVertCount > numvertices /*simplif::face_target*/
1113                        &&
1114                        decimate_min_error() < simplif::error_tolerance
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
1136//-------------------------------------------------------------------------
1137//      Generate simplification model.
1138//-------------------------------------------------------------------------
1139void    SimplificationMethod::generateSimplifModel(void)
1140{
1141        int             face_index      =       0;
1142        int             vertID;
1143        float   x,y,z;
1144
1145        //      For each submesh.
1146        bool added_vertices = false;
1147        for (size_t     i =     0;      i       <       mInitialMesh->mSubMeshCount;    i++)
1148        {
1149                //      If is not a tree leaves submesh.
1150                if (i != indexMeshLeaves)
1151                {
1152                        //      For all the vertices of each submesh.
1153                        for (   size_t  j       =       0;
1154                                        j < mInitialMesh->mSubMesh[i].mVertexBuffer->mVertexCount;
1155                                        j++)
1156                        {
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
1161                                //      If the vertex is not in vertices_map, then is added.
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));
1166
1167                                M0.in_Normal(simplif::Vec3(
1168                                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mNormal[j].x,
1169                                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mNormal[j].y,
1170                                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mNormal[j].z));
1171
1172                                M0.in_TexCoord(simplif::Vec2(
1173                                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mTexCoords[j].x,
1174                                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mTexCoords[j].y));
1175
1176                                added_vertices = true;
1177
1178                                //      Add vertex to multimap.
1179                                vertexMultimap.insert(vertex_pair(_float3_(x,y,z),vertID));
1180                        }
1181                }
1182
1183                //      If is shared vertex buffer object.
1184                if (mInitialMesh->mSubMesh[i].mSharedVertexBuffer && added_vertices)
1185                {
1186                        printf("Shared break");
1187                        break;
1188                }
1189        }
1190
1191        //      For each submesh.
1192        for (size_t     i = 0;  i < mInitialMesh->mSubMeshCount;        i++)
1193        {
1194                if (i != indexMeshLeaves)
1195                {
1196                        for (   Geometry::Index j       =       0;
1197                                                j < mInitialMesh->mSubMesh[i].mIndexCount;
1198                                                j       +=      3)
1199                        {
1200                                //      +1 is required because the first index in the
1201                                //      simplification method is 1
1202                                //      Index of the vertex in vertices_map.
1203                                Geometry::Index index0  =               mInitialMesh->mSubMesh[i].mIndex[j];
1204                               
1205                                Geometry::Index index1  =               mInitialMesh->mSubMesh[i].mIndex[j + 1];
1206                               
1207                                Geometry::Index index2  =               mInitialMesh->mSubMesh[i].mIndex[j + 2];
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;
1217                        }
1218                }
1219        }
1220        number_of_triangles     =       face_index;
1221}
1222
1223//-------------------------------------------------------------------------
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.
1228//-------------------------------------------------------------------------
1229MeshSimplificationSequence *SimplificationMethod::Decimate(     float lod,
1230                                                                                                                                                                                                                                                int simpliftype,
1231                                                                                                                                                                                                                                                TIPOFUNC upb)
1232{
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
1252        simplifmethod_init();
1253
1254        if (simpliftype == 0)
1255        {
1256                //      Percentage option.
1257                simplifmethod_run((int)(number_of_triangles*lod),upb);
1258        }
1259        else
1260        {
1261                //      Number of vertices option.
1262                simplifmethod_runv((int)lod,upb);
1263        }
1264
1265        MAPAINDIND *unique_verts_inds_by_geo =
1266                new MAPAINDIND[mInitialMesh->mSubMeshCount];
1267
1268        MAPAINDIND      shared_vertex_map;
1269
1270        REPINDLIST *ver_inds_rep_by_geo = new REPINDLIST[mInitialMesh->mSubMeshCount];
1271
1272        //      Index counter by submesh.
1273        int *inextvert = new int[mInitialMesh->mSubMeshCount];
1274
1275        for (unsigned int       i = 0;  i < mInitialMesh->mSubMeshCount;        i++)
1276        {
1277                inextvert[i] = 0;
1278        }
1279
1280        //      Construct the model.
1281        std::cout << "M0.faceCount(): " << M0.faceCount() << std::endl;
1282
1283        //      For each face.
1284        for (int        i = 0;  i < M0.faceCount();     i++)
1285        {
1286                if (M0.face(i)->isValid())
1287                {
1288                        simplif::Face *auxface  =       M0.face(i);
1289
1290                        //      Determine to which submesh pertains the triangle.
1291                        int igeo = auxface->igeo;
1292
1293                        //      For each index of the face.
1294                        for (size_t     j = 0; j < 3; j++)
1295                        {
1296                                if (shared_vertex)
1297                                {
1298                                        //      Insert to each submesh its triangles.
1299                                        findit =        shared_vertex_map.find(auxface->vertex(j)->vID);
1300
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);
1327                        }
1328                }
1329        }
1330
1331        //      Output simplified mesh.
1332        mGeoMesh                                                                =       new Mesh();
1333        mGeoMesh->mVertexBuffer =       new     VertexBuffer();
1334
1335        mGeoMesh->mSubMeshCount = mInitialMesh->mSubMeshCount;
1336
1337        //      Memory allocation for the submeshes.
1338        mGeoMesh->mSubMesh = new SubMesh[mInitialMesh->mSubMeshCount];
1339
1340        //      Fill up bounding box settings.
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;
1349
1350        //      Copy skeleton name.
1351        if (mInitialMesh->hasSkeleton)
1352        {
1353                mGeoMesh->hasSkeleton   =       true;
1354
1355                strcpy(mGeoMesh->mSkeletonName,mInitialMesh->mSkeletonName);
1356        }
1357
1358        //      If the mesh has shared vertex.
1359        if (shared_vertex)
1360        {
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())
1390                {
1391                        bone.vertexIndex        =       (*it).second;
1392
1393                        mGeoMesh->mBones.push_back(bone);
1394                        vertex_found    =       true;
1395                }
1396        }
1397        //------------------------------------------------------------//
1398
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{
1606        bool copiedShared = false;
1607
1608        //      For each submesh.
1609        for (size_t     i = 0;  i < mInitialMesh->mSubMeshCount;        i++)
1610        {
1611                mGeoMesh->mSubMesh[i].mStripCount       =       0;
1612                mGeoMesh->mSubMesh[i].mStrip                    =       NULL;
1613
1614                mGeoMesh->
1615                        mSubMesh[i].mSharedVertexBuffer =       false;
1616
1617                strcpy( mGeoMesh->mSubMesh[i].mMaterialName,
1618                                mInitialMesh->mSubMesh[i].mMaterialName);
1619
1620                //      Copy submesh bones.
1621                if (!mInitialMesh->mSubMesh[i].mBones.empty())
1622                {
1623                        for (   unsigned int j = 0;
1624                                                j < mInitialMesh->mSubMesh[i].mBones.size();
1625                                                j++)
1626                        {
1627                                mGeoMesh->mSubMesh[i].mBones.push_back(mInitialMesh->
1628                                                mSubMesh[i].mBones[j]);
1629                        }
1630                }
1631
1632                if (i != indexMeshLeaves)
1633                {
1634                        //      Indices vectors.
1635                        mGeoMesh->mSubMesh[i].mIndexCount       =       ver_inds_rep_by_geo[i].size();
1636
1637                        mGeoMesh->mSubMesh[i].mIndex                    =       new Geometry::Index[mGeoMesh->
1638                                mSubMesh[i].mIndexCount];
1639
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.
1644                                mGeoMesh->mSubMesh[i].mIndex[j] =
1645                                        unique_verts_inds_by_geo[i][ver_inds_rep_by_geo[i][j]];
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
1666                        mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount       =
1667                                unique_verts_inds_by_geo[i].size();
1668
1669                        mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexInfo        =
1670                                mInitialMesh->mSubMesh[i].mVertexBuffer->mVertexInfo;
1671
1672                        //      Allocate memory for position, normal and texutre coordinates.
1673                        mGeoMesh->mSubMesh[i].mVertexBuffer->mPosition  =
1674                                new Vector3[mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount];
1675
1676                        mGeoMesh->mSubMesh[i].mVertexBuffer->mNormal            =
1677                                new Vector3[mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount];
1678
1679                        mGeoMesh->mSubMesh[i].mVertexBuffer->mTexCoords =
1680                                new Vector2[mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount];
1681
1682                        for (MAPAINDIND::iterator mapit = unique_verts_inds_by_geo[i].begin();
1683                                                mapit != unique_verts_inds_by_geo[i].end();
1684                                                mapit++)
1685                        {
1686                                //      Key and value.
1687                                int isrc = mapit->first;
1688                                int idst = mapit->second;
1689
1690                                //      Vertex coordinate.
1691                                //      Construction of the submeshes.
1692                                Vector3 v3(     (Real)M0.vertex(isrc)->operator [](0),
1693                                                (Real)M0.vertex(isrc)->operator [](1),
1694                                                (Real)M0.vertex(isrc)->operator [](2));
1695
1696                                mGeoMesh->mSubMesh[i].mVertexBuffer->mPosition[idst]    =       v3;
1697
1698                                //      Normal coordinates.
1699                                Vector3 v3n(    (Real)M0.normal(isrc)(0),
1700                                                (Real)M0.normal(isrc)(1),
1701                                                (Real)M0.normal(isrc)(2));
1702
1703                                mGeoMesh->mSubMesh[i].mVertexBuffer->mNormal[idst]      =       v3n;
1704
1705                                //      Texture coordinates.
1706                                Vector2 v2(     (Real)M0.texcoord(isrc)(0),
1707                                                (Real)M0.texcoord(isrc)(1));
1708
1709                                mGeoMesh->mSubMesh[i].mVertexBuffer->mTexCoords[idst]   =       v2;
1710                        }
1711                }
1712                //      Leaves mesh.
1713                else
1714                {
1715                        mGeoMesh->mSubMesh[i].mIndexCount       =       
1716                                                                                                                mInitialMesh->mSubMesh[i].mIndexCount;
1717
1718                        mGeoMesh->mSubMesh[i].mIndex    =               
1719                                                new Geometry::Index[mGeoMesh->mSubMesh[i].mIndexCount];
1720
1721                        //      Copy the leaves submesh indexes.
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];
1727                        }
1728
1729                        //      Copy the leaves submesh vertices.
1730                        mGeoMesh->mSubMesh[i].mVertexBuffer     =       new VertexBuffer();
1731
1732                        mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount       =
1733                                mInitialMesh->mSubMesh[i].mVertexBuffer->mVertexCount;
1734
1735                        mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexInfo        =
1736                                mInitialMesh->mSubMesh[i].mVertexBuffer->mVertexInfo;
1737
1738                        //      Allocate memory for position, normal and texture coordinates.
1739                        mGeoMesh->mSubMesh[i].mVertexBuffer->mPosition  =
1740                                new Vector3[mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount];
1741
1742                        mGeoMesh->mSubMesh[i].mVertexBuffer->mNormal    =
1743                                new Vector3[mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount];
1744
1745                        mGeoMesh->mSubMesh[i].mVertexBuffer->mTexCoords =
1746                                new Vector2[mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount];
1747
1748                        for (   unsigned int j = 0;
1749                                        j < mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount;
1750                                        j++)
1751                        {
1752                                //      Position.
1753                                mGeoMesh->mSubMesh[i].mVertexBuffer->mPosition[j].x     =
1754                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mPosition[j].x;
1755
1756                                mGeoMesh->mSubMesh[i].mVertexBuffer->mPosition[j].y     =
1757                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mPosition[j].y;
1758
1759                                mGeoMesh->mSubMesh[i].mVertexBuffer->mPosition[j].z     =
1760                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mPosition[j].z;
1761
1762                                //      Normals.
1763                                mGeoMesh->mSubMesh[i].mVertexBuffer->mNormal[j].x       =
1764                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mNormal[j].x;
1765
1766                                mGeoMesh->mSubMesh[i].mVertexBuffer->mNormal[j].y       =
1767                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mNormal[j].y;
1768
1769                                mGeoMesh->mSubMesh[i].mVertexBuffer->mNormal[j].z       =
1770                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mNormal[j].z;
1771
1772                                //      Textures.
1773                                mGeoMesh->mSubMesh[i].mVertexBuffer->mTexCoords[j].x    =
1774                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mTexCoords[j].x;
1775
1776                                mGeoMesh->mSubMesh[i].mVertexBuffer->mTexCoords[j].y    =
1777                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mTexCoords[j].y;
1778                        }
1779                }
1780        }
1781}
1782
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();
1791
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;
1798
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++)
1816                {
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]];
1820                }
1821        }
1822
1823        mGeoMesh->mVertexBuffer->mVertexCount   =       shared_vertex_map.size();
1824
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        }
1867}
1868
1869//-------------------------------------------------------------------------
1870//      Set submesh leaves.
1871//-------------------------------------------------------------------------
1872void SimplificationMethod::setMeshLeaves(int meshLeaves)
1873{
1874        indexMeshLeaves =       meshLeaves;
1875}
1876
1877//      Gets mesh simplified.
1878Mesh    *       SimplificationMethod::GetMesh()
1879{
1880        //      Delete void submeshes.
1881        eraseVoidSubMeshes(mGeoMesh);
1882
1883        return  mGeoMesh;
1884}
1885
Note: See TracBrowser for help on using the repository browser.