source: GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoTreeSimplifier.cpp @ 834

Revision 834, 31.1 KB checked in by gumbau, 18 years ago (diff)

GeoLodTreeLibrary? leaves load from older leaf file format

Line 
1#include "GeoTreeSimplifier.h"
2#include "Hoja.h"
3
4#include <iostream>
5#include <fstream>
6#include <ctime>
7
8using namespace Geometry;
9using namespace std;
10
11TreeSimplifier::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
21        mesh    =       new Geometry::Mesh();
22        *mesh   =       *m;
23
24        //      Sets the progress bar.
25        mUPB    =       upb;
26}
27
28TreeSimplifier::~TreeSimplifier()
29{
30        delete  mtreesimpsequence;
31}
32
33// Returns the simplified mesh.
34Geometry::Mesh *TreeSimplifier::GetMesh ()
35{
36        return  mesh;
37}
38
39Geometry::TreeSimplificationSequence *TreeSimplifier::GetSimplificationSequence()
40{
41        return  mtreesimpsequence;
42}
43
44void TreeSimplifier::Simplify(Real paramlod,    Index meshLeaves)
45{
46        // paramlod indica el número de vértices
47        long    int     totalv;
48        long    int     hnueva;
49        float                   diam;
50
51        //      2006-02-22
52        float                   percent;
53        long    int     update;
54       
55        totalv  =       0;
56       
57        Mesh2Estructura(objmesh, meshLeaves);
58       
59        diam = DiametroEsferaEnvolvente();
60
61        EstableceCriterio(diam);
62
63        // El paramlod lo uso como condición de parada de la simplificación
64        if (paramlod >= 6)
65        {
66                //      2006-02-22
67                update  =       (activas - (6 * paramlod)) / 80;
68                percent =       0.5;
69               
70                while ( activas > (6*paramlod))
71                {
72                        //      2006-02-22
73                        if (mUPB        &&      (((long int)(activas - (6 * paramlod)) % update) == 0))
74                        {
75                                mUPB(percent);
76                        }
77                       
78                        hnueva  =       Colapsa(diam);
79                       
80                        EstableceCriterio2(diam, hnueva);
81                }
82        }
83        else
84        {
85                //      2006-02-22
86                update  =       (activas - 6) / 80;
87                percent =       0.5;
88               
89                while ( activas > 6)
90                {
91                        //      2006-02-22
92                        if (mUPB        &&      (((activas - 6) % update) == 0))
93                        {
94                                mUPB(percent);
95                        }
96                       
97                        hnueva  =       Colapsa(diam);
98                       
99                        EstableceCriterio2(diam, hnueva);
100                }
101        }
102
103        EscribeMesh(meshLeaves);
104       
105        //      2006-02-22
106        //      Fit progress bar to 100%.
107        if (mUPB)
108        {
109                mUPB(40);
110        }
111}
112
113void TreeSimplifier::Mesh2Estructura(   const Mesh      *mesh,
114                                                                                                                                                        Index                           meshLeaves)
115{
116        // Calcular el número de vértices
117        long int countv=0;
118        long int pos=0;
119        long int v1, v2, v3;
120        long int num_triangulo=0; // Identifica los triángulos en las hojas
121
122        //      2006-02-21.
123        float                   percent;
124        long    int     update;
125       
126        countv+=(long int)mesh->mSubMesh[meshLeaves].mVertexBuffer->mVertexCount;
127        Vertex  = new float[2*countv][3];
128       
129        //      2006-02-21.
130        update  =       mesh->mSubMesh[meshLeaves].mVertexBuffer->mVertexCount / 20;
131        percent =       0.5;
132       
133        for (unsigned int j=0; j<mesh->mSubMesh[meshLeaves].mVertexBuffer->mVertexCount; j++)
134        {
135                //      2006-02-21.
136                if (mUPB        &&      ((j % update) == 0))
137                {
138                        mUPB(percent);
139                }
140               
141                Vertex[pos][0] = mesh->mSubMesh[meshLeaves].mVertexBuffer->mPosition[j].x;
142                Vertex[pos][1] = mesh->mSubMesh[meshLeaves].mVertexBuffer->mPosition[j].y;
143                Vertex[pos][2] = mesh->mSubMesh[meshLeaves].mVertexBuffer->mPosition[j].z;
144                pos++;
145        }
146
147        // Calcular el número de hojas
148        counth+=(long)mesh->mSubMesh[meshLeaves].mIndexCount;
149        counth=counth/6; // Se supone que cada 6 índices forman una hoja.
150
151        if ( counth > 0)
152        {
153                Hojasa  = new Hoja[2*counth];
154        }
155
156        activas = counth;
157
158        // Insertar las hojas en la estructura
159        pos=0;
160
161        //      2006-02-21.
162        update  =       mesh->mSubMesh[meshLeaves].mIndexCount  / 20;
163        percent =       0.5;
164       
165        // Cada hoja son 6 vértices
166        for (unsigned int j=0; j<mesh->mSubMesh[meshLeaves].mIndexCount; j=j+6)
167        {
168                //      2006-02-21.
169                if (mUPB        &&      ((j % update) == 0))
170                {
171                        mUPB(percent);
172                }
173               
174                // Primer triángulo
175                v1=mesh->mSubMesh[meshLeaves].mIndex[j];
176                v2=mesh->mSubMesh[meshLeaves].mIndex[j+1];
177                v3=mesh->mSubMesh[meshLeaves].mIndex[j+2];
178                Hojasa[pos].Vert_Hoja[0]=v1;
179                Hojasa[pos].Vert_Hoja[1]=v2;
180                Hojasa[pos].Vert_Hoja[2]=v3;
181                num_triangulo++;
182                Hojasa[pos].id_triangulo[0]=num_triangulo;
183
184                // Segundo triángulo
185                v3=mesh->mSubMesh[meshLeaves].mIndex[j+5];
186                Hojasa[pos].Vert_Hoja[3]=v3;
187                num_triangulo++;
188                Hojasa[pos].id_triangulo[1]=num_triangulo;
189
190                Centroh(Hojasa[pos]);
191                GetNormal(Hojasa[pos]);
192                pos++;
193        }
194}
195
196float TreeSimplifier::max(float a,      float b)
197{
198        if (a>b) return (a);
199        else return(b);
200}
201
202float TreeSimplifier::min(float a,      float b)
203{
204        if (a>b) return (b);
205        else return(a);
206}
207
208float TreeSimplifier::distan(   float   x1,     float   y1,     float   z1,
209                                                                                                                        float x2,       float y2,       float z2)
210{
211        float dist = 0;
212
213        dist = ((x2-x1)*(x2-x1)) + ((y2-y1)*(y2-y1)) + ((z2-z1)*(z2-z1));
214
215        return ( dist);
216}
217
218//--------------------------------------------------------------------------------------------------------------------------------
219//  CALCULA EL CENTRO DE UNA HOJA
220//--------------------------------------------------------------------------------------------------------------------------------
221
222
223void TreeSimplifier::Centroh(Hoja       &Hoja1)
224{
225        float   max_x;
226        float   max_y;
227        float   max_z;
228        float   min_x;
229        float   min_y;
230        float   min_z;
231       
232        //x1
233        max_x   =       max(max(Vertex[Hoja1.Vert_Hoja[0]][0],
234                                                                        Vertex[Hoja1.Vert_Hoja[1]][0]),
235                                                max(Vertex[Hoja1.Vert_Hoja[2]][0],
236                                                                        Vertex[Hoja1.Vert_Hoja[3]][0]));
237       
238        min_x   =       min(min(Vertex[Hoja1.Vert_Hoja[0]][0],
239                                                                        Vertex[Hoja1.Vert_Hoja[1]][0]),
240                                                min(Vertex[Hoja1.Vert_Hoja[2]][0],
241                                                                        Vertex[Hoja1.Vert_Hoja[3]][0]));
242
243        Hoja1.Centro[0] = (max_x + min_x)/2;
244
245        //y1
246        max_y   =       max(max(Vertex[Hoja1.Vert_Hoja[0]][1],
247                                                                        Vertex[Hoja1.Vert_Hoja[1]][1]),
248                                                max(Vertex[Hoja1.Vert_Hoja[2]][1],
249                                                                        Vertex[Hoja1.Vert_Hoja[3]][1]));
250       
251        min_y   =       min(min(Vertex[Hoja1.Vert_Hoja[0]][1],
252                                                                        Vertex[Hoja1.Vert_Hoja[1]][1]),
253                                                min(Vertex[Hoja1.Vert_Hoja[2]][1],
254                                                                        Vertex[Hoja1.Vert_Hoja[3]][1]));
255
256        Hoja1.Centro[1] =       (max_y + min_y) / 2;
257       
258        //z1
259        max_z   =       max(max(Vertex[Hoja1.Vert_Hoja[0]][2],
260                                                                        Vertex[Hoja1.Vert_Hoja[1]][2]),
261                                                max(Vertex[Hoja1.Vert_Hoja[2]][2],
262                                                                        Vertex[Hoja1.Vert_Hoja[3]][2]));
263       
264        min_z   =       min(min(Vertex[Hoja1.Vert_Hoja[0]][2],
265                                                                        Vertex[Hoja1.Vert_Hoja[1]][2]),
266                                                min(Vertex[Hoja1.Vert_Hoja[2]][2],
267                                                                        Vertex[Hoja1.Vert_Hoja[3]][2]));
268
269        Hoja1.Centro[2] =       (max_z + min_z) / 2;
270}
271
272//--------------------------------------------------------------------------------------------------------------------------------
273//  CALCULA LA NORMAL DE UNA HOJA
274//--------------------------------------------------------------------------------------------------------------------------------
275void TreeSimplifier::GetNormal(Hoja &aHoja)
276{
277        float onex, oney, onez;
278        float twox, twoy, twoz;
279        float threex, threey, threez;
280
281        onex=Vertex[aHoja.Vert_Hoja[0]][0]; oney= Vertex[aHoja.Vert_Hoja[0]][1]; onez = Vertex[aHoja.Vert_Hoja[0]][2];
282        twox = Vertex[aHoja.Vert_Hoja[1]][0]; twoy = Vertex[aHoja.Vert_Hoja[1]][1]; twoz = Vertex[aHoja.Vert_Hoja[1]][2];
283        threex = Vertex[aHoja.Vert_Hoja[2]][0]; threey = Vertex[aHoja.Vert_Hoja[2]][1]; threez = Vertex[aHoja.Vert_Hoja[2]][2];
284       
285        aHoja.Normal[0] = ((twoz-onez)*(threey-oney)) - ((twoy-oney)*(threez-onez));
286        aHoja.Normal[1] = ((twox-onex)*(threez-onez)) - ((threex-onex)*(twoz-onez));
287        aHoja.Normal[2] = ((threex-onex)*(twoy-oney)) - ((twox-onex)*(threey-oney));
288
289       
290}
291//--------------------------------------------------------------------------------------------------------------------------------
292//  CALCULA LA distancia de Hausdorff ( distancia entre nubes de puntos)
293//--------------------------------------------------------------------------------------------------------------------------------
294float TreeSimplifier::Hausdorff(Hoja &aHoja, Hoja& h2)
295{
296        float onex, oney, onez;
297        float twox, twoy, twoz;
298        float threex, threey, threez;
299        float fourx, foury, fourz;
300        float x1, y1, z1;
301        float x2, y2, z2;
302        float x3, y3, z3;
303        float x4, y4, z4;
304        float dist1, dist2, dist3, dist4, distmp, dista, distb, dist;
305
306        onex=Vertex[aHoja.Vert_Hoja[0]][0]; oney= Vertex[aHoja.Vert_Hoja[0]][1]; onez = Vertex[aHoja.Vert_Hoja[0]][2];
307        twox = Vertex[aHoja.Vert_Hoja[1]][0]; twoy = Vertex[aHoja.Vert_Hoja[1]][1]; twoz = Vertex[aHoja.Vert_Hoja[1]][2];
308        threex = Vertex[aHoja.Vert_Hoja[2]][0]; threey = Vertex[aHoja.Vert_Hoja[2]][1]; threez = Vertex[aHoja.Vert_Hoja[2]][2];
309        fourx = Vertex[aHoja.Vert_Hoja[3]][0]; foury = Vertex[aHoja.Vert_Hoja[3]][1]; fourz = Vertex[aHoja.Vert_Hoja[3]][2];
310       
311
312        x1 = Vertex[h2.Vert_Hoja[0]][0]; y1 = Vertex[h2.Vert_Hoja[0]][1]; z1 = Vertex[h2.Vert_Hoja[0]][2];
313        x2 = Vertex[h2.Vert_Hoja[1]][0]; y2 = Vertex[h2.Vert_Hoja[1]][1]; z2 = Vertex[h2.Vert_Hoja[1]][2];
314        x3 = Vertex[h2.Vert_Hoja[2]][0]; y3 = Vertex[h2.Vert_Hoja[2]][1]; z3 = Vertex[h2.Vert_Hoja[2]][2];
315        x4 = Vertex[h2.Vert_Hoja[3]][0]; y4 = Vertex[h2.Vert_Hoja[3]][1]; z4 = Vertex[h2.Vert_Hoja[3]][2];
316
317        // guardo las distancias mínimas de cada vértice a los 4 contrarios.
318        dist1 = distan ( onex, oney,onez,x1,y1,z1);
319        // vertice 1 con los 4 de la otra hoja
320
321        distmp = distan ( onex, oney,onez,x2,y2,z2);
322        if ( distmp < dist1) dist1 = distmp;
323
324        distmp = distan ( onex, oney,onez,x3,y3,z3);
325        if ( distmp < dist1) dist1 = distmp;
326
327        distmp = distan ( onex, oney,onez,x4,y4,z4);
328        if ( distmp < dist1) dist1 = distmp;
329
330        // vertice 2 con los 4 de la otra hoja
331
332        dist2 = distan ( twox, twoy,twoz,x1,y1,z1);
333       
334        distmp = distan ( twox, twoy,twoz,x2,y2,z2);
335        if ( distmp < dist2) dist2 = distmp;
336       
337        distmp = distan ( twox, twoy,twoz,x3,y3,z3);
338        if ( distmp < dist2) dist2 = distmp;
339       
340        distmp = distan ( twox, twoy,twoz,x4,y4,z4);
341        if ( distmp < dist2) dist2 = distmp;
342
343        // vertice 3 con los 4 de la otra hoja
344
345        dist3 = distan ( threex, threey,threez,x1,y1,z1);
346       
347        distmp = distan ( threex, threey,threez,x2,y2,z2);
348        if ( distmp < dist3) dist3 = distmp;
349
350        distmp = distan ( threex, threey,threez,x3,y3,z3);
351        if ( distmp < dist3) dist3 = distmp;
352
353        distmp = distan ( threex, threey,threez,x4,y4,z4);
354        if ( distmp < dist3) dist3 = distmp;
355
356
357        // vertice 4 con los 4 de la otra hoja
358
359        dist4 = distan ( fourx, foury,fourz,x1,y1,z1);
360       
361        distmp = distan ( fourx, foury,fourz,x2,y2,z2);
362        if ( distmp < dist4) dist4 = distmp;
363
364        distmp = distan ( fourx, foury,fourz,x3,y3,z3);
365        if ( distmp < dist4) dist4 = distmp;
366       
367        distmp = distan ( fourx, foury,fourz,x4,y4,z4);
368        if ( distmp < dist4) dist4 = distmp;
369
370        //de entre estos cojo el máximo
371
372        dista =  max(dist1, max(dist2, max(dist3, dist4)));
373
374        //LO MISMO PERO A LA INVERSA
375
376        dist1 = distan ( x1,y1,z1, onex, oney, onez);
377        // vertice 1 con los 4 de la otra hoja
378
379        distmp = distan ( x1,y1,z1, twox, twoy, twoz);
380        if ( distmp < dist1) dist1 = distmp;
381
382        distmp = distan ( x1,y1,z1, threex, threey, threez);
383        if ( distmp < dist1) dist1 = distmp;
384
385        distmp = distan ( x1,y1,z1, fourx, foury, fourz);
386        if ( distmp < dist1) dist1 = distmp;
387
388        //2
389        dist2 = distan ( x2,y2,z2, onex, oney, onez);
390        // vertice 2 con los 4 de la otra hoja
391
392        distmp = distan ( x2,y2,z2, twox, twoy, twoz);
393        if ( distmp < dist2) dist2 = distmp;
394
395        distmp = distan ( x2,y2,z2, threex, threey, threez);
396        if ( distmp < dist2) dist2 = distmp;
397
398        distmp = distan ( x2,y2,z2, fourx, foury, fourz);
399        if ( distmp < dist2) dist2 = distmp;
400
401
402                //3
403        dist3 = distan ( x3,y3,z3, onex, oney, onez);
404        // vertice 3 con los 4 de la otra hoja
405
406        distmp = distan ( x3,y3,z3, twox, twoy, twoz);
407        if ( distmp < dist3) dist3 = distmp;
408
409        distmp = distan ( x3,y3,z3, threex, threey, threez);
410        if ( distmp < dist3) dist3 = distmp;
411
412        distmp = distan ( x3,y3,z3, fourx, foury, fourz);
413        if ( distmp < dist3) dist3 = distmp;
414
415                //4
416        dist4 = distan ( x4,y4,z4, onex, oney, onez);
417        // vertice 4 con los 4 de la otra hoja
418
419        distmp = distan ( x4,y4,z4, twox, twoy, twoz);
420        if ( distmp < dist4) dist4 = distmp;
421
422        distmp = distan ( x4,y4,z4, threex, threey, threez);
423        if ( distmp < dist4) dist4 = distmp;
424
425        distmp = distan ( x4,y4,z4, fourx, foury, fourz);
426        if ( distmp < dist4) dist4 = distmp;
427
428        //
429        distb =  max(dist1, max(dist2, max(dist3, dist4)));
430
431        dist  = max ( dista, distb);
432        return ( dist);
433       
434}
435
436//--------------------------------------------------------------------------------------------------------------------------------
437// CALCULA LA DISTANCIA ENTRE HOJAS
438//--------------------------------------------------------------------------------------------------------------------------------
439
440void TreeSimplifier::DistanciaEntreHojas(void)
441{
442        float dist, distmp ;
443        int j;
444
445        for ( int i=0;i<counth;i++)
446        {
447                if ( Hojasa[i].existe == true) // si la hoja aun existe
448                {
449                        // inicializo para poder comparar
450                        if ( i == (counth-1)) j = 0;
451                                else j = i+1;
452                        while (Hojasa[j].existe == false) j++;
453                        //dist = Hojasa[i].Distancia(Hojasa[j]);
454                        dist = Hausdorff( Hojasa[i], Hojasa[j]);
455
456                        Hojasa[i].hoja_cerca = j;
457                        // empiezo los calculos
458                        for ( j =0; j<(counth-1);j++)
459                        {
460                                if ( j == i)
461                                        break;
462                                if ( Hojasa[j].existe == true) // si la hoja aun existe
463                                {
464                                        distmp = Hausdorff(Hojasa[i], Hojasa[j]);
465                                        if ( distmp < dist )
466                                        {
467                                                dist = distmp;
468                                                Hojasa[i].hoja_cerca = j;
469                                        }
470                                }
471                               
472                        }
473                        Hojasa[i].dist = dist;
474                }
475        }
476
477}
478
479//--------------------------------------------------------------------------------------------------------------------------------
480// DEVUELVE LA HOJA QUE TIENE UNA DISTANCIA MENOR
481//--------------------------------------------------------------------------------------------------------------------------------
482long int TreeSimplifier::MinimaDistancia ( void)
483{
484        float                   mindist;
485        long int        cual;
486        int                             i;
487
488        mindist =       0;
489        cual            =       -1;
490        i                               =       0;
491       
492        //inicializo
493        while (Hojasa[i].existe != true)
494        {
495                i++;
496        }
497       
498        mindist =       Hojasa[i].dist;
499        cual            =       i;
500       
501        //busco la minima
502        for (i = 0; i < counth; i++)
503        {
504                if (Hojasa[i].existe == true)
505                {
506                        if ( mindist > Hojasa[i].dist)
507                        {
508                                mindist = Hojasa[i].dist;
509                                cual = i;
510                        }
511                }
512
513        }
514        return (cual);
515}
516
517//--------------------------------------------------------------------------------------------------------------------------------
518// CALCULA LA COPLANARIDAD ENTRE HOJAS
519//--------------------------------------------------------------------------------------------------------------------------------
520void TreeSimplifier::CoplanarEntreHojas(FILE    *fp_coplanar)
521{
522        float   cop;
523        float   coptmp;
524        int     i;
525        int     j;
526
527        for ( i=0;i<counth;i++)
528        {
529                if ( Hojasa[i].existe == true) // si la hoja aun existe
530                {
531                        // inicializo para poder comparar
532                        if ( i == (counth-1))
533                        {
534                                j       =       0;
535                        }
536                        else
537                        {
538                                j =     i + 1;
539                        }
540                       
541                        while (Hojasa[j].existe == false)
542                        {
543                                j++;
544                        }
545                       
546                        cop                                                                     =       Hojasa[i].Coplanaridad(Hojasa[j]);
547                        Hojasa[i].hoja_cop      =       j;
548                       
549                        // empiezo los calculos
550                        for (j = 0; j < (counth-1); j++)
551                        {
552                                // si la hoja aun existe.
553                                if (( j != i) && (Hojasa[j].existe == true))
554                                {
555                                        coptmp  =       Hojasa[i].Coplanaridad(Hojasa[j]);
556
557                                        // COJO EL MAS COPLANAR , CERCANO A 1.
558                                        if (coptmp > cop)
559                                        {
560                                                cop                                                                     =       coptmp;
561                                                Hojasa[i].hoja_cop      =       j;
562                                        }
563                                }
564                        }
565                        Hojasa[i].coplanar      =       1 - cop; //  8/6/01 LO INVIERTO
566                }
567        }
568}
569
570//--------------------------------------------------------------------------------------------------------------------------------
571//
572//--------------------------------------------------------------------------------------------------------------------------------
573void TreeSimplifier::DosMayores(float *mayores, int     *indices)
574{
575        float   m1;
576        int             i;
577
578        if      (mayores[0] < mayores[1])
579        {
580                m1                                      =       mayores[0];
581                mayores[0]      =       mayores[1];
582                mayores[1]      =       m1;
583
584                i                                               =       indices[0];
585                indices[0]      =       indices[1];
586                indices[1]      =       i;
587        }
588
589        if (mayores [2] < mayores [3])
590        {
591                m1                                      =       mayores[2];
592                mayores[2]      =       mayores[3];
593                mayores [3]     =       m1;
594
595                i                                               =       indices[2];
596                indices[2]      =       indices[3];
597                indices[3]      =       i;
598        }
599
600        if  (mayores[0] < mayores[2])
601        {
602                m1                                      =       mayores[0];
603                mayores[0]      =       mayores[2];
604                mayores[2]      =       m1;
605
606                i                                               =       indices[0];
607                indices[0]      =       indices[2];
608                indices[2]      =       i;
609        }
610
611        if (mayores [2] < mayores [3])
612        {
613                m1                                      =       mayores[2];
614                mayores[2]      =       mayores[3];
615                mayores [3]     =       m1;
616
617                i                                               =       indices[2];
618                indices[2]      =       indices[3];
619                indices[3]      =       i;
620        }
621
622        if (mayores [1] < mayores [2])
623        {
624                m1                                      =       mayores[1];
625                mayores[1]      =       mayores[2];
626                mayores [2]     =       m1;
627
628                i                                               = indices[1];
629                indices[1]      = indices[2];
630                indices[2]      = i;
631        }               
632}
633
634//--------------------------------------------------------------------------------------------------------------------------------
635//
636//--------------------------------------------------------------------------------------------------------------------------------
637//float TreeSimplifier::DiametroEsferaEnvolvente (FILE* fp_simplifica)
638float TreeSimplifier::DiametroEsferaEnvolvente()
639{
640        float xmax, xmin, ymax, ymin, zmax, zmin;
641        float diametro, cx, cy, cz;
642        int j;
643
644        //      2006-02-21.
645        float                   percent;
646        long    int     update;
647
648        //inicializo al primero de los vértices de las hojas
649
650        xmax = Vertex[Hojasa[0].Vert_Hoja[0]][0];
651        xmin = xmax;
652
653        ymax = Vertex[Hojasa[0].Vert_Hoja[0]][1];
654        ymin = ymax;
655
656        zmax = Vertex[Hojasa[0].Vert_Hoja[0]][2];
657        zmin = zmax;
658
659        // ahora busco los maximos y los minimos correspondientes
660
661
662        //      2006-02-21
663        update  =       counth / 20;
664        percent =       0.5;
665        for (int i = 1; i < counth; i++)
666        {
667                //      2006-02-21
668                if (mUPB        &&      ((i % update) == 0))
669                {
670                        mUPB(percent);
671                }
672               
673                for ( j=0;j<4;j++)
674                {
675                       
676                if ( xmax < Vertex[Hojasa[i].Vert_Hoja[j]][0]) xmax = Vertex[Hojasa[i].Vert_Hoja[j]][0];
677                if ( xmin > Vertex[Hojasa[i].Vert_Hoja[j]][0]) xmin = Vertex[Hojasa[i].Vert_Hoja[j]][0];
678
679                if ( ymax < Vertex[Hojasa[i].Vert_Hoja[j]][1]) ymax = Vertex[Hojasa[i].Vert_Hoja[j]][1];
680                if ( ymin > Vertex[Hojasa[i].Vert_Hoja[j]][1]) ymin = Vertex[Hojasa[i].Vert_Hoja[j]][1];
681               
682                if ( zmax < Vertex[Hojasa[i].Vert_Hoja[j]][2]) zmax = Vertex[Hojasa[i].Vert_Hoja[j]][2];
683                if ( zmin > Vertex[Hojasa[i].Vert_Hoja[j]][2]) zmin = Vertex[Hojasa[i].Vert_Hoja[j]][2];
684
685                }
686        }
687
688        cx = (xmax + xmin)/2;
689        cy = (ymax + ymin)/2;
690        cz = (zmax + zmin)/2;
691
692
693        diametro = ((xmax-xmin)*(xmax-xmin)) + ((ymax-ymin)*(ymax-ymin)) + ((zmax-zmin)*(zmax-zmin));
694
695return (diametro);
696}
697
698//--------------------------------------------------------------------------------------------------------------------------------
699//  normaliza las distancia
700//--------------------------------------------------------------------------------------------------------------------------------
701void TreeSimplifier::NormalizaDistancia (float diametro)
702{
703        float dtmp;
704        for (int i=0; i<counth;i++)
705        {
706                dtmp = Hojasa[i].dist;
707                Hojasa[i].dist = dtmp / diametro;
708               
709        }
710}
711
712//--------------------------------------------------------------------------------------------------------------------------------
713//  establece el criterio como (K1 * dist + K2 * cop)/ K1+K2
714//--------------------------------------------------------------------------------------------------------------------------------
715void TreeSimplifier::EstableceCriterio(float diametro)
716{
717        //      Para empezar establezco K1 y K2 con 0,5
718        float coptmp2, coptmp, distmp2, distmp, criteriotmp;
719        int i, j, nhojasi, nhojasj;
720
721        //      2006-02-21
722        float                   percent;
723        long    int     update;
724       
725        update  =       counth / 30;
726        percent =       1;
727       
728        for ( i=0; i<counth;i++)
729        {
730                //      2005-02-21
731                if (mUPB        &&      ((i % update) == 0))
732                {
733                        mUPB(percent);
734                }
735               
736                if (Hojasa[i].existe == true)
737                {
738                        //incializo criterio a un numero elevado
739                        Hojasa[i].criterio = 1000;
740                        nhojasi = Hojasa[i].Cuantas_hojas;
741                        //coplanaridad
742                        for ( j =0; j<counth;j++)
743                        {
744                                if (( j != i) && ( Hojasa[j].existe == true)) // si la hoja aun existe
745                                {
746                                        //17/09/01 ANTES DE CALCULAR NADA, COMPRUEBO QUE ESTAS DOS HOJAS
747                                        // SE PODRIAN COLAPSAR, ED, QUE LA DIFERENCIA DE HOJAS QUE COLAPSAN
748                                        // ES COMO MÁXIMO 1
749
750                                        nhojasj = Hojasa[j].Cuantas_hojas;
751
752                                        if ( abs((nhojasi - nhojasj)) < 2)
753                                        {
754                                                //coplanaridad y lo invierto
755                                                coptmp2 = Hojasa[i].Coplanaridad(Hojasa[j]);
756                                                coptmp = 1 - coptmp2;
757                                                //distancia y la normalizo
758                                                distmp2 = Hausdorff( Hojasa[i], Hojasa[j]);
759                                                distmp = distmp2 / diametro;
760                                                // calculo el criterio para esa hoja
761                                                criteriotmp = (( K1 * distmp * distmp ) + (K2 * coptmp * distmp))/ (K1 + K2);
762                                                //selecciono el criterio menor
763                                                if (Hojasa[i].criterio > criteriotmp)
764                                                {
765                                                        Hojasa[i].criterio = criteriotmp;
766                                                        Hojasa[i].hoja_crit = j;
767                                                }
768                                        }
769                                }
770                               
771                        }
772                }
773        }
774}
775
776//--------------------------------------------------------------------------------------------------------------------------------
777//  establece el criterio despues de colapsar
778//--------------------------------------------------------------------------------------------------------------------------------
779void TreeSimplifier::EstableceCriterio2 ( float                 diametro,
780                                                                                                                                                                        long int        hojanueva)
781{
782        //Para empezar establezco K1 y K2 con 0,5
783        float  coptmp2, coptmp, distmp2, distmp, criteriotmp;
784        int i, j, nhojasi, nhojasj;
785        //ESTAN EN tres PROCEDIMIENTOS: COLAPSA, ESTABLECECRITERIO Y ESTABLECECRITERIO2
786       
787        for (i = 0; i < counth; i++)
788        {
789                if ((Hojasa[i].existe == true) && (i != hojanueva))
790                {       
791                        nhojasi = Hojasa[i].Cuantas_hojas;
792                        //¿ SE HA DESACTIVADO LA HOJA_CRIT QUE GUARDABA LA HOJA?
793                        if ( Hojasa[Hojasa[i].hoja_crit].existe == false)
794                        {
795                                Hojasa[i].criterio = 1000;
796
797                                //coplanaridad
798                                for ( j =0; j<counth;j++)
799                                {
800                                        if (( j != i) && ( Hojasa[j].existe == true)) // si la hoja aun existe
801                                        {
802                                                //17/09/01 ANTES DE CALCULAR NADA, COMPRUEBO QUE ESTAS DOS HOJAS
803                                                // SE PODRIAN COLAPSAR, ED, QUE LA DIFERENCIA DE HOJAS QUE COLAPSAN
804                                                // ES COMO MÁXIMO 1
805
806                                                nhojasj = Hojasa[j].Cuantas_hojas;
807
808                                                if ( abs((nhojasi - nhojasj)) < 2)
809                                                {
810
811                                                        //coplanaridad y lo invierto
812                                                        coptmp2 = Hojasa[i].Coplanaridad(Hojasa[j]);
813                                                        coptmp = 1 - coptmp2;   
814                                                        //distancia y la normalizo     
815                                                //      distmp2 = Hojasa[i].Distancia(Hojasa[j]);
816                                                        distmp2 = Hausdorff( Hojasa[i],  Hojasa[j]);
817                                                        distmp = distmp2 / diametro;
818                                                        // calculo el criterio para esa hoja
819                                                        criteriotmp = (( K1 * distmp * distmp ) + (K2 * coptmp * distmp))/ (K1 + K2);
820                                                        //selecciono el criterio menor
821                                                        if (Hojasa[i].criterio > criteriotmp)
822                                                        {
823                                                                Hojasa[i].criterio = criteriotmp;
824                                                                Hojasa[i].hoja_crit = j;
825                                                        }
826                                                }
827                                        }
828                                }
829                        }
830                        else
831                        { // CALCULARE SI EL CRITERIO CON ESTA HOJA ES MENOR QUE EL ANTERIOR
832                                nhojasj = Hojasa[hojanueva].Cuantas_hojas;//17/09/01
833
834                                if ( abs((nhojasi - nhojasj)) < 2)
835                                {
836                                        //coplanaridad y lo invierto
837                                        coptmp2 = Hojasa[i].Coplanaridad(Hojasa[hojanueva]);
838                                        coptmp = 1 - coptmp2;
839                                        //distancia y la normalizo
840                                        //distmp2 = Hojasa[i].Distancia(Hojasa[hojanueva]);
841                                        distmp2 = Hausdorff( Hojasa[i], Hojasa[hojanueva]);
842                                        distmp = distmp2 / diametro;
843                                        // calculo el criterio para esa hoja
844                                        criteriotmp = (( K1 * distmp * distmp ) + (K2 * coptmp * distmp))/ (K1 + K2);
845                                        //selecciono el criterio menor
846                                        if (Hojasa[i].criterio > criteriotmp)
847                                        {       
848                                                Hojasa[i].criterio = criteriotmp;
849                                                Hojasa[i].hoja_crit = hojanueva;
850                                        }
851                                }
852                        }
853                }
854        }
855}
856//--------------------------------------------------------------------------------------------------------------------------------
857// DEVUELVE LA HOJA QUE TIENE EL NUMERO EN EL CAMPO CRITERIO MENOR
858//--------------------------------------------------------------------------------------------------------------------------------
859
860long int TreeSimplifier::MinimoCriterio (void)
861{
862        float mincrit =0;
863        long int cual=-1;
864        int i=0;
865       
866        //inicializo
867        while (Hojasa[i].existe != true) i++;
868        mincrit = Hojasa[i].criterio;
869        cual =i;
870        //busco la minima
871        for ( i=0;i<counth;i++)
872
873        {
874                if (Hojasa[i].existe == true)
875                {
876                        if ( mincrit> Hojasa[i].criterio)
877                        {
878                                mincrit = Hojasa[i].criterio;
879                                cual = i;
880                        }
881                }
882               
883        }
884        return (cual);
885}
886
887
888//--------------------------------------------------------------------------------------------------------------------------------
889//
890//--------------------------------------------------------------------------------------------------------------------------------
891void TreeSimplifier::ElijeVertices(Hoja& Hoja1, Hoja& Hoja2, long int count)
892{
893        // criterio es el de los dos vertices más alejados del centro de la otra hoja
894       
895        float a,b,c;
896        float dist[4];
897        int indices[4];
898       
899        // primero de la primera hoja cojo los dos primeros vertices
900
901
902        a = Vertex[Hoja1.Vert_Hoja[0]][0];
903        b = Vertex[Hoja1.Vert_Hoja[0]][1];
904        c = Vertex[Hoja1.Vert_Hoja[0]][2];
905
906        dist[0] = ((Hoja2.Centro[0]-a)*(Hoja2.Centro[0]-a)) + ((Hoja2.Centro[1]-b)*(Hoja2.Centro[1]-b)) +
907                   ((Hoja2.Centro[2]-c)*(Hoja2.Centro[2]-c));
908
909       
910        a = Vertex[Hoja1.Vert_Hoja[1]][0];
911        b = Vertex[Hoja1.Vert_Hoja[1]][1];
912        c = Vertex[Hoja1.Vert_Hoja[1]][2];
913
914        dist[1] = ((Hoja2.Centro[0]-a)*(Hoja2.Centro[0]-a)) + ((Hoja2.Centro[1]-b)*(Hoja2.Centro[1]-b)) +
915                   ((Hoja2.Centro[2]-c)*(Hoja2.Centro[2]-c));
916
917        a = Vertex[Hoja1.Vert_Hoja[2]][0];
918        b = Vertex[Hoja1.Vert_Hoja[2]][1];
919        c = Vertex[Hoja1.Vert_Hoja[2]][2];
920
921        dist[2] = ((Hoja2.Centro[0]-a)*(Hoja2.Centro[0]-a)) + ((Hoja2.Centro[1]-b)*(Hoja2.Centro[1]-b)) +
922                   ((Hoja2.Centro[2]-c)*(Hoja2.Centro[2]-c));
923
924
925        a = Vertex[Hoja1.Vert_Hoja[3]][0];
926        b = Vertex[Hoja1.Vert_Hoja[3]][1];
927        c = Vertex[Hoja1.Vert_Hoja[3]][2];
928
929        dist[3] = ((Hoja2.Centro[0]-a)*(Hoja2.Centro[0]-a)) + ((Hoja2.Centro[1]-b)*(Hoja2.Centro[1]-b)) +
930                   ((Hoja2.Centro[2]-c)*(Hoja2.Centro[2]-c));
931
932        for ( int i=0;i<4;i++) indices[i]=i;
933
934        DosMayores(dist, indices);
935       
936        Hojasa[counth].Vert_Hoja[0] = Hoja1.Vert_Hoja[indices[0]];
937        Hojasa[counth].Vert_Hoja[1] = Hoja1.Vert_Hoja[indices[1]];
938       
939        // segunda hoja los dos ultimos vertices
940
941       
942        a = Vertex[Hoja2.Vert_Hoja[0]][0];
943        b = Vertex[Hoja2.Vert_Hoja[0]][1];
944        c = Vertex[Hoja2.Vert_Hoja[0]][2];
945
946        dist[0] = ((Hoja1.Centro[0]-a)*(Hoja1.Centro[0]-a)) + ((Hoja1.Centro[1]-b)*(Hoja1.Centro[1]-b)) +
947                   ((Hoja1.Centro[2]-c)*(Hoja1.Centro[2]-c));
948
949       
950        a = Vertex[Hoja2.Vert_Hoja[1]][0];
951        b = Vertex[Hoja2.Vert_Hoja[1]][1];
952        c = Vertex[Hoja2.Vert_Hoja[1]][2];
953
954        dist[1] = ((Hoja2.Centro[0]-a)*(Hoja2.Centro[0]-a)) + ((Hoja1.Centro[1]-b)*(Hoja1.Centro[1]-b)) +
955                   ((Hoja2.Centro[2]-c)*(Hoja2.Centro[2]-c));
956
957        a = Vertex[Hoja2.Vert_Hoja[2]][0];
958        b = Vertex[Hoja2.Vert_Hoja[2]][1];
959        c = Vertex[Hoja2.Vert_Hoja[2]][2];
960
961        dist[2] = ((Hoja1.Centro[0]-a)*(Hoja1.Centro[0]-a)) + ((Hoja1.Centro[1]-b)*(Hoja1.Centro[1]-b)) +
962                   ((Hoja1.Centro[2]-c)*(Hoja1.Centro[2]-c));
963
964
965        a = Vertex[Hoja2.Vert_Hoja[3]][0];
966        b = Vertex[Hoja2.Vert_Hoja[3]][1];
967        c = Vertex[Hoja2.Vert_Hoja[3]][2];
968
969        dist[3] = ((Hoja1.Centro[0]-a)*(Hoja1.Centro[0]-a)) + ((Hoja1.Centro[1]-b)*(Hoja1.Centro[1]-b)) +
970                   ((Hoja1.Centro[2]-c)*(Hoja1.Centro[2]-c));
971
972        for ( int i=0;i<4;i++) indices[i]=i;
973
974        DosMayores(dist, indices);
975       
976        Hojasa[counth].Vert_Hoja[2] = Hoja2.Vert_Hoja[indices[0]];
977        Hojasa[counth].Vert_Hoja[3] = Hoja2.Vert_Hoja[indices[1]];
978
979
980
981       
982}
983
984//--------------------------------------------------------------------------------------------------------------------------------
985// AÑADE HOJAS
986//--------------------------------------------------------------------------------------------------------------------------------
987//long int TreeSimplifier::Colapsa (Geometry::TreeSimplificationSequence *tss, float diametro)
988long int TreeSimplifier::Colapsa(float diametro)
989{
990        long int i=0, cual=-1;
991        long int otra = -1;
992        float coptmp, coptmp2, distmp, distmp2, criteriotmp;
993//      char linea[250];
994
995//      cual=MinimaDistancia();
996        cual=MinimoCriterio();
997//      otra = Hojasa[cual].hoja_cerca; //para la distancia
998//      otra = Hojasa[cual].hoja_cop;
999        otra = Hojasa[cual].hoja_crit;
1000
1001        //desactivo las hojas cercanas
1002        Hojasa[cual].existe = false;
1003        Hojasa[otra].existe = false;
1004        //creo la hoja nueva
1005
1006        Hojasa[counth].hoja_cerca = -1;
1007        Hojasa[counth].dist = 0;
1008        Hojasa[counth].hoja_cop = -1;
1009        Hojasa[counth].coplanar = 0;
1010
1011        Hojasa[counth].Cuantas_hojas = Hojasa[cual].Cuantas_hojas + Hojasa[otra].Cuantas_hojas;
1012        ElijeVertices(Hojasa[cual], Hojasa[otra], counth);
1013        Centroh (Hojasa[counth]);
1014        GetNormal ( Hojasa[counth]);
1015
1016        //18/09/01
1017        if (Hojasa[counth].Cuantas_hojas > 60 )
1018        {
1019                        Hojasa[counth].existe = false;
1020                        activas--;
1021        }
1022        else
1023        {
1024                //establezco el criterio para la hoja nueva
1025        Hojasa[counth].existe = true;
1026                Hojasa[counth].criterio = 1000;
1027
1028                //coplanaridad
1029                for (int j = 0; j < (counth+1); j++)
1030                {
1031                        if (( j != counth) && ( Hojasa[j].existe == true)) // si la hoja aun existe
1032                        {
1033                        //coplanaridad y lo invierto
1034                        coptmp2 = Hojasa[counth].Coplanaridad(Hojasa[j]);
1035                        coptmp = 1 - coptmp2;
1036                        //distancia y la normalizo
1037                        //distmp2 = Hojasa[counth].Distancia(Hojasa[j]);
1038                        distmp2 = Hausdorff(Hojasa[counth], Hojasa[j]);
1039                        distmp = distmp2 / diametro;
1040                        // calculo el criterio para esa hoja
1041                        criteriotmp = (( K1 * distmp * distmp ) + (K2 * coptmp * distmp))/ (K1 + K2);
1042                        //selecciono el criterio menor
1043                        if (Hojasa[counth].criterio > criteriotmp)
1044                        {
1045                                Hojasa[counth].criterio = criteriotmp;
1046                                Hojasa[counth].hoja_crit = j;}
1047                        }
1048                }
1049        }       
1050
1051        // Crear el paso de simplificación
1052        Geometry::TreeSimplificationSequence::Step pasosimp;
1053        pasosimp.mV0=Hojasa[cual].id_triangulo[0];
1054        pasosimp.mV1=Hojasa[cual].id_triangulo[1];
1055        pasosimp.mT0=Hojasa[otra].id_triangulo[0];
1056        pasosimp.mT1=Hojasa[otra].id_triangulo[1];
1057
1058        // Nuevos vértices
1059        pasosimp.mNewQuad[0]=Hojasa[counth].Vert_Hoja[0];
1060        pasosimp.mNewQuad[1]=Hojasa[counth].Vert_Hoja[1];
1061        pasosimp.mNewQuad[2]=Hojasa[counth].Vert_Hoja[2];
1062        pasosimp.mNewQuad[3]=Hojasa[counth].Vert_Hoja[3];
1063
1064        // Insertar el paso de simplificación
1065        mtreesimpsequence->mSteps.push_back(pasosimp);
1066
1067        //incremento el numero de hojas
1068        counth++;
1069        activas--;
1070        return (counth-1);//porque lo he incrementado en la linea de antes
1071}
1072
1073//--------------------------------------------------------------------------------------------------------------------------------
1074// ESCRIBE EL mIndex EN EL MESH DE SALIDA
1075//--------------------------------------------------------------------------------------------------------------------------------
1076void TreeSimplifier::EscribeMesh(int idMeshLeaves)
1077{
1078        // Calcular el número de indices después de simplificar
1079        long int tamIndex       =       activas * 6; // Cada hoja tiene 6 índices
1080
1081        //      2006-02-21.
1082        float                   percent;
1083        long    int     update;
1084       
1085        delete [] mesh->mSubMesh[idMeshLeaves].mIndex;
1086        mesh->mSubMesh[idMeshLeaves].mIndexCount=tamIndex;
1087        mesh->mSubMesh[idMeshLeaves].mIndex=new Geometry::Index[tamIndex];
1088
1089        // Recorrer las hojas, comprobar las que están activas y copiar los índices al mesh.
1090        Geometry::Index indice=0;
1091
1092        //      2006-02-21.
1093        update  =       counth  / 10;
1094        percent =       1;
1095       
1096        for (long j=0; j<counth;j++)
1097        {
1098                //      2006-02-21
1099                if (mUPB        &&      ((j % update) == 0))
1100                {
1101                        mUPB(percent);
1102                }
1103               
1104                if ( Hojasa[j].existe == true) // si la hoja aun existe
1105                {
1106                        mesh->mSubMesh[idMeshLeaves].mIndex[indice]=Hojasa[j].Vert_Hoja[0];
1107                        mesh->mSubMesh[idMeshLeaves].mIndex[indice+1]=Hojasa[j].Vert_Hoja[1];
1108                        mesh->mSubMesh[idMeshLeaves].mIndex[indice+2]=Hojasa[j].Vert_Hoja[2];
1109                        mesh->mSubMesh[idMeshLeaves].mIndex[indice+3]=Hojasa[j].Vert_Hoja[2];
1110                        mesh->mSubMesh[idMeshLeaves].mIndex[indice+4]=Hojasa[j].Vert_Hoja[1];
1111                        mesh->mSubMesh[idMeshLeaves].mIndex[indice+5]=Hojasa[j].Vert_Hoja[3];
1112                        indice=indice+6;
1113                }
1114        }
1115}
Note: See TracBrowser for help on using the repository browser.