Ignore:
Timestamp:
06/09/06 08:24:19 (18 years ago)
Author:
gumbau
Message:
 
File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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} 
Note: See TracChangeset for help on using the changeset viewer.