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

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