00001 #include "region.h"
00002 #include "resollu.h"
00003
00004
00005 #include <fstream>
00006 #include <iostream>
00007
00008
00009 double Region::Compute_nrj_sommet_sur_mesh (Vertex_handle pV)
00010 {
00011 double min;
00012
00013 Vertex_handle pV3D;
00014 pV3D=pV;
00015 this->vh3Dfrom2D(pV3D);
00016
00017
00018 Vector nv = pV3D->normal();
00019
00020 Halfedge_around_vertex_circulator h = pV3D->vertex_begin();
00021
00022 min = nv * h->facet()->normal();
00023
00024 do {
00025 h++;
00026
00027 if( (nv * h->facet()->normal()) < min ) min = nv * h->facet()->normal();
00028
00029 } while(h != pV3D->vertex_begin() );
00030
00031 return min;
00032 }
00033
00034
00035 double Region::Compute_nrj_sommet (Vertex_handle pV)
00036 {
00037 double nrj=0;
00038 int count=0;
00039
00040 Vertex_handle pV3D;
00041 pV3D=pV;
00042 this->vh3Dfrom2D(pV3D);
00043
00044 Vertex_handle SommetMini = _mesh3D.vertices_begin();
00045
00046 for(Polyhedron::Vertex_iterator j = _mesh3D.vertices_begin(); j != _mesh3D.vertices_end() ; ++j) {
00047
00048 if (has_smaller_distance_to_point(pV3D->point(), j->point(), SommetMini->point())) SommetMini = j;
00049 }
00050
00051
00052
00053 Halfedge_around_vertex_circulator h = SommetMini->vertex_begin();
00054
00055 Facet_handle pF = h->facet();
00056
00057 double M[3][MAT_SIZE];
00058 double U[3];
00059 double B[3];
00060
00061 Halfedge_around_facet_circulator h2 = pF->facet_begin();
00062
00063 if (CGAL::circulator_size(h2)!=3) { std::cout << "ERROR in Compute_nrj_sommet: facet must be triangle" << std::endl; exit(-1); }
00064
00065 do {
00066 M[count][0]=h2->vertex()->point()[0];
00067 M[count][1]=h2->vertex()->point()[1];
00068 M[count][2]=h2->vertex()->point()[2];
00069
00070 U[count++] = Compute_nrj_sommet_sur_mesh( h2->vertex() );
00071
00072 } while(h2 != pF->facet_begin() );
00073
00074 if(! ResoudreSysteme(M, U, B, 3) ) { std::cout << "ERROR in Compute_nrj_sommet: problem occured during matrix resolution" << std::endl; exit(-1); }
00075
00076 nrj= B[0]*pV->point()[0]+B[1]*pV->point()[1]+B[2]*pV->point()[2];
00077
00078 return nrj;
00079 }
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00102 class Border_Edge_circulator {
00103 public:
00104 typedef Enriched_polyhedron<Enriched_kernel,Enriched_items> Polyhedron ;
00105 typedef Polyhedron::Vertex_handle Vertex_handle;
00106 typedef Polyhedron::Halfedge_handle Halfedge_handle;
00107 typedef Polyhedron::Halfedge_around_vertex_circulator Halfedge_around_vertex_circulator;
00108 typedef Polyhedron::Edge_iterator Edge_iterator;
00109
00110 private:
00112 Halfedge_handle prec ;
00113 public:
00119 Border_Edge_circulator(Edge_iterator Ei) : prec(Ei) {
00120 }
00121
00123 void operator++() {
00124 Vertex_handle vh = prec->vertex() ;
00125 Halfedge_around_vertex_circulator h = vh->vertex_begin() ;
00126 bool DEBUGprecNonModifie = true ;
00127 do
00128 {
00129 if ((h->is_border()) && (h->opposite()->vertex() != prec->opposite()->vertex()))
00130 {
00131 prec=h->opposite() ;
00132 DEBUGprecNonModifie = false ;
00133 }
00134 h++ ;
00135 } while (h != vh->vertex_begin()) ;
00136 if (DEBUGprecNonModifie)
00137 {
00138 std::cout << "***dans Border_Edge_iterator : prec non modifie" << std::endl ;
00139 exit(-1) ;
00140 }
00141 }
00142
00149 Halfedge_handle operator*() {
00150 return prec ;
00151 }
00152
00154 bool operator==(Halfedge_handle h) {
00155 return (prec == h) ;
00156 }
00157
00159 bool operator!=(Halfedge_handle h) {
00160 return (prec != h) ;
00161 }
00162 };
00163
00164
00165
00166
00167
00168
00169
00170
00171 void Region::Compute_Parameterization()
00172 {
00173 typedef CGAL::Simple_cartesian<double> Kernel;
00174 typedef CGAL::Filtered_kernel_adaptor<Kernel> K;
00175
00176
00177 assert ( this->valide3D() );
00178
00179 K::Compute_squared_distance_3 squared_distance;
00180
00181
00182
00183 int nbv = _mesh3D.size_of_vertices();
00184 int bs = _mesh3D.size_of_border_edges();
00185 int bhe = _mesh3D.size_of_border_halfedges();
00186 int nbf = _mesh3D.size_of_facets();
00187
00188
00189 std::cout << "nombre de sommets de la region locale " << nbv << std::endl;
00190 std::cout << "nombre d'aretes au bord " << bs << std::endl;
00191 std::cout << "nombre de demi-aretes au bord " << bhe << std::endl;
00192 std::cout << "nombre de facets " << nbf << std::endl;
00193
00194 Point c1,c2,c3,c4;
00195
00196 double d12=0,d23=0,d34=0,d41=0;
00197 double dist_totale=0;
00198 double cmax=0;
00199 double dist=0;
00200
00201
00202
00203
00204
00205
00206 _mesh2D.normalize_border();
00207
00208
00209
00210 if( nbv<801 ) cmax=6;
00211 else cmax=40;
00212
00213
00214 c1=Point(0,cmax,0);
00215 c2=Point(0,0,0);
00216 c3=Point(cmax,0,0);
00217 c4=Point(cmax,cmax,0);
00218
00219
00220
00221 Point p1,p2;
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231 int count=0;
00232 Border_Edge_circulator h(_mesh2D.border_edges_begin());
00233
00234
00235 p2= (*h)->vertex()->point();
00236 do
00237 {
00238 p1=p2;
00239 p2= (*h)->vertex()->point();
00240
00241
00242
00243 dist_totale += sqrt(squared_distance( p1, p2));
00244
00245 ++h ;
00246
00247 } while (h != _mesh2D.border_edges_begin()) ;
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263 h = _mesh2D.border_edges_begin();
00264 p2= (*h)->vertex()->point();
00265
00266 do
00267 {
00268 p1=p2;
00269 p2= (*h)->vertex()->point();
00270
00271 dist = sqrt(squared_distance( p1, p2));
00272
00273
00274 if(d12 + dist <= dist_totale/4) d12 += dist;
00275 else if (d23 + dist <= dist_totale/4) d23 += dist;
00276 else if (d34 + dist <= dist_totale/4) d34 += dist;
00277 else d41 += dist;
00278
00279 ++h;
00280
00281 } while (h != _mesh2D.border_edges_begin()) ;
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301 if(d12 <= 0) d12=0.00001;
00302 if(d23 <= 0) d23=0.00001;
00303 if(d34 <= 0) d34=0.00001;
00304 if(d41 <= 0) d41=0.00001;
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318 h = _mesh2D.border_edges_begin();
00319
00320 count=0;
00321 dist=0;
00322 p2=(*h)->vertex()->point();
00323 while (1) {
00324 p1=p2;
00325 p2 = (*h)->vertex()->point();
00326
00327 dist += sqrt(squared_distance( p1, p2 ));
00328
00329
00330
00331 if (dist >= d12) break;
00332
00333 (*h)->vertex()->point()=c1+(c2-c1)*dist/d12;
00334 std::cout << "Nouveau point [" << (*h)->vertex()->point()[0] << "][" << (*h)->vertex()->point()[1] << "][" << (*h)->vertex()->point()[2] << "]" << std::endl;
00335
00336 ++h;
00337
00338 count++;
00339 }
00340
00341 dist=0;
00342 p2=(*h)->vertex()->point();
00343 while (1) {
00344 p1=p2;
00345 p2 = (*h)->vertex()->point();
00346 dist += sqrt(squared_distance( p1, p2 ));
00347
00348
00349
00350 if (dist >= d23) break;
00351
00352 (*h)->vertex()->point()=c2+(c3-c2)*dist/d23;
00353 std::cout << "Nouveau point [" << (*h)->vertex()->point()[0] << "][" << (*h)->vertex()->point()[1] << "][" << (*h)->vertex()->point()[2] << "]" << std::endl;
00354
00355 ++h;
00356
00357 count++;
00358 }
00359
00360 dist=0;
00361 p2=(*h)->vertex()->point();
00362 while (1) {
00363 p1=p2;
00364 p2 = (*h)->vertex()->point();
00365 dist += sqrt(squared_distance( p1, p2 ));
00366
00367
00368
00369 if (dist >= d34) break;
00370
00371 (*h)->vertex()->point()=c3+(c4-c3)*dist/d34;
00372 std::cout << "Nouveau point [" << (*h)->vertex()->point()[0] << "][" << (*h)->vertex()->point()[1] << "][" << (*h)->vertex()->point()[2] << "]" << std::endl;
00373
00374
00375 ++h;
00376 count++;
00377 }
00378
00379 dist=0;
00380 p2=(*h)->vertex()->point();
00381
00382 do {
00383 p1=p2;
00384 p2 = (*h)->vertex()->point();
00385 dist += sqrt(squared_distance( p1, p2 )) ;
00386
00387 (*h)->vertex()->point()=c4+(c1-c4)*dist/d41;
00388 std::cout << "Nouveau point [" << (*h)->vertex()->point()[0] << "][" << (*h)->vertex()->point()[1] << "][" << (*h)->vertex()->point()[2] << "]" << std::endl;
00389
00390
00391 ++h;
00392
00393 count++;
00394 } while (h != _mesh2D.border_edges_begin()) ;
00395
00396 std::cout << "nb de points modifies :" << count << std::endl;
00397
00398
00399
00400
00401
00402
00403 count=0;
00404 dist=0;
00405
00406 Trace2file("AAAavantParamInt.off") ;
00407
00408
00409
00410
00411
00412
00413 int Dimension = _mesh2D.size_of_vertices() - _mesh2D.size_of_border_edges() ;
00414 double Kmatx[Dimension][MAT_SIZE], Kmaty[Dimension][MAT_SIZE] ;
00415 double Ux[Dimension], Uy[Dimension] ;
00416 double Bx[Dimension], By[Dimension] ;
00417 int icount = 0 ;
00418
00419 for(Vertex_iterator i = _mesh2D.vertices_begin(); i != _mesh2D.vertices_end(); i++)
00420 {
00421 std::cout << "un sommet ! " ;
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443 if (isBorderVertex(i))
00444 {
00445
00446 }
00447 else
00448 {
00449
00450 double sommeUx = 0 ;
00451 double sommeUy = 0 ;
00452
00453 Halfedge_around_vertex_circulator h = i->vertex_begin() ;
00454 do
00455 {
00456 Vertex_handle vh = h->opposite()->vertex() ;
00457
00458 std::cout << " un sommet ! " ;
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475 if (isBorderVertex(vh))
00476 {
00477
00478
00479 sommeUx += 1/((double) (i->vertex_degree())) * vh->point()[0] ;
00480 sommeUy += 1/((double) (i->vertex_degree())) * vh->point()[1] ;
00481 std::cout << sommeUx << " " << sommeUy << " " << vh->halfedge()->opposite()->is_border() ;
00482 }
00483
00484 std::cout << std::endl ;
00485 h++;
00486 } while (h != i->vertex_begin()) ;
00487 Ux[icount] = sommeUx ;
00488 Uy[icount] = sommeUy ;
00489
00490
00491
00492
00493
00494 std::cout<<"["<<icount<<"] " ;
00495 for (int iKmat = 0 ; iKmat < MAT_SIZE ; iKmat++)
00496 {
00497 if (iKmat != icount)
00498 {
00499 if (isEdge(icount,iKmat))
00500 {
00501 std::cout<<i->vertex_degree() ;
00502 Kmatx[icount][iKmat] = -1/((double) i->vertex_degree()) ;
00503 Kmaty[icount][iKmat] = -1/((double) i->vertex_degree()) ;
00504 }
00505 else
00506 {
00507 std::cout<<"0" ;
00508 Kmatx[icount][iKmat] = 0 ;
00509 Kmaty[icount][iKmat] = 0 ;
00510 }
00511 }
00512 else
00513 {
00514 std::cout<<"1" ;
00515 Kmatx[icount][iKmat] = 1 ;
00516 Kmaty[icount][iKmat] = 1 ;
00517 }
00518 }
00519 std::cout << std::endl ;
00520 icount++ ;
00521 }
00522 }
00523 std::cout << std::endl ;
00524 std::cout << "icount="<<icount<<", Dimension="<<Dimension<<std::endl ;
00525
00526
00527 if (!ResoudreSysteme(Kmatx, Ux, Bx, Dimension))
00528 std::cout << "***ERREUR dans ResoudreSysteme en x" ;
00529 if (!ResoudreSysteme(Kmaty, Uy, By, Dimension))
00530 std::cout << "***ERREUR dans ResoudreSysteme en y" ;
00531
00532
00533 int iB = 0 ;
00534 for(Vertex_iterator i2d = _mesh2D.vertices_begin(); i2d != _mesh2D.vertices_end(); i2d++)
00535 {
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553 if (!isBorderVertex(i2d))
00554 {
00555 Point p2d=Point(Bx[iB], By[iB], 0) ;
00556 i2d->point()=p2d ;
00557 iB++ ;
00558 }
00559 }
00560
00561 Trace2file("AAAapresParamInt.off") ;
00562
00563
00564
00565
00566
00567
00568 }
00569
00570
00571 bool Region::isBorderVertex(Vertex_handle vh)
00572 {
00573 Halfedge_around_vertex_circulator hh = vh->vertex_begin() ;
00574 do
00575 {
00576 if ((hh->is_border()) || (hh->opposite()->is_border()))
00577 {
00578 return true ;
00579 }
00580 hh++ ;
00581 } while (hh != vh->vertex_begin()) ;
00582 return false ;
00583 }
00584
00585
00586
00587 bool Region::isEdge(int i, int j)
00588 {
00589 if (i==j)
00590 return false ;
00591 int count=0 ;
00592 Vertex_handle vi, vj ;
00593 for(Vertex_iterator v = _mesh2D.vertices_begin() ; v != _mesh2D.vertices_end() ; v++)
00594 {
00595 if (count==i)
00596 vi=v ;
00597 if (count==j)
00598 vj=v ;
00599 if (!isBorderVertex(v))
00600 {
00601 count++ ;
00602 }
00603 }
00604 Halfedge_around_vertex_circulator hh = vi->vertex_begin() ;
00605 do
00606 {
00607 if (hh->opposite()->vertex() == vj)
00608 return true ;
00609 hh++ ;
00610 } while (hh != vi->vertex_begin()) ;
00611 return false ;
00612 }
00613
00614
00615
00616
00617
00618
00619
00620 void Region::Trace2file(char* filename)
00621 {
00622 std::ofstream fichier;
00623
00624 fichier.open(filename, std::ios::out | std::ios::trunc);
00625 if(fichier.bad()){
00626 return;
00627 }
00628
00629
00630 CGAL::set_ascii_mode( fichier);
00631 fichier << "OFF" << std::endl << _mesh2D.size_of_vertices() << ' '
00632 << _mesh2D.size_of_facets() << " 0" << std::endl;
00633 std::copy( _mesh2D.points_begin(), _mesh2D.points_end(),
00634 std::ostream_iterator<Point>( fichier, "\n"));
00635 for ( Facet_iterator i = _mesh2D.facets_begin(); i != _mesh2D.facets_end(); ++i) {
00636 Halfedge_around_facet_circulator j = i->facet_begin();
00637
00638 CGAL_assertion( CGAL::circulator_size(j) >= 3);
00639 fichier << CGAL::circulator_size(j) << ' ';
00640 do {
00641 fichier << ' ' << std::distance(_mesh2D.vertices_begin(), j->vertex());
00642 } while ( ++j != i->facet_begin());
00643 fichier << std::endl;
00644 }
00645 fichier.close();
00646
00647 }
00648
00649
00650
00651
00652
00653 void Region::vh2Dfrom3D (Vertex_handle& vh)
00654 {
00655 Polyhedron::Vertex_iterator j2D = _mesh2D.vertices_begin();
00656
00657 for(Polyhedron::Vertex_iterator j = _mesh3D.vertices_begin(); j != _mesh3D.vertices_end() ; j++)
00658 {
00659
00660
00661
00662
00663 if ( j->point() == vh->point() ){ vh=j2D; break; }
00664
00665 ++j2D;
00666 }
00667 }
00668
00669
00670
00671
00672 void Region::vh3Dfrom2D(Vertex_handle& vh)
00673 {
00674 Polyhedron::Vertex_iterator j3D = _mesh3D.vertices_begin();
00675
00676 for(Polyhedron::Vertex_iterator j = _mesh2D.vertices_begin(); j != _mesh2D.vertices_end() ; j++)
00677 {
00678 if ( j->point() == vh->point() ){ vh=j3D; break; }
00679
00680 ++j3D;
00681 }
00682 }
00683
00684
00685
00686 void Region::Point3D_from_2D(Point& p)
00687 {
00688 int count=0;
00689
00690
00691 Polyhedron::Vertex_iterator j3D = _mesh3D.vertices_begin();
00692 for(Vertex_iterator pVertex = _mesh2D.vertices_begin(); pVertex != _mesh2D.vertices_end(); pVertex++)
00693 {
00694
00695 if (p == pVertex->point() ) { p=j3D->point(); return; }
00696 j3D++;
00697 }
00698
00699 Facet_handle pF2D;
00700 Facet_handle pF3D=_mesh3D.facets_begin();
00701
00702 for ( Facet_iterator i = _mesh2D.facets_begin(); i != _mesh2D.facets_end(); i++)
00703 {
00704 if( this->Appartient_facet(i,p) ) { pF2D=i; break; }
00705
00706 pF3D++;
00707 }
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738 double (*M)[200] = new double [2][200];
00739
00740 double U[2];
00741 double B[2];
00742 Point Mespt2D[3];
00743
00744 Point Mespt3D[3];
00745
00746 Halfedge_around_facet_circulator h2 = pF2D->facet_begin();
00747
00748 if (CGAL::circulator_size(h2)!=3) { std::cout << "ERROR in Compute_nrj_sommet: facet must be triangle" << std::endl; exit(-1); }
00749
00750 do {
00751 Mespt2D[count++]=h2->vertex()->point();
00752 h2++;
00753 } while(h2 != pF2D->facet_begin() );
00754
00755
00756 M[0][0]=Mespt2D[0][0]-Mespt2D[2][0];
00757 M[0][1]=Mespt2D[1][0]-Mespt2D[2][0];
00758
00759 M[1][0]=Mespt2D[0][1]-Mespt2D[2][1];
00760 M[1][1]=Mespt2D[1][1]-Mespt2D[2][1];
00761
00762 U[0]=p[0]-Mespt2D[2][0];
00763 U[1]=p[1]-Mespt2D[2][1];
00764
00765 std::cout << "Avant appel a ResoudreSysteme" << std::endl;
00766 if(! ResoudreSysteme(M, U, B, 2) ) { std::cout << "ERROR in Point3D_from_2D: problem occured during matrix resolution" << std::endl; exit(-1); }
00767 std::cout << "Apres appel a ResoudreSysteme" << std::endl;
00768
00769
00770
00771
00772
00773
00774
00775
00776 h2 = pF3D->facet_begin();
00777
00778 count=0;
00779
00780 if (CGAL::circulator_size(h2)!=3) { std::cout << "ERROR in Compute_nrj_sommet: facet must be triangle" << std::endl; exit(-1); }
00781 std::cout << "Avant le 2eme do" << std::endl;
00782 do {
00783 Mespt3D[count++]=h2->vertex()->point();
00784 h2++;
00785 } while(h2 != pF3D->facet_begin() );
00786
00787 std::cout << "creation de x, y et z" << std::endl;
00788 double x = B[0]*Mespt3D[0][0]+B[1]*Mespt3D[1][0]+(1-B[0]+B[1])*Mespt3D[2][0];
00789 double y = B[0]*Mespt3D[0][1]+B[1]*Mespt3D[1][1]+(1-B[0]+B[1])*Mespt3D[2][1];
00790 double z = B[0]*Mespt3D[0][2]+B[1]*Mespt3D[1][2]+(1-B[0]+B[1])*Mespt3D[2][2];
00791 std::cout << "creation de x, y et z terminee" << std::endl;
00792
00793 p = Point(x,y,z);
00794
00795 delete [] M;
00796
00797 }
00798
00799
00800
00801
00802