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

Revision 2194, 45.4 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::vert_info& v0_info = vertex_info(v0);
200        simplif::vert_info& v1_info = vertex_info(v1);
201
202        simplif::pair_info *pair = new simplif::pair_info(v0,v1);
203
204        v0_info.pairs.add(pair);
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        /*
610        if ((*v0) != (*v1))
611        {
612        */
613                //      Gets the vertex that is not the candidate.
614                if ((*v1) == candidate)
615                {
616                        vert                                                            = v0;
617                        v0                                                                      =       v1;
618                        v1                                                                      =       vert;
619                }
620
621                take_bone_from_vert = v0;
622
623                f0      =       _float3_((*v0)[X],(*v0)[Y],(*v0)[Z]);
624                f1      =       _float3_((*v1)[X],(*v1)[Y],(*v1)[Z]);
625
626                while ((it = vertexMultimap.find(f1)) != vertexMultimap.end())
627                {
628                        twin_found      =       false;
629
630                        lonely_vert     =       m.vertex((*it).second);
631
632                        //      Debug.
633                        if ((*it).second == 10988)
634                        {
635                                cout    <<      "Lonely: "
636                                                        <<      lonely_vert->vID
637                                                        <<      endl;
638                        }
639                       
640                        for (int        i       =       0;      i < lonely_vert->edgeUses().length();   i++)
641                        {
642                                econ    =       lonely_vert->edgeUses()(i);
643
644                                if (((*econ->org()) == (*v0))
645                                                ||
646                                                ((*econ->dest()) == (*v0)))
647                                {
648                                        lb      =       vertexMultimap.lower_bound(f0);
649                                        ub      =       vertexMultimap.upper_bound(f0);
650
651                                        //      For each vertex.
652                                        while   (lb != ub)
653                                        {
654                                                //      If removed vertex is found.
655                                                if (((*lb).second == econ->org()->vID)
656                                                                ||
657                                                                ((*lb).second == econ->dest()->vID))
658                                                {
659                                                        twin_found      =       true;
660
661                                                        //      Break while.
662                                                        lb      =       ub;
663                                                }
664                                                else
665                                                {
666                                                        //      Next iteration.
667                                                        lb++;
668                                                }
669                                        }
670
671                                        break;
672                                }
673                        }
674
675                        //      If a twin edge has been found.
676                        if (twin_found)
677                        {
678                                //      Debug.
679                                cout    <<      "Twin Contracted..."    <<      endl;
680
681                                //      Extract twin edge from heap.
682                                pair    =       new_pair(econ->org(),econ->dest());
683
684                                //      Copy candidate.
685                                pair->candidate =       candidate;
686
687                                pair->notInHeap();
688
689                                //      Contract twin pair.
690                                do_contract(m, pair, 1);
691                                M0.validVertCount--;
692                        }
693                        else
694                        {
695                                //      Debug.
696                                cout    <<      "Contracting new pair..."       <<      endl;
697
698                                new_vert        =       m.newVertex(candidate[X],candidate[Y],candidate[Z]);
699
700                                //      Add new vert to multimap.
701                                x       =       (*new_vert)[X];
702                                y       =       (*new_vert)[Y];
703                                z       =       (*new_vert)[Z];
704
705                                simplif::Vertex *v;
706
707                                //      Debug.
708                                if (new_vert->vID == 10988)
709                                {
710                                        cout    <<      "["
711                                                                <<      x
712                                                                <<      ","
713                                                                <<      y
714                                                                <<      ","
715                                                                <<      z
716                                                                <<      "]"
717                                                                <<      endl;
718
719                                       
720                                        v       =       m.vertex(10988);
721                                }
722
723                                //      Adds new vertex to multimap.
724                                vertexMultimap.insert(vertex_pair(_float3_(x,y,z),new_vert->vID));
725
726                                //      Creates new edge.
727                                edge    =       m.newEdge(new_vert,lonely_vert);
728
729                                //      We assume here there are the same number of vertices
730                                //      and texture coordinates and normals.
731
732                                // Assign a texture coordinate for the vertex.
733                                simplif::Vec2 newtexcoord = m.texcoord(lonely_vert->vID);
734                                m.in_TexCoord(newtexcoord);
735
736                                //      Assign a normal coordinate for the vbertex.
737                                simplif::Vec3 newnormal = m.normal(lonely_vert->vID);
738                                m.in_Normal(newnormal);
739
740                                //      Adds new vertex information to simplification sequence.
741                                vertex_added.id                         =       new_vert->vID;
742
743                                vertex_added.bonefrom   =       take_bone_from_vert->vID;
744
745                                vertex_added.position   =       Vector3(candidate[X],
746                                                                                                                                                                candidate[Y],
747                                                                                                                                                                candidate[Z]);
748
749                                simplif::Vec2 tc                        = m.texcoord(new_vert->vID);
750                                vertex_added.texcoord   =       Vector2(tc[X],tc[Y]);
751
752                                simplif::Vec3 vn                = m.normal(new_vert->vID);
753                                vertex_added.normal     =       Vector3(vn[X],vn[Y],vn[Z]);
754
755                                msimpseq->mNewVertices.push_back(vertex_added);
756
757                                pair                                            =       new_pair(new_vert,lonely_vert);
758                                pair->candidate =       candidate;
759                                pair->notInHeap();
760
761                                //      Debug.
762                                cout    <<      "new: "
763                                                        <<      new_vert->vID
764                                                        <<      "("
765                                                        <<      (*new_vert)[X]
766                                                        <<      ","
767                                                        <<      (*new_vert)[Y]
768                                                        <<      ","
769                                                        <<      (*new_vert)[Z]
770                                                        <<      ") lonely: "
771                                                        <<      lonely_vert->vID
772                                                        <<      "("
773                                                        <<      (*lonely_vert)[X]
774                                                        <<      ","
775                                                        <<      (*lonely_vert)[Y]
776                                                        <<      ","
777                                                        <<      (*lonely_vert)[Z]
778                                                        <<      ")"
779                                                        <<      endl;
780
781                                //      Contract new pair.
782                                do_contract(m, pair, 1);
783                                M0.validVertCount--;
784                        }
785                }
786        /*
787        }
788        */
789}
790
791//-------------------------------------------------------------------------
792//-------------------------------------------------------------------------
793simplif::real SimplificationMethod::decimate_error(simplif::Vertex *v)
794{
795        simplif::vert_info& info = vertex_info(v);
796
797        simplif::real err = simplif::quadrix_evaluate_vertex(*v, info.Q);
798
799    if ( simplif::will_weight_by_area )
800                {
801                        err /= info.norm;
802                }
803
804    return err;
805}
806
807//-------------------------------------------------------------------------
808//      Extract the minimum cost of the the valid nodes (not simplified)
809//-------------------------------------------------------------------------
810simplif::real SimplificationMethod::decimate_min_error()
811{
812        simplif::heap_node *top;
813        simplif::pair_info *pair;
814
815        for(;;)
816        {
817                top = heap->top();
818               
819                if( !top )
820                {
821                        return -1.0;
822                }
823
824                pair = (simplif::pair_info *)top->obj;
825
826                if( pair->isValid() )
827                {
828                        break;
829                }
830
831                top = heap->extract();
832                delete_pair(pair);
833        }
834
835        return pair->cost;
836}
837
838//-------------------------------------------------------------------------
839//      Returns the maximum error by vertex
840//-------------------------------------------------------------------------
841simplif::real SimplificationMethod::decimate_max_error(simplif::Model& m)
842{
843        simplif::real max_err = 0;
844
845        for(int i=0; i<m.vertCount(); i++)
846                if( m.vertex(i)->isValid() )
847                {
848                        max_err = MAX(max_err, decimate_error(m.vertex(i)));
849                }
850
851        return max_err;
852}
853
854//-------------------------------------------------------------------------
855//      Initializations
856//-------------------------------------------------------------------------
857void SimplificationMethod::decimate_init(       simplif::Model  &m,
858                                                                                                                                                                        simplif::real   limit)
859{
860        int i,j;
861
862        //      Reserve memory for vert_info array.
863        vinfo.init(m.vertCount()*2);
864
865        if (simplif::will_use_vertex_constraint)
866        {
867                //      For each vertex, calculate contraints.
868                for     (i      =       0;      i < m.vertCount();      i++)
869                {
870                        simplif::Vertex *v      =       m.vertex(i);
871                       
872                        if (v->isValid())
873                        {
874                                vertex_info(v).Q = simplif::quadrix_vertex_constraint(*v);
875                        }
876                }
877        }
878
879        //      For each face, recalculate constraints.
880        for (i  =       0;      i < m.faceCount();      i++)
881        {
882                if (m.face(i)->isValid())
883                {
884                        if (simplif::will_use_plane_constraint)
885                        {
886                                simplif::Mat4 Q = simplif::quadrix_plane_constraint(*m.face(i));
887                                simplif::real norm = 0.0;
888
889                                if (simplif::will_weight_by_area)
890                                {
891                                        norm    =               m.face(i)->area();
892                                        Q                       *=      norm;
893                                }
894
895                                for (j  =       0;      j < 3;  j++)
896                                {
897                                        vertex_info(m.face(i)->vertex(j)).Q                     +=      Q;
898                                        vertex_info(m.face(i)->vertex(j)).norm  +=      norm;
899                                }
900                        }
901                }
902        }
903
904        if (simplif::will_constrain_boundaries)
905        {
906                //      For each edge, recalculate constraints.
907                for (i  =       0;      i < m.edgeCount();      i++)
908                {
909                        if (m.edge(i)->isValid() && simplif::check_for_discontinuity(m.edge(i)))
910                        {
911                                simplif::Mat4 B = simplif::quadrix_discontinuity_constraint(m.edge(i));
912                                simplif::real norm = 0.0;
913
914                                if (simplif::will_weight_by_area)
915                                {
916                                        norm    =               simplif::norm2(*m.edge(i)->org() - *m.edge(i)->dest());
917                                        B                       *=      norm;
918                                }
919
920                                B *= simplif::boundary_constraint_weight;
921                                vertex_info(m.edge(i)->org()).Q += B;
922                                vertex_info(m.edge(i)->org()).norm += norm;
923                                vertex_info(m.edge(i)->dest()).Q += B;
924                                vertex_info(m.edge(i)->dest()).norm += norm;
925                        }
926                }
927        }
928
929        //      Create heap.
930        heap = new simplif::Heap(m.validEdgeCount);
931
932        int pair_count = 0;
933
934        //      For each edge, add pairs to heap.
935        for (i  =       0;      i < m.edgeCount();      i++)
936        {
937                if (m.edge(i)->isValid())
938                {
939                        simplif::pair_info *pair = new_pair(m.edge(i)->org(), m.edge(i)->dest());
940                        //pointers_to_remove.push_back(pair);
941
942                        compute_pair_info(pair);
943                        pair_count++;
944                }
945        }
946
947        if (limit < 0)
948        {
949                limit   =       m.bounds.radius * 0.05;
950        }
951       
952        proximity_limit =       limit * limit;
953       
954        if (proximity_limit > 0)
955        {
956                simplif::ProxGrid grid(m.bounds.min, m.bounds.max, limit);
957               
958                //      Add points to grid.
959                for (i  =       0;      i < m.vertCount();      i++)
960                {
961                        grid.addPoint(m.vertex(i));
962                }
963
964                simplif::buffer<simplif::Vec3 *> nearby(32);
965               
966                //      For each vertex.
967                for (i  =       0;      i < m.vertCount();      i++)
968                {
969                        nearby.reset();
970                        grid.proximalPoints(m.vertex(i), nearby);
971
972                        for (j  =       0;      j < nearby.length();    j++)
973                        {
974                                simplif::Vertex *v1 = m.vertex(i);
975                                simplif::Vertex *v2 = (simplif::Vertex *)nearby(j);
976
977                                if (v1->isValid() && v2->isValid())
978                                {
979#ifdef SAFETY
980                                        assert(pair_is_valid(v1,v2));
981#endif
982                                        if (!check_for_pair(v1,v2))
983                                        {
984                                                simplif::pair_info *pair = new_pair(v1,v2);
985                                                compute_pair_info(pair);
986                                                pair_count++;
987                                        }
988                                }
989                        }
990                }
991        }
992}
993
994//-------------------------------------------------------------------------
995//      Initilizations
996//-------------------------------------------------------------------------
997void SimplificationMethod::simplifmethod_init(void)
998{
999        // Change mesh structure.
1000        generateSimplifModel();
1001               
1002        M0.bounds.complete();
1003
1004        initialVertCount = M0.vertCount();
1005        initialEdgeCount = M0.edgeCount();
1006        initialFaceCount = M0.faceCount();
1007
1008        // Get rid of degenerate faces.
1009        for (int        i       =       0;      i < M0.faceCount();     i++)
1010        {
1011                if (!M0.face(i)->plane().isValid())
1012                {
1013                        M0.killFace(M0.face(i));
1014                }
1015        }
1016
1017        M0.removeDegeneracy(M0.allFaces());
1018
1019        // Get rid of unused vertices.
1020        for (int        i       =       0;      i < M0.vertCount();     i++)
1021        {
1022                if (M0.vertex(i)->edgeUses().length() == 0)
1023                {
1024                        M0.vertex(i)->kill();
1025                }
1026        }
1027}
1028
1029//-------------------------------------------------------------------------
1030//      Do the contractions till the required LOD (percentage option)
1031//-------------------------------------------------------------------------
1032void SimplificationMethod::simplifmethod_run(int finalfaces,TIPOFUNC upb)
1033{
1034        decimate_init(M0, simplif::pair_selection_tolerance);
1035        unsigned        int     contador        =       0;
1036        float                                   percent; // simplification percentage.
1037
1038        percent =       (float)(2.0 * 100.0) / (M0.validFaceCount - finalfaces);
1039
1040        //      Update progress bar.
1041        if (upb)
1042        {
1043                upb(0.0);
1044        }
1045
1046        /*
1047        for (   std::vector<MeshSimplificationSequence::Step>::iterator
1048                                it      =       decim_data.begin();
1049                                it != decim_data.end();
1050                                it++)
1051        {
1052                it->mModfaces.clear();
1053        }
1054       
1055        decim_data.clear();
1056        */
1057
1058        //      Debug.
1059        cout    <<      "M0.validFaceCount: "   <<      M0.validFaceCount       <<      endl;
1060        cout    <<      "finalfaces: "                          <<      finalfaces                              <<      endl;
1061       
1062        while ( M0.validFaceCount > finalfaces/*simplif::face_target*/
1063                                        && M0.validFaceCount > 1
1064                                        && decimate_min_error() < simplif::error_tolerance )
1065        {
1066                decimate_contract(M0);
1067
1068                //      Update progress bar.
1069                if (upb)
1070                {
1071                        upb(percent);
1072                }
1073        }
1074
1075        //      Update progress bar.
1076        if (upb)
1077        {
1078                upb(100.0);
1079        }
1080}
1081
1082//-------------------------------------------------------------------------
1083//      Do the contractions till the required LOD (number of vertices option)
1084//-------------------------------------------------------------------------
1085void SimplificationMethod::simplifmethod_runv(int numvertices,TIPOFUNC upb)
1086{
1087        decimate_init(M0, simplif::pair_selection_tolerance);
1088        unsigned        int     contador        =       0;
1089        int                                             previousValidVertCount;
1090        float                                   percent; // Simplification percentage.
1091
1092        previousValidVertCount  =       0;
1093
1094        percent =       (float)(2.0 * 100.0)
1095                                                /
1096                                                (float)((M0.validFaceCount - numvertices / 3.0));
1097
1098        //      Update progress bar.
1099        if (upb)
1100        {
1101                upb(0.0);
1102        }
1103
1104        /*
1105        for (   std::vector<MeshSimplificationSequence::Step>::iterator
1106                                it      =       decim_data.begin();
1107                                it != decim_data.end();
1108                                it++)
1109        {
1110                it->mModfaces.clear();
1111        }
1112       
1113        decim_data.clear();
1114        */
1115
1116        //      Debug.
1117        cout    <<      "M0.validVertCount:     "       <<      M0.validVertCount       <<      endl;
1118        cout    <<      "numvertices:   "       <<      numvertices     <<      endl;
1119
1120        while(  M0.validVertCount > numvertices /*simplif::face_target*/
1121                        &&
1122                        decimate_min_error() < simplif::error_tolerance
1123                        &&
1124                        previousValidVertCount  !=      M0.validVertCount)
1125        {
1126                previousValidVertCount  =       M0.validVertCount;
1127
1128                decimate_contract(M0);
1129
1130                //      Update progress bar.
1131                if (upb)
1132                {
1133                        upb(percent);
1134                }
1135        }
1136
1137        //      Update progress bar.
1138        if (upb)
1139        {
1140                upb(100.0);
1141        }
1142}
1143
1144//-------------------------------------------------------------------------
1145//      Generate simplification model.
1146//-------------------------------------------------------------------------
1147void    SimplificationMethod::generateSimplifModel(void)
1148{
1149        int             face_index      =       0;
1150        int             vertID;
1151        float   x,y,z;
1152
1153        //      For each submesh.
1154        bool added_vertices = false;
1155        for (size_t     i =     0;      i       <       mInitialMesh->mSubMeshCount;    i++)
1156        {
1157                //      If is not a tree leaves submesh.
1158                if (i != indexMeshLeaves)
1159                {
1160                        //      For all the vertices of each submesh.
1161                        for (   size_t  j       =       0;
1162                                        j < mInitialMesh->mSubMesh[i].mVertexBuffer->mVertexCount;
1163                                        j++)
1164                        {
1165                                x       =       mInitialMesh->mSubMesh[i].mVertexBuffer->mPosition[j].x;
1166                                y       =       mInitialMesh->mSubMesh[i].mVertexBuffer->mPosition[j].y;
1167                                z       =       mInitialMesh->mSubMesh[i].mVertexBuffer->mPosition[j].z;
1168
1169                                //      If the vertex is not in vertices_map, then is added.
1170                                vertID  =       M0.in_Vertex(simplif::Vec3(
1171                                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mPosition[j].x,
1172                                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mPosition[j].y,
1173                                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mPosition[j].z));
1174
1175                                M0.in_Normal(simplif::Vec3(
1176                                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mNormal[j].x,
1177                                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mNormal[j].y,
1178                                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mNormal[j].z));
1179
1180                                M0.in_TexCoord(simplif::Vec2(
1181                                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mTexCoords[j].x,
1182                                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mTexCoords[j].y));
1183
1184                                added_vertices = true;
1185
1186                                //      Add vertex to multimap.
1187                                vertexMultimap.insert(vertex_pair(_float3_(x,y,z),vertID));
1188                        }
1189                }
1190
1191                //      If is shared vertex buffer object.
1192                if (mInitialMesh->mSubMesh[i].mSharedVertexBuffer && added_vertices)
1193                {
1194                        printf("Shared break");
1195                        break;
1196                }
1197        }
1198
1199        //      For each submesh.
1200        for (size_t     i = 0;  i < mInitialMesh->mSubMeshCount;        i++)
1201        {
1202                if (i != indexMeshLeaves)
1203                {
1204                        for (   Geometry::Index j       =       0;
1205                                                j < mInitialMesh->mSubMesh[i].mIndexCount;
1206                                                j       +=      3)
1207                        {
1208                                //      +1 is required because the first index in the
1209                                //      simplification method is 1
1210                                //      Index of the vertex in vertices_map.
1211                                Geometry::Index index0  =               mInitialMesh->mSubMesh[i].mIndex[j];
1212                               
1213                                Geometry::Index index1  =               mInitialMesh->mSubMesh[i].mIndex[j + 1];
1214                               
1215                                Geometry::Index index2  =               mInitialMesh->mSubMesh[i].mIndex[j + 2];
1216                               
1217                                //      Create a triangle with its indices in vertices_map.
1218                                face_index      =       M0.miin_Face(
1219                                                index0,
1220                                                index1,
1221                                                index2);
1222
1223                                //      igeo allows to identify the submesh that contains the triangle.
1224                                M0.face(face_index)->igeo       =       (int)i;
1225                        }
1226                }
1227        }
1228        number_of_triangles     =       face_index;
1229}
1230
1231//-------------------------------------------------------------------------
1232//      simplifmethod_init is executed to do some initalizations
1233//      simplifmethod_run is executed to do the decimation
1234//      Then, the simpified model is created and the decimation
1235//      information is returned.
1236//-------------------------------------------------------------------------
1237MeshSimplificationSequence *SimplificationMethod::Decimate(     float lod,
1238                                                                                                                                                                                                                                                int simpliftype,
1239                                                                                                                                                                                                                                                TIPOFUNC upb)
1240{
1241        bool                                                                                            shared_vertex;
1242        unsigned        int                                                             vertex_count;
1243        std::map<int,int>::iterator     findit;
1244        //      Initialize      vertex count.
1245        vertex_count    =       0;
1246
1247        //      Initialize shared vertex buffer flag.
1248        shared_vertex   =       false;
1249
1250        //      Determines if the mesh have shared vertex buffer.
1251        for (int i = 0; i < mInitialMesh->mSubMeshCount;        i++)
1252        {
1253                if (mInitialMesh->mSubMesh[i].mSharedVertexBuffer)
1254                {
1255                        shared_vertex   =       true;
1256                        break;
1257                }
1258        }
1259
1260        simplifmethod_init();
1261
1262        if (simpliftype == 0)
1263        {
1264                //      Percentage option.
1265                simplifmethod_run((int)(number_of_triangles*lod),upb);
1266        }
1267        else
1268        {
1269                //      Number of vertices option.
1270                simplifmethod_runv((int)lod,upb);
1271        }
1272
1273        MAPAINDIND *unique_verts_inds_by_geo =
1274                new MAPAINDIND[mInitialMesh->mSubMeshCount];
1275
1276        MAPAINDIND      shared_vertex_map;
1277
1278        REPINDLIST *ver_inds_rep_by_geo = new REPINDLIST[mInitialMesh->mSubMeshCount];
1279
1280        //      Index counter by submesh.
1281        int *inextvert = new int[mInitialMesh->mSubMeshCount];
1282
1283        for (unsigned int       i = 0;  i < mInitialMesh->mSubMeshCount;        i++)
1284        {
1285                inextvert[i] = 0;
1286        }
1287
1288        //      Construct the model.
1289        std::cout << "M0.faceCount(): " << M0.faceCount() << std::endl;
1290
1291        //      For each face.
1292        for (int        i = 0;  i < M0.faceCount();     i++)
1293        {
1294                if (M0.face(i)->isValid())
1295                {
1296                        simplif::Face *auxface  =       M0.face(i);
1297
1298                        //      Determine to which submesh pertains the triangle.
1299                        int igeo = auxface->igeo;
1300
1301                        //      For each index of the face.
1302                        for (size_t     j = 0; j < 3; j++)
1303                        {
1304                                if (shared_vertex)
1305                                {
1306                                        //      Insert to each submesh its triangles.
1307                                        findit =        shared_vertex_map.find(auxface->vertex(j)->vID);
1308
1309                                        if (findit == shared_vertex_map.end())
1310                                        {
1311                                                //      If it is not added... add and map it.
1312                                                shared_vertex_map[auxface->vertex(j)->vID] =    vertex_count;
1313
1314                                                vertex_count++;
1315                                        }
1316                                }
1317                                else
1318                                {
1319                                        //      Insert to each submesh its triangles.
1320                                        findit =        unique_verts_inds_by_geo[igeo].
1321                                                find(auxface->vertex(j)->vID);
1322
1323                                        if (findit == unique_verts_inds_by_geo[igeo].end())
1324                                        {
1325                                                //      If it is not added... add and map it.
1326                                                unique_verts_inds_by_geo[igeo][auxface->vertex(j)->vID] =
1327                                                        inextvert[igeo];
1328
1329                                                inextvert[igeo]++;
1330                                        }
1331                                }
1332
1333                                //      Total number of indices by submesh.
1334                                ver_inds_rep_by_geo[igeo].push_back(auxface->vertex(j)->vID);
1335                        }
1336                }
1337        }
1338
1339        //      Output simplified mesh.
1340        mGeoMesh                                                                =       new Mesh();
1341        mGeoMesh->mVertexBuffer =       new     VertexBuffer();
1342
1343        mGeoMesh->mSubMeshCount = mInitialMesh->mSubMeshCount;
1344
1345        //      Memory allocation for the submeshes.
1346        mGeoMesh->mSubMesh = new SubMesh[mInitialMesh->mSubMeshCount];
1347
1348        //      Fill up bounding box settings.
1349        mGeoMesh->mMeshBounds.maxX                                      =       mInitialMesh->mMeshBounds.maxX;
1350        mGeoMesh->mMeshBounds.maxY                                      =       mInitialMesh->mMeshBounds.maxY;
1351        mGeoMesh->mMeshBounds.maxZ                                      =       mInitialMesh->mMeshBounds.maxZ;
1352        mGeoMesh->mMeshBounds.minX                                      =       mInitialMesh->mMeshBounds.minX;
1353        mGeoMesh->mMeshBounds.minY                                      =       mInitialMesh->mMeshBounds.minY;
1354        mGeoMesh->mMeshBounds.minZ                                      =       mInitialMesh->mMeshBounds.minZ;
1355        mGeoMesh->mMeshBounds.radius                            =       mInitialMesh->mMeshBounds.radius;
1356        mGeoMesh->mMeshBounds.scaleFactor               =       mInitialMesh->mMeshBounds.scaleFactor;
1357
1358        //      Copy skeleton name.
1359        if (mInitialMesh->hasSkeleton)
1360        {
1361                mGeoMesh->hasSkeleton   =       true;
1362
1363                strcpy(mGeoMesh->mSkeletonName,mInitialMesh->mSkeletonName);
1364        }
1365
1366        //      If the mesh has shared vertex.
1367        if (shared_vertex)
1368        {
1369                fillUpSharedVertices(shared_vertex_map,ver_inds_rep_by_geo);
1370        }
1371        else
1372        {
1373                fillUpVertices(unique_verts_inds_by_geo,ver_inds_rep_by_geo);
1374        }
1375
1376        //------------------------//
1377        //      Bones reassignment.             //
1378        //------------------------//
1379        VertexBoneAssignment    bone;
1380        bool                                                                    vertex_found;
1381        MAPAINDIND::iterator    it;
1382
1383        addNewBoneAssignments();
1384
1385        //      For each bone assignment.
1386        for (unsigned int i = 0; i < mInitialMesh->mBones.size(); i++)
1387        {
1388                bone.vertexIndex        =       mInitialMesh->mBones[i].vertexIndex;
1389                bone.boneIndex          =       mInitialMesh->mBones[i].boneIndex;
1390                bone.weight                             =       mInitialMesh->mBones[i].weight;
1391
1392                vertex_found    =       false;
1393
1394                //      If the vertex is found in the simplification model.
1395                if ((it = shared_vertex_map.find(bone.vertexIndex))
1396                                !=
1397                                shared_vertex_map.end())
1398                {
1399                        bone.vertexIndex        =       (*it).second;
1400
1401                        mGeoMesh->mBones.push_back(bone);
1402                        vertex_found    =       true;
1403                }
1404        }
1405        //------------------------------------------------------------//
1406
1407        delete[] unique_verts_inds_by_geo;
1408        delete[] ver_inds_rep_by_geo;
1409        delete[] inextvert;
1410
1411        //      Store the simplification steps in MeshSimplificationSequence.
1412        int     acum    =       0;
1413
1414        for (size_t i   =       0; i < mInitialMesh->mSubMeshCount; i++)
1415        {
1416                if (mInitialMesh->mSubMesh[i].mSharedVertexBuffer)
1417                {
1418                        first_index_submesh[i]  =       0;
1419                }
1420                else
1421                {
1422                        first_index_submesh[i]  =       acum;
1423                }
1424
1425                acum    +=      (int)mInitialMesh->mSubMesh[i].mVertexBuffer->mVertexCount;
1426        }
1427
1428        vector<int>     v0;
1429        vector<int>     v1;
1430        vector<int>     submesh0;
1431        vector<int>     submesh1;
1432
1433        return msimpseq;
1434}
1435
1436//-------------------------------------------------------------------------
1437//      Add bone assignments for new bones.
1438//-------------------------------------------------------------------------
1439void    SimplificationMethod::addNewBoneAssignments()
1440{
1441        size_t  vertex_id;
1442        size_t  bones_count;
1443        VertexBoneAssignment bone;
1444        vector<VertexBoneAssignment>::iterator  it;
1445
1446        //      Copy new vertices.
1447        for (unsigned   int     i       =       0;      i < msimpseq->mNewVertices.size();      i++)
1448        {
1449                vertex_id       =       msimpseq->mNewVertices[i].id;
1450
1451                //      Initialize number of bones.
1452                bones_count     =       mInitialMesh->mBones.size();
1453
1454                // check if my twin-vertex-bone has a bone assignment
1455                // we check only the GeoMesh bones because the lodstrips
1456                // only works for sharedvertex bones.
1457                for (int  j = 0; j < bones_count; j++)
1458                {
1459                        it      =       mInitialMesh->mBones.begin() + j;
1460
1461                        if (it->vertexIndex == msimpseq->mNewVertices[i].bonefrom)
1462                        {
1463                                bone.vertexIndex        = vertex_id;
1464                                bone.boneIndex          = it->boneIndex;
1465                                bone.weight                             = it->weight;
1466
1467                                mInitialMesh->mBones.push_back(bone);
1468                                bones_count++;
1469                        }
1470                }
1471        }
1472}
1473
1474//-------------------------------------------------------------------------
1475//      Erase submeshes that have not indices.
1476//-------------------------------------------------------------------------
1477void    SimplificationMethod::eraseVoidSubMeshes(Mesh   *geoMesh)
1478{
1479        SubMesh *geosubmesh;
1480        size_t  valid_submesh_count;
1481        size_t  submesh;
1482
1483        valid_submesh_count     =       0;
1484
1485        //      For each submesh.
1486        for     (size_t i       =       0; i < geoMesh->mSubMeshCount;  i++)
1487        {
1488                //      Debug.
1489                cout    <<      "Indices of submesh "
1490                                        <<      i
1491                                        <<      ": "
1492                                        <<      geoMesh->mSubMesh[i].mIndexCount
1493                                        <<      endl;
1494
1495                if ((geoMesh->mSubMesh[i].mIndexCount > 0)
1496                                ||
1497                                (indexMeshLeaves == i))
1498                {
1499                        valid_submesh_count++;
1500                }
1501        }
1502
1503        //      Reassign submesh count.
1504        geoMesh->mSubMeshCount  =       valid_submesh_count;
1505
1506        //      Reserve memory for valid submeshes.
1507        geosubmesh      =       new     SubMesh[valid_submesh_count];
1508
1509        submesh =       0;
1510       
1511        //      For each submesh.
1512        for (size_t i = 0; i < geoMesh->mSubMeshCount; i++)
1513        {
1514                //      If leaves submesh is found.
1515                if (indexMeshLeaves == i)
1516                {
1517                        geosubmesh[i].mStripCount       =       0;
1518                        geosubmesh[i].mStrip                    =       NULL;
1519
1520                        geosubmesh[i].mSharedVertexBuffer       =       false;
1521
1522                        strcpy( geosubmesh[i].mMaterialName,
1523                                        mInitialMesh->mSubMesh[i].mMaterialName);
1524
1525                        //      Copy submesh bones.
1526                        if (!mInitialMesh->mSubMesh[i].mBones.empty())
1527                        {
1528                                for (   size_t j = 0;
1529                                                j < mInitialMesh->mSubMesh[i].mBones.size();
1530                                                j++)
1531                                {
1532                                        geosubmesh[i].mBones.push_back(mInitialMesh->
1533                                                        mSubMesh[i].mBones[j]);
1534                                }
1535                        }
1536
1537                        //      Leaves mesh.
1538                        geosubmesh[i].mIndexCount       =       
1539                                mInitialMesh->mSubMesh[i].mIndexCount;
1540
1541                        geosubmesh[i].mIndex    =
1542                                new Geometry::Index[geosubmesh[i].mIndexCount];
1543
1544                        memcpy( geosubmesh[i].mIndex,
1545                                        mInitialMesh->mSubMesh[i].mIndex,
1546                                        mInitialMesh->mSubMesh[i].mIndexCount * sizeof(Index));
1547
1548                        //      Copy the leaves submesh vertices.
1549                        geosubmesh[i].mVertexBuffer     =
1550                                mInitialMesh->mSubMesh[i].mVertexBuffer->Clone();
1551
1552                        //      Next valid submesh.
1553                        submesh++;
1554                }
1555                else if (geoMesh->mSubMesh[i].mIndexCount > 0)
1556                {
1557                        geosubmesh[submesh].mSharedVertexBuffer =
1558                                                                        geoMesh->mSubMesh[i].mSharedVertexBuffer;
1559
1560                        geosubmesh[submesh].mVertexBuffer       =       geoMesh->mVertexBuffer;
1561
1562                        geosubmesh[submesh].mType                               =       geoMesh->mSubMesh[i].mType;
1563
1564                        geosubmesh[submesh].mStripCount =       geoMesh->mSubMesh[i].mStripCount;
1565
1566                        geosubmesh[submesh].mIndexCount =       geoMesh->mSubMesh[i].mIndexCount;
1567
1568                        //      Reserve memory for indices.
1569                        geosubmesh[submesh].mIndex      =
1570                                                                                                        new Index[geosubmesh[submesh].mIndexCount];
1571
1572                        //      Copy indices.
1573                        memcpy( geosubmesh[submesh].mIndex,
1574                                        geoMesh->mSubMesh[i].mIndex,
1575                                        geoMesh->mSubMesh[i].mIndexCount * sizeof(Index));
1576
1577                        //      Reserve memory for array of strips.
1578                        geosubmesh[submesh].mStrip      =
1579                                new Index*[geoMesh->mSubMesh[submesh].mStripCount];
1580
1581                        //      Copy strip list of the submesh.
1582                        for (size_t j = 0; j < geoMesh->mSubMesh[i].mStripCount; j++)
1583                        {
1584                                geosubmesh[submesh].mStrip[j]   =       geoMesh->mSubMesh[i].mStrip[j];
1585                        }
1586
1587                        strcpy( geosubmesh[submesh].mMaterialName,
1588                                        geoMesh->mSubMesh[i].mMaterialName);
1589
1590                        for (size_t     j       =       0;      j < geoMesh->mSubMesh[i].mBones.size(); j++)
1591                        {
1592                                geosubmesh[submesh].mBones
1593                                        .push_back(geoMesh->mSubMesh[i].mBones[j]);
1594                        }
1595
1596                        //      Next valid submesh.
1597                        submesh++;
1598                }
1599        }
1600
1601        //      Delete submeshes.
1602        delete  []geoMesh->mSubMesh;
1603
1604        geoMesh->mSubMesh       =       geosubmesh;
1605}
1606
1607//-------------------------------------------------------------------------
1608//      Fill up vertices.
1609//-------------------------------------------------------------------------
1610void    SimplificationMethod::fillUpVertices(
1611                                                                                                                        MAPAINDIND      *unique_verts_inds_by_geo,
1612                                                                                                                        REPINDLIST      *ver_inds_rep_by_geo)
1613{
1614        bool copiedShared = false;
1615
1616        //      For each submesh.
1617        for (size_t     i = 0;  i < mInitialMesh->mSubMeshCount;        i++)
1618        {
1619                mGeoMesh->mSubMesh[i].mStripCount       =       0;
1620                mGeoMesh->mSubMesh[i].mStrip                    =       NULL;
1621
1622                mGeoMesh->
1623                        mSubMesh[i].mSharedVertexBuffer =       false;
1624
1625                strcpy( mGeoMesh->mSubMesh[i].mMaterialName,
1626                                mInitialMesh->mSubMesh[i].mMaterialName);
1627
1628                //      Copy submesh bones.
1629                if (!mInitialMesh->mSubMesh[i].mBones.empty())
1630                {
1631                        for (   unsigned int j = 0;
1632                                                j < mInitialMesh->mSubMesh[i].mBones.size();
1633                                                j++)
1634                        {
1635                                mGeoMesh->mSubMesh[i].mBones.push_back(mInitialMesh->
1636                                                mSubMesh[i].mBones[j]);
1637                        }
1638                }
1639
1640                if (i != indexMeshLeaves)
1641                {
1642                        //      Indices vectors.
1643                        mGeoMesh->mSubMesh[i].mIndexCount       =       ver_inds_rep_by_geo[i].size();
1644
1645                        mGeoMesh->mSubMesh[i].mIndex                    =       new Geometry::Index[mGeoMesh->
1646                                mSubMesh[i].mIndexCount];
1647
1648                        //      Store the indices.
1649                        for (unsigned int       j = 0;  j < mGeoMesh->mSubMesh[i].mIndexCount;  j++)
1650                        {
1651                                //      Obtain the indices that point at VertexBuffer.
1652                                mGeoMesh->mSubMesh[i].mIndex[j] =
1653                                        unique_verts_inds_by_geo[i][ver_inds_rep_by_geo[i][j]];
1654                        }
1655
1656                        //      Copy the vertices.
1657                        if (mGeoMesh->mSubMesh[i].mSharedVertexBuffer)
1658                        {
1659                                //      Shared vertices.
1660                                if (!copiedShared)
1661                                {
1662                                        mGeoMesh->mVertexBuffer = new VertexBuffer();
1663                                        copiedShared                                            = true;
1664                                }
1665
1666                                mGeoMesh->mSubMesh[i].mVertexBuffer = mGeoMesh->mVertexBuffer;
1667                        }
1668                        else
1669                        {
1670                                //      There's no shared vertices.
1671                                mGeoMesh->mSubMesh[i].mVertexBuffer     =       new VertexBuffer();
1672                        }
1673
1674                        mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount       =
1675                                unique_verts_inds_by_geo[i].size();
1676
1677                        mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexInfo        =
1678                                mInitialMesh->mSubMesh[i].mVertexBuffer->mVertexInfo;
1679
1680                        //      Allocate memory for position, normal and texutre coordinates.
1681                        mGeoMesh->mSubMesh[i].mVertexBuffer->mPosition  =
1682                                new Vector3[mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount];
1683
1684                        mGeoMesh->mSubMesh[i].mVertexBuffer->mNormal            =
1685                                new Vector3[mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount];
1686
1687                        mGeoMesh->mSubMesh[i].mVertexBuffer->mTexCoords =
1688                                new Vector2[mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount];
1689
1690                        for (MAPAINDIND::iterator mapit = unique_verts_inds_by_geo[i].begin();
1691                                                mapit != unique_verts_inds_by_geo[i].end();
1692                                                mapit++)
1693                        {
1694                                //      Key and value.
1695                                int isrc = mapit->first;
1696                                int idst = mapit->second;
1697
1698                                //      Vertex coordinate.
1699                                //      Construction of the submeshes.
1700                                Vector3 v3(     (Real)M0.vertex(isrc)->operator [](0),
1701                                                (Real)M0.vertex(isrc)->operator [](1),
1702                                                (Real)M0.vertex(isrc)->operator [](2));
1703
1704                                mGeoMesh->mSubMesh[i].mVertexBuffer->mPosition[idst]    =       v3;
1705
1706                                //      Normal coordinates.
1707                                Vector3 v3n(    (Real)M0.normal(isrc)(0),
1708                                                (Real)M0.normal(isrc)(1),
1709                                                (Real)M0.normal(isrc)(2));
1710
1711                                mGeoMesh->mSubMesh[i].mVertexBuffer->mNormal[idst]      =       v3n;
1712
1713                                //      Texture coordinates.
1714                                Vector2 v2(     (Real)M0.texcoord(isrc)(0),
1715                                                (Real)M0.texcoord(isrc)(1));
1716
1717                                mGeoMesh->mSubMesh[i].mVertexBuffer->mTexCoords[idst]   =       v2;
1718                        }
1719                }
1720                //      Leaves mesh.
1721                else
1722                {
1723                        mGeoMesh->mSubMesh[i].mIndexCount       =       
1724                                                                                                                mInitialMesh->mSubMesh[i].mIndexCount;
1725
1726                        mGeoMesh->mSubMesh[i].mIndex    =               
1727                                                new Geometry::Index[mGeoMesh->mSubMesh[i].mIndexCount];
1728
1729                        //      Copy the leaves submesh indexes.
1730                        for (   unsigned int    j       =       0;
1731                                                j < mGeoMesh->mSubMesh[i].mIndexCount;
1732                                                j++)
1733                        {
1734                                mGeoMesh->mSubMesh[i].mIndex[j] =       mInitialMesh->mSubMesh[i].mIndex[j];
1735                        }
1736
1737                        //      Copy the leaves submesh vertices.
1738                        mGeoMesh->mSubMesh[i].mVertexBuffer     =       new VertexBuffer();
1739
1740                        mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount       =
1741                                mInitialMesh->mSubMesh[i].mVertexBuffer->mVertexCount;
1742
1743                        mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexInfo        =
1744                                mInitialMesh->mSubMesh[i].mVertexBuffer->mVertexInfo;
1745
1746                        //      Allocate memory for position, normal and texture coordinates.
1747                        mGeoMesh->mSubMesh[i].mVertexBuffer->mPosition  =
1748                                new Vector3[mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount];
1749
1750                        mGeoMesh->mSubMesh[i].mVertexBuffer->mNormal    =
1751                                new Vector3[mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount];
1752
1753                        mGeoMesh->mSubMesh[i].mVertexBuffer->mTexCoords =
1754                                new Vector2[mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount];
1755
1756                        for (   unsigned int j = 0;
1757                                        j < mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount;
1758                                        j++)
1759                        {
1760                                //      Position.
1761                                mGeoMesh->mSubMesh[i].mVertexBuffer->mPosition[j].x     =
1762                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mPosition[j].x;
1763
1764                                mGeoMesh->mSubMesh[i].mVertexBuffer->mPosition[j].y     =
1765                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mPosition[j].y;
1766
1767                                mGeoMesh->mSubMesh[i].mVertexBuffer->mPosition[j].z     =
1768                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mPosition[j].z;
1769
1770                                //      Normals.
1771                                mGeoMesh->mSubMesh[i].mVertexBuffer->mNormal[j].x       =
1772                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mNormal[j].x;
1773
1774                                mGeoMesh->mSubMesh[i].mVertexBuffer->mNormal[j].y       =
1775                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mNormal[j].y;
1776
1777                                mGeoMesh->mSubMesh[i].mVertexBuffer->mNormal[j].z       =
1778                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mNormal[j].z;
1779
1780                                //      Textures.
1781                                mGeoMesh->mSubMesh[i].mVertexBuffer->mTexCoords[j].x    =
1782                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mTexCoords[j].x;
1783
1784                                mGeoMesh->mSubMesh[i].mVertexBuffer->mTexCoords[j].y    =
1785                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mTexCoords[j].y;
1786                        }
1787                }
1788        }
1789}
1790
1791//-------------------------------------------------------------------------
1792//      Fill up shared vertices.
1793//-------------------------------------------------------------------------
1794void    SimplificationMethod::fillUpSharedVertices(
1795                                                                                                                MAPAINDIND      &shared_vertex_map,
1796                                                                                                                REPINDLIST      *ver_inds_rep_by_geo)
1797{
1798        mGeoMesh->mVertexBuffer = new VertexBuffer();
1799
1800        //      For each submesh.
1801        for (size_t     i = 0;  i < mInitialMesh->mSubMeshCount;        i++)
1802        {
1803                mGeoMesh->
1804                        mSubMesh[i].mSharedVertexBuffer =       mInitialMesh->
1805                                                                                                                                                                        mSubMesh[i].mSharedVertexBuffer;
1806
1807                //      Reassign submesh vertex buffers.
1808                mGeoMesh->mSubMesh[i].mVertexBuffer = mGeoMesh->mVertexBuffer;
1809
1810                mGeoMesh->mSubMesh[i].mStripCount       =       0;
1811                mGeoMesh->mSubMesh[i].mStrip                    =       NULL;
1812
1813                strcpy( mGeoMesh->mSubMesh[i].mMaterialName,
1814                                mInitialMesh->mSubMesh[i].mMaterialName);
1815
1816                //      Indices vectors.
1817                mGeoMesh->mSubMesh[i].mIndexCount       =       ver_inds_rep_by_geo[i].size();
1818
1819                mGeoMesh->mSubMesh[i].mIndex                    =       new Geometry::Index[mGeoMesh->
1820                                                                                                                                                                                                mSubMesh[i].mIndexCount];
1821
1822                //      Store the indices.
1823                for (unsigned int       j = 0;  j < mGeoMesh->mSubMesh[i].mIndexCount;  j++)
1824                {
1825                        //      Obtain the indices that point at VertexBuffer.
1826                        mGeoMesh->mSubMesh[i].mIndex[j] =
1827                                shared_vertex_map[ver_inds_rep_by_geo[i][j]];
1828                }
1829        }
1830
1831        mGeoMesh->mVertexBuffer->mVertexCount   =       shared_vertex_map.size();
1832
1833        mGeoMesh->mVertexBuffer->mVertexInfo    =       
1834                                                                                                                        mInitialMesh->mVertexBuffer->mVertexInfo;
1835
1836        //      Allocate memory for position, normal and texutre coordinates.
1837        mGeoMesh->mVertexBuffer->mPosition      =
1838                new Vector3[mGeoMesh->mVertexBuffer->mVertexCount];
1839
1840        mGeoMesh->mVertexBuffer->mNormal                =
1841                new Vector3[mGeoMesh->mVertexBuffer->mVertexCount];
1842
1843        mGeoMesh->mVertexBuffer->mTexCoords     =
1844                new Vector2[mGeoMesh->mVertexBuffer->mVertexCount];
1845
1846        for (MAPAINDIND::iterator mapit = shared_vertex_map.begin();
1847                        mapit != shared_vertex_map.end();
1848                        mapit++)
1849        {
1850                //      Key and value.
1851                int isrc = mapit->first;
1852                int idst = mapit->second;
1853
1854                //      Vertex coordinate.
1855                //      Construction of the submeshes.
1856                Vector3 v3(     (Real)M0.vertex(isrc)->operator [](0),
1857                                                                (Real)M0.vertex(isrc)->operator [](1),
1858                                                                (Real)M0.vertex(isrc)->operator [](2));
1859
1860                mGeoMesh->mVertexBuffer->mPosition[idst]        =       v3;
1861
1862                //      Normal coordinates.
1863                Vector3 v3n((Real)M0.normal(isrc)(0),
1864                                                                (Real)M0.normal(isrc)(1),
1865                                                                (Real)M0.normal(isrc)(2));
1866
1867                mGeoMesh->mVertexBuffer->mNormal[idst]  =       v3n;
1868
1869                //      Texture coordinates.
1870                Vector2 v2(     (Real)M0.texcoord(isrc)(0),
1871                                                                (Real)M0.texcoord(isrc)(1));
1872
1873                mGeoMesh->mVertexBuffer->mTexCoords[idst]       =       v2;
1874        }
1875}
1876
1877//-------------------------------------------------------------------------
1878//      Set submesh leaves.
1879//-------------------------------------------------------------------------
1880void SimplificationMethod::setMeshLeaves(int meshLeaves)
1881{
1882        indexMeshLeaves =       meshLeaves;
1883}
1884
1885//      Gets mesh simplified.
1886Mesh    *       SimplificationMethod::GetMesh()
1887{
1888        //      Delete void submeshes.
1889        eraseVoidSubMeshes(mGeoMesh);
1890
1891        return  mGeoMesh;
1892}
1893
Note: See TracBrowser for help on using the repository browser.