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

Revision 895, 31.2 KB checked in by gumbau, 18 years ago (diff)

Working LODTree constructor and visualizer

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