Changeset 1007


Ignore:
Timestamp:
06/09/06 08:24:19 (18 years ago)
Author:
gumbau
Message:
 
Location:
GTP/trunk/Lib/Geom/shared
Files:
1 deleted
16 edited

Legend:

Unmodified
Added
Removed
  • GTP/trunk/Lib/Geom/shared/GTGeometry/GTGeometry.vcproj

    r980 r1007  
    363363                        </File> 
    364364                        <File 
    365                                 RelativePath=".\src\libs\auxiliar.h"> 
     365                                RelativePath=".\include\auxiliar.h"> 
    366366                        </File> 
    367367                        <File 
     
    375375                        </File> 
    376376                        <File 
    377                                 RelativePath=".\src\libs\GeoBase.h"> 
     377                                RelativePath=".\include\GeoBase.h"> 
    378378                        </File> 
    379379                        <File 
  • GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoLodStripsLibrary.h

    r980 r1007  
    7878                        SmallInt        mTotalStrips;           ///Total strips of the multiresolution object. 
    7979                        SmallInt        mTotalVertices; ///Total vertices of the multiresolution object. 
     80                        SmallInt        mMaxVerticesLOD;///Number of vertices of the max LOD. 
    8081                        SmallInt        mTotalChanges;  ///Total changes of the multiresolution object. 
    8182                        SmallInt        mLods;                                  ///Available Lods. 
  • GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoMeshSimpSequence.h

    r986 r1007  
    4848                        struct Step 
    4949                        { 
    50                                 Index mV0, mV1; 
    51                                 Index mT0, mT1; 
    52                                 float x,y,z; 
    53                                 std::vector<Index> mModfaces; 
     50                                Index mV0; 
     51                                Index   mV1; 
     52                                Index mT0; 
     53                                Index   mT1; 
     54                                float x; 
     55                                float   y; 
     56                                float   z; 
     57                                 
     58                                std::vector<Index>      mModfaces; 
    5459 
    5560                                //      Indicates the the step is obligatory to execute 
     
    7883 
    7984#endif 
     85 
  • GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoMeshSimplifier.h

    r980 r1007  
    66#include        "GeoMeshSimpSequence.h" 
    77#include        "vmi_simplifier.h" 
     8#include        "change.h" 
    89 
    910//#include "SimplificationMethod.h" 
     
    8687                void    findVertex(size_t       submesh, size_t index); 
    8788                 
     89                //      Gets the VMI mesh simplification sequence. 
     90                void    GetMeshSimpSequence(); 
     91 
    8892        public: 
    8993 
  • GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoTreeSimplifier.h

    r774 r1007  
    66#include "Hoja.h" 
    77 
    8 #define K1              0.8f //distancia 
    9 #define K2              0.2f // coplanar 
     8#define K1              0.8f //distance factor 
     9#define K2              0.2f //coplanar factor 
     10 
     11class LeafOctree; 
    1012 
    1113namespace Geometry 
     
    3436        public: 
    3537                /// Class constructor. Retrieves a pointer to a valid Mesh object to simplify 
    36                 TreeSimplifier( const Geometry::Mesh    *, 
    37                                                                                 Geometry::TIPOFUNC              upb=0); 
     38                TreeSimplifier(const Geometry::Mesh *, Geometry::TIPOFUNC upb=0); 
    3839 
    3940                /// Class destructor. 
    4041                ~TreeSimplifier(void); 
    41  
    42                 /// Copy constructor 
    43                 //TreeSimplifier(const TreeSimplifier&); 
    44  
    45                 /// Assignment operator 
    46                 //TreeSimplifier& operator =(const TreeSimplifier&); 
    4742 
    4843                /// Starts the simplification process. Receives as a parameter the LOD factor in a range of [0,1]. 
     
    5550                TreeSimplificationSequence *GetSimplificationSequence(); 
    5651 
    57         //private: 
    58                 void Centroh(Hoja       &); 
    59                 void GetNormal(Hoja     &); 
    60                 void DistanciaEntreHojas(void); 
    61                 void CoplanarEntreHojas(FILE*); 
    62                 float DiametroEsferaEnvolvente(); 
    63                 void EstableceCriterio(float); 
     52        private: 
     53                void CalculateLeafCenter(Hoja &); 
     54                void CalculateLeafNormal(Hoja &); 
     55                float CalculateLeafArea(Hoja &) const; 
     56                void CoplanarBetweenLeaves(void); 
     57                float BoundingSphereDiameter() const; 
     58//              void SetCriteria(float);  // to be erased: obsolete! 
     59                void SetCriteriaOptimized(float); 
    6460 
    65                 float max(float, float); 
    66                 float min(float, float); 
     61                float max(float, float) const; 
     62                float min(float, float) const; 
    6763 
    68                 //long int Colapsa (TreeSimplificationSequence *, float); 
    69                 long int Colapsa(float); 
    70                 void DosMayores(float*, int* ); 
    71                 void ElijeVertices(Hoja& , Hoja& , long int); 
    72                 float Hausdorff(Hoja &, Hoja&); 
    73                 float distan(float, float, float, float, float, float); 
    74                 long int MinimaDistancia(void); 
    75                 void NormalizaDistancia(float diametro); 
    76                 void EstableceCriterio2(float, long int); 
    77                 long int MinimoCriterio(void); 
     64                long int Collapse(float); 
     65                void TwoGreater(float*, int* ); 
     66                void ChooseVertices(Hoja& , Hoja& , long int); 
     67                float HausdorffOptimized(const Hoja &, const Hoja&) const; 
     68                float DistanceFromCenters(const Hoja &, const Hoja &) const; 
     69                float distan(float, float, float, float, float, float) const; 
     70                long int MinDistance(void); 
     71                void NormalizeDistance(float diametro); 
     72//              void SetCriteria2(float, long int); obsolete! 
     73                void SetCriteria2Optimized(float, long int); 
     74                long int MinCriteria(void); 
    7875 
    79                 void Mesh2Estructura(   const Geometry::Mesh *, 
    80                                                                                                         Index); 
    81                  
    82                 void EscribeMesh(int); 
     76                void Mesh2Structure(const Geometry::Mesh *,Index); 
     77                void BuildOutputMesh(int); 
     78                void CrossProduct(const float *v1, const float *v2, float *res) const; 
     79                float SquaredModule(const float *v) const; 
    8380 
    84                 Mesh                    *mesh; // objeto mesh simplificado (para la salida) 
     81                Mesh                    *mesh; // simplified mesh object (for output) 
    8582                const                   Mesh *objmesh; 
    8683                float                   (*Vertex)[3]; 
    87                 Hoja                    *Hojasa;  // las activas 
    88                 long int        activas, counth; 
     84                Hoja                    *Leaves; 
     85                long int        activeLeaves, countLeaves; 
    8986                TreeSimplificationSequence      *mtreesimpsequence; 
    9087                 
    91         private: 
    9288                //      Update progress bar. 
    9389                Geometry::TIPOFUNC      mUPB; 
     90 
     91                // the octree used to speed up the simplification process 
     92                LeafOctree *octree; 
     93                void RecursiveCreateLeafOctree(LeafOctree*, int deep); // this is called from CreateLeafNode 
     94                void RecursiveFillOctreeWithLeaves(LeafOctree*); 
     95                LeafOctree* CreateLeafOctree(int deep); // generates a new leaf octree and returns its root node 
     96                int vertex_count; 
     97                LeafOctree ** octree_owning_leaf; 
     98                LeafOctree *GetMinOctreeNodeForLeaf(LeafOctree *start, const Hoja &leaf); 
     99                bool PruneOctree(LeafOctree *); // erases one octree level and translates its leaves to the parent. Returns true if the node itself was pruned 
    94100        }; 
    95101} 
  • GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoLodStripsLibrary.cpp

    r985 r1007  
    327327uint32  LodStripsLibrary::MaxVertices() 
    328328{ 
    329         uint32  number_of_vertices; 
    330  
    331         number_of_vertices      =       mTotalVertices; 
    332  
    333         return  number_of_vertices; 
     329        return  mMaxVerticesLOD; 
    334330} 
    335331 
     
    340336 
    341337        //      Total vertices less total lod. 
    342         number_of_vertices      =       mTotalVertices - (mMaxLod + 1); 
     338        number_of_vertices      =       mMaxVerticesLOD - (mMinLod + 1); 
    343339 
    344340        return  number_of_vertices; 
     
    394390void            LodStripsLibrary::TrimByLod(uint32 minLod, uint32 maxLod) 
    395391{ 
     392        //      Refresh number of vercies of the max lod. 
     393        mMaxVerticesLOD +=      mMaxLod - maxLod; 
     394         
    396395        mMinLod =       minLod; 
    397396        mMaxLod =       maxLod; 
     
    621620                //      Max / Min values for LOD. 
    622621                mLods                                                                                   =       int(p_changes.size()); 
    623                 mMinLod                                                                         =       0; 
    624                 mMaxLod                                                                         =       mLods; 
     622                mMaxLod                                                                         =       0; 
     623                mMinLod                                                                         =       mLods; 
    625624 
    626625                //// CHAPUZA PROVISIONAL: EL ULTIMO ELEMENTO SE REPITE 2 VECES V.v 
     
    632631                } 
    633632 
    634                 mTotalVertices                  =       int(mFileVertices.size()); 
    635                 mTotalStrips                            =       int(mFileStrips.size()); 
    636                 mTotalChanges                           =       int(mFileChangesLOD.size()); 
     633                mTotalVertices          =       int(mFileVertices.size()); 
     634                mMaxVerticesLOD         =       mTotalVertices; 
     635                mTotalStrips                    =       int(mFileStrips.size()); 
     636                mTotalChanges                   =       int(mFileChangesLOD.size()); 
    637637 
    638638                //Copy the data to the structure we will use 
  • GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoMeshSimpSequence.cpp

    r774 r1007  
    6363} 
    6464 
    65 void MeshSimplificationSequence::Save(Serializer &s)  
     65void MeshSimplificationSequence::Save(Serializer &s) 
    6666{ 
    6767        //Stores the simplification sequence in a file 
     
    7878                sprintf(simp,"%u %u %u %u %u %f &", paso.mV0, paso.mV1, paso.mT0, paso.mT1,paso.obligatorio,paso.x); 
    7979                s.WriteData(simp,sizeof(char),strlen(simp)); 
    80                 for (unsigned int j=0; j<paso.mModfaces.size(); j++)  
     80                for (unsigned int j=0; j<paso.mModfaces.size(); j++) 
    8181                { 
    8282                        sprintf(simp," %u",paso.mModfaces.operator [](j)); 
  • GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoMeshSimplifier.cpp

    r985 r1007  
    139139        VMI::bLoadCamerasFromFile = GL_FALSE; 
    140140 
    141         VMI::cameraType = 1; 
     141        VMI::cameraType = 2; 
    142142        VMI::radius = 1.3; 
    143143        VMI::fov = 60.0; 
     
    169169 
    170170        //glutInit(&argc, argv); 
    171         glutInitDisplayMode(GLUT_DEPTH | GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA); /* RGB and Alpha */ 
     171        // RGB and Alpha. 
     172        glutInitDisplayMode(GLUT_DEPTH | GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA);  
    172173        glutInitWindowSize(VMI::width, VMI::height); 
    173174        glutInitWindowPosition(100, 100); 
     
    262263        //      Load a geometry mesh for vmi mesh. 
    263264        loadMesh(); 
     265 
     266        GetMeshSimpSequence(); 
    264267} 
    265268 
     
    287290        loadMesh(); 
    288291 
     292        GetMeshSimpSequence(); 
    289293} 
    290294 
     
    294298//      return mGeoMesh; 
    295299//} 
     300 
     301//--------------------------------------------------------------------------- 
     302//      Gets the VMI mesh simplification sequence. 
     303//--------------------------------------------------------------------------- 
     304void    ViewPointDrivenSimplifier::GetMeshSimpSequence() 
     305{ 
     306        unsigned        int j = 0; 
     307         
     308        MeshSimplificationSequence::Step        current_step; 
     309         
     310        msimpsequence   =       new MeshSimplificationSequence(); 
     311         
     312        //      Debug. 
     313        cout    <<      "GetMeshsimpSequence VMI" 
     314                                <<      endl; 
     315 
     316        //      For each simplification step. 
     317        for (unsigned   int i = 0;      i < VMI::mVMISteps.size();      i++) 
     318        { 
     319                current_step.mV0        =       VMI::mVMISteps[i].mV0; 
     320                current_step.mV1        =       VMI::mVMISteps[i].mV1; 
     321                current_step.mT0        =       VMI::mVMISteps[i].mT0; 
     322                current_step.mT1        =       VMI::mVMISteps[i].mT1; 
     323                 
     324                current_step.x  =       VMI::mVMISteps[i].x; 
     325                current_step.y  =       VMI::mVMISteps[i].y; 
     326                current_step.z  =       VMI::mVMISteps[i].z; 
     327 
     328                current_step.obligatorio        =       VMI::mVMISteps[i].obligatory; 
     329 
     330                //      For each face modificated. 
     331                while (j < VMI::mVMISteps[i].mModfaces.size()) 
     332                { 
     333                        current_step.mModfaces.push_back(VMI::mVMISteps[i].mModfaces[j]); 
     334                         
     335                        j++; 
     336                } 
     337                 
     338                //      Debug. 
     339                cout    <<      "Step " 
     340                                        <<      i 
     341                                        <<      " added." 
     342                                        <<      endl; 
     343                 
     344                msimpsequence->mSteps.push_back(current_step); 
     345        } 
     346} 
    296347 
    297348//--------------------------------------------------------------------------- 
  • GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoTreeSimplifier.cpp

    r998 r1007  
    44#include <iostream> 
    55#include <fstream> 
    6 #include <ctime> 
    76 
    87using namespace Geometry; 
    98using namespace std; 
    109 
    11 TreeSimplifier::TreeSimplifier( const   Mesh    *m, 
    12                                                                                                                                 TIPOFUNC                upb) 
    13 { 
    14         objmesh                                         =       m; 
    15         mtreesimpsequence       =       new Geometry::TreeSimplificationSequence(); 
    16         //mtreesimpsequence=NULL; 
    17         activas =       0; 
    18         counth  =       0; 
    19  
    20         // Mesh de salida 
     10const int VISIT_PARENTS_DEEP=1; 
     11 
     12class LeafOctree 
     13{ 
     14public: 
     15        float left, right, bottom, top, front, back; 
     16        std::vector<int> leaves; ///< leaves that are too much big to fit in any of the child leaves of this octree leaf 
     17        LeafOctree* parent; 
     18        LeafOctree* children[8]; 
     19        bool PointInsideOctree(float x, float y, float z) const { 
     20                return (x>=left && x<=right && y>=bottom && y<=top && z>=front && z<=back); 
     21        } 
     22        bool HasChildren(void) const { return (children[0] && children[1] && children[2] && children[3] && children[4] && children[5] && children[6] && children[7]); } 
     23}; 
     24 
     25TreeSimplifier::TreeSimplifier(const Mesh *m, TIPOFUNC upb) 
     26{ 
     27        objmesh = m; 
     28        mtreesimpsequence = new Geometry::TreeSimplificationSequence(); 
     29        activeLeaves =  0; 
     30        countLeaves      =      0; 
     31 
     32        // Output mesh 
    2133        mesh    =       new Geometry::Mesh(); 
    2234        *mesh   =       *m; 
     
    4153        return  mtreesimpsequence; 
    4254} 
    43  
     55/*#include <time.h> // necesario para gettickcount 
     56#include <map>*/ 
    4457void TreeSimplifier::Simplify(Real lodfactor,   Index meshLeaves) 
    4558{ 
    46         // paramlod indica el número de vértices 
    4759        long    int     totalv; 
    48         long    int     hnueva; 
    49         float                   diam; 
    50  
    51         //      2006-02-22 
    52         float                   percent; 
    53         long    int     update; 
    54          
     60        long    int     newleaf; 
     61        float   diam; 
     62 
    5563        totalv  =       0; 
    56          
    57         Mesh2Estructura(objmesh, meshLeaves); 
    58          
    59         diam = DiametroEsferaEnvolvente(); 
    60  
    61         EstableceCriterio(diam); 
    62  
    63         float paramlod = lodfactor * activas * 0.01f; 
    64  
    65         // El paramlod lo uso como condición de parada de la simplificación 
    66         if (paramlod >= 6) 
    67         { 
    68                 //      2006-02-22 
    69                 update  =       long((activas - (6 * paramlod)) / 80); 
    70                 percent =       0.5; 
    71                  
    72                 while ( activas > (6*paramlod)) 
    73                 { 
    74                         //      2006-02-22 
    75                         if (mUPB        &&      (((long int)(activas - (6 * paramlod)) % update) == 0)) 
    76                         { 
    77                                 mUPB(percent); 
    78                         } 
    79                          
    80                         hnueva  =       Colapsa(diam); 
    81                          
    82                         EstableceCriterio2(diam, hnueva); 
    83                 } 
    84         } 
    85         else 
    86         { 
    87                 //      2006-02-22 
    88                 update  =       (activas - 6) / 80; 
    89                 percent =       0.5; 
    90                  
    91                 while ( activas > 6)  
    92                 { 
    93                         //      2006-02-22 
    94                         if (mUPB        &&      (((activas - 6) % update) == 0)) 
    95                         { 
    96                                 mUPB(percent); 
    97                         } 
    98                          
    99                         hnueva  =       Colapsa(diam); 
    100                          
    101                         EstableceCriterio2(diam, hnueva); 
    102                 } 
    103         } 
    104  
    105         EscribeMesh(meshLeaves); 
    106          
    107         //      2006-02-22 
    108         //      Fit progress bar to 100%. 
    109         if (mUPB) 
    110         { 
    111                 mUPB(40); 
    112         } 
    113 } 
    114  
    115 void TreeSimplifier::Mesh2Estructura(   const Mesh      *mesh, 
    116                                                                                                                                                         Index                           meshLeaves) 
    117 { 
    118         // Calcular el número de vértices 
     64 
     65/*      // DEBUG 
     66        FILE *f = fopen("timelog.txt","wt"); 
     67        int initime = time(0); 
     68        fprintf(f,"initime: %d", initime); fflush(f); 
     69        // DEBUG*/ 
     70         
     71        Mesh2Structure(objmesh, meshLeaves); 
     72         
     73        diam = BoundingSphereDiameter(); 
     74 
     75        // precalculate the octree to speed up the simplification process 
     76        const int octree_deep = 2; 
     77        octree=CreateLeafOctree(octree_deep); 
     78 
     79        SetCriteriaOptimized(diam); 
     80 
     81        int target_face_count = (int)((lodfactor*0.01f) * activeLeaves); 
     82        int update_each = (activeLeaves - target_face_count)/68; 
     83//      int prune_each = octree_deep?(activeLeaves - target_face_count)/octree_deep:0; 
     84         
     85//      FILE *fp = fopen("pruning.txt","wt"); // DEBUG 
     86 
     87/*      std::map<float,int> hojas_x_crit; 
     88        for (int i=0; i<countLeaves; i++) 
     89                hojas_x_crit[Leaves[i].criterio] = i; 
     90 
     91        int *leaf_order = new int[countLeaves]; 
     92        std::map<float,int>::iterator kkit = hojas_x_crit.begin(); 
     93        for (int i=0; i<countLeaves; i++, kkit++) 
     94                leaf_order[i] = kkit->second;*/ 
     95 
     96//      int erased_leaves = 0; 
     97        while (activeLeaves > target_face_count) 
     98        { 
     99                static int erased_faces_since_last_update = 0; 
     100                if (mUPB && erased_faces_since_last_update >= update_each) 
     101                { 
     102                        erased_faces_since_last_update=0; 
     103                        mUPB(1); 
     104                } 
     105 
     106/*              static int erased_faces_since_last_prune = 0; 
     107                if (octree_deep && erased_faces_since_last_prune >= prune_each) 
     108                { 
     109                        erased_faces_since_last_prune=0; 
     110                        int pruneinitime = time(0); 
     111                        PruneOctree(octree); 
     112                        int prunefintime = time(0); 
     113                        // DEBUG                         
     114                        fprintf(fp,"pruning at %d activeLeaves [%d (s)]\n", activeLeaves, prunefintime-pruneinitime); fflush(f); 
     115                        // DEBUG 
     116                }*/ 
     117 
     118                erased_faces_since_last_update++;                                
     119//              erased_faces_since_last_prune++; 
     120 
     121                newleaf = Collapse(diam); 
     122                SetCriteria2Optimized(diam, newleaf); 
     123//              erased_leaves++; 
     124        } 
     125 
     126//      fclose(fp); 
     127 
     128/*      int fintime = time(0); 
     129        fprintf(f,"fintime: %d",fintime); fflush(f); 
     130        fprintf(f,"total: %d (s)",fintime-initime); fflush(f); 
     131        fclose(f);*/ 
     132 
     133        BuildOutputMesh(meshLeaves);     
     134} 
     135 
     136void TreeSimplifier::Mesh2Structure(const Mesh *mesh, Index meshLeaves) 
     137{ 
    119138        long int countv=0; 
    120139        long int pos=0; 
    121140        long int v1, v2, v3; 
    122         long int num_triangulo=0; // Identifica los triángulos en las hojas 
    123  
    124         //      2006-02-21. 
    125         float                   percent; 
    126         long    int     update; 
    127          
    128         countv+=(long int)mesh->mSubMesh[meshLeaves].mVertexBuffer->mVertexCount; 
     141        long int triangleID=0; 
     142 
     143        countv += vertex_count = (int)mesh->mSubMesh[meshLeaves].mVertexBuffer->mVertexCount;    
    129144        Vertex  = new float[2*countv][3]; 
    130          
    131         //      2006-02-21. 
    132         update  =       long(mesh->mSubMesh[meshLeaves].mVertexBuffer->mVertexCount / 20); 
    133         percent =       0.5; 
     145                 
     146        int update_each = (int)(mesh->mSubMesh[meshLeaves].mVertexBuffer->mVertexCount / 5); 
    134147         
    135148        for (unsigned int j=0; j<mesh->mSubMesh[meshLeaves].mVertexBuffer->mVertexCount; j++) 
    136149        { 
    137                 //      2006-02-21. 
    138                 if (mUPB        &&      ((j % update) == 0)) 
    139                 { 
    140                         mUPB(percent); 
    141                 } 
     150                static int ticks_since_last_update = 0; 
     151                if (mUPB && ticks_since_last_update>=update_each) 
     152                { 
     153                        ticks_since_last_update=0; 
     154                        mUPB(1); 
     155                } 
     156                ticks_since_last_update++; 
    142157                 
    143158                Vertex[pos][0] = mesh->mSubMesh[meshLeaves].mVertexBuffer->mPosition[j].x;  
     
    147162        } 
    148163 
    149         // Calcular el número de hojas 
    150         counth+=(long)mesh->mSubMesh[meshLeaves].mIndexCount; 
    151         counth=counth/6; // Se supone que cada 6 índices forman una hoja. 
    152  
    153         if ( counth > 0) 
    154         { 
    155                 Hojasa  = new Hoja[2*counth]; 
    156         } 
    157  
    158         activas = counth; 
    159  
    160         // Insertar las hojas en la estructura 
     164        // Calculate the number of leaves 
     165        countLeaves += (long)mesh->mSubMesh[meshLeaves].mIndexCount; 
     166        countLeaves=countLeaves/6; // Each leaf is composed of 6 indices 
     167 
     168        if (countLeaves > 0) 
     169                Leaves = new Hoja[2*countLeaves]; 
     170 
     171        activeLeaves = countLeaves; 
     172 
     173        // Insert leaves into the structure 
    161174        pos=0; 
    162175 
    163         update  =       long(mesh->mSubMesh[meshLeaves].mIndexCount     / 20); 
    164         percent =       0.5; 
    165          
    166         // Cada hoja son 6 vértices 
     176        update_each = (int)(mesh->mSubMesh[meshLeaves].mIndexCount / 5); 
     177         
     178        // Each leaf is composed of 6 vertices 
    167179        for (unsigned int j=0; j<mesh->mSubMesh[meshLeaves].mIndexCount; j=j+6)  
    168180        { 
    169                 //      2006-02-21. 
    170                 if (mUPB        &&      ((j % update) == 0)) 
    171                 { 
    172                         mUPB(percent); 
    173                 } 
     181                static int ticks_since_last_update = 0; 
     182                if (mUPB && ticks_since_last_update>=update_each) 
     183                { 
     184                        ticks_since_last_update=0; 
     185                        mUPB(1); 
     186                } 
     187                ticks_since_last_update+=6; 
    174188                 
    175                 // Primer triángulo 
     189                // first triangle 
    176190                v1=mesh->mSubMesh[meshLeaves].mIndex[j]; 
    177191                v2=mesh->mSubMesh[meshLeaves].mIndex[j+1]; 
    178192                v3=mesh->mSubMesh[meshLeaves].mIndex[j+2]; 
    179                 Hojasa[pos].Vert_Hoja[0]=v1; 
    180                 Hojasa[pos].Vert_Hoja[1]=v2; 
    181                 Hojasa[pos].Vert_Hoja[2]=v3; 
    182                 Hojasa[pos].id_triangulo[0]=num_triangulo; 
    183                 Hojasa[pos].existe=true; 
    184                 num_triangulo++; 
    185  
    186                 // Segundo triángulo 
     193                Leaves[pos].Vert_Hoja[0]=v1; 
     194                Leaves[pos].Vert_Hoja[1]=v2; 
     195                Leaves[pos].Vert_Hoja[2]=v3; 
     196                Leaves[pos].id_triangulo[0]=triangleID; 
     197                Leaves[pos].existe=true; 
     198                triangleID++; 
     199 
     200                // second triangle 
    187201                v3=mesh->mSubMesh[meshLeaves].mIndex[j+5]; 
    188                 Hojasa[pos].Vert_Hoja[3]=v3; 
    189                 Hojasa[pos].id_triangulo[1]=num_triangulo; 
    190                 num_triangulo++; 
    191  
    192                 Centroh(Hojasa[pos]); 
    193                 GetNormal(Hojasa[pos]); 
     202                Leaves[pos].Vert_Hoja[3]=v3; 
     203                Leaves[pos].id_triangulo[1]=triangleID; 
     204                triangleID++; 
     205 
     206                CalculateLeafCenter(Leaves[pos]); 
     207                CalculateLeafNormal(Leaves[pos]); 
    194208                pos++; 
    195209        } 
    196210} 
    197211 
    198 float TreeSimplifier::max(float a,      float b) 
     212float TreeSimplifier::max(float a,      float b) const 
    199213{ 
    200214        if (a>b) return (a); 
     
    202216} 
    203217 
    204 float TreeSimplifier::min(float a,      float b) 
     218float TreeSimplifier::min(float a,      float b) const 
    205219{ 
    206220        if (a>b) return (b); 
     
    208222} 
    209223 
    210 float TreeSimplifier::distan(   float   x1,     float   y1,     float   z1, 
    211                                                                                                                         float x2,       float y2,       float z2) 
    212 { 
    213         float dist = 0; 
    214  
    215         dist = ((x2-x1)*(x2-x1)) + ((y2-y1)*(y2-y1)) + ((z2-z1)*(z2-z1)); 
    216  
    217         return ( dist); 
    218 } 
    219  
    220 //-------------------------------------------------------------------------------------------------------------------------------- 
    221 //  CALCULA EL CENTRO DE UNA HOJA 
    222 //-------------------------------------------------------------------------------------------------------------------------------- 
    223  
    224  
    225 void TreeSimplifier::Centroh(Hoja       &Hoja1) 
     224float TreeSimplifier::distan(float x1, float y1, float z1, float x2, float y2, float z2) const 
     225{ 
     226        return ((x2-x1)*(x2-x1)) + ((y2-y1)*(y2-y1)) + ((z2-z1)*(z2-z1)); 
     227} 
     228 
     229// Calculates the center of a leaf 
     230void TreeSimplifier::CalculateLeafCenter(Hoja &auxleaf) 
    226231{ 
    227232        float   max_x; 
     
    233238         
    234239        //x1 
    235         max_x   =       max(max(Vertex[Hoja1.Vert_Hoja[0]][0], 
    236                                                                         Vertex[Hoja1.Vert_Hoja[1]][0]), 
    237                                                 max(Vertex[Hoja1.Vert_Hoja[2]][0], 
    238                                                                         Vertex[Hoja1.Vert_Hoja[3]][0])); 
    239          
    240         min_x   =       min(min(Vertex[Hoja1.Vert_Hoja[0]][0], 
    241                                                                         Vertex[Hoja1.Vert_Hoja[1]][0]), 
    242                                                 min(Vertex[Hoja1.Vert_Hoja[2]][0], 
    243                                                                         Vertex[Hoja1.Vert_Hoja[3]][0])); 
    244  
    245         Hoja1.Centro[0] = (max_x + min_x)/2; 
     240        max_x   =       max(max(Vertex[auxleaf.Vert_Hoja[0]][0],Vertex[auxleaf.Vert_Hoja[1]][0]), 
     241                                    max(Vertex[auxleaf.Vert_Hoja[2]][0],Vertex[auxleaf.Vert_Hoja[3]][0])); 
     242         
     243        min_x   =       min(min(Vertex[auxleaf.Vert_Hoja[0]][0],Vertex[auxleaf.Vert_Hoja[1]][0]), 
     244                                        min(Vertex[auxleaf.Vert_Hoja[2]][0],Vertex[auxleaf.Vert_Hoja[3]][0])); 
     245 
     246        auxleaf.Centro[0] = (max_x + min_x)/2; 
    246247 
    247248        //y1 
    248         max_y   =       max(max(Vertex[Hoja1.Vert_Hoja[0]][1], 
    249                                                                         Vertex[Hoja1.Vert_Hoja[1]][1]), 
    250                                                 max(Vertex[Hoja1.Vert_Hoja[2]][1], 
    251                                                                         Vertex[Hoja1.Vert_Hoja[3]][1])); 
    252          
    253         min_y   =       min(min(Vertex[Hoja1.Vert_Hoja[0]][1], 
    254                                                                         Vertex[Hoja1.Vert_Hoja[1]][1]), 
    255                                                 min(Vertex[Hoja1.Vert_Hoja[2]][1], 
    256                                                                         Vertex[Hoja1.Vert_Hoja[3]][1])); 
    257  
    258         Hoja1.Centro[1] =       (max_y + min_y) / 2; 
     249        max_y   =       max(max(Vertex[auxleaf.Vert_Hoja[0]][1],Vertex[auxleaf.Vert_Hoja[1]][1]), 
     250                                        max(Vertex[auxleaf.Vert_Hoja[2]][1],Vertex[auxleaf.Vert_Hoja[3]][1])); 
     251         
     252        min_y   =       min(min(Vertex[auxleaf.Vert_Hoja[0]][1],Vertex[auxleaf.Vert_Hoja[1]][1]), 
     253                                        min(Vertex[auxleaf.Vert_Hoja[2]][1],Vertex[auxleaf.Vert_Hoja[3]][1])); 
     254 
     255        auxleaf.Centro[1]       =       (max_y + min_y) / 2; 
    259256         
    260257        //z1 
    261         max_z   =       max(max(Vertex[Hoja1.Vert_Hoja[0]][2], 
    262                                                                         Vertex[Hoja1.Vert_Hoja[1]][2]), 
    263                                                 max(Vertex[Hoja1.Vert_Hoja[2]][2], 
    264                                                                         Vertex[Hoja1.Vert_Hoja[3]][2])); 
    265          
    266         min_z   =       min(min(Vertex[Hoja1.Vert_Hoja[0]][2], 
    267                                                                         Vertex[Hoja1.Vert_Hoja[1]][2]), 
    268                                                 min(Vertex[Hoja1.Vert_Hoja[2]][2], 
    269                                                                         Vertex[Hoja1.Vert_Hoja[3]][2])); 
    270  
    271         Hoja1.Centro[2] =       (max_z + min_z) / 2; 
    272 } 
    273  
    274 //-------------------------------------------------------------------------------------------------------------------------------- 
    275 //  CALCULA LA NORMAL DE UNA HOJA 
    276 //-------------------------------------------------------------------------------------------------------------------------------- 
    277 void TreeSimplifier::GetNormal(Hoja &aHoja) 
     258        max_z   =       max(max(Vertex[auxleaf.Vert_Hoja[0]][2],Vertex[auxleaf.Vert_Hoja[1]][2]), 
     259                                        max(Vertex[auxleaf.Vert_Hoja[2]][2],Vertex[auxleaf.Vert_Hoja[3]][2])); 
     260         
     261        min_z   =       min(min(Vertex[auxleaf.Vert_Hoja[0]][2],Vertex[auxleaf.Vert_Hoja[1]][2]), 
     262                                        min(Vertex[auxleaf.Vert_Hoja[2]][2],Vertex[auxleaf.Vert_Hoja[3]][2])); 
     263 
     264        auxleaf.Centro[2]       =       (max_z + min_z) / 2; 
     265} 
     266 
     267 
     268//  calculate the normal vector of a leaf 
     269void TreeSimplifier::CalculateLeafNormal(Hoja &auxleaf) 
    278270{ 
    279271        float onex, oney, onez; 
     
    281273        float threex, threey, threez; 
    282274 
    283         onex=Vertex[aHoja.Vert_Hoja[0]][0]; oney= Vertex[aHoja.Vert_Hoja[0]][1]; onez = Vertex[aHoja.Vert_Hoja[0]][2]; 
    284         twox = Vertex[aHoja.Vert_Hoja[1]][0]; twoy = Vertex[aHoja.Vert_Hoja[1]][1]; twoz = Vertex[aHoja.Vert_Hoja[1]][2]; 
    285         threex = Vertex[aHoja.Vert_Hoja[2]][0]; threey = Vertex[aHoja.Vert_Hoja[2]][1]; threez = Vertex[aHoja.Vert_Hoja[2]][2]; 
    286          
    287         aHoja.Normal[0] = ((twoz-onez)*(threey-oney)) - ((twoy-oney)*(threez-onez)); 
    288         aHoja.Normal[1] = ((twox-onex)*(threez-onez)) - ((threex-onex)*(twoz-onez)); 
    289         aHoja.Normal[2] = ((threex-onex)*(twoy-oney)) - ((twox-onex)*(threey-oney)); 
    290  
    291          
    292 } 
    293 //-------------------------------------------------------------------------------------------------------------------------------- 
    294 //  CALCULA LA distancia de Hausdorff ( distancia entre nubes de puntos) 
    295 //-------------------------------------------------------------------------------------------------------------------------------- 
    296 float TreeSimplifier::Hausdorff(Hoja &aHoja, Hoja& h2) 
     275        onex   = Vertex[auxleaf.Vert_Hoja[0]][0]; oney   = Vertex[auxleaf.Vert_Hoja[0]][1]; onez   = Vertex[auxleaf.Vert_Hoja[0]][2]; 
     276        twox   = Vertex[auxleaf.Vert_Hoja[1]][0]; twoy   = Vertex[auxleaf.Vert_Hoja[1]][1]; twoz   = Vertex[auxleaf.Vert_Hoja[1]][2]; 
     277        threex = Vertex[auxleaf.Vert_Hoja[2]][0]; threey = Vertex[auxleaf.Vert_Hoja[2]][1]; threez = Vertex[auxleaf.Vert_Hoja[2]][2]; 
     278         
     279        auxleaf.Normal[0] = ((twoz-onez)*(threey-oney)) - ((twoy-oney)*(threez-onez)); 
     280        auxleaf.Normal[1] = ((twox-onex)*(threez-onez)) - ((threex-onex)*(twoz-onez)); 
     281        auxleaf.Normal[2] = ((threex-onex)*(twoy-oney)) - ((twox-onex)*(threey-oney));   
     282} 
     283 
     284 
     285//  calculate the Hausdorff distance (distance between point clouds) 
     286/*float TreeSimplifier::Hausdorff(Hoja &leaf1, Hoja& leaf2) const 
    297287{ 
    298288        float onex, oney, onez; 
     
    306296        float dist1, dist2, dist3, dist4, distmp, dista, distb, dist; 
    307297 
    308         onex=Vertex[aHoja.Vert_Hoja[0]][0]; oney= Vertex[aHoja.Vert_Hoja[0]][1]; onez = Vertex[aHoja.Vert_Hoja[0]][2]; 
    309         twox = Vertex[aHoja.Vert_Hoja[1]][0]; twoy = Vertex[aHoja.Vert_Hoja[1]][1]; twoz = Vertex[aHoja.Vert_Hoja[1]][2]; 
    310         threex = Vertex[aHoja.Vert_Hoja[2]][0]; threey = Vertex[aHoja.Vert_Hoja[2]][1]; threez = Vertex[aHoja.Vert_Hoja[2]][2]; 
    311         fourx = Vertex[aHoja.Vert_Hoja[3]][0]; foury = Vertex[aHoja.Vert_Hoja[3]][1]; fourz = Vertex[aHoja.Vert_Hoja[3]][2]; 
    312          
    313  
    314         x1 = Vertex[h2.Vert_Hoja[0]][0]; y1 = Vertex[h2.Vert_Hoja[0]][1]; z1 = Vertex[h2.Vert_Hoja[0]][2]; 
    315         x2 = Vertex[h2.Vert_Hoja[1]][0]; y2 = Vertex[h2.Vert_Hoja[1]][1]; z2 = Vertex[h2.Vert_Hoja[1]][2]; 
    316         x3 = Vertex[h2.Vert_Hoja[2]][0]; y3 = Vertex[h2.Vert_Hoja[2]][1]; z3 = Vertex[h2.Vert_Hoja[2]][2]; 
    317         x4 = Vertex[h2.Vert_Hoja[3]][0]; y4 = Vertex[h2.Vert_Hoja[3]][1]; z4 = Vertex[h2.Vert_Hoja[3]][2]; 
    318  
    319         // guardo las distancias mínimas de cada vértice a los 4 contrarios. 
     298        onex=Vertex[leaf1.Vert_Hoja[0]][0]; oney= Vertex[leaf1.Vert_Hoja[0]][1]; onez = Vertex[leaf1.Vert_Hoja[0]][2]; 
     299        twox = Vertex[leaf1.Vert_Hoja[1]][0]; twoy = Vertex[leaf1.Vert_Hoja[1]][1]; twoz = Vertex[leaf1.Vert_Hoja[1]][2]; 
     300        threex = Vertex[leaf1.Vert_Hoja[2]][0]; threey = Vertex[leaf1.Vert_Hoja[2]][1]; threez = Vertex[leaf1.Vert_Hoja[2]][2]; 
     301        fourx = Vertex[leaf1.Vert_Hoja[3]][0]; foury = Vertex[leaf1.Vert_Hoja[3]][1]; fourz = Vertex[leaf1.Vert_Hoja[3]][2]; 
     302         
     303 
     304        x1 = Vertex[leaf2.Vert_Hoja[0]][0]; y1 = Vertex[leaf2.Vert_Hoja[0]][1]; z1 = Vertex[leaf2.Vert_Hoja[0]][2]; 
     305        x2 = Vertex[leaf2.Vert_Hoja[1]][0]; y2 = Vertex[leaf2.Vert_Hoja[1]][1]; z2 = Vertex[leaf2.Vert_Hoja[1]][2]; 
     306        x3 = Vertex[leaf2.Vert_Hoja[2]][0]; y3 = Vertex[leaf2.Vert_Hoja[2]][1]; z3 = Vertex[leaf2.Vert_Hoja[2]][2]; 
     307        x4 = Vertex[leaf2.Vert_Hoja[3]][0]; y4 = Vertex[leaf2.Vert_Hoja[3]][1]; z4 = Vertex[leaf2.Vert_Hoja[3]][2]; 
     308 
    320309        dist1 = distan ( onex, oney,onez,x1,y1,z1); 
    321         // vertice 1 con los 4 de la otra hoja 
    322310 
    323311        distmp = distan ( onex, oney,onez,x2,y2,z2); 
     
    330318        if ( distmp < dist1) dist1 = distmp; 
    331319 
    332         // vertice 2 con los 4 de la otra hoja 
    333  
    334320        dist2 = distan ( twox, twoy,twoz,x1,y1,z1); 
    335321         
     
    343329        if ( distmp < dist2) dist2 = distmp; 
    344330 
    345         // vertice 3 con los 4 de la otra hoja 
    346331 
    347332        dist3 = distan ( threex, threey,threez,x1,y1,z1); 
     
    357342 
    358343 
    359         // vertice 4 con los 4 de la otra hoja 
    360344 
    361345        dist4 = distan ( fourx, foury,fourz,x1,y1,z1); 
     
    370354        if ( distmp < dist4) dist4 = distmp; 
    371355 
    372         //de entre estos cojo el máximo 
    373356 
    374357        dista =  max(dist1, max(dist2, max(dist3, dist4))); 
    375358 
    376         //LO MISMO PERO A LA INVERSA 
    377  
    378359        dist1 = distan ( x1,y1,z1, onex, oney, onez); 
    379         // vertice 1 con los 4 de la otra hoja 
    380360 
    381361        distmp = distan ( x1,y1,z1, twox, twoy, twoz); 
     
    388368        if ( distmp < dist1) dist1 = distmp; 
    389369 
    390         //2 
    391370        dist2 = distan ( x2,y2,z2, onex, oney, onez); 
    392         // vertice 2 con los 4 de la otra hoja 
    393371 
    394372        distmp = distan ( x2,y2,z2, twox, twoy, twoz); 
     
    404382                //3 
    405383        dist3 = distan ( x3,y3,z3, onex, oney, onez); 
    406         // vertice 3 con los 4 de la otra hoja 
    407384 
    408385        distmp = distan ( x3,y3,z3, twox, twoy, twoz); 
     
    417394                //4 
    418395        dist4 = distan ( x4,y4,z4, onex, oney, onez); 
    419         // vertice 4 con los 4 de la otra hoja 
    420396 
    421397        distmp = distan ( x4,y4,z4, twox, twoy, twoz); 
     
    435411         
    436412} 
    437  
    438 //-------------------------------------------------------------------------------------------------------------------------------- 
    439 // CALCULA LA DISTANCIA ENTRE HOJAS 
    440 //-------------------------------------------------------------------------------------------------------------------------------- 
    441  
     413*/ 
     414 
     415//  Calculate the Hausdorff distance (distance between point clouds) (Optimized) 
     416float TreeSimplifier::HausdorffOptimized(const Hoja &leaf1, const Hoja& leaf2) const 
     417{ 
     418        float onex, oney, onez; 
     419        float twox, twoy, twoz; 
     420        float threex, threey, threez; 
     421        float fourx, foury, fourz; 
     422        float x1, y1, z1; 
     423        float x2, y2, z2; 
     424        float x3, y3, z3; 
     425        float x4, y4, z4; 
     426        float dist1, dist2, dist3, dist4, distmp, dista, distb, dist; 
     427 
     428        onex   = Vertex[leaf1.Vert_Hoja[0]][0]; oney   = Vertex[leaf1.Vert_Hoja[0]][1]; onez   = Vertex[leaf1.Vert_Hoja[0]][2]; 
     429        twox   = Vertex[leaf1.Vert_Hoja[1]][0]; twoy   = Vertex[leaf1.Vert_Hoja[1]][1]; twoz   = Vertex[leaf1.Vert_Hoja[1]][2]; 
     430        threex = Vertex[leaf1.Vert_Hoja[2]][0]; threey = Vertex[leaf1.Vert_Hoja[2]][1]; threez = Vertex[leaf1.Vert_Hoja[2]][2]; 
     431        fourx  = Vertex[leaf1.Vert_Hoja[3]][0]; foury  = Vertex[leaf1.Vert_Hoja[3]][1]; fourz  = Vertex[leaf1.Vert_Hoja[3]][2]; 
     432 
     433        x1 = Vertex[leaf2.Vert_Hoja[0]][0]; y1 = Vertex[leaf2.Vert_Hoja[0]][1]; z1 = Vertex[leaf2.Vert_Hoja[0]][2]; 
     434        x2 = Vertex[leaf2.Vert_Hoja[1]][0]; y2 = Vertex[leaf2.Vert_Hoja[1]][1]; z2 = Vertex[leaf2.Vert_Hoja[1]][2]; 
     435        x3 = Vertex[leaf2.Vert_Hoja[2]][0]; y3 = Vertex[leaf2.Vert_Hoja[2]][1]; z3 = Vertex[leaf2.Vert_Hoja[2]][2]; 
     436        x4 = Vertex[leaf2.Vert_Hoja[3]][0]; y4 = Vertex[leaf2.Vert_Hoja[3]][1]; z4 = Vertex[leaf2.Vert_Hoja[3]][2]; 
     437 
     438        // variables used to cache distances 
     439        float one1,one2,one3,one4, two1,two2,two3,two4, three1,three2,three3,three4, four1,four2,four3,four4; 
     440 
     441        // Store the minimal distances from each of the 4 vertices to the other 4 vertices 
     442        one1 = dist1 = distan ( onex, oney,onez,x1,y1,z1); 
     443         
     444        one2 = distmp = distan ( onex, oney,onez,x2,y2,z2); 
     445        if ( distmp < dist1) dist1 = distmp; 
     446 
     447        one3 = distmp = distan ( onex, oney,onez,x3,y3,z3); 
     448        if ( distmp < dist1) dist1 = distmp; 
     449 
     450        one4 = distmp = distan ( onex, oney,onez,x4,y4,z4); 
     451        if ( distmp < dist1) dist1 = distmp; 
     452 
     453         
     454        two1 = dist2 = distan ( twox, twoy,twoz,x1,y1,z1); 
     455         
     456        two2 = distmp = distan ( twox, twoy,twoz,x2,y2,z2); 
     457        if ( distmp < dist2) dist2 = distmp; 
     458         
     459        two3 = distmp = distan ( twox, twoy,twoz,x3,y3,z3); 
     460        if ( distmp < dist2) dist2 = distmp; 
     461         
     462        two4 = distmp = distan ( twox, twoy,twoz,x4,y4,z4); 
     463        if ( distmp < dist2) dist2 = distmp; 
     464 
     465         
     466        three1 = dist3 = distan ( threex, threey,threez,x1,y1,z1); 
     467         
     468        three2 = distmp = distan ( threex, threey,threez,x2,y2,z2); 
     469        if ( distmp < dist3) dist3 = distmp; 
     470 
     471        three3 = distmp = distan ( threex, threey,threez,x3,y3,z3); 
     472        if ( distmp < dist3) dist3 = distmp; 
     473 
     474        three4 = distmp = distan ( threex, threey,threez,x4,y4,z4); 
     475        if ( distmp < dist3) dist3 = distmp; 
     476 
     477 
     478        four1 = dist4 = distan ( fourx, foury,fourz,x1,y1,z1); 
     479         
     480        four2 = distmp = distan ( fourx, foury,fourz,x2,y2,z2); 
     481        if ( distmp < dist4) dist4 = distmp; 
     482 
     483        four3 = distmp = distan ( fourx, foury,fourz,x3,y3,z3); 
     484        if ( distmp < dist4) dist4 = distmp; 
     485         
     486        four4 = distmp = distan ( fourx, foury,fourz,x4,y4,z4); 
     487        if ( distmp < dist4) dist4 = distmp; 
     488 
     489        // pick up the maximum value from those 4 
     490 
     491        dista =  max(dist1, max(dist2, max(dist3, dist4))); 
     492 
     493        // now use the cached distances to perform the reverse distances 
     494 
     495        dist1 = one1;  //distan ( x1,y1,z1, onex, oney, onez); 
     496 
     497        distmp = two1; //distan ( x1,y1,z1, twox, twoy, twoz); 
     498        if ( distmp < dist1) dist1 = distmp; 
     499 
     500        distmp =  three1; //distan ( x1,y1,z1, threex, threey, threez); 
     501        if ( distmp < dist1) dist1 = distmp; 
     502 
     503        distmp = four1; //distan ( x1,y1,z1, fourx, foury, fourz); 
     504        if ( distmp < dist1) dist1 = distmp; 
     505 
     506        //2 
     507        dist2 = one2; //distan ( x2,y2,z2, onex, oney, onez); 
     508 
     509        distmp = two2; //distan ( x2,y2,z2, twox, twoy, twoz); 
     510        if ( distmp < dist2) dist2 = distmp; 
     511 
     512        distmp = three2; //distan ( x2,y2,z2, threex, threey, threez); 
     513        if ( distmp < dist2) dist2 = distmp; 
     514 
     515        distmp = four2; //distan ( x2,y2,z2, fourx, foury, fourz); 
     516        if ( distmp < dist2) dist2 = distmp; 
     517 
     518 
     519                //3 
     520        dist3 = one3; //distan ( x3,y3,z3, onex, oney, onez); 
     521 
     522        distmp = two3; //distan ( x3,y3,z3, twox, twoy, twoz); 
     523        if ( distmp < dist3) dist3 = distmp; 
     524 
     525        distmp = three3; //distan ( x3,y3,z3, threex, threey, threez); 
     526        if ( distmp < dist3) dist3 = distmp; 
     527 
     528        distmp = four3; //distan ( x3,y3,z3, fourx, foury, fourz); 
     529        if ( distmp < dist3) dist3 = distmp; 
     530 
     531                //4 
     532        dist4 = one4; //distan ( x4,y4,z4, onex, oney, onez); 
     533 
     534        distmp = two4; //distan ( x4,y4,z4, twox, twoy, twoz); 
     535        if ( distmp < dist4) dist4 = distmp; 
     536 
     537        distmp = three4; //distan ( x4,y4,z4, threex, threey, threez); 
     538        if ( distmp < dist4) dist4 = distmp; 
     539 
     540        distmp = four4; //distan ( x4,y4,z4, fourx, foury, fourz); 
     541        if ( distmp < dist4) dist4 = distmp; 
     542 
     543        // 
     544        distb =  max(dist1, max(dist2, max(dist3, dist4))); 
     545 
     546        dist  = max ( dista, distb); 
     547        return ( dist); 
     548         
     549} 
     550 
     551 
     552// Calculate the distance between leaves 
     553/* 
    442554void TreeSimplifier::DistanciaEntreHojas(void) 
    443555{ 
     
    445557        int j; 
    446558 
    447         for ( int i=0;i<counth;i++) 
    448         { 
    449                 if ( Hojasa[i].existe == true) // si la hoja aun existe 
     559        for ( int i=0;i<countLeaves;i++) 
     560        { 
     561                if ( Leaves[i].existe == true) // si la hoja aun existe 
    450562                { 
    451563                        // inicializo para poder comparar 
    452                         if ( i == (counth-1)) j = 0;  
     564                        if ( i == (countLeaves-1)) j = 0;  
    453565                                else j = i+1; 
    454                         while (Hojasa[j].existe == false) j++; 
    455                         //dist = Hojasa[i].Distancia(Hojasa[j]); 
    456                         dist = Hausdorff( Hojasa[i], Hojasa[j]); 
    457  
    458                         Hojasa[i].hoja_cerca = j; 
     566                        while (Leaves[j].existe == false) j++; 
     567                        //dist = Leaves[i].Distancia(Leaves[j]); 
     568                        dist = HausdorffOptimizado( Leaves[i], Leaves[j]); 
     569 
     570                        Leaves[i].hoja_cerca = j; 
    459571                        // empiezo los calculos 
    460                         for ( j =0; j<(counth-1);j++) 
     572                        for ( j =0; j<(countLeaves-1);j++) 
    461573                        { 
    462574                                if ( j == i)  
    463575                                        break; 
    464                                 if ( Hojasa[j].existe == true) // si la hoja aun existe 
     576                                if ( Leaves[j].existe == true) // si la hoja aun existe 
    465577                                { 
    466                                         distmp = Hausdorff(Hojasa[i], Hojasa[j]); 
     578                                        distmp = HausdorffOptimizado(Leaves[i], Leaves[j]); 
    467579                                        if ( distmp < dist )  
    468580                                        { 
    469581                                                dist = distmp; 
    470                                                 Hojasa[i].hoja_cerca = j; 
     582                                                Leaves[i].hoja_cerca = j; 
    471583                                        } 
    472584                                } 
    473585                                 
    474586                        } 
    475                         Hojasa[i].dist = dist; 
    476                 } 
    477         } 
    478  
    479 } 
    480  
    481 //-------------------------------------------------------------------------------------------------------------------------------- 
    482 // DEVUELVE LA HOJA QUE TIENE UNA DISTANCIA MENOR 
    483 //-------------------------------------------------------------------------------------------------------------------------------- 
    484 long int TreeSimplifier::MinimaDistancia ( void) 
    485 { 
    486         float                   mindist; 
    487         long int        cual; 
    488         int                             i; 
    489  
    490         mindist =       0; 
    491         cual            =       -1; 
    492         i                               =       0; 
    493          
    494         //inicializo 
    495         while (Hojasa[i].existe != true) 
    496         { 
     587                        Leaves[i].dist = dist; 
     588                } 
     589        } 
     590 
     591}*/ 
     592 
     593// Returns the leaf which distance is the lowest 
     594long int TreeSimplifier::MinDistance(void) 
     595{ 
     596        float           mindist=0.0f; 
     597        long int        which=-1; 
     598        int                     i=0; 
     599 
     600/*      //init 
     601        while (Leaves[i].existe != true) 
    497602                i++; 
    498         } 
    499          
    500         mindist =       Hojasa[i].dist; 
    501         cual            =       i; 
    502          
    503         //busco la minima 
    504         for (i = 0; i < counth; i++) 
    505         { 
    506                 if (Hojasa[i].existe == true) 
    507                 { 
    508                         if ( mindist > Hojasa[i].dist) 
     603         
     604        mindist = Leaves[i].dist; 
     605        which   = i; 
     606*/       
     607        // search the minimum 
     608        for (i = 0; i < countLeaves; i++) 
     609        { 
     610                if (Leaves[i].existe) 
     611                { 
     612                        if (mindist > Leaves[i].dist || which==-1) 
    509613                        { 
    510                                 mindist = Hojasa[i].dist; 
    511                                 cual = i; 
     614                                mindist = Leaves[i].dist; 
     615                                which = i; 
    512616                        } 
    513617                } 
    514618 
    515619        } 
    516         return (cual); 
    517 } 
    518  
    519 //-------------------------------------------------------------------------------------------------------------------------------- 
    520 // CALCULA LA COPLANARIDAD ENTRE HOJAS 
    521 //-------------------------------------------------------------------------------------------------------------------------------- 
    522 void TreeSimplifier::CoplanarEntreHojas(FILE    *fp_coplanar) 
     620        return which; 
     621} 
     622 
     623// Calculate the coplanarity between leaves 
     624void TreeSimplifier::CoplanarBetweenLeaves(void) 
    523625{ 
    524626        float   cop; 
     
    527629        int     j; 
    528630 
    529         for ( i=0;i<counth;i++) 
    530         { 
    531                 if ( Hojasa[i].existe == true) // si la hoja aun existe 
    532                 { 
    533                         // inicializo para poder comparar 
    534                         if ( i == (counth-1)) 
     631        for (i=0;i<countLeaves;i++) 
     632        { 
     633                if (Leaves[i].existe) 
     634                { 
     635                        if (i == countLeaves-1) 
     636                                j       =       0; 
     637                        else 
     638                                j =     i + 1; 
     639                         
     640                        while (Leaves[j].existe == false) 
     641                                j++; 
     642                         
     643                        cop     = Leaves[i].Coplanaridad(Leaves[j]); 
     644                        Leaves[i].hoja_cop      =       j; 
     645                         
     646                        for (j=0; j<countLeaves-1; j++) 
    535647                        { 
    536                                 j       =       0; 
    537                         } 
    538                         else 
    539                         { 
    540                                 j =     i + 1; 
    541                         } 
    542                          
    543                         while (Hojasa[j].existe == false) 
    544                         { 
    545                                 j++; 
    546                         } 
    547                          
    548                         cop                                                                     =       Hojasa[i].Coplanaridad(Hojasa[j]); 
    549                         Hojasa[i].hoja_cop      =       j; 
    550                          
    551                         // empiezo los calculos 
    552                         for (j = 0; j < (counth-1); j++) 
    553                         { 
    554                                 // si la hoja aun existe. 
    555                                 if (( j != i) && (Hojasa[j].existe == true)) 
     648                                if (( j != i) && (Leaves[j].existe)) 
    556649                                { 
    557                                         coptmp  =       Hojasa[i].Coplanaridad(Hojasa[j]); 
    558  
    559                                         // COJO EL MAS COPLANAR , CERCANO A 1. 
     650                                        coptmp  =       Leaves[i].Coplanaridad(Leaves[j]); 
     651 
     652                                        // Take the most coplanar: close to 1 
    560653                                        if (coptmp > cop) 
    561654                                        { 
    562                                                 cop                                                                     =       coptmp; 
    563                                                 Hojasa[i].hoja_cop      =       j; 
     655                                                cop     = coptmp; 
     656                                                Leaves[i].hoja_cop = j; 
    564657                                        } 
    565658                                } 
    566659                        } 
    567                         Hojasa[i].coplanar      =       1 - cop; //  8/6/01 LO INVIERTO 
    568                 } 
    569         } 
    570 } 
    571  
    572 //-------------------------------------------------------------------------------------------------------------------------------- 
    573 //  
    574 //-------------------------------------------------------------------------------------------------------------------------------- 
    575 void TreeSimplifier::DosMayores(float *mayores, int     *indices) 
     660                        Leaves[i].coplanar = 1 - cop; 
     661                } 
     662        } 
     663} 
     664 
     665void TreeSimplifier::TwoGreater(float *maj, int *indices) 
    576666{ 
    577667        float   m1; 
    578668        int             i; 
    579669 
    580         if      (mayores[0] < mayores[1]) 
    581         { 
    582                 m1                                      =       mayores[0]; 
    583                 mayores[0]      =       mayores[1]; 
    584                 mayores[1]      =       m1; 
    585  
    586                 i                                               =       indices[0]; 
    587                 indices[0]      =       indices[1]; 
    588                 indices[1]      =       i; 
    589         } 
    590  
    591         if (mayores [2] < mayores [3]) 
    592         { 
    593                 m1                                      =       mayores[2]; 
    594                 mayores[2]      =       mayores[3]; 
    595                 mayores [3]     =       m1; 
    596  
    597                 i                                               =       indices[2]; 
     670        if      (maj[0] < maj[1]) 
     671        { 
     672                m1      = maj[0]; 
     673                maj[0] = maj[1]; 
     674                maj[1] = m1; 
     675 
     676                i =     indices[0]; 
     677                indices[0] = indices[1]; 
     678                indices[1] = i; 
     679        } 
     680 
     681        if (maj[2] < maj[3]) 
     682        { 
     683                m1      = maj[2]; 
     684                maj[2] = maj[3]; 
     685                maj[3]  = m1; 
     686                i       = indices[2]; 
     687                indices[2] = indices[3]; 
     688                indices[3] = i; 
     689        } 
     690 
     691        if  (maj[0] < maj[2]) 
     692        { 
     693                m1              =       maj[0]; 
     694                maj[0]  =       maj[2]; 
     695                maj[2]  =       m1; 
     696                i               =       indices[0]; 
     697                indices[0]      =       indices[2]; 
     698                indices[2]      =       i; 
     699        } 
     700 
     701        if (maj[2] < maj[3]) 
     702        { 
     703                m1              =       maj[2]; 
     704                maj[2]  =       maj[3]; 
     705                maj [3] =       m1; 
     706 
     707                i                       =       indices[2]; 
    598708                indices[2]      =       indices[3]; 
    599709                indices[3]      =       i; 
    600710        } 
    601711 
    602         if  (mayores[0] < mayores[2]) 
    603         { 
    604                 m1                                      =       mayores[0]; 
    605                 mayores[0]      =       mayores[2]; 
    606                 mayores[2]      =       m1; 
    607  
    608                 i                                               =       indices[0]; 
    609                 indices[0]      =       indices[2]; 
    610                 indices[2]      =       i; 
    611         } 
    612  
    613         if (mayores [2] < mayores [3]) 
    614         { 
    615                 m1                                      =       mayores[2]; 
    616                 mayores[2]      =       mayores[3]; 
    617                 mayores [3]     =       m1; 
    618  
    619                 i                                               =       indices[2]; 
    620                 indices[2]      =       indices[3]; 
    621                 indices[3]      =       i; 
    622         } 
    623  
    624         if (mayores [1] < mayores [2]) 
    625         { 
    626                 m1                                      =       mayores[1]; 
    627                 mayores[1]      =       mayores[2]; 
    628                 mayores [2]     =       m1; 
    629  
    630                 i                                               = indices[1]; 
     712        if (maj [1] < maj [2]) 
     713        { 
     714                m1              =       maj[1]; 
     715                maj[1]  =       maj[2]; 
     716                maj [2] =       m1; 
     717 
     718                i                       = indices[1]; 
    631719                indices[1]      = indices[2]; 
    632720                indices[2]      = i; 
     
    634722} 
    635723 
    636 //-------------------------------------------------------------------------------------------------------------------------------- 
    637 //  
    638 //-------------------------------------------------------------------------------------------------------------------------------- 
    639 //float TreeSimplifier::DiametroEsferaEnvolvente (FILE* fp_simplifica) 
    640 float TreeSimplifier::DiametroEsferaEnvolvente() 
     724float TreeSimplifier::BoundingSphereDiameter(void) const 
    641725{ 
    642726        float xmax, xmin, ymax, ymin, zmax, zmin; 
    643         float diametro, cx, cy, cz; 
     727        float diameter, cx, cy, cz; 
    644728        int j; 
    645729 
    646         //      2006-02-21. 
    647         float                   percent; 
    648         long    int     update; 
    649  
    650         //inicializo al primero de los vértices de las hojas 
    651  
    652         xmax = Vertex[Hojasa[0].Vert_Hoja[0]][0]; 
     730        // initialize all vertices to the first 
     731        xmax = Vertex[Leaves[0].Vert_Hoja[0]][0]; 
    653732        xmin = xmax; 
    654733 
    655         ymax = Vertex[Hojasa[0].Vert_Hoja[0]][1]; 
     734        ymax = Vertex[Leaves[0].Vert_Hoja[0]][1]; 
    656735        ymin = ymax; 
    657736 
    658         zmax = Vertex[Hojasa[0].Vert_Hoja[0]][2]; 
     737        zmax = Vertex[Leaves[0].Vert_Hoja[0]][2]; 
    659738        zmin = zmax; 
    660739 
    661         // ahora busco los maximos y los minimos correspondientes 
    662  
    663  
    664         //      2006-02-21 
    665         update  =       counth / 20; 
    666         percent =       0.5; 
    667         for (int i = 1; i < counth; i++) 
    668         { 
    669                 //      2006-02-21 
    670                 if (mUPB        &&      ((i % update) == 0)) 
    671                 { 
    672                         mUPB(percent); 
    673                 } 
     740        // search for max and mins 
     741 
     742        int update_each = countLeaves / 5; 
     743        for (int i = 1; i < countLeaves; i++) 
     744        { 
     745                static int ticks_since_last_update = 0; 
     746                if (mUPB && ticks_since_last_update>=update_each) 
     747                { 
     748                        ticks_since_last_update=0; 
     749                        mUPB(1); 
     750                } 
     751                ticks_since_last_update++; 
    674752                 
    675                 for ( j=0;j<4;j++) 
    676                 { 
     753                for (j=0;j<4;j++) 
     754                {                        
     755                        if ( xmax < Vertex[Leaves[i].Vert_Hoja[j]][0]) xmax = Vertex[Leaves[i].Vert_Hoja[j]][0]; 
     756                        if ( xmin > Vertex[Leaves[i].Vert_Hoja[j]][0]) xmin = Vertex[Leaves[i].Vert_Hoja[j]][0]; 
     757 
     758                        if ( ymax < Vertex[Leaves[i].Vert_Hoja[j]][1]) ymax = Vertex[Leaves[i].Vert_Hoja[j]][1]; 
     759                        if ( ymin > Vertex[Leaves[i].Vert_Hoja[j]][1]) ymin = Vertex[Leaves[i].Vert_Hoja[j]][1]; 
    677760                         
    678                 if ( xmax < Vertex[Hojasa[i].Vert_Hoja[j]][0]) xmax = Vertex[Hojasa[i].Vert_Hoja[j]][0]; 
    679                 if ( xmin > Vertex[Hojasa[i].Vert_Hoja[j]][0]) xmin = Vertex[Hojasa[i].Vert_Hoja[j]][0]; 
    680  
    681                 if ( ymax < Vertex[Hojasa[i].Vert_Hoja[j]][1]) ymax = Vertex[Hojasa[i].Vert_Hoja[j]][1]; 
    682                 if ( ymin > Vertex[Hojasa[i].Vert_Hoja[j]][1]) ymin = Vertex[Hojasa[i].Vert_Hoja[j]][1]; 
    683                  
    684                 if ( zmax < Vertex[Hojasa[i].Vert_Hoja[j]][2]) zmax = Vertex[Hojasa[i].Vert_Hoja[j]][2]; 
    685                 if ( zmin > Vertex[Hojasa[i].Vert_Hoja[j]][2]) zmin = Vertex[Hojasa[i].Vert_Hoja[j]][2]; 
    686  
     761                        if ( zmax < Vertex[Leaves[i].Vert_Hoja[j]][2]) zmax = Vertex[Leaves[i].Vert_Hoja[j]][2]; 
     762                        if ( zmin > Vertex[Leaves[i].Vert_Hoja[j]][2]) zmin = Vertex[Leaves[i].Vert_Hoja[j]][2]; 
    687763                } 
    688764        } 
     
    692768        cz = (zmax + zmin)/2; 
    693769 
    694  
    695         diametro = ((xmax-xmin)*(xmax-xmin)) + ((ymax-ymin)*(ymax-ymin)) + ((zmax-zmin)*(zmax-zmin)); 
    696  
    697 return (diametro); 
    698 } 
    699  
    700 //-------------------------------------------------------------------------------------------------------------------------------- 
    701 //  normaliza las distancia 
    702 //-------------------------------------------------------------------------------------------------------------------------------- 
    703 void TreeSimplifier::NormalizaDistancia (float diametro) 
     770        diameter = ((xmax-xmin)*(xmax-xmin)) + ((ymax-ymin)*(ymax-ymin)) + ((zmax-zmin)*(zmax-zmin)); 
     771 
     772        return (diameter); 
     773} 
     774 
     775void TreeSimplifier::NormalizeDistance(float diameter) 
    704776{ 
    705777        float dtmp; 
    706         for (int i=0; i<counth;i++) 
    707         { 
    708                 dtmp = Hojasa[i].dist; 
    709                 Hojasa[i].dist = dtmp / diametro; 
     778        for (int i=0; i<countLeaves;i++) 
     779        { 
     780                dtmp = Leaves[i].dist; 
     781                Leaves[i].dist = dtmp / diameter; 
    710782                 
    711783        } 
    712784} 
    713  
     785/* 
     786 
     787        THIS FUNCTION IS OBSOLETE, AND NEEDS TO BE ERASED 
    714788//-------------------------------------------------------------------------------------------------------------------------------- 
    715789//  establece el criterio como (K1 * dist + K2 * cop)/ K1+K2 
     
    721795        int i, j, nhojasi, nhojasj; 
    722796 
    723         //      2006-02-21 
    724         float                   percent; 
    725         long    int     update; 
    726          
    727         update  =       counth / 30; 
    728         percent =       1; 
    729          
    730         for ( i=0; i<counth;i++) 
    731         { 
    732                 //      2005-02-21 
    733                 if (mUPB        &&      ((i % update) == 0)) 
    734                 { 
    735                         mUPB(percent); 
    736                 } 
    737                  
    738                 if (Hojasa[i].existe == true) 
     797        int update_each = countLeaves / 30; 
     798         
     799        for ( i=0; i<countLeaves;i++) 
     800        { 
     801                if (Leaves[i].existe == true) 
    739802                { 
    740803                        //incializo criterio a un numero elevado 
    741                         Hojasa[i].criterio = 1000; 
    742                         nhojasi = int(Hojasa[i].Cuantas_hojas); 
     804                        Leaves[i].criterio = 1000; 
     805                        nhojasi = int(Leaves[i].Cuantas_hojas); 
    743806                        //coplanaridad 
    744                         for ( j =0; j<counth;j++) 
     807                        for ( j =0; j<countLeaves;j++) 
    745808                        { 
    746                                 if (( j != i) && ( Hojasa[j].existe == true)) // si la hoja aun existe 
     809                                if (( j != i) && ( Leaves[j].existe == true)) // si la hoja aun existe 
    747810                                { 
    748811                                        //17/09/01 ANTES DE CALCULAR NADA, COMPRUEBO QUE ESTAS DOS HOJAS  
     
    750813                                        // ES COMO MÁXIMO 1 
    751814 
    752                                         nhojasj = int(Hojasa[j].Cuantas_hojas); 
     815                                        nhojasj = int(Leaves[j].Cuantas_hojas); 
    753816 
    754817                                        if ( abs((nhojasi - nhojasj)) < 2) 
    755818                                        { 
    756819                                                //coplanaridad y lo invierto 
    757                                                 coptmp2 = Hojasa[i].Coplanaridad(Hojasa[j]);  
     820                                                coptmp2 = Leaves[i].Coplanaridad(Leaves[j]);  
    758821                                                coptmp = 1 - coptmp2; 
    759822                                                //distancia y la normalizo 
    760                                                 distmp2 = Hausdorff( Hojasa[i], Hojasa[j]);  
     823                                                distmp2 = Hausdorff( Leaves[i], Leaves[j]);  
    761824                                                distmp = distmp2 / diametro; 
    762825                                                // calculo el criterio para esa hoja 
    763826                                                criteriotmp = (( K1 * distmp * distmp ) + (K2 * coptmp * distmp))/ (K1 + K2); 
    764827                                                //selecciono el criterio menor 
    765                                                 if (Hojasa[i].criterio > criteriotmp)  
     828                                                if (Leaves[i].criterio > criteriotmp)  
    766829                                                { 
    767                                                         Hojasa[i].criterio = criteriotmp; 
    768                                                         Hojasa[i].hoja_crit = j; 
     830                                                        Leaves[i].criterio = criteriotmp; 
     831                                                        Leaves[i].hoja_crit = j; 
    769832                                                } 
    770833                                        } 
     
    787850        //ESTAN EN tres PROCEDIMIENTOS: COLAPSA, ESTABLECECRITERIO Y ESTABLECECRITERIO2 
    788851         
    789         for (i = 0; i < counth; i++) 
    790         { 
    791                 if ((Hojasa[i].existe == true) && (i != hojanueva)) 
     852        for (i = 0; i < countLeaves; i++) 
     853        { 
     854                if ((Leaves[i].existe == true) && (i != hojanueva)) 
    792855                {        
    793                         nhojasi = int(Hojasa[i].Cuantas_hojas); 
     856                        nhojasi = int(Leaves[i].Cuantas_hojas); 
    794857                        //¿ SE HA DESACTIVADO LA HOJA_CRIT QUE GUARDABA LA HOJA? 
    795                         if ( Hojasa[Hojasa[i].hoja_crit].existe == false) 
     858                        if ( Leaves[Leaves[i].hoja_crit].existe == false) 
    796859                        { 
    797                                 Hojasa[i].criterio = 1000; 
     860                                Leaves[i].criterio = 1000; 
    798861 
    799862                                //coplanaridad 
    800                                 for ( j =0; j<counth;j++) 
     863                                for ( j =0; j<countLeaves;j++) 
    801864                                { 
    802                                         if (( j != i) && ( Hojasa[j].existe == true)) // si la hoja aun existe 
     865                                        if (( j != i) && ( Leaves[j].existe == true)) // si la hoja aun existe 
    803866                                        { 
    804867                                                //17/09/01 ANTES DE CALCULAR NADA, COMPRUEBO QUE ESTAS DOS HOJAS  
     
    806869                                                // ES COMO MÁXIMO 1 
    807870 
    808                                                 nhojasj = int(Hojasa[j].Cuantas_hojas); 
     871                                                nhojasj = int(Leaves[j].Cuantas_hojas); 
    809872 
    810873                                                if ( abs((nhojasi - nhojasj)) < 2) 
     
    812875 
    813876                                                        //coplanaridad y lo invierto 
    814                                                         coptmp2 = Hojasa[i].Coplanaridad(Hojasa[j]);  
     877                                                        coptmp2 = Leaves[i].Coplanaridad(Leaves[j]);  
    815878                                                        coptmp = 1 - coptmp2;    
    816879                                                        //distancia y la normalizo       
    817                                                 //      distmp2 = Hojasa[i].Distancia(Hojasa[j]);  
    818                                                         distmp2 = Hausdorff( Hojasa[i],  Hojasa[j]);  
     880                                                //      distmp2 = Leaves[i].Distancia(Leaves[j]);  
     881                                                        distmp2 = Hausdorff( Leaves[i],  Leaves[j]);  
    819882                                                        distmp = distmp2 / diametro; 
    820883                                                        // calculo el criterio para esa hoja 
    821884                                                        criteriotmp = (( K1 * distmp * distmp ) + (K2 * coptmp * distmp))/ (K1 + K2); 
    822885                                                        //selecciono el criterio menor 
    823                                                         if (Hojasa[i].criterio > criteriotmp)  
     886                                                        if (Leaves[i].criterio > criteriotmp)  
    824887                                                        { 
    825                                                                 Hojasa[i].criterio = criteriotmp; 
    826                                                                 Hojasa[i].hoja_crit = j; 
     888                                                                Leaves[i].criterio = criteriotmp; 
     889                                                                Leaves[i].hoja_crit = j; 
    827890                                                        } 
    828891                                                } 
     
    832895                        else 
    833896                        { // CALCULARE SI EL CRITERIO CON ESTA HOJA ES MENOR QUE EL ANTERIOR 
    834                                 nhojasj = int(Hojasa[hojanueva].Cuantas_hojas); 
     897                                nhojasj = int(Leaves[hojanueva].Cuantas_hojas); 
    835898 
    836899                                if ( abs((nhojasi - nhojasj)) < 2) 
    837900                                { 
    838901                                        //coplanaridad y lo invierto 
    839                                         coptmp2 = Hojasa[i].Coplanaridad(Hojasa[hojanueva]);  
     902                                        coptmp2 = Leaves[i].Coplanaridad(Leaves[hojanueva]);  
    840903                                        coptmp = 1 - coptmp2; 
    841904                                        //distancia y la normalizo 
    842                                         //distmp2 = Hojasa[i].Distancia(Hojasa[hojanueva]);  
    843                                         distmp2 = Hausdorff( Hojasa[i], Hojasa[hojanueva]);  
     905                                        //distmp2 = Leaves[i].Distancia(Leaves[hojanueva]);  
     906                                        distmp2 = Hausdorff( Leaves[i], Leaves[hojanueva]);  
    844907                                        distmp = distmp2 / diametro; 
    845908                                        // calculo el criterio para esa hoja 
    846909                                        criteriotmp = (( K1 * distmp * distmp ) + (K2 * coptmp * distmp))/ (K1 + K2); 
    847910                                        //selecciono el criterio menor 
    848                                         if (Hojasa[i].criterio > criteriotmp)  
     911                                        if (Leaves[i].criterio > criteriotmp)  
    849912                                        {        
    850                                                 Hojasa[i].criterio = criteriotmp; 
    851                                                 Hojasa[i].hoja_crit = hojanueva; 
     913                                                Leaves[i].criterio = criteriotmp; 
     914                                                Leaves[i].hoja_crit = hojanueva; 
    852915                                        } 
    853916                                } 
     
    855918                } 
    856919        } 
    857 } 
    858 //-------------------------------------------------------------------------------------------------------------------------------- 
    859 // DEVUELVE LA HOJA QUE TIENE EL NUMERO EN EL CAMPO CRITERIO MENOR 
    860 //-------------------------------------------------------------------------------------------------------------------------------- 
    861  
    862 long int TreeSimplifier::MinimoCriterio (void) 
    863 { 
    864         float mincrit =0; 
    865         long int cual=-1; 
    866         int i=0; 
    867          
    868         //inicializo 
    869         while (Hojasa[i].existe != true) i++; 
    870         mincrit = Hojasa[i].criterio; 
    871         cual =i; 
    872         //busco la minima 
    873         for ( i=0;i<counth;i++) 
    874  
    875         { 
    876                 if (Hojasa[i].existe == true) 
    877                 { 
    878                         if ( mincrit> Hojasa[i].criterio) 
     920}*/ 
     921 
     922 
     923 
     924// Gets the laf with the minimum criteria 
     925long int TreeSimplifier::MinCriteria (void) 
     926{ 
     927        float mincrit=0.0f; 
     928        long int which=-1; 
     929                 
     930/*      while (Leaves[i].existe != true) i++; 
     931        mincrit = Leaves[i].criterio; 
     932        which =i; 
     933        */ 
     934        for (int i=0;i<countLeaves;i++) 
     935        { 
     936                if (Leaves[i].existe) 
     937                { 
     938                        if (mincrit>Leaves[i].criterio || which==-1) 
    879939                        { 
    880                                 mincrit = Hojasa[i].criterio; 
    881                                 cual = i; 
     940                                mincrit = Leaves[i].criterio; 
     941                                which = i; 
    882942                        } 
    883943                } 
    884944                 
    885945        } 
    886         return (cual); 
    887 } 
    888  
    889  
    890 //-------------------------------------------------------------------------------------------------------------------------------- 
    891 //  
    892 //-------------------------------------------------------------------------------------------------------------------------------- 
    893 void TreeSimplifier::ElijeVertices(Hoja& Hoja1, Hoja& Hoja2, long int count) 
    894 { 
    895         // criterio es el de los dos vertices más alejados del centro de la otra hoja 
    896          
     946        return which; 
     947} 
     948 
     949 
     950void TreeSimplifier::ChooseVertices(Hoja& leaf1, Hoja& leaf2, long int count) 
     951{ 
    897952        float a,b,c; 
    898953        float dist[4]; 
    899954        int indices[4]; 
    900955         
    901         // primero de la primera hoja cojo los dos primeros vertices 
    902  
    903  
    904         a = Vertex[Hoja1.Vert_Hoja[0]][0]; 
    905         b = Vertex[Hoja1.Vert_Hoja[0]][1]; 
    906         c = Vertex[Hoja1.Vert_Hoja[0]][2]; 
    907  
    908         dist[0] = ((Hoja2.Centro[0]-a)*(Hoja2.Centro[0]-a)) + ((Hoja2.Centro[1]-b)*(Hoja2.Centro[1]-b)) + 
    909                    ((Hoja2.Centro[2]-c)*(Hoja2.Centro[2]-c)); 
    910  
    911          
    912         a = Vertex[Hoja1.Vert_Hoja[1]][0]; 
    913         b = Vertex[Hoja1.Vert_Hoja[1]][1]; 
    914         c = Vertex[Hoja1.Vert_Hoja[1]][2]; 
    915  
    916         dist[1] = ((Hoja2.Centro[0]-a)*(Hoja2.Centro[0]-a)) + ((Hoja2.Centro[1]-b)*(Hoja2.Centro[1]-b)) + 
    917                    ((Hoja2.Centro[2]-c)*(Hoja2.Centro[2]-c)); 
    918  
    919         a = Vertex[Hoja1.Vert_Hoja[2]][0]; 
    920         b = Vertex[Hoja1.Vert_Hoja[2]][1]; 
    921         c = Vertex[Hoja1.Vert_Hoja[2]][2]; 
    922  
    923         dist[2] = ((Hoja2.Centro[0]-a)*(Hoja2.Centro[0]-a)) + ((Hoja2.Centro[1]-b)*(Hoja2.Centro[1]-b)) + 
    924                    ((Hoja2.Centro[2]-c)*(Hoja2.Centro[2]-c)); 
    925  
    926  
    927         a = Vertex[Hoja1.Vert_Hoja[3]][0]; 
    928         b = Vertex[Hoja1.Vert_Hoja[3]][1]; 
    929         c = Vertex[Hoja1.Vert_Hoja[3]][2]; 
    930  
    931         dist[3] = ((Hoja2.Centro[0]-a)*(Hoja2.Centro[0]-a)) + ((Hoja2.Centro[1]-b)*(Hoja2.Centro[1]-b)) + 
    932                    ((Hoja2.Centro[2]-c)*(Hoja2.Centro[2]-c)); 
     956        a = Vertex[leaf1.Vert_Hoja[0]][0]; 
     957        b = Vertex[leaf1.Vert_Hoja[0]][1]; 
     958        c = Vertex[leaf1.Vert_Hoja[0]][2]; 
     959 
     960        dist[0] = ((leaf2.Centro[0]-a)*(leaf2.Centro[0]-a)) + ((leaf2.Centro[1]-b)*(leaf2.Centro[1]-b)) + 
     961                   ((leaf2.Centro[2]-c)*(leaf2.Centro[2]-c)); 
     962 
     963         
     964        a = Vertex[leaf1.Vert_Hoja[1]][0]; 
     965        b = Vertex[leaf1.Vert_Hoja[1]][1]; 
     966        c = Vertex[leaf1.Vert_Hoja[1]][2]; 
     967 
     968        dist[1] = ((leaf2.Centro[0]-a)*(leaf2.Centro[0]-a)) + ((leaf2.Centro[1]-b)*(leaf2.Centro[1]-b)) + 
     969                   ((leaf2.Centro[2]-c)*(leaf2.Centro[2]-c)); 
     970 
     971        a = Vertex[leaf1.Vert_Hoja[2]][0]; 
     972        b = Vertex[leaf1.Vert_Hoja[2]][1]; 
     973        c = Vertex[leaf1.Vert_Hoja[2]][2]; 
     974 
     975        dist[2] = ((leaf2.Centro[0]-a)*(leaf2.Centro[0]-a)) + ((leaf2.Centro[1]-b)*(leaf2.Centro[1]-b)) + 
     976                   ((leaf2.Centro[2]-c)*(leaf2.Centro[2]-c)); 
     977 
     978 
     979        a = Vertex[leaf1.Vert_Hoja[3]][0]; 
     980        b = Vertex[leaf1.Vert_Hoja[3]][1]; 
     981        c = Vertex[leaf1.Vert_Hoja[3]][2]; 
     982 
     983        dist[3] = ((leaf2.Centro[0]-a)*(leaf2.Centro[0]-a)) + ((leaf2.Centro[1]-b)*(leaf2.Centro[1]-b)) + 
     984                   ((leaf2.Centro[2]-c)*(leaf2.Centro[2]-c)); 
    933985 
    934986        for ( int i=0;i<4;i++) indices[i]=i; 
    935987 
    936         DosMayores(dist, indices); 
    937          
    938         Hojasa[counth].Vert_Hoja[0] = Hoja1.Vert_Hoja[indices[0]];  
    939         Hojasa[counth].Vert_Hoja[1] = Hoja1.Vert_Hoja[indices[1]];  
    940          
    941         // segunda hoja los dos ultimos vertices 
    942  
    943          
    944         a = Vertex[Hoja2.Vert_Hoja[0]][0]; 
    945         b = Vertex[Hoja2.Vert_Hoja[0]][1]; 
    946         c = Vertex[Hoja2.Vert_Hoja[0]][2]; 
    947  
    948         dist[0] = ((Hoja1.Centro[0]-a)*(Hoja1.Centro[0]-a)) + ((Hoja1.Centro[1]-b)*(Hoja1.Centro[1]-b)) + 
    949                    ((Hoja1.Centro[2]-c)*(Hoja1.Centro[2]-c)); 
    950  
    951          
    952         a = Vertex[Hoja2.Vert_Hoja[1]][0]; 
    953         b = Vertex[Hoja2.Vert_Hoja[1]][1]; 
    954         c = Vertex[Hoja2.Vert_Hoja[1]][2]; 
    955  
    956         dist[1] = ((Hoja2.Centro[0]-a)*(Hoja2.Centro[0]-a)) + ((Hoja1.Centro[1]-b)*(Hoja1.Centro[1]-b)) + 
    957                    ((Hoja2.Centro[2]-c)*(Hoja2.Centro[2]-c)); 
    958  
    959         a = Vertex[Hoja2.Vert_Hoja[2]][0]; 
    960         b = Vertex[Hoja2.Vert_Hoja[2]][1]; 
    961         c = Vertex[Hoja2.Vert_Hoja[2]][2]; 
    962  
    963         dist[2] = ((Hoja1.Centro[0]-a)*(Hoja1.Centro[0]-a)) + ((Hoja1.Centro[1]-b)*(Hoja1.Centro[1]-b)) + 
    964                    ((Hoja1.Centro[2]-c)*(Hoja1.Centro[2]-c)); 
    965  
    966  
    967         a = Vertex[Hoja2.Vert_Hoja[3]][0]; 
    968         b = Vertex[Hoja2.Vert_Hoja[3]][1]; 
    969         c = Vertex[Hoja2.Vert_Hoja[3]][2]; 
    970  
    971         dist[3] = ((Hoja1.Centro[0]-a)*(Hoja1.Centro[0]-a)) + ((Hoja1.Centro[1]-b)*(Hoja1.Centro[1]-b)) + 
    972                    ((Hoja1.Centro[2]-c)*(Hoja1.Centro[2]-c)); 
     988        TwoGreater(dist, indices); 
     989         
     990        Leaves[countLeaves].Vert_Hoja[0] = leaf1.Vert_Hoja[indices[0]];  
     991        Leaves[countLeaves].Vert_Hoja[1] = leaf1.Vert_Hoja[indices[1]];  
     992         
     993 
     994         
     995        a = Vertex[leaf2.Vert_Hoja[0]][0]; 
     996        b = Vertex[leaf2.Vert_Hoja[0]][1]; 
     997        c = Vertex[leaf2.Vert_Hoja[0]][2]; 
     998 
     999        dist[0] = ((leaf1.Centro[0]-a)*(leaf1.Centro[0]-a)) + ((leaf1.Centro[1]-b)*(leaf1.Centro[1]-b)) + 
     1000                   ((leaf1.Centro[2]-c)*(leaf1.Centro[2]-c)); 
     1001 
     1002         
     1003        a = Vertex[leaf2.Vert_Hoja[1]][0]; 
     1004        b = Vertex[leaf2.Vert_Hoja[1]][1]; 
     1005        c = Vertex[leaf2.Vert_Hoja[1]][2]; 
     1006 
     1007        dist[1] = ((leaf2.Centro[0]-a)*(leaf2.Centro[0]-a)) + ((leaf1.Centro[1]-b)*(leaf1.Centro[1]-b)) + 
     1008                   ((leaf2.Centro[2]-c)*(leaf2.Centro[2]-c)); 
     1009 
     1010        a = Vertex[leaf2.Vert_Hoja[2]][0]; 
     1011        b = Vertex[leaf2.Vert_Hoja[2]][1]; 
     1012        c = Vertex[leaf2.Vert_Hoja[2]][2]; 
     1013 
     1014        dist[2] = ((leaf1.Centro[0]-a)*(leaf1.Centro[0]-a)) + ((leaf1.Centro[1]-b)*(leaf1.Centro[1]-b)) + 
     1015                   ((leaf1.Centro[2]-c)*(leaf1.Centro[2]-c)); 
     1016 
     1017 
     1018        a = Vertex[leaf2.Vert_Hoja[3]][0]; 
     1019        b = Vertex[leaf2.Vert_Hoja[3]][1]; 
     1020        c = Vertex[leaf2.Vert_Hoja[3]][2]; 
     1021 
     1022        dist[3] = ((leaf1.Centro[0]-a)*(leaf1.Centro[0]-a)) + ((leaf1.Centro[1]-b)*(leaf1.Centro[1]-b)) + 
     1023                   ((leaf1.Centro[2]-c)*(leaf1.Centro[2]-c)); 
    9731024 
    9741025        for ( int i=0;i<4;i++) indices[i]=i; 
    9751026 
    976         DosMayores(dist, indices); 
    977          
    978         Hojasa[counth].Vert_Hoja[2] = Hoja2.Vert_Hoja[indices[0]];  
    979         Hojasa[counth].Vert_Hoja[3] = Hoja2.Vert_Hoja[indices[1]];  
    980  
    981  
    982  
    983          
    984 } 
    985  
    986 //-------------------------------------------------------------------------------------------------------------------------------- 
    987 // AÑADE HOJAS  
    988 //-------------------------------------------------------------------------------------------------------------------------------- 
    989 //long int TreeSimplifier::Colapsa (Geometry::TreeSimplificationSequence *tss, float diametro) 
    990 long int TreeSimplifier::Colapsa(float diametro) 
    991 { 
    992         long int i=0, cual=-1; 
    993         long int otra = -1; 
    994         float coptmp, coptmp2, distmp, distmp2, criteriotmp; 
    995 //      char linea[250]; 
    996  
    997 //      cual=MinimaDistancia(); 
    998         cual=MinimoCriterio(); 
    999 //      otra = Hojasa[cual].hoja_cerca; //para la distancia 
    1000 //      otra = Hojasa[cual].hoja_cop; 
    1001         otra = Hojasa[cual].hoja_crit; 
     1027        TwoGreater(dist, indices); 
     1028         
     1029        Leaves[countLeaves].Vert_Hoja[2] = leaf2.Vert_Hoja[indices[0]];  
     1030        Leaves[countLeaves].Vert_Hoja[3] = leaf2.Vert_Hoja[indices[1]];  
     1031 
     1032 
     1033 
     1034         
     1035} 
     1036 
     1037// Add leaves 
     1038long int TreeSimplifier::Collapse(float diam) 
     1039{ 
     1040        long int i=0, which=-1; 
     1041        long int other = -1; 
     1042        float coptmp, coptmp2, distmp, distmp2, criteriatmp; 
     1043 
     1044        which=MinCriteria(); 
     1045        other = Leaves[which].hoja_crit; 
    10021046 
    10031047        //desactivo las hojas cercanas 
    1004         Hojasa[cual].existe = false; 
    1005         Hojasa[otra].existe = false; 
     1048        Leaves[which].existe = false; 
     1049        Leaves[other].existe = false; 
    10061050        //creo la hoja nueva 
    10071051 
    1008         Hojasa[counth].hoja_cerca = -1; 
    1009         Hojasa[counth].dist = 0; 
    1010         Hojasa[counth].hoja_cop = -1; 
    1011         Hojasa[counth].coplanar = 0; 
    1012  
    1013         Hojasa[counth].Cuantas_hojas = Hojasa[cual].Cuantas_hojas + Hojasa[otra].Cuantas_hojas; 
    1014         ElijeVertices(Hojasa[cual], Hojasa[otra], counth); 
    1015         Centroh (Hojasa[counth]); 
    1016         GetNormal ( Hojasa[counth]); 
    1017  
    1018         //18/09/01  
    1019         if (Hojasa[counth].Cuantas_hojas > 60 ) 
    1020         { 
    1021                         Hojasa[counth].existe = false; 
    1022                         activas--; 
     1052        Leaves[countLeaves].hoja_cerca = -1; 
     1053        Leaves[countLeaves].dist = 0; 
     1054        Leaves[countLeaves].hoja_cop = -1; 
     1055        Leaves[countLeaves].coplanar = 0; 
     1056 
     1057        Leaves[countLeaves].Cuantas_hojas = Leaves[which].Cuantas_hojas + Leaves[other].Cuantas_hojas; 
     1058//      Leaves[countLeaves].Cuantas_hojas = 10; 
     1059        ChooseVertices(Leaves[which], Leaves[other], countLeaves); 
     1060        CalculateLeafCenter (Leaves[countLeaves]); 
     1061        CalculateLeafNormal (Leaves[countLeaves]); 
     1062 
     1063        // find out the minimal octree node that can contain this leaf 
     1064        LeafOctree *onode = GetMinOctreeNodeForLeaf(octree,Leaves[countLeaves]); 
     1065        octree_owning_leaf[countLeaves] = onode; 
     1066        onode->leaves.push_back(countLeaves); 
     1067 
     1068/*      if (Leaves[countLeaves].Cuantas_hojas > 60 ) 
     1069        { 
     1070                        Leaves[countLeaves].existe = false; 
     1071                        activeLeaves--; 
    10231072        } 
    10241073        else 
    1025         { 
    1026                 //establezco el criterio para la hoja nueva 
    1027         Hojasa[counth].existe = true; 
    1028                 Hojasa[counth].criterio = 1000; 
    1029                 Hojasa[counth].id_triangulo[0] = counth*2; 
    1030                 Hojasa[counth].id_triangulo[1] = counth*2+1; 
    1031  
    1032                 //coplanaridad 
    1033                 for (int j = 0; j < (counth+1); j++) 
    1034                 { 
    1035                         if (( j != counth) && ( Hojasa[j].existe == true)) // si la hoja aun existe 
     1074        {               */ 
     1075        Leaves[countLeaves].existe = true; 
     1076                Leaves[countLeaves].criterio = 1000000.0f; 
     1077                Leaves[countLeaves].id_triangulo[0] = countLeaves*2; 
     1078                Leaves[countLeaves].id_triangulo[1] = countLeaves*2+1; 
     1079 
     1080                float area_leaf_i = CalculateLeafArea(Leaves[i])/diam; 
     1081 
     1082                for (int j = 0; j < (countLeaves+1); j++){ 
     1083/*              int visit_parents = VISIT_PARENTS_DEEP; 
     1084                for (LeafOctree *octreenode = octree_owning_leaf[i]; octreenode && visit_parents>=0; octreenode=octreenode->parent, visit_parents--) 
     1085                { 
     1086                        for (std::vector<int>::iterator it=octreenode->leaves.begin(); it!=octreenode->leaves.end(); it++) 
    10361087                        { 
    1037                         //coplanaridad y lo invierto 
    1038                         coptmp2 = Hojasa[counth].Coplanaridad(Hojasa[j]);  
    1039                         coptmp = 1 - coptmp2; 
    1040                         //distancia y la normalizo 
    1041                         //distmp2 = Hojasa[counth].Distancia(Hojasa[j]);  
    1042                         distmp2 = Hausdorff(Hojasa[counth], Hojasa[j]);  
    1043                         distmp = distmp2 / diametro; 
    1044                         // calculo el criterio para esa hoja 
    1045                         criteriotmp = (( K1 * distmp * distmp ) + (K2 * coptmp * distmp))/ (K1 + K2); 
    1046                         //selecciono el criterio menor 
    1047                         if (Hojasa[counth].criterio > criteriotmp)  
    1048                         { 
    1049                                 Hojasa[counth].criterio = criteriotmp; 
    1050                                 Hojasa[counth].hoja_crit = j;} 
    1051                         } 
    1052                 } 
    1053         }        
     1088                                int j = *it;*/ 
     1089 
     1090                                if (j != countLeaves && Leaves[j].existe) 
     1091                                { 
     1092                                        coptmp2 = Leaves[countLeaves].Coplanaridad(Leaves[j]);  
     1093                                        coptmp = 1 - coptmp2; 
     1094                                        //distmp2 = HausdorffOptimized(Leaves[countLeaves], Leaves[j]); 
     1095                                        distmp2 = DistanceFromCenters(Leaves[countLeaves], Leaves[j]); 
     1096                                        distmp = distmp2 / diam; 
     1097                                         
     1098                                        criteriatmp = (( K1 * distmp * distmp ) + (K2 * coptmp * distmp))/ (K1 + K2); 
     1099                                        criteriatmp *= CalculateLeafArea(Leaves[j])/diam + area_leaf_i; 
     1100                                        criteriatmp *= Leaves[j].Cuantas_hojas + Leaves[i].Cuantas_hojas; 
     1101                                         
     1102                                        if (Leaves[countLeaves].criterio > criteriatmp)  
     1103                                        { 
     1104                                                Leaves[countLeaves].criterio = criteriatmp; 
     1105                                                Leaves[countLeaves].hoja_crit = j; 
     1106                                        } 
     1107                                } 
     1108        //              } 
     1109                } 
     1110//      }        
    10541111 
    10551112        // Crear el paso de simplificación 
    10561113        Geometry::TreeSimplificationSequence::Step pasosimp; 
    1057         pasosimp.mV0=Hojasa[cual].id_triangulo[0]; 
    1058         pasosimp.mV1=Hojasa[cual].id_triangulo[1]; 
    1059         pasosimp.mT0=Hojasa[otra].id_triangulo[0]; 
    1060         pasosimp.mT1=Hojasa[otra].id_triangulo[1]; 
     1114        pasosimp.mV0=Leaves[which].id_triangulo[0]; 
     1115        pasosimp.mV1=Leaves[which].id_triangulo[1]; 
     1116        pasosimp.mT0=Leaves[other].id_triangulo[0]; 
     1117        pasosimp.mT1=Leaves[other].id_triangulo[1]; 
    10611118 
    10621119        // Nuevos vértices 
    1063         pasosimp.mNewQuad[0]=Hojasa[counth].Vert_Hoja[0]; 
    1064         pasosimp.mNewQuad[1]=Hojasa[counth].Vert_Hoja[1]; 
    1065         pasosimp.mNewQuad[2]=Hojasa[counth].Vert_Hoja[2]; 
    1066         pasosimp.mNewQuad[3]=Hojasa[counth].Vert_Hoja[3]; 
     1120        pasosimp.mNewQuad[0]=Leaves[countLeaves].Vert_Hoja[0]; 
     1121        pasosimp.mNewQuad[1]=Leaves[countLeaves].Vert_Hoja[1]; 
     1122        pasosimp.mNewQuad[2]=Leaves[countLeaves].Vert_Hoja[2]; 
     1123        pasosimp.mNewQuad[3]=Leaves[countLeaves].Vert_Hoja[3]; 
    10671124 
    10681125        // Insertar el paso de simplificación 
     
    10701127 
    10711128        //incremento el numero de hojas 
    1072         counth++; 
    1073         activas--; 
    1074         return (counth-1);//porque lo he incrementado en la linea de antes 
    1075 } 
    1076  
    1077 //-------------------------------------------------------------------------------------------------------------------------------- 
    1078 // ESCRIBE EL mIndex EN EL MESH DE SALIDA 
    1079 //-------------------------------------------------------------------------------------------------------------------------------- 
    1080 void TreeSimplifier::EscribeMesh(int idMeshLeaves)  
    1081 { 
    1082         // Calcular el número de indices después de simplificar 
    1083         long int tamIndex       =       activas * 6; // Cada hoja tiene 6 índices 
    1084  
    1085         //      2006-02-21. 
    1086         float                   percent; 
    1087         long    int     update; 
    1088          
     1129        countLeaves++; 
     1130        activeLeaves--; 
     1131        return (countLeaves-1);//porque lo he incrementado en la linea de antes 
     1132} 
     1133 
     1134void TreeSimplifier::BuildOutputMesh(int idMeshLeaves)  
     1135{ 
     1136        // Calculate the resulting index count after simplifying 
     1137        long int tamIndex       =       activeLeaves * 6; // Each leaf has got 6 indices 
     1138 
    10891139        delete [] mesh->mSubMesh[idMeshLeaves].mIndex; 
    10901140        mesh->mSubMesh[idMeshLeaves].mIndexCount=tamIndex; 
    10911141        mesh->mSubMesh[idMeshLeaves].mIndex=new Geometry::Index[tamIndex]; 
    10921142 
    1093         // Recorrer las hojas, comprobar las que están activas y copiar los índices al mesh. 
    1094         Geometry::Index indice=0; 
    1095  
    1096         //      2006-02-21. 
    1097         update  =       counth  / 10; 
    1098         percent =       1; 
    1099          
    1100         for (long j=0; j<counth;j++) 
    1101         { 
    1102                 //      2006-02-21 
    1103                 if (mUPB        &&      ((j % update) == 0)) 
    1104                 { 
    1105                         mUPB(percent); 
    1106                 } 
     1143        // Iterate through all active leaves and dump them to the final mesh 
     1144        Geometry::Index index=0; 
     1145 
     1146        int update_each = countLeaves / 10; 
     1147         
     1148        for (long j=0; j<countLeaves;j++) 
     1149        { 
     1150                static int ticks_since_last_update = 0; 
     1151                if (mUPB && ticks_since_last_update>=update_each) 
     1152                { 
     1153                        ticks_since_last_update=0; 
     1154                        mUPB(1); 
     1155                } 
     1156                ticks_since_last_update++; 
    11071157                 
    1108                 if ( Hojasa[j].existe == true) // si la hoja aun existe 
    1109                 { 
    1110                         mesh->mSubMesh[idMeshLeaves].mIndex[indice]=Hojasa[j].Vert_Hoja[0]; 
    1111                         mesh->mSubMesh[idMeshLeaves].mIndex[indice+1]=Hojasa[j].Vert_Hoja[1]; 
    1112                         mesh->mSubMesh[idMeshLeaves].mIndex[indice+2]=Hojasa[j].Vert_Hoja[2]; 
    1113                         mesh->mSubMesh[idMeshLeaves].mIndex[indice+3]=Hojasa[j].Vert_Hoja[2]; 
    1114                         mesh->mSubMesh[idMeshLeaves].mIndex[indice+4]=Hojasa[j].Vert_Hoja[1]; 
    1115                         mesh->mSubMesh[idMeshLeaves].mIndex[indice+5]=Hojasa[j].Vert_Hoja[3]; 
    1116                         indice=indice+6; 
    1117                 } 
    1118         } 
    1119 } 
     1158                if (Leaves[j].existe) 
     1159                { 
     1160//                      if (index<6) 
     1161//                      { 
     1162                                mesh->mSubMesh[idMeshLeaves].mIndex[index]=Leaves[j].Vert_Hoja[0]; 
     1163                                mesh->mSubMesh[idMeshLeaves].mIndex[index+1]=Leaves[j].Vert_Hoja[1]; 
     1164                                mesh->mSubMesh[idMeshLeaves].mIndex[index+2]=Leaves[j].Vert_Hoja[2]; 
     1165                                mesh->mSubMesh[idMeshLeaves].mIndex[index+3]=Leaves[j].Vert_Hoja[2]; 
     1166                                mesh->mSubMesh[idMeshLeaves].mIndex[index+4]=Leaves[j].Vert_Hoja[1]; 
     1167                                mesh->mSubMesh[idMeshLeaves].mIndex[index+5]=Leaves[j].Vert_Hoja[3]; 
     1168/*                      } 
     1169                        else 
     1170                        { 
     1171                                mesh->mSubMesh[idMeshLeaves].mIndex[index]=0; 
     1172                                mesh->mSubMesh[idMeshLeaves].mIndex[index+1]=0; 
     1173                                mesh->mSubMesh[idMeshLeaves].mIndex[index+2]=0; 
     1174                                mesh->mSubMesh[idMeshLeaves].mIndex[index+3]=0; 
     1175                                mesh->mSubMesh[idMeshLeaves].mIndex[index+4]=0; 
     1176                                mesh->mSubMesh[idMeshLeaves].mIndex[index+5]=0; 
     1177                        }*/ 
     1178                        index=index+6; 
     1179                } 
     1180        } 
     1181} 
     1182 
     1183LeafOctree* TreeSimplifier::CreateLeafOctree(int deep) 
     1184{ 
     1185        LeafOctree *leafoctree = new LeafOctree; 
     1186        leafoctree->parent=NULL; 
     1187        leafoctree->left = Vertex[0][0]; 
     1188        leafoctree->right = Vertex[0][0]; 
     1189        leafoctree->bottom = Vertex[0][1]; 
     1190        leafoctree->top = Vertex[0][1]; 
     1191        leafoctree->front = Vertex[0][2]; 
     1192        leafoctree->back = Vertex[0][2]; 
     1193 
     1194        // calcualte the limits of the octree 
     1195        for (int i=0; i<vertex_count; i++) 
     1196        { 
     1197                if (leafoctree->left>Vertex[i][0]) 
     1198                        leafoctree->left=Vertex[i][0]; 
     1199                if (leafoctree->right<Vertex[i][0]) 
     1200                        leafoctree->right=Vertex[i][0]; 
     1201                if (leafoctree->bottom>Vertex[i][1]) 
     1202                        leafoctree->bottom=Vertex[i][1]; 
     1203                if (leafoctree->top<Vertex[i][1]) 
     1204                        leafoctree->top=Vertex[i][1]; 
     1205                if (leafoctree->front>Vertex[i][2]) 
     1206                        leafoctree->front=Vertex[i][2]; 
     1207                if (leafoctree->back<Vertex[i][2]) 
     1208                        leafoctree->back=Vertex[i][2]; 
     1209        } 
     1210 
     1211        // setup the initial leaves buffer 
     1212        leafoctree->leaves.clear(); 
     1213        octree_owning_leaf=new LeafOctree*[countLeaves*2]; // *2 to reserve memory for all simplified leaves 
     1214        for (int i=0; i<countLeaves; i++) 
     1215        { 
     1216                leafoctree->leaves.push_back(i); 
     1217                octree_owning_leaf[i] = leafoctree; 
     1218        } 
     1219 
     1220        // generate the octree given an arbitrary depth 
     1221        RecursiveCreateLeafOctree(leafoctree,deep); 
     1222 
     1223        // fill the octree 
     1224        RecursiveFillOctreeWithLeaves(leafoctree); 
     1225 
     1226        return leafoctree; 
     1227} 
     1228 
     1229void TreeSimplifier::RecursiveCreateLeafOctree(LeafOctree *parent, int deep) 
     1230{ 
     1231        for (int i=0; i<8; i++) 
     1232        { 
     1233                parent->children[i] = NULL; 
     1234                if (deep>0) 
     1235                { 
     1236                        LeafOctree *child = parent->children[i] = new LeafOctree; 
     1237 
     1238                        child->parent = parent; 
     1239                        switch(i) 
     1240                        { 
     1241                        case 0:  
     1242                                child->left=parent->left;  
     1243                                child->right=(parent->left+parent->right)*0.5f; 
     1244                                child->bottom=(parent->bottom+parent->top)*0.5f;  
     1245                                child->top=parent->top; 
     1246                                child->front=parent->front; 
     1247                                child->back=(parent->front+parent->back)*0.5f; break; 
     1248                        case 1:  
     1249                                child->left=(parent->left+parent->right)*0.5f;  
     1250                                child->right=parent->right; 
     1251                                child->bottom=(parent->bottom+parent->top)*0.5f;  
     1252                                child->top=parent->top; 
     1253                                child->front=parent->front; 
     1254                                child->back=(parent->front+parent->back)*0.5f; break; 
     1255                        case 2:  
     1256                                child->left=parent->left; 
     1257                                child->right=(parent->left+parent->right)*0.5f; 
     1258                                child->bottom=parent->bottom; 
     1259                                child->top=(parent->bottom+parent->top)*0.5f; 
     1260                                child->front=parent->front; 
     1261                                child->back=(parent->front+parent->back)*0.5f; break; 
     1262                        case 3:  
     1263                                child->left=(parent->left+parent->right)*0.5f; 
     1264                                child->right=parent->right; 
     1265                                child->bottom=parent->bottom; 
     1266                                child->top=(parent->bottom+parent->top)*0.5f; 
     1267                                child->front=parent->front; 
     1268                                child->back=(parent->front+parent->back)*0.5f; break; 
     1269                        case 4:  
     1270                                child->left=parent->left;  
     1271                                child->right=(parent->left+parent->right)*0.5f; 
     1272                                child->bottom=(parent->bottom+parent->top)*0.5f;  
     1273                                child->top=parent->top; 
     1274                                child->back=parent->back; 
     1275                                child->front=(parent->front+parent->back)*0.5f; break; 
     1276                        case 5:  
     1277                                child->left=(parent->left+parent->right)*0.5f;  
     1278                                child->right=parent->right; 
     1279                                child->bottom=(parent->bottom+parent->top)*0.5f;  
     1280                                child->top=parent->top; 
     1281                                child->back=parent->back; 
     1282                                child->front=(parent->front+parent->back)*0.5f; break; 
     1283                        case 6:  
     1284                                child->left=parent->left; 
     1285                                child->right=(parent->left+parent->right)*0.5f; 
     1286                                child->bottom=parent->bottom; 
     1287                                child->top=(parent->bottom+parent->top)*0.5f; 
     1288                                child->back=parent->back; 
     1289                                child->front=(parent->front+parent->back)*0.5f; break; 
     1290                        case 7:  
     1291                                child->left=(parent->left+parent->right)*0.5f; 
     1292                                child->right=parent->right; 
     1293                                child->bottom=parent->bottom; 
     1294                                child->top=(parent->bottom+parent->top)*0.5f; 
     1295                                child->back=parent->back; 
     1296                                child->front=(parent->front+parent->back)*0.5f; break; 
     1297                        } 
     1298                        RecursiveCreateLeafOctree(parent->children[i],deep-1); 
     1299                } 
     1300        } 
     1301 
     1302} 
     1303 
     1304void TreeSimplifier::RecursiveFillOctreeWithLeaves(LeafOctree *o) 
     1305{    
     1306        for (int i=0; i<8; i++) 
     1307        { 
     1308                LeafOctree *child = o->children[i]; 
     1309                if (child) 
     1310                { 
     1311                        for (std::vector<int>::iterator it=o->leaves.begin(); it!=o->leaves.end(); ) 
     1312                        { 
     1313                                int idleaf = *it; 
     1314                                int idv0 = Leaves[idleaf].Vert_Hoja[0]; 
     1315                                int idv1 = Leaves[idleaf].Vert_Hoja[1]; 
     1316                                int idv2 = Leaves[idleaf].Vert_Hoja[2]; 
     1317                                int idv3 = Leaves[idleaf].Vert_Hoja[3]; 
     1318 
     1319                                float * v0 = Vertex[idv0]; 
     1320                                float * v1 = Vertex[idv1]; 
     1321                                float * v2 = Vertex[idv2]; 
     1322                                float * v3 = Vertex[idv3]; 
     1323 
     1324                                // if the leaf fits completely inside a child, the child owns it 
     1325                                if (child->PointInsideOctree(v0[0],v0[1],v0[2]) && 
     1326                                        child->PointInsideOctree(v1[0],v1[1],v1[2]) && 
     1327                                        child->PointInsideOctree(v2[0],v2[1],v2[2]) && 
     1328                                        child->PointInsideOctree(v3[0],v3[1],v3[2])) 
     1329                                { 
     1330                                        child->leaves.push_back(idleaf); 
     1331                                        it = o->leaves.erase(it); 
     1332                                        octree_owning_leaf[idleaf] = child; 
     1333                                } 
     1334                                else 
     1335                                        it++;  
     1336                        } 
     1337                        // recurse all valid children 
     1338                        RecursiveFillOctreeWithLeaves(o->children[i]); 
     1339                } 
     1340        } 
     1341} 
     1342 
     1343void TreeSimplifier::SetCriteriaOptimized(float diam) 
     1344{ 
     1345        float coptmp2, coptmp, distmp2, distmp, criteriatmp; 
     1346        int i, j, nleavesi, nleavesj; 
     1347 
     1348        int update_each = countLeaves / 20; 
     1349         
     1350        for ( i=0; i<countLeaves;i++) 
     1351        { 
     1352                static int ticks_since_last_update = 0; 
     1353                if (mUPB && ticks_since_last_update>=update_each) 
     1354                { 
     1355                        ticks_since_last_update=0; 
     1356                        mUPB(1); 
     1357                } 
     1358                ticks_since_last_update++; 
     1359                 
     1360                if (Leaves[i].existe == true) 
     1361                { 
     1362                        Leaves[i].criterio = 1000000.0f; 
     1363                        nleavesi = int(Leaves[i].Cuantas_hojas); 
     1364                        float area_leaf_i = CalculateLeafArea(Leaves[i])/diam; 
     1365 
     1366                        // Use only the leaves which belong the the same octree node as leaf i or to its parents                 
     1367                        int visit_parents = VISIT_PARENTS_DEEP; 
     1368                        for (LeafOctree *octreenode = octree_owning_leaf[i]; octreenode; octreenode=octreenode->parent, visit_parents--) 
     1369                        { 
     1370                                for (std::vector<int>::iterator it=octreenode->leaves.begin(); it!=octreenode->leaves.end(); it++) 
     1371                                { 
     1372                                        j = *it; 
     1373//                              for (j=0; j<countLeaves; j++) 
     1374//                              { 
     1375                                        if (j!=i && Leaves[j].existe) 
     1376                                        { 
     1377                                                nleavesj = int(Leaves[j].Cuantas_hojas); 
     1378 
     1379        //                                      if ( abs((nleavesi - nleavesj)) < 2) 
     1380        //                                      {                                                        
     1381                                                        coptmp2 = Leaves[i].Coplanaridad(Leaves[j]); 
     1382                                                        coptmp = 1 - coptmp2; 
     1383 
     1384                                                        //distmp2 = HausdorffOptimized( Leaves[i], Leaves[j]);  
     1385                                                        distmp2 = DistanceFromCenters(Leaves[i], Leaves[j]);  
     1386                                                        distmp = distmp2 / diam; 
     1387 
     1388                                                        //criteriatmp = (( K1 * distmp * distmp ) + (K2 * coptmp * distmp))/ (K1 + K2); 
     1389                                                        criteriatmp = distmp; 
     1390                                                        // select the lowest 
     1391                                                        criteriatmp *= CalculateLeafArea(Leaves[j])/diam + area_leaf_i; 
     1392                                                        criteriatmp *= Leaves[j].Cuantas_hojas + Leaves[i].Cuantas_hojas; 
     1393                                                        if (Leaves[i].criterio > criteriatmp) 
     1394                                                        { 
     1395                                                                Leaves[i].criterio = criteriatmp; 
     1396                                                                Leaves[i].hoja_crit = j; 
     1397                                                        } 
     1398                //                              } 
     1399                                        } 
     1400                                }                                
     1401                        } 
     1402                } 
     1403        } 
     1404} 
     1405 
     1406 
     1407void TreeSimplifier::SetCriteria2Optimized(float diam, long int newleaf) 
     1408{ 
     1409        float  coptmp2, coptmp, distmp2, distmp, criteriatmp; 
     1410        int i, j, nleavesi, nleavesj; 
     1411         
     1412        for (i = 0; i < countLeaves; i++) 
     1413        { 
     1414                if (Leaves[i].existe && i!=newleaf) 
     1415                {        
     1416                        float area_leaf_i = CalculateLeafArea(Leaves[i])/diam; 
     1417                        nleavesi = int(Leaves[i].Cuantas_hojas); 
     1418                        if ( Leaves[Leaves[i].hoja_crit].existe == false) 
     1419                        { 
     1420                                Leaves[i].criterio = 1000000.0f; 
     1421 
     1422                                int visit_parents = VISIT_PARENTS_DEEP; 
     1423                                for (LeafOctree *octreenode = octree_owning_leaf[i]; octreenode; octreenode=octreenode->parent, visit_parents--) 
     1424                                { 
     1425                                        for (std::vector<int>::iterator it=octreenode->leaves.begin(); it!=octreenode->leaves.end(); it++) 
     1426                                        { 
     1427                                                j = *it; 
     1428        //                      for (j=0; j<countLeaves; j++) 
     1429        //                      { 
     1430                                                if (j!=i && Leaves[j].existe) 
     1431                                                { 
     1432                                                        nleavesj = int(Leaves[j].Cuantas_hojas); 
     1433 
     1434//                                                      if ( abs((nleavesi - nleavesj)) < 2) 
     1435//                                                      { 
     1436                                                                coptmp2 = Leaves[i].Coplanaridad(Leaves[j]);  
     1437                                                                coptmp = 1 - coptmp2;    
     1438                                                         
     1439                                                         
     1440                                                                //distmp2 = HausdorffOptimized( Leaves[i],  Leaves[j]);  
     1441                                                                distmp2 = DistanceFromCenters( Leaves[i], Leaves[j]);  
     1442                                                                distmp = distmp2 / diam; 
     1443 
     1444                                                                criteriatmp = (( K1 * distmp * distmp ) + (K2 * coptmp * distmp))/ (K1 + K2); 
     1445                                                                criteriatmp *= CalculateLeafArea(Leaves[j])/diam + area_leaf_i; 
     1446                                                                criteriatmp *= Leaves[j].Cuantas_hojas + Leaves[i].Cuantas_hojas; 
     1447                                                                 
     1448                                                                // select the leaf with the lowest criteria 
     1449                                                                if (Leaves[i].criterio > criteriatmp)  
     1450                                                                { 
     1451                                                                        Leaves[i].criterio = criteriatmp; 
     1452                                                                        Leaves[i].hoja_crit = j; 
     1453                                                                } 
     1454                                                //      } 
     1455                                                } 
     1456                                        } 
     1457                                } 
     1458                        } 
     1459                        else 
     1460                        {  
     1461                                nleavesj = int(Leaves[newleaf].Cuantas_hojas); 
     1462 
     1463//                              if ( abs((nleavesi - nleavesj)) < 2) 
     1464//                              { 
     1465                                        coptmp2 = Leaves[i].Coplanaridad(Leaves[newleaf]);  
     1466                                        coptmp = 1 - coptmp2; 
     1467 
     1468                                        //distmp2 = HausdorffOptimized( Leaves[i], Leaves[newleaf]);  
     1469                                        distmp2 = DistanceFromCenters( Leaves[i], Leaves[newleaf]);  
     1470                                        distmp = distmp2 / diam; 
     1471                                         
     1472                                        criteriatmp = (( K1 * distmp * distmp ) + (K2 * coptmp * distmp))/ (K1 + K2); 
     1473                                        criteriatmp *= CalculateLeafArea(Leaves[newleaf])/diam + area_leaf_i; 
     1474                                        criteriatmp *= Leaves[newleaf].Cuantas_hojas + Leaves[i].Cuantas_hojas; 
     1475                                         
     1476                                        if (Leaves[i].criterio > criteriatmp)  
     1477                                        {        
     1478                                                Leaves[i].criterio = criteriatmp; 
     1479                                                Leaves[i].hoja_crit = newleaf; 
     1480                                        } 
     1481//                              } 
     1482                        } 
     1483                } 
     1484        } 
     1485} 
     1486 
     1487 
     1488LeafOctree *TreeSimplifier::GetMinOctreeNodeForLeaf(LeafOctree *start, const Hoja &leaf) 
     1489{ 
     1490        int idv0 = leaf.Vert_Hoja[0]; 
     1491        int idv1 = leaf.Vert_Hoja[1]; 
     1492        int idv2 = leaf.Vert_Hoja[2]; 
     1493        int idv3 = leaf.Vert_Hoja[3]; 
     1494 
     1495        float * v0 = Vertex[idv0]; 
     1496        float * v1 = Vertex[idv1]; 
     1497        float * v2 = Vertex[idv2]; 
     1498        float * v3 = Vertex[idv3]; 
     1499 
     1500        if (start->PointInsideOctree(v0[0],v0[1],v0[2]) && 
     1501                start->PointInsideOctree(v1[0],v1[1],v1[2]) && 
     1502                start->PointInsideOctree(v2[0],v2[1],v2[2]) && 
     1503                start->PointInsideOctree(v3[0],v3[1],v3[2])) 
     1504        { 
     1505                return start; 
     1506        } 
     1507 
     1508        for (int i=0; i<8; i++) 
     1509                if (start->children[i]) 
     1510                { 
     1511                        LeafOctree *selectedNode = GetMinOctreeNodeForLeaf(start->children[i],leaf); 
     1512                        if (selectedNode) 
     1513                                return selectedNode; 
     1514                } 
     1515 
     1516        return NULL; 
     1517} 
     1518 
     1519float TreeSimplifier::DistanceFromCenters(const Hoja &leaf1, const Hoja &leaf2) const 
     1520{ 
     1521        float onex, oney, onez; 
     1522        float twox, twoy, twoz; 
     1523        float threex, threey, threez; 
     1524        float fourx, foury, fourz; 
     1525        float x1, y1, z1; 
     1526        float x2, y2, z2; 
     1527        float x3, y3, z3; 
     1528        float x4, y4, z4; 
     1529 
     1530        onex   = Vertex[leaf1.Vert_Hoja[0]][0]; oney   = Vertex[leaf1.Vert_Hoja[0]][1]; onez   = Vertex[leaf1.Vert_Hoja[0]][2]; 
     1531        twox   = Vertex[leaf1.Vert_Hoja[1]][0]; twoy   = Vertex[leaf1.Vert_Hoja[1]][1]; twoz   = Vertex[leaf1.Vert_Hoja[1]][2]; 
     1532        threex = Vertex[leaf1.Vert_Hoja[2]][0]; threey = Vertex[leaf1.Vert_Hoja[2]][1]; threez = Vertex[leaf1.Vert_Hoja[2]][2]; 
     1533        fourx  = Vertex[leaf1.Vert_Hoja[3]][0]; foury  = Vertex[leaf1.Vert_Hoja[3]][1]; fourz  = Vertex[leaf1.Vert_Hoja[3]][2]; 
     1534 
     1535        float center1x = (onex + twox + threex + fourx)*0.25f; 
     1536        float center1y = (oney + twoy + threey + foury)*0.25f; 
     1537        float center1z = (onez + twoz + threez + fourz)*0.25f; 
     1538 
     1539        x1 = Vertex[leaf2.Vert_Hoja[0]][0]; y1 = Vertex[leaf2.Vert_Hoja[0]][1]; z1 = Vertex[leaf2.Vert_Hoja[0]][2]; 
     1540        x2 = Vertex[leaf2.Vert_Hoja[1]][0]; y2 = Vertex[leaf2.Vert_Hoja[1]][1]; z2 = Vertex[leaf2.Vert_Hoja[1]][2]; 
     1541        x3 = Vertex[leaf2.Vert_Hoja[2]][0]; y3 = Vertex[leaf2.Vert_Hoja[2]][1]; z3 = Vertex[leaf2.Vert_Hoja[2]][2]; 
     1542        x4 = Vertex[leaf2.Vert_Hoja[3]][0]; y4 = Vertex[leaf2.Vert_Hoja[3]][1]; z4 = Vertex[leaf2.Vert_Hoja[3]][2]; 
     1543 
     1544        float center2x = (x1 + x2 + x3 + x4)*0.25f; 
     1545        float center2y = (y1 + y2 + y3 + y4)*0.25f; 
     1546        float center2z = (z1 + z2 + z3 + z4)*0.25f; 
     1547 
     1548        return distan(center1x,center1y,center1z,center2x,center2y,center2z); 
     1549} 
     1550 
     1551 
     1552bool TreeSimplifier::PruneOctree(LeafOctree *octree) 
     1553{ 
     1554        if (octree->HasChildren()) 
     1555        { 
     1556                for (int i=0; i<8; i++) 
     1557                        if (octree->children[i]) 
     1558                                if (PruneOctree(octree->children[i])) // if child was pruned, nullify it 
     1559                                        octree->children[i]=NULL;                        
     1560        } 
     1561        else 
     1562        { 
     1563                if (octree->parent) 
     1564                { 
     1565                        for (std::vector<int>::iterator it=octree->leaves.begin(); it!=octree->leaves.end(); it++) 
     1566                        { 
     1567                                int idleaf = *it; 
     1568                                octree->parent->leaves.push_back(idleaf); 
     1569                                octree_owning_leaf[idleaf] = octree->parent; 
     1570                        } 
     1571                        return true; 
     1572                } 
     1573        } 
     1574        return false; 
     1575} 
     1576 
     1577void TreeSimplifier::CrossProduct(const float *v1, const float *v2, float *res) const 
     1578{ 
     1579        res[0] = v1[1]*v2[2] - v1[2]*v2[1]; 
     1580        res[1] = v1[2]*v2[0] - v1[0]*v2[2]; 
     1581        res[2] = v1[0]*v2[1] - v1[1]*v2[0]; 
     1582} 
     1583 
     1584float TreeSimplifier::SquaredModule(const float *v) const 
     1585{ 
     1586        return (v[0]*v[0] + v[1]*v[1] + v[2]*v[2]); 
     1587} 
     1588 
     1589 
     1590float TreeSimplifier::CalculateLeafArea(Hoja &leaf) const 
     1591{ 
     1592        int idv0 = leaf.Vert_Hoja[0]; 
     1593        int idv1 = leaf.Vert_Hoja[1]; 
     1594        int idv2 = leaf.Vert_Hoja[2]; 
     1595        int idv3 = leaf.Vert_Hoja[3]; 
     1596 
     1597        float * v0 = Vertex[idv0]; 
     1598        float * v1 = Vertex[idv1]; 
     1599        float * v2 = Vertex[idv2]; 
     1600        float * v3 = Vertex[idv3]; 
     1601 
     1602        float v1v0[3] = {v1[0]-v0[0],v1[1]-v0[1],v1[2]-v0[2]}; 
     1603        float v2v0[3] = {v2[0]-v0[0],v2[1]-v0[1],v2[2]-v0[2]}; 
     1604        float v2v1[3] = {v2[0]-v1[0],v2[1]-v1[1],v2[2]-v1[2]}; 
     1605        float v3v1[3] = {v3[0]-v1[0],v3[1]-v1[1],v3[2]-v1[2]}; 
     1606         
     1607        float cross1[3], cross2[3]; 
     1608 
     1609        CrossProduct(v1v0,v2v0,cross1); 
     1610        CrossProduct(v2v1,v3v1,cross2); 
     1611 
     1612        float mod1 = SquaredModule(cross1); 
     1613        float mod2 = SquaredModule(cross2); 
     1614 
     1615        return mod1*0.5f + mod2*0.5f; 
     1616} 
  • GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/SimplificationMethod.cpp

    r986 r1007  
    222222        simplifstep.y = (float)vdesp[qslim::Y]; 
    223223        simplifstep.z = (float)vdesp[qslim::Z]; 
    224         simplifstep.mV1 = v0->validID(); // the simplification method returns as v0 the alive vertex 
    225         simplifstep.mV0 = v1->validID(); // the simplification method returns as v1 the dead vertex 
    226  
    227         // Number of triangles that are removed in this simplification step 
    228         int _numDelTris = 0; // 1 or 2 triangles can be removed 
    229  
    230         for (i=0; i<changed.length(); i++) 
    231         { 
    232                 if (! changed(i)->isValid()) 
     224         
     225        //      Submeshes which pertains each vertex 
     226        simplifstep.mV1 = v0->validID();  
     227 
     228        //      The simplification method returns as v1 the dead vertex. 
     229        simplifstep.mV0 = v1->validID(); 
     230 
     231        //      Number of triangles that are removed in this simplification step. 
     232        int _numDelTris = 0; // 1 or 2 triangles can be removed. 
     233 
     234        for (i = 0;     i < changed.length();   i++) 
     235        { 
     236                if (!changed(i)->isValid()) 
     237                { 
    233238                        _numDelTris++; 
    234         } 
    235         int del_index=0; 
     239                } 
     240        } 
     241 
     242        int del_index   =       0; 
    236243 
    237244        // mModfaces y mT0, mT1 of simplifstep stores the triangles id's -> geomesh has not triangles id's 
     
    239246        { 
    240247                qslim::Face *auxface = changed(i); 
    241                 if (auxface->isValid())  
     248 
     249                if (auxface->isValid()) 
    242250                { 
    243251                        // Modified triangles 
    244252                        simplifstep.mModfaces.push_back(auxface->validID()); 
    245253                } 
    246                 else  
     254                else 
    247255                { 
    248256                        // Removed triangles 
     
    252260                                simplifstep.mT1=auxface->validID(); 
    253261                        } 
    254                         else  
    255                         { 
    256                                 if(del_index==0)  
     262                        else 
     263                        { 
     264                                if(del_index==0) 
    257265                                { 
    258266                                        simplifstep.mT0=auxface->validID(); 
    259267                                        del_index++; 
    260268                                } 
    261                                 else  
     269                                else 
    262270                                { 
    263271                                        simplifstep.mT1=auxface->validID(); 
  • GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/SimplificationMethod.h

    r981 r1007  
    2222        int initialFaceCount; 
    2323 
    24         inline qslim::vert_info& vertex_info(qslim::Vertex *v){ return vinfo(v->validID()); } 
    25         qslim::real pair_mesh_penalty(qslim::Model& M, qslim::Vertex *v1, qslim::Vertex *v2, qslim::Vec3& vnew); 
    26         int predict_face(qslim::Face& F, qslim::Vertex *v1, qslim::Vertex *v2, qslim::Vec3& vnew, qslim::Vec3& f1, qslim::Vec3& f2, qslim::Vec3& f3); 
     24        inline qslim::vert_info& vertex_info(qslim::Vertex *v) 
     25        { 
     26                return vinfo(v->validID()); 
     27        } 
     28         
     29        qslim::real pair_mesh_penalty(qslim::Model& M, 
     30                                                                                                                                qslim::Vertex *v1, 
     31                                                                                                                                qslim::Vertex *v2, 
     32                                                                                                                                qslim::Vec3& vnew); 
     33         
     34        int predict_face(qslim::Face& F, 
     35                                                                        qslim::Vertex *v1, 
     36                                                                        qslim::Vertex *v2, 
     37                                                                        qslim::Vec3& vnew, 
     38                                                                        qslim::Vec3& f1, 
     39                                                                        qslim::Vec3& f2, 
     40                                                                        qslim::Vec3& f3); 
     41         
    2742        bool check_for_pair(qslim::Vertex *v0, qslim::Vertex *v1); 
     43         
    2844        qslim::pair_info *new_pair(qslim::Vertex *v0, qslim::Vertex *v1); 
     45         
    2946        void delete_pair(qslim::pair_info *pair); 
     47         
    3048        void do_contract(qslim::Model& m, qslim::pair_info *pair); 
     49         
    3150        bool decimate_quadric(qslim::Vertex *v, qslim::Mat4& Q); 
     51         
    3252        void decimate_contract(qslim::Model& m); 
     53         
    3354        qslim::real decimate_error(qslim::Vertex *v); 
     55         
    3456        qslim::real decimate_min_error(); 
     57         
    3558        qslim::real decimate_max_error(qslim::Model& m); 
     59         
    3660        void decimate_init(qslim::Model& m, qslim::real limit); 
     61         
    3762        bool pair_is_valid(qslim::Vertex *u, qslim::Vertex *v); 
     63         
    3864        void simplifmethod_run(int,     Geometry::TIPOFUNC      upb=0); 
     65         
    3966        void simplifmethod_runv(int,    Geometry::TIPOFUNC      upb=0); 
     67         
    4068        void simplifmethod_init(void); 
    4169 
    42         //To map the mesh with de simplification method structure 
    43         std::map<int,std::vector<int> > submeshmap; //submeshes which pertains each vertex 
    44         std::map<int,std::vector<int> > vertexbuffermap; //vertices of the VertexBuffer that point at this vertex of the simplification method 
     70        //      To map the mesh with de simplification method structure. 
     71        //      Submeshes which pertains each vertex. 
     72        std::map<int,std::vector<int> > submeshmap; 
     73         
     74        //      Vertices of the VertexBuffer that point  
     75        //      at this vertex of the simplification method. 
     76        std::map<int,std::vector<int> > vertexbuffermap;  
    4577 
    46         //simplification sequence of the simplification method 
     78        //      Simplification sequence of the simplification method. 
    4779        std::vector<Geometry::MeshSimplificationSequence::Step> decim_data; 
     80         
    4881        std::string meshName; 
     82         
    4983        void WriteOBJ(void); 
     84         
    5085        unsigned int *first_index_submesh; 
     86         
    5187        //std::vector<qslim::pair_info *> pointers_to_remove; 
    5288 
    5389        int indexMeshLeaves; 
     90         
    5491public: 
     92         
    5593        const Geometry::Mesh *objmesh; 
    56         int number_of_triangles; //total number of triangles of all the submeshes 
     94         
     95        //      Total number of triangles of all the submeshes. 
     96        int number_of_triangles; 
     97         
    5798        SimplificationMethod(const Geometry::Mesh *m); 
     99         
    58100        void geomesh2simplifModel(void); 
    59         Geometry::MeshSimplificationSequence *Decimate(float lod, int simpliftype,Geometry::TIPOFUNC    upb=0); 
     101         
     102        Geometry::MeshSimplificationSequence *Decimate( float lod, 
     103                                                                                                                                                                                                        int simpliftype, 
     104                                                                                                                                                                                                        Geometry::TIPOFUNC      upb=0); 
     105         
    60106        void setMeshLeaves(int meshLeaves); 
    61107 
    62         //      Gets mesh simplified. 
     108        ///     Gets mesh simplified. 
    63109        Geometry::Mesh  *       GetMesh(); 
    64110         
     
    66112        ~SimplificationMethod(); 
    67113}; 
     114 
  • GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/vmi/include/change.h

    r983 r1007  
    22#define __change_h_ 
    33 
    4 #include "mesh.h" 
     4#include        "mesh.h" 
     5#include        <vector> 
    56 
    67namespace       VMI 
    78{ 
    8 typedef struct change { 
    9   int e; 
    10   int u, v;           // Edge 
    11   int numDel;         // Number of deleted triangles 
    12   Triangle *deleted;  // List of deleted triangles  
    13   int numMod;         // Number of modified triangles  
    14   Triangle *modified; // List of triangles deleted   
    15 } Change; 
     9        typedef struct change 
     10        { 
     11                int e; 
     12                int u, v;           // Edge 
     13                int numDel;         // Number of deleted triangles 
     14                Triangle *deleted;  // List of deleted triangles  
     15                int numMod;         // Number of modified triangles  
     16                Triangle *modified; // List of triangles deleted   
     17        } Change; 
    1618 
    17 extern Change *createChange (Mesh *mesh, int e); 
    18 extern void writeChange(FILE* file, Change *c); 
    19 extern void deleteChange(Change *c); 
    20 extern void printChange(Change *c); 
     19        // Represents a simplification step in the sequence. 
     20        struct vmiStep 
     21        { 
     22                unsigned int    mV0; 
     23                unsigned int    mV1; 
     24                unsigned int    mT0; 
     25                unsigned int    mT1; 
     26                float x; 
     27                float   y; 
     28                float   z; 
     29                 
     30                std::vector<unsigned int>       mModfaces; 
    2131 
    22 extern void modifyTriangle(Triangle *t, int c, int p); 
    23 extern int isATriangleToModify(Triangle *t, int c, int p); 
    24 extern int getTrianglesToModify(Mesh *mesh, int c, int p, Triangle *modified); 
    25 extern int isATriangleToDelete(Triangle *t, int c, int p); 
    26 extern int getTrianglesToDelete(Mesh *mesh, int numMod, Triangle *modified, Triangle *deleted, int c, int p); 
     32                //      Indicates the the step is obligatory to execute 
     33                //      joined width the following step. 
     34                unsigned int obligatory; 
     35        }; 
    2736 
    28 extern void modifyTriangles(Mesh *mesh, Change *c); 
    29 extern void unmodifyTriangles(Mesh *mesh, Change *c); 
    30 extern void deleteTriangles(Mesh *mesh, Change *c); 
    31 extern void undeleteTriangles(Mesh *mesh, Change *c); 
     37        // Stores all the simplification steps. 
     38        extern  std::vector<vmiStep> mVMISteps; 
    3239 
    33 extern void printList(Triangle *list, int n); 
    34 extern void deleteItem(Triangle *list, int *n, int item); 
     40        extern Change *createChange (Mesh *mesh, int e); 
     41        extern void writeChange(FILE* file, Change *c); 
     42        extern void deleteChange(Change *c); 
     43        extern void printChange(Change *c); 
    3544 
    36 extern void doChange(Mesh *mesh, Change *c); 
    37 extern void undoChange(Mesh *mesh, Change *c); 
    38 extern void computeChanges(Mesh *mesh, Change *c); 
     45        extern void modifyTriangle(Triangle *t, int c, int p); 
     46        extern int isATriangleToModify(Triangle *t, int c, int p); 
     47        extern int getTrianglesToModify(Mesh *mesh, int c, int p, Triangle *modified); 
     48        extern int isATriangleToDelete(Triangle *t, int c, int p); 
     49        extern int getTrianglesToDelete(Mesh *mesh, int numMod, Triangle *modified, Triangle *deleted, int c, int p); 
    3950 
     51        extern void modifyTriangles(Mesh *mesh, Change *c); 
     52        extern void unmodifyTriangles(Mesh *mesh, Change *c); 
     53        extern void deleteTriangles(Mesh *mesh, Change *c); 
     54        extern void undeleteTriangles(Mesh *mesh, Change *c); 
     55 
     56        extern void printList(Triangle *list, int n); 
     57        extern void deleteItem(Triangle *list, int *n, int item); 
     58 
     59        extern void doChange(Mesh *mesh, Change *c); 
     60        extern void undoChange(Mesh *mesh, Change *c); 
     61        extern void computeChanges(Mesh *mesh, Change *c); 
     62 
     63        //      Save simplification sequence in Geometry Game Tools format. 
     64        extern void     saveSimplificationSequence(Change       *c); 
    4065} 
    4166 
  • GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/vmi/src/change.cpp

    r983 r1007  
    99 
    1010using namespace VMI; 
     11 
     12std::vector<VMI::vmiStep> VMI::mVMISteps; 
    1113 
    1214Change *VMI::createChange (Mesh *mesh, int e) { 
     
    2931} 
    3032 
    31 void VMI::deleteChange(Change *c) { 
    32      
    33     if (NULL != c) { 
    34         if (c->deleted != NULL)   free(c->deleted); 
    35         if (c->modified != NULL)  free(c->modified); 
    36         c->modified = NULL; 
    37         c->deleted = NULL; 
    38         c->numDel = 0; 
    39         c->numMod = 0; 
    40          
    41         free(c); 
    42         c = NULL; 
    43     } 
    44 } 
    45  
    46 void VMI::writeChange(FILE* file, Change *c) { 
    47     int i; 
    48  
    49     fputc('v',file); 
    50     fputc('%',file); 
    51     fprintf(file, " %d %d 0 0 0 ", c->v, c->u); 
    52  
    53     for (i=0; i<c->numDel; i++) { 
    54         fprintf(file, "%d ", c->deleted[i].id); 
    55     } 
    56  
    57     fputc('&',file); 
    58     for (i=0; i<c->numMod; i++) { 
    59         fprintf(file, " %d", c->modified[i].id); 
    60     } 
    61  
    62     fputc('\n',file); 
    63 } 
    64  
    65 void VMI::printChange(Change *c) { 
    66     int i; 
    67      
    68     if (NULL != c) { 
    69          
    70         printf("e%d(%d,%d)\n",c->e,c->u,c->v); 
    71          
    72         printf("d %d\n", c->numDel); 
    73         for (i=0;i<c->numDel;i++) { 
    74             printf(" %d", c->deleted[i].id); 
    75         } 
    76         printf("\n"); 
    77         printf("m %d\n", c->numMod); 
    78         for (i=0;i<c->numMod;i++) { 
    79             printf(" %d", c->modified[i].id); 
    80         } 
    81         printf("\n"); 
    82     } 
    83 } 
    84  
    85 void VMI::modifyTriangle(Triangle *t, int c, int p) { 
    86      
    87     if ((int)t->indices[0] == c) 
    88         t->indices[0]= p; 
    89     if ((int)t->indices[1] == c) 
    90         t->indices[1]= p; 
    91     if ((int)t->indices[2] == c) 
    92         t->indices[2]= p; 
    93 } 
    94  
    95 int VMI::isATriangleToModify(Triangle *t, int c, int p) { 
    96     int u = t->indices[0], 
    97         v = t->indices[1], 
    98         w = t->indices[2]; 
    99      
    100     if ((u == c) || (v == c) || (w == c)) return TRUE; 
    101  
    102     return FALSE; 
    103 } 
    104  
    105 void VMI::modifyTriangles(Mesh *mesh, Change *c) { 
    106     int i, t; 
    107      
    108     for (i=0; i<c->numMod; i++) { 
    109         t = c->modified[i].id; 
    110         modifyTriangle(&mesh->triangles[t], c->u, c->v); 
    111  
    112         //printf("New area of triangle %d:\n", t); 
    113         mesh->triangles[t].area = computeTriangleArea(mesh->vertices, &mesh->triangles[t]); 
    114  
    115         computeTriangleNormal(mesh->vertices, &mesh->triangles[t]); 
    116     } 
    117 } 
    118  
    119 void VMI::unmodifyTriangles(Mesh *mesh, Change *c) { 
    120     int i, t; 
    121      
    122     for (i=0; i<c->numMod; i++) { 
    123         t = c->modified[i].id; 
    124  
    125         memcpy(&mesh->triangles[t], &c->modified[i], sizeof(Triangle)); 
    126         /*printf("t(%d %d %d)\n", mesh->triangles[t].indices[0],  
    127                                   mesh->triangles[t].indices[1], 
    128                                   mesh->triangles[t].indices[2]);*/ 
    129     } 
    130 } 
    131  
    132 void VMI::deleteTriangles(Mesh *mesh, Change *c) { 
    133     int i, t; 
    134      
    135     for (i=0; i<c->numDel; i++) { 
    136         t = c->deleted[i].id; 
    137  
    138         //printf("Deleting triangle %d\n",t); 
    139         mesh->triangles[t].enable = FALSE; 
    140         mesh->currentNumTriangles--; 
    141     } 
    142 } 
    143  
    144 void VMI::undeleteTriangles(Mesh *mesh, Change *c) { 
    145     int i, t; 
    146      
    147     for (i=0; i<c->numDel; i++) { 
    148         t = c->deleted[i].id; 
    149          
    150         memcpy(&mesh->triangles[t], &c->deleted[i], sizeof(Triangle)); 
    151         /*printf("t(%d %d %d)\n", mesh->triangles[t].indices[0],  
    152                                   mesh->triangles[t].indices[1],  
    153                                   mesh->triangles[t].indices[2]);*/ 
    154  
    155         mesh->triangles[t].enable = TRUE; 
    156         mesh->currentNumTriangles++; 
    157     } 
    158 } 
    159  
    160 int VMI::getTrianglesToModify(Mesh *mesh, int c, int p, Triangle *modified) { 
    161     GLuint i, num = 0; 
    162      
    163     for (i=0; i<mesh->numTriangles; i++) { 
    164         if ((mesh->triangles[i].enable == TRUE) &&  
    165             isATriangleToModify(&mesh->triangles[i], c, p)) { 
    166                                                       
    167                 //printf("Triangle to modify %d\n", i); 
    168                 // Save the original values of the triangle 
    169                 memcpy(&modified[num], &mesh->triangles[i], sizeof(Triangle)); 
    170                 num++; 
    171         } 
    172     } 
    173      
    174     return num; 
    175 } 
    176  
    177 int VMI::isATriangleToDelete(Triangle *t, int c, int p) { 
    178     int u = t->indices[0], 
    179         v = t->indices[1], 
    180         w = t->indices[2]; 
    181      
    182     if (((u == c) && ( v == p)) || 
    183         ((u == c) && ( w == p)) ||  
    184         ((v == c) && ( w == p))) 
    185         return TRUE; 
    186     if (((u == p) && ( v == c)) || 
    187         ((u == p) && ( w == c)) ||  
    188         ((v == p) && ( w == c))) 
    189         return TRUE; 
    190  
    191     return FALSE; 
    192 } 
    193  
    194 int VMI::getTrianglesToDelete(Mesh *mesh, int numMod, Triangle *modified, Triangle *deleted, int c, int p) { 
    195     int i, num = 0; 
    196     GLuint t; 
    197      
    198     for (i=0; i<numMod; i++) { 
    199         t = modified[i].id; 
    200          
    201         if (isATriangleToDelete(&mesh->triangles[t], c, p)) { 
    202                                                       
    203             //printf("Triangle to delete %d\n",t);                     
    204             memcpy(&deleted[num], &modified[i], sizeof(Triangle)); 
    205             num++; 
    206         } 
    207     } 
    208     return num; 
    209 } 
    210  
    211 void VMI::printList(Triangle *list, int n) { 
    212     int i; 
    213      
    214     for (i=0; i<n; i++) 
    215         printf("%d ",list[i].id); 
    216  
    217     printf("\n"); 
    218 } 
    219  
    220 void VMI::deleteItem(Triangle *list, int *n, int item) { 
    221     int i, j; 
    222      
    223     for (i=0; i<*n; i++) { 
    224         if (list[i].id == (GLuint)item) { 
    225             // delete it 
    226             for (j =i + 1 ; j<*n; j++) 
    227                 list[j - 1] = list[j]; 
    228             (*n)--; 
    229             i--; // Delete all ocurrencies of an item 
    230         } 
    231     } 
     33void VMI::deleteChange(Change *c) 
     34{ 
     35 
     36        if (NULL != c) 
     37        { 
     38                if (c->deleted != NULL)   free(c->deleted); 
     39                if (c->modified != NULL)  free(c->modified); 
     40                c->modified = NULL; 
     41                c->deleted = NULL; 
     42                c->numDel = 0; 
     43                c->numMod = 0; 
     44 
     45                free(c); 
     46                c = NULL; 
     47        } 
     48} 
     49 
     50void VMI::writeChange(FILE* file, Change *c) 
     51{ 
     52        int i; 
     53 
     54        fputc('v',file); 
     55        fputc('%',file); 
     56        fprintf(file, " %d %d 0 0 0 ", c->v, c->u); 
     57 
     58        for (i=0; i<c->numDel; i++) { 
     59                fprintf(file, "%d ", c->deleted[i].id); 
     60        } 
     61 
     62        fputc('&',file); 
     63        for (i=0; i<c->numMod; i++) { 
     64                fprintf(file, " %d", c->modified[i].id); 
     65        } 
     66 
     67        fputc('\n',file); 
     68} 
     69 
     70void VMI::printChange(Change *c) 
     71{ 
     72        int i; 
     73 
     74        if (NULL != c) { 
     75 
     76                printf("e%d(%d,%d)\n",c->e,c->u,c->v); 
     77 
     78                printf("d %d\n", c->numDel); 
     79                for (i=0;i<c->numDel;i++) { 
     80                        printf(" %d", c->deleted[i].id); 
     81                } 
     82                printf("\n"); 
     83                printf("m %d\n", c->numMod); 
     84                for (i=0;i<c->numMod;i++) { 
     85                        printf(" %d", c->modified[i].id); 
     86                } 
     87                printf("\n"); 
     88        } 
     89} 
     90 
     91void VMI::modifyTriangle(Triangle *t, int c, int p) 
     92{ 
     93 
     94        if ((int)t->indices[0] == c) 
     95                t->indices[0]= p; 
     96        if ((int)t->indices[1] == c) 
     97                t->indices[1]= p; 
     98        if ((int)t->indices[2] == c) 
     99                t->indices[2]= p; 
     100} 
     101 
     102int VMI::isATriangleToModify(Triangle *t, int c, int p) 
     103{ 
     104        int u = t->indices[0], 
     105                        v = t->indices[1], 
     106                        w = t->indices[2]; 
     107 
     108        if ((u == c) || (v == c) || (w == c)) return TRUE; 
     109 
     110        return FALSE; 
     111} 
     112 
     113void VMI::modifyTriangles(Mesh *mesh, Change *c) 
     114{ 
     115        int i, t; 
     116 
     117        for (i=0; i<c->numMod; i++) 
     118        { 
     119                t = c->modified[i].id; 
     120                modifyTriangle(&mesh->triangles[t], c->u, c->v); 
     121 
     122                //printf("New area of triangle %d:\n", t); 
     123                mesh->triangles[t].area = computeTriangleArea(mesh->vertices, &mesh->triangles[t]); 
     124 
     125                computeTriangleNormal(mesh->vertices, &mesh->triangles[t]); 
     126        } 
     127} 
     128 
     129void VMI::unmodifyTriangles(Mesh *mesh, Change *c) 
     130{ 
     131        int i, t; 
     132 
     133        for (i=0; i<c->numMod; i++) { 
     134                t = c->modified[i].id; 
     135 
     136                memcpy(&mesh->triangles[t], &c->modified[i], sizeof(Triangle)); 
     137                /*printf("t(%d %d %d)\n", mesh->triangles[t].indices[0],  
     138                        mesh->triangles[t].indices[1], 
     139                        mesh->triangles[t].indices[2]);*/ 
     140        } 
     141} 
     142 
     143void VMI::deleteTriangles(Mesh *mesh, Change *c) 
     144{ 
     145        int i, t; 
     146 
     147        for (i=0; i<c->numDel; i++) 
     148        { 
     149                t = c->deleted[i].id; 
     150 
     151                //printf("Deleting triangle %d\n",t); 
     152                mesh->triangles[t].enable = FALSE; 
     153                mesh->currentNumTriangles--; 
     154        } 
     155} 
     156 
     157void VMI::undeleteTriangles(Mesh *mesh, Change *c) 
     158{ 
     159        int i, t; 
     160 
     161        for (i=0; i<c->numDel; i++) 
     162        { 
     163                t = c->deleted[i].id; 
     164 
     165                memcpy(&mesh->triangles[t], &c->deleted[i], sizeof(Triangle)); 
     166                /*printf("t(%d %d %d)\n", mesh->triangles[t].indices[0],  
     167                        mesh->triangles[t].indices[1],  
     168                        mesh->triangles[t].indices[2]);*/ 
     169 
     170                mesh->triangles[t].enable = TRUE; 
     171                mesh->currentNumTriangles++; 
     172        } 
     173} 
     174 
     175int VMI::getTrianglesToModify(Mesh *mesh, int c, int p, Triangle *modified) 
     176{ 
     177        GLuint i, num = 0; 
     178 
     179        for (i=0; i<mesh->numTriangles; i++) 
     180        { 
     181                if ((mesh->triangles[i].enable == TRUE) &&  
     182                                isATriangleToModify(&mesh->triangles[i], c, p)) 
     183                { 
     184 
     185                        //printf("Triangle to modify %d\n", i); 
     186                        // Save the original values of the triangle 
     187                        memcpy(&modified[num], &mesh->triangles[i], sizeof(Triangle)); 
     188                        num++; 
     189                } 
     190        } 
     191 
     192        return num; 
     193} 
     194 
     195int VMI::isATriangleToDelete(Triangle *t, int c, int p) 
     196{ 
     197        int u = t->indices[0], 
     198                        v = t->indices[1], 
     199                        w = t->indices[2]; 
     200 
     201        if (((u == c) && ( v == p)) || 
     202                        ((u == c) && ( w == p)) ||  
     203                        ((v == c) && ( w == p))) 
     204                return TRUE; 
     205        if (((u == p) && ( v == c)) || 
     206                        ((u == p) && ( w == c)) ||  
     207                        ((v == p) && ( w == c))) 
     208                return TRUE; 
     209 
     210        return FALSE; 
     211} 
     212 
     213int VMI::getTrianglesToDelete(Mesh *mesh, int numMod, Triangle *modified, Triangle *deleted, int c, int p) 
     214{ 
     215        int i, num = 0; 
     216        GLuint t; 
     217 
     218        for (i=0; i<numMod; i++) 
     219        { 
     220                t = modified[i].id; 
     221 
     222                if (isATriangleToDelete(&mesh->triangles[t], c, p)) 
     223                {                                              
     224                        //printf("Triangle to delete %d\n",t);                     
     225                        memcpy(&deleted[num], &modified[i], sizeof(Triangle)); 
     226                        num++; 
     227                } 
     228        } 
     229        return num; 
     230} 
     231 
     232void VMI::printList(Triangle *list, int n) 
     233{ 
     234        int i; 
     235 
     236        for (i=0; i<n; i++) 
     237                printf("%d ",list[i].id); 
     238 
     239        printf("\n"); 
     240} 
     241 
     242void VMI::deleteItem(Triangle *list, int *n, int item) 
     243{ 
     244        int i, j; 
     245 
     246        for (i=0; i<*n; i++) 
     247        { 
     248                if (list[i].id == (GLuint)item) 
     249                { 
     250                        // delete it 
     251                        for (j =i + 1 ; j<*n; j++) 
     252                                list[j - 1] = list[j]; 
     253                        (*n)--; 
     254                        i--; // Delete all ocurrencies of an item 
     255                } 
     256        } 
    232257} 
    233258 
     
    235260 
    236261// Compute the triangle mesh changes due to a heap node simplification 
    237 void VMI::computeChanges(Mesh *mesh, Change *c) { 
    238     Triangle m[MAX_NUM_TRI], d[MAX_NUM_TRI/2]; 
    239     int numMod = getTrianglesToModify(mesh, c->u, c->v, m); 
    240     int numDel = getTrianglesToDelete(mesh, numMod, m, d, c->u, c->v); 
    241     int i; 
    242      
    243     //printf("d %d\n",numDel); 
    244     //printList(d, numDel); 
    245  
    246     for (i=0; i<numDel; i++) 
    247         deleteItem(m, &numMod, d[i].id); 
    248  
    249     //printf("m %d\n",numMod); 
    250     //printList(m, numMod); 
    251     //getchar(); 
    252      
    253     c->numDel = numDel; 
    254     // Free memory 
    255     if (c->deleted != NULL) free(c->deleted); 
    256     // Allocate memory 
    257     c->deleted = (Triangle *)malloc(sizeof(Triangle) * numDel); 
    258     if (c->deleted == NULL) { 
    259         fprintf(stderr, "Error allocating memory\n"); 
    260         exit(1); 
    261     } 
    262     memcpy(c->deleted, d, sizeof(Triangle) * numDel); 
    263      
    264     c->numMod = numMod; 
    265     // Free memory 
    266     if (c->modified != NULL) free(c->modified); 
    267     // Allocate memory 
    268     c->modified = (Triangle *)malloc(sizeof(Triangle) * numMod); 
    269     if (c->modified == NULL) { 
    270         fprintf(stderr, "Error allocating memory\n"); 
    271         exit(1); 
    272     } 
    273     memcpy(c->modified, m, sizeof(Triangle) * numMod); 
    274  
    275     //printChange(c); 
    276     //getchar(); 
     262void VMI::computeChanges(Mesh *mesh, Change *c) 
     263{ 
     264        Triangle m[MAX_NUM_TRI], d[MAX_NUM_TRI/2]; 
     265        int numMod = getTrianglesToModify(mesh, c->u, c->v, m); 
     266        int numDel = getTrianglesToDelete(mesh, numMod, m, d, c->u, c->v); 
     267        int i; 
     268 
     269        //printf("d %d\n",numDel); 
     270        //printList(d, numDel); 
     271 
     272        for (i=0; i<numDel; i++) 
     273                deleteItem(m, &numMod, d[i].id); 
     274 
     275        //printf("m %d\n",numMod); 
     276        //printList(m, numMod); 
     277        //getchar(); 
     278 
     279        c->numDel = numDel; 
     280        // Free memory 
     281        if (c->deleted != NULL) free(c->deleted); 
     282        // Allocate memory 
     283        c->deleted = (Triangle *)malloc(sizeof(Triangle) * numDel); 
     284         
     285        if (c->deleted == NULL) 
     286        { 
     287                fprintf(stderr, "Error allocating memory\n"); 
     288                exit(1); 
     289        } 
     290         
     291        memcpy(c->deleted, d, sizeof(Triangle) * numDel); 
     292 
     293        c->numMod = numMod; 
     294         
     295        // Free memory 
     296        if (c->modified != NULL) free(c->modified); 
     297         
     298        // Allocate memory 
     299        c->modified = (Triangle *)malloc(sizeof(Triangle) * numMod); 
     300         
     301        if (c->modified == NULL) 
     302        { 
     303                fprintf(stderr, "Error allocating memory\n"); 
     304                exit(1); 
     305        } 
     306         
     307        memcpy(c->modified, m, sizeof(Triangle) * numMod); 
     308 
     309        //printChange(c); 
     310        //getchar(); 
    277311} 
    278312 
    279313// Update the triangle mesh due to a heap node simplification 
    280 void VMI::doChange(Mesh *mesh, Change *c) { 
    281      
    282     modifyTriangles(mesh, c); 
    283      
    284     deleteTriangles(mesh, c); 
    285  
    286     mesh->vertices[c->u].enable = FALSE; 
    287     mesh->currentNumVertices--; 
    288 } 
    289  
    290 void VMI::undoChange(Mesh *mesh, Change *c) { 
    291      
    292     unmodifyTriangles(mesh, c); 
    293      
    294     undeleteTriangles(mesh, c); 
    295  
    296     mesh->vertices[c->u].enable = TRUE; 
    297     mesh->currentNumVertices++; 
    298 } 
     314void VMI::doChange(Mesh *mesh, Change *c) 
     315{ 
     316        modifyTriangles(mesh, c); 
     317 
     318        deleteTriangles(mesh, c); 
     319 
     320        mesh->vertices[c->u].enable = FALSE; 
     321        mesh->currentNumVertices--; 
     322} 
     323 
     324void VMI::undoChange(Mesh *mesh, Change *c) 
     325{     
     326        unmodifyTriangles(mesh, c); 
     327 
     328        undeleteTriangles(mesh, c); 
     329 
     330        mesh->vertices[c->u].enable = TRUE; 
     331        mesh->currentNumVertices++; 
     332} 
     333 
     334//      Save simplification sequence in Geometry Game Tools format. 
     335extern void     VMI::saveSimplificationSequence(Change  *c) 
     336{ 
     337        vmiStep step; 
     338        step.mV0        =       c->u; 
     339        step.mV1        =       c->v; 
     340 
     341        //      If only one triangle has been deleted. 
     342        if (c->numDel == 1) 
     343        { 
     344                step.mT0        =       c->deleted[0].id; 
     345                step.mT1        =       c->deleted[0].id; 
     346        } 
     347        //      If two triangles have been deleted. 
     348        else 
     349        { 
     350                step.mT0        =       c->deleted[0].id; 
     351                step.mT1        =       c->deleted[1].id; 
     352        } 
     353 
     354        step.x  =       0.0; 
     355        step.y  =       0.0; 
     356        step.z  =       0.0; 
     357 
     358        //      Write obligatory field. 
     359        step.obligatory =       0; 
     360 
     361        //      List of new triangles. 
     362        //      For each modified triangle. 
     363        for (int        i = 0;  i < c->numMod;  i++) 
     364        { 
     365                step.mModfaces.push_back(c->modified[i].id); 
     366        } 
     367 
     368        //      Add step to list of changes. 
     369        mVMISteps.push_back(step); 
     370} 
  • GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/vmi/src/simplify.cpp

    r983 r1007  
    424424/////////////////////////////////////////////////////////////////////////////// 
    425425 
    426 void VMI::simplifyModel(Mesh *mesh, GLuint numDemandedTri) { 
    427     int e; 
    428     Change *c; 
    429     FILE* file = NULL; 
    430     char s[MAX_CHAR]; 
    431     double cost = 0.0; 
    432     bheap_t *h = NULL; 
    433     float       percent =       (40.0) / (float)(mesh->numTriangles - numDemandedTri); 
    434  
    435     if (numDemandedTri > mesh->currentNumTriangles) return; 
    436  
    437     if (bSaveLog == TRUE) { // Save changes into a file 
     426void VMI::simplifyModel(Mesh *mesh, GLuint numDemandedTri) 
     427{ 
     428        int                     e; 
     429        Change  *c; 
     430        FILE            *file                                   = NULL; 
     431        FILE            *file_simp_seq  =       NULL; 
     432        char            s[MAX_CHAR]; 
     433        double  cost                                            = 0.0; 
     434        bheap_t *h                                                      = NULL; 
     435        float           percent =       (40.0) / (float)(mesh->numTriangles - numDemandedTri); 
     436 
     437        if (numDemandedTri > mesh->currentNumTriangles) 
     438        { 
     439                return; 
     440        } 
     441 
     442        // Save changes into a file 
     443        if (bSaveLog == TRUE) 
     444        { 
    438445#ifdef SALIENCY        
    439446#ifdef KL // Kullback-Leibler 
    440         sprintf(s,"%s_VKL_S.log", filename); 
     447                sprintf(s,"%s_VKL_S.log", filename); 
    441448#endif 
    442449#ifdef MI // Mutual Information 
    443         sprintf(s,"%s_VMI_S.log", filename); 
     450                sprintf(s,"%s_VMI_S.log", filename); 
    444451#endif 
    445452#ifdef HE // Hellinger 
    446         sprintf(s,"%s_VHE_S.log", filename); 
     453                sprintf(s,"%s_VHE_S.log", filename); 
    447454#endif 
    448455#ifdef CS // Chi-Square 
    449         sprintf(s,"%s_VCS_S.log", filename); 
     456                sprintf(s,"%s_VCS_S.log", filename); 
    450457#endif 
    451458#else 
    452459#ifdef KL // Kullback-Leibler 
    453         sprintf(s,"%s_VKL.log", filename); 
     460                sprintf(s,"%s_VKL.log", filename); 
    454461#endif 
    455462#ifdef MI // Mutual Information 
    456         sprintf(s,"%s_VMI.log", filename); 
     463                sprintf(s,"%s_VMI.log", filename); 
    457464#endif 
    458465#ifdef HE // Hellinger 
    459         sprintf(s,"%s_VHE.log", filename); 
     466                sprintf(s,"%s_VHE.log", filename); 
    460467#endif 
    461468#ifdef CS // Chi-Square 
    462         sprintf(s,"%s_VCS.log", filename); 
    463 #endif 
    464 #endif 
    465          
    466         glmWriteOBJ(pmodel, s, GLM_NONE); 
    467          
    468         /* open the file */ 
    469         file = fopen(s, "a+"); 
    470         if (!file) { 
    471             fprintf(stderr, "simplifyModel() failed: can't open file \"%s\" to write.\n", s); 
    472             exit(1); 
    473         } 
    474     } 
    475  
    476     h = initHeap(mesh); 
    477  
    478     printf("Starting simplification...\n"); 
    479  
    480     while (mesh->currentNumTriangles > numDemandedTri /*&& cost == 0.0*/) { 
    481          
    482         // Get the edge that has the minimum cost 
    483         e = bh_min(h); 
    484  
    485         c = createChange(mesh, e); 
    486  
    487         // Apply the edge collapse 
    488         computeChanges(mesh, c); 
    489         doChange(mesh, c); 
    490  
    491         if (bSaveLog == TRUE) writeChange(file, c); 
    492  
    493         cost = h->a[h->p[e]].key; 
    494         printf("Edge collapse e%d(%d,%d) %f MIN d %d m %d\n",c->e, c->u, c->v, cost, c->numDel, c->numMod); 
    495  
    496         mesh->edges[e].enable = FALSE; 
    497         bh_delete(h, e); 
    498          
    499         // Get projected areas after the edge collapse 
    500         getProjectedAreas(histogram, numCameras); 
    501  
    502         computeCameraIs(histogram, numCameras, initialIs); 
    503  
    504         // Update the heap according to the edge collapse 
    505         h = updateHeap(h, mesh, c); 
    506  
    507                                 mUPB((float)c->numDel * percent); 
    508  
    509         deleteChange(c); 
    510  
    511         printf("t %d\n", mesh->currentNumTriangles); 
    512     } 
    513  
    514     if (bSaveLog == TRUE) { 
    515         fclose(file); 
    516         printf("Log file written...Ok\n"); 
    517     } 
    518  
    519     bh_free(h); 
    520 } 
     469                sprintf(s,"%s_VCS.log", filename); 
     470#endif 
     471#endif 
     472 
     473                glmWriteOBJ(pmodel, s, GLM_NONE); 
     474 
     475                /* open the file */ 
     476                file = fopen(s, "a+"); 
     477                 
     478                if (!file) 
     479                { 
     480                        fprintf(stderr, "simplifyModel() failed: can't open file \"%s\" to write.\n", s); 
     481                        exit(1); 
     482                } 
     483        } 
     484 
     485        //      Open file of simplification sequence. 
     486        file_simp_seq   =       fopen("SimplifSequence.txt", "w"); 
     487         
     488        if (!file_simp_seq) 
     489        { 
     490                fprintf(stderr, 
     491                                                "simplifyModel() failed: ", 
     492                                                "can't open file \"SimplifSequence\" to write.\n"); 
     493        } 
     494         
     495        h = initHeap(mesh); 
     496 
     497        printf("Starting simplification...\n"); 
     498 
     499        while (mesh->currentNumTriangles > numDemandedTri /*&& cost == 0.0*/) 
     500        { 
     501                // Get the edge that has the minimum cost 
     502                e = bh_min(h); 
     503 
     504                c = createChange(mesh, e); 
     505 
     506                // Apply the edge collapse 
     507                computeChanges(mesh, c); 
     508                doChange(mesh, c); 
     509 
     510                if (bSaveLog == TRUE) writeChange(file, c); 
     511 
     512                //      Write Simplification sequence. 
     513                saveSimplificationSequence(c); 
     514                 
     515                cost = h->a[h->p[e]].key; 
     516                 
     517                printf( "Edge collapse e%d(%d,%d) %f MIN d %d m %d\n", 
     518                                                c->e, 
     519                                                c->u, 
     520                                                c->v, 
     521                                                cost, 
     522                                                c->numDel, 
     523                                                c->numMod); 
     524 
     525                mesh->edges[e].enable = FALSE; 
     526                 
     527                bh_delete(h, e); 
     528 
     529                // Get projected areas after the edge collapse 
     530                getProjectedAreas(histogram, numCameras); 
     531 
     532                computeCameraIs(histogram, numCameras, initialIs); 
     533 
     534                // Update the heap according to the edge collapse 
     535                h = updateHeap(h, mesh, c); 
     536 
     537                mUPB((float)c->numDel * percent); 
     538 
     539                deleteChange(c); 
     540 
     541                printf("t %d\n", mesh->currentNumTriangles); 
     542        } 
     543 
     544        if (bSaveLog == TRUE) 
     545        { 
     546                fclose(file); 
     547                printf("Log file written...Ok\n"); 
     548        } 
     549 
     550        //      Close simplification sequence file. 
     551        fclose(file_simp_seq); 
     552 
     553        bh_free(h); 
     554} 
     555 
  • GTP/trunk/Lib/Geom/shared/GeoTool/src/GeoMeshViewUI.cpp

    r998 r1007  
    2424        //      Deactive Lod tree visualization. 
    2525        geoMeshView->deactiveLodTree(); 
     26 
     27        geoMeshView->resetTextures(); 
     28        BuildLoadTextureSubMeshMenu(); 
    2629 
    2730        //      Repaint the window. 
     
    919922                        //      Show title. 
    920923                        mProcessTitle->label("Visualize LodTrees"); 
    921  
    922                         // set the submesh with triangle lists as the leaves submesh 
    923                         geoMeshView->setLeavesSubMesh(geoMeshView->findLeavesSubMesh()); 
    924924 
    925925                        //      Show the Visulize LodTree panel. 
     
    17901790                for(int i=0; i<mGeoMesh->mSubMeshCount;i++) 
    17911791                { 
    1792                         char *cadena=new char[12]; 
     1792                        char *cadena=new char[256]; 
    17931793 
    17941794                        if (geoMeshView->getLeavesSubMesh() >= 0) 
     
    21032103    else 
    21042104    { 
    2105         // Simplificar hasta un número de vértices. 
     2105        //      Simplificar hasta un número de vértices. 
    21062106        uint32 v    =    (uint32)mMeshReduction->fvalue(); 
    21072107 
    2108         // Simplifica el geomesh -> Parámetro es un factor LOD [0,1]. 
     2108        //      Simplifica el geomesh -> Parámetro es un factor LOD [0,1]. 
    21092109        mMeshSimplifier->Simplify(v); 
    21102110 
    2111         //    Deletes the previous mesh. 
     2111        //      Deletes the previous mesh. 
    21122112        delete mUndoMesh; 
    21132113 
    21142114        mUndoMesh    =    new Mesh(); 
    21152115 
    2116         //    Sets the undo mesh. 
     2116        //      Sets the undo mesh. 
    21172117        *mUndoMesh    =    *mGeoMesh; 
    21182118 
     
    21212121        mGeoMesh    =    mMeshSimplifier->GetMesh(); 
    21222122 
    2123         //    Visualize the mesh. 
     2123        //      Visualize the mesh. 
    21242124        geoMeshView->setMesh(mGeoMesh); 
    21252125    } 
     
    21272127    return    true; 
    21282128} 
    2129  
    21302129 
    21312130//--------------------------------------------------------------------------- 
     
    23822381 
    23832382        //      Sets the slider range. 
    2384         mLodStripSlider->range(lodStripsLib->MaxLod(), 
    2385                                                                                 lodStripsLib->MinLod()); 
     2383        mLodStripSlider->range(lodStripsLib->MinLod(),lodStripsLib->MaxLod()); 
    23862384 
    23872385        //      Pass to geomeshview the lod strips object. 
     
    23892387         
    23902388        //      Puts the slider in the max position. 
    2391         mLodStripSlider->value(lodStripsLib->MinLod()); 
     2389        //mLodStripSlider->value(lodStripsLib->MinLod()); 
    23922390} 
    23932391 
     
    25212519                        //      Restore simplification state. 
    25222520                        simplificationState     =       NO_SIMPLIFICATION; 
    2523  
    2524                         geoMeshView->resetTextures(); 
    2525                         BuildLoadTextureSubMeshMenu(); 
    25262521                } 
    25272522        } 
  • GTP/trunk/Lib/Geom/shared/GeoTool/src/GeoTool.cpp

    r980 r1007  
    44#endif 
    55 
     6#include <malloc.h> 
    67#include "GeoMeshViewUI.h" 
    78 
     
    1516int main(int argc, char **argv) 
    1617{ 
     18        _set_sbh_threshold(1016); 
     19 
    1720        interface       =       new GeoMeshViewUI(incrementa); 
    1821         
Note: See TracChangeset for help on using the changeset viewer.