/home/ann2.ext/paccaulf/projsem2/ContourActif/mesh.cpp

Aller à la documentation de ce fichier.
00001 //
00002 // Mesh.cpp : implementation of the Mesh class 
00003 // 
00004 
00005 #include "mesh.h" 
00006 
00007 // STL stuff 
00008 #include <iostream> 
00009 #include <fstream>
00010 //#include <list>
00011 #include "math.h"
00012 
00013 // CGAL (off) 
00014 #include <CGAL/IO/Polyhedron_iostream.h>
00015 #include <CGAL/Triangulation_2.h>
00016 
00017 // OpenGL stuff
00018 #include <GL/gl.h>
00019 
00020 // Mesh construction/destruction 
00021 Mesh::Mesh(const char* filename) 
00022 {
00023         _isValid = false;
00024         
00025         if(loadFromFile(filename))
00026           {
00027                 _mesh->normalize_border();
00028                 
00029                 if(!_mesh->is_closed())
00030                   {
00031                         std::cout << "*** Warning: mesh is not closed ***" << std::endl;
00032                   }
00033                 if(!_mesh->is_pure_triangle())
00034                   {
00035                         std::cout << "*** Warning: mesh is not pure triangle ***" << std::endl;
00036                   }
00037                 if(_mesh->empty())
00038                   {
00039                         std::cout << "*** Warning: mesh is empty ***" << std::endl;
00040                   }
00041                 if(!_mesh->is_valid(false,3))
00042                   {
00043                         _message = "Mesh is not combinatorially consistent";
00044                   }
00045                 else
00046                   {
00047                         _isValid = true;
00048                         _mesh->set_index_vertices();
00049                         _mesh->set_index_edges();
00050                         _mesh->compute_normals();
00051                   }
00052           }
00053         else _message = "Impossible to load file";
00054 }; 
00055 
00056 Mesh::~Mesh()
00057 { 
00058         delete _mesh; 
00059 }; 
00060 
00061 void Mesh::compute_normals()
00062 {
00063         _mesh->compute_normals();
00064 };
00065 
00066 bool Mesh::isValid() const
00067 {
00068         return _isValid;
00069 };
00070 char* Mesh::message() const
00071 {
00072         return _message;
00073 };
00074 
00075 std::size_t Mesh::size_of_vertices() const
00076 {
00077         return _mesh->size_of_vertices();
00078 };
00079 
00080 std::size_t Mesh::size_of_facets() const
00081 {
00082         return _mesh->size_of_facets();
00083 };
00084 
00085 // draw using OpenGL commands (display lists) 
00086 void Mesh::draw(bool smooth_shading, bool use_normals, bool invert_normals) const 
00087 {   
00088         // draw polygons
00089         glColor3f(0.0,0.5,0.8); // bleu turquoise
00090     
00091         Facet_iterator pFacet = facets_begin();
00092         for(;pFacet != facets_end();pFacet++)
00093           {
00094                 // begin polygon assembly
00095                 glBegin(GL_POLYGON);
00096                 gl_draw_facet(pFacet,smooth_shading,use_normals,invert_normals);
00097                 glEnd(); // end polygon assembly
00098           }
00099         glFlush(); 
00100         
00101 };
00102 
00103 void Mesh::gl_draw_facet(Facet_handle pFacet, bool smooth_shading, bool use_normals, bool invert_normals) const
00104 {
00105         // one normal per face
00106         if(use_normals && !smooth_shading)
00107           {
00108                 const Vector& normal = pFacet->normal();
00109                 if (invert_normals) glNormal3f(-normal[0],-normal[1],-normal[2]);
00110                 else glNormal3f(normal[0],normal[1],normal[2]);
00111           }
00112         
00113         // revolve around current face to get vertices
00114         Halfedge_around_facet_circulator pHalfedge = pFacet->facet_begin();
00115         do
00116           {
00117                   // one normal per vertex
00118                   if(use_normals && smooth_shading)
00119                         {
00120                           const Vector normal = pHalfedge->vertex()->normal();
00121                           if (invert_normals) glNormal3f(-normal[0],-normal[1],-normal[2]);
00122                           else glNormal3f(normal[0],normal[1],normal[2]);
00123                         }
00124                   
00125                   // polygon assembly is performed per vertex
00126                   const Point& point  = pHalfedge->vertex()->point();
00127                   glVertex3d(point[0],point[1],point[2]);
00128           }while(++pHalfedge != pFacet->facet_begin());
00129 };
00130 
00131 // superimpose edges 
00132 void Mesh::draw_edges() const
00133 {
00134         glColor3f(0.0,0.0,0.0);
00135         glBegin(GL_LINES);
00136         for(Halfedge_iterator h = _mesh->edges_begin(); h != _mesh->edges_end(); h++)
00137           {
00138                 // assembly and draw line segment
00139                 const Point& p1 = h->prev()->vertex()->point();
00140                 const Point& p2 = h->vertex()->point();
00141                 glVertex3f(p1[0],p1[1],p1[2]);
00142                 glVertex3f(p2[0],p2[1],p2[2]);
00143           }
00144         glEnd();
00145 }; 
00146 
00147 // superimpose vertices 
00148 void Mesh::draw_vertices() const
00149 {
00150         glDisable(GL_LIGHTING);
00151         glPointSize(10.0);
00152         glColor3f(0.7,1.0,0.1); // jaune fluo
00153         glBegin(GL_POINTS);
00154         for(Vertex_iterator pPoint = _mesh->vertices_begin(); pPoint != _mesh->vertices_end(); pPoint++)
00155                 glVertex3f(pPoint->point()[0],pPoint->point()[1],pPoint->point()[2]);
00156         glEnd();
00157         glPointSize(1.0);
00158         glEnable(GL_LIGHTING);
00159 };
00160 
00161 void Mesh::BoundingBox(double * centre, double * diameter)
00162 // Calcule la plus petite boite englobante contenant les sommets de la surface
00163 {
00164         double w, h, k;
00165         
00166         Vertex_iterator pPoint = vertices_begin();
00167         
00168         double min[3] = { pPoint->point()[0],pPoint->point()[1],pPoint->point()[2] };
00169         double max[3] = { pPoint->point()[0],pPoint->point()[1],pPoint->point()[2] };
00170         for (Vertex_iterator pPoint = vertices_begin(); pPoint != vertices_end(); pPoint++) {
00171                 if (pPoint->point()[0] > max[0]) max[0] = pPoint->point()[0];
00172                 if (pPoint->point()[0] < min[0]) min[0] = pPoint->point()[0];
00173                 if (pPoint->point()[1] > max[1]) max[1] = pPoint->point()[1];
00174                 if (pPoint->point()[1] < min[1]) min[1] = pPoint->point()[1];
00175                 if (pPoint->point()[2] > max[2]) max[2] = pPoint->point()[2];
00176                 if (pPoint->point()[2] < min[2]) min[2] = pPoint->point()[2];
00177         }
00178         centre[0] = (max[0]+min[0])/2.0; w = (max[0]-min[0])/2.0;
00179         centre[1] = (max[1]+min[1])/2.0; h = (max[1]-min[1])/2.0;
00180         centre[2] = (max[2]+min[2])/2.0; k = (max[2]-min[2])/2.0;
00181         (*diameter) = (w>h)?w:h; if (k>(*diameter)) (*diameter) = k;
00182         
00183         if (*diameter < 0.1) (*diameter) = 0.1;
00184 };
00185 
00186 // open document file 
00187 bool Mesh::loadFromFile(const char* filename) 
00188 { 
00189         char* file_ext = strstr(filename,".off"); 
00190         if (( file_ext == NULL ) || ( strcmp(file_ext,".off") != 0 ))
00191           { 
00192                 std::cerr << " *** Unexpected file format (.off required)" << std::endl;        
00193                 return false; 
00194           }
00195         
00196         // allocate a new mesh 
00197         _mesh = new Enriched_polyhedron<Enriched_kernel,Enriched_items>; 
00198         CGAL_assertion(_mesh != NULL); 
00199         
00200         // read from stream  
00201         std::ifstream stream(filename); 
00202         if(!stream) 
00203           { 
00204                 std::cerr << "*** Error while opening file " << filename << std::endl;  
00205                 return false; 
00206           } 
00207         stream >> *_mesh; 
00208         
00209         if ((_mesh->size_of_vertices() == 0)|| (_mesh->size_of_facets() == 0)) {
00210                 
00211                 std::cout << "*** Warning: mesh is not manifold ***" << std::endl;
00212                 return false;
00213         }
00214         
00215         std::cout << _mesh->size_of_vertices() << " vertices, ";
00216         std::cout << _mesh->size_of_facets() << " faces" << std::endl;
00217         
00218         return true; 
00219 };
00220 
00221 void Mesh::saveToFile(const char* filename) const
00222 {
00223         std::ofstream fichier;
00224         
00225         fichier.open(filename, std::ios::out | std::ios::trunc);
00226         if(fichier.bad()){
00227                 return;
00228         }
00229         
00230         // Write polyhedron in Object File Format (OFF).
00231         CGAL::set_ascii_mode( fichier);
00232         fichier << "OFF" << std::endl << _mesh->size_of_vertices() << ' ' 
00233                 << _mesh->size_of_facets() << " 0" << std::endl;
00234         std::copy( _mesh->points_begin(), _mesh->points_end(),
00235                            std::ostream_iterator<Mesh::Point>( fichier, "\n"));
00236         for (  Mesh::Facet_iterator i = _mesh->facets_begin(); i != _mesh->facets_end(); ++i) {
00237                 Mesh::Halfedge_around_facet_circulator j = i->facet_begin();
00238                 // Facets in polyhedral surfaces are at least triangles.
00239                 CGAL_assertion( CGAL::circulator_size(j) >= 3);
00240                 fichier << CGAL::circulator_size(j) << ' ';
00241                 do {
00242                         fichier << ' ' << std::distance(_mesh->vertices_begin(), j->vertex());
00243                 } while ( ++j != i->facet_begin());
00244                 fichier << std::endl;
00245         }
00246         fichier.close();
00247 };
00248 
00249 // returns the nearest Vertex_handle of the facet F to the selectedPoint, which is supposedly on a facet named F.
00250 Mesh::Vertex_handle Mesh::nearestVertexOnFacet(Mesh::Point selectedPoint) {
00251         Vertex_handle SommetMini = _mesh->vertices_begin();
00252         for(Mesh::Vertex_iterator j = _mesh->vertices_begin(); j != _mesh->vertices_end() ; ++j) {
00253                 if (has_smaller_distance_to_point(selectedPoint,
00254                                                                                   j->point(),
00255                                                                                   SommetMini->point())) {
00256                         SommetMini = j;
00257                 }
00258         }
00259         
00260         std::cout << "sommet le plus proche = "
00261             << SommetMini->point()[0] << ' '
00262             << SommetMini->point()[1] << ' '
00263             << SommetMini->point()[2] << std::endl ;
00264         return SommetMini ;
00265 };
00266 
00267 void Mesh::drawUserSnake()
00268 {
00269         
00270         // on affiche ce sommet
00271         
00272         Mesh::Vertex_handle vtx1 = *(_snake_vertex.begin()) ;
00273         //if (_mesh->_snake_vertex.)
00274         
00275         glDisable(GL_LIGHTING) ;
00276         for(std::vector < Mesh::Vertex_handle >::iterator i=_snake_vertex.begin() ;
00277                 i != _snake_vertex.end() ;
00278                 ++i) 
00279           {      
00280                 glPointSize(10.0) ;
00281                 
00282                 glBegin(GL_POINTS) ;
00283                 
00284                 glColor3f(1.0,0.0,0.0) ;
00285                 
00286                 glVertex3f((*i)->point()[0]-0.01*dir[0],
00287                                    (*i)->point()[1]-0.01*dir[1],
00288                                    (*i)->point()[2]-0.01*dir[2]) ;
00289                 
00290                 glEnd() ;
00291                 
00292                 glPointSize(1.0) ;
00293                 
00294                 drawSnakePath(vtx1, *i, 0) ;
00295                 
00296                 vtx1 = *i ;
00297                 
00298           }
00299         glEnable(GL_LIGHTING) ;
00300         //glFlush() ;
00301         
00302         
00303         
00304         
00305 }
00306 
00307 void Mesh::drawSnakePath(Mesh::Vertex_handle source, Mesh::Vertex_handle target, int drawPathEnds = 3)
00308 {
00309         
00310         glPointSize(6.0f);
00311         
00312         glColor3f(1.0,0.0,0.0);
00313         
00314         glBegin(GL_POINTS);     
00315         
00316         if (drawPathEnds == 1 || drawPathEnds == 3)
00317                 // affichage du point de depart 
00318                 glVertex3f(source->point()[0],source->point()[1],source->point()[2]);
00319         if (drawPathEnds == 2 || drawPathEnds == 3)     
00320                 // affichage du point d'arrivee
00321                 glVertex3f(target->point()[0],target->point()[1],target->point()[2]);   
00322         
00323         glEnd();
00324         
00325         glPointSize(1.0f);
00326         
00327         glColor3f(1.0,1.0,0.0);
00328         
00329         glLineWidth(5.0);
00330         
00331         glBegin(GL_LINES);
00332         
00333         //1. on parcourt l ensemble des chemins formant le snake
00334         // (ex : du sommet 0 au sommet 1, puis du sommet 1 au sommet 2, etc.)
00335         
00336         for (std::vector<Mesh::Vertex_chemin>::iterator vcv = _snake_total.begin() ;
00337                  vcv != _snake_total.end() ;
00338                  vcv++) 
00339           {
00340                 
00341                 Mesh::Point p1 =  (*(vcv->begin()))->point() ;
00342                 //2. on parcourt l ensemble des points d un chemin
00343                 
00344                 for (Mesh::Vertex_chemin::iterator vc = vcv->begin() ;
00345                          vc != vcv->end() ;
00346                          vc++)
00347                   {
00348                         Mesh::Point p2 =  (*vc)->point() ;
00349                         
00350                         glVertex3f(p1[0]-0.001*dir[0],
00351                                            p1[1]-0.001*dir[1],
00352                                            p1[2]-0.001*dir[2]);
00353                         
00354                         glVertex3f(p2[0]-0.001*dir[0],
00355                                            p2[1]-0.001*dir[0],
00356                                            p2[2]-0.001*dir[0]);
00357                         
00358                         p1=p2;
00359                   } 
00360           }
00361         
00362         
00363         glColor3f(0.3,0.6,0.4);
00364         
00365         glLineWidth(15.0);
00366         
00367         glBegin(GL_LINES);
00368         
00369         for(Mesh::Halfedge_iterator h = _mesh->border_halfedges_begin(); h != _mesh->halfedges_end(); h++)
00370           {
00371                 // assembly and draw line segment
00372                 const Mesh::Point& p1 = h->prev()->vertex()->point();
00373                 const Mesh::Point& p2 = h->vertex()->point();
00374                 
00375                 glVertex3f(p1[0],p1[1],p1[2]);
00376                 glVertex3f(p2[0],p2[1],p2[2]);
00377           }
00378         
00379         glEnd();
00380         
00381         glLineWidth(1.0);
00382 }
00383 
00384 /***********************************************************************************/
00385 /*                                                                                 */
00386 /*                   l e s   f o n c t i o n s   d e   v i n c e                   */
00387 /*                                                                                 */
00388 /***********************************************************************************/
00389 
00390 /* drawLocalRegion
00391 dessine la region locale en superposition au mesh entier 
00392 c'est une copie de la procedure draw de Mesh
00393 */
00394 void Mesh::drawLocalRegion() 
00395 {
00396         Polyhedron* P = _snake_fini.getRegion()->mesh3D() ;
00397         glColor3f(0.8,0.8,0.8); // gris
00398         glLineWidth(2.0);
00399         for(Polyhedron::Facet_iterator pFacet = P->facets_begin(); pFacet != P->facets_end(); pFacet++)
00400           {
00401                 glBegin(GL_POLYGON);
00402                 
00403                 Polyhedron::Halfedge_around_facet_circulator pHalfedge = pFacet->facet_begin();
00404                 do
00405                   {
00406                           const Vector& normal = orthogonal_vector ( pHalfedge->vertex()->point(), 
00407                                                                                                                  pHalfedge->next()->vertex()->point(), 
00408                                                                                                                  pHalfedge->prev()->vertex()->point());
00409                           //computes an orthogonal vector of the plane defined by p, q and r, which is directed to the positive side of this plane.
00410                           
00411                           
00412                           //CGAL::cross_product( pHalfedge->next()->vertex()->point() - pHalfedge->vertex()->point(), pHalfedge->prev()->vertex()->point() - pHalfedge->vertex()->point() ); 
00413                           
00414                           glNormal3f(-normal[0],-normal[1],-normal[2]);
00415                           
00416                           // polygon assembly is performed per vertex
00417                           const Point& point  = pHalfedge->vertex()->point();
00418                           
00419                           glVertex3d(point[0]-0.01*normal[0],point[1]-0.01*normal[1],point[2]-0.01*normal[2]);
00420                           
00421                   }while(++pHalfedge != pFacet->facet_begin());
00422                 
00423                 glEnd();
00424                 
00425           }
00426         glLineWidth(1.0);
00427         
00428 }
00429 
00430 /* drawLocalRegion
00431 dessine la region locale parametrisee (2D) toute seule (sans superposition au mesh entier)
00432 c'est une copie de la procedure draw de Mesh
00433 */
00434 void Mesh::draw2dRegion() {
00435         Polyhedron* P = _snake_fini.getRegion()->mesh2D() ;
00436         glColor3f(0.8,0.8,0.8); // gris
00437         glLineWidth(2.0);
00438         for(Polyhedron::Facet_iterator pFacet = P->facets_begin(); pFacet != P->facets_end(); pFacet++)
00439           {
00440                 glBegin(GL_POLYGON);
00441                 
00442                 Polyhedron::Halfedge_around_facet_circulator pHalfedge = pFacet->facet_begin();
00443                 do
00444                   {
00445                           const Vector& normal = orthogonal_vector ( pHalfedge->vertex()->point(), 
00446                                                                                                                  pHalfedge->next()->vertex()->point(), 
00447                                                                                                                  pHalfedge->prev()->vertex()->point());
00448                           //computes an orthogonal vector of the plane defined by p, q and r, which is directed to the positive side of this plane.
00449                           
00450                           
00451                           //CGAL::cross_product( pHalfedge->next()->vertex()->point() - pHalfedge->vertex()->point(), pHalfedge->prev()->vertex()->point() - pHalfedge->vertex()->point() ); 
00452                           
00453                           glNormal3f(-normal[0],-normal[1],-normal[2]);
00454                           
00455                           // polygon assembly is performed per vertex
00456                           const Point& point  = pHalfedge->vertex()->point();
00457                           
00458                           glVertex3d(point[0],point[1],point[2]);
00459                           
00460                   }while(++pHalfedge != pFacet->facet_begin());
00461                 
00462                 glEnd();
00463                 
00464           }
00465         glLineWidth(1.0);
00466         
00467 }
00468 
00469 
00470 // superimpose bounding edges
00471 /* approx_shortest_path
00472 calcul du plus court chemin entre source et target
00473 resultat mis dans chemin
00474 */
00475 void Mesh::approx_shortest_path(Mesh::Vertex_chemin &chemin, Vertex_handle source, Vertex_handle target) const
00476 {
00477         if (source == target) 
00478           {
00479                 std::cout<<"source == target !"<<std::endl ;
00480                 exit(-1) ;
00481           }
00482         else
00483           {
00484                 //std::cout<<"source != target"<<std::endl ;  
00485           }
00486         
00487         // maintenant on va se choisir 2 sommets du maillage et on va tracer un chemin approximativement optimal
00488         // de la source a la cible      
00489         Point prochainmin, prochainp;
00490         
00491         // nombre d iterations
00492         int count=0;
00493     
00494         // sommet source rajoute
00495         chemin.push_back(source) ;
00496         
00497         Vertex_handle pVertexCour = source ;
00498         
00499         while( (pVertexCour!=target) && (count<=2000) ){// tant que l'on n'a pas atteint la cible
00500         
00501                 // on regarde autour de ce point
00502                 Halfedge_around_vertex_circulator curr; 
00503                 
00504                 //vertices_circulator
00505                 
00506                 curr = pVertexCour->vertex_begin(); // on se place sur la premiere halfedge
00507         
00508                 Vertex_handle pVermin = curr->prev()->vertex(); // le vertex courant autour
00509                 
00510                 prochainmin=pVermin->point();// le prochain point choisi autour pour le moment
00511                         
00512                         curr++;
00513                         do { 
00514                                 prochainp = curr->prev()->vertex()->point(); 
00515                                 
00516                                 if( has_smaller_distance_to_point(target->point(), prochainp, prochainmin) ) {
00517                                         pVermin=curr->prev()->vertex(); 
00518                                         prochainmin=prochainp; 
00519                                 }
00520                                 
00521                         }  while (curr++ != pVertexCour->vertex_begin()); // tant que l'on n'a pas fait un tour complet
00522                         
00523                         // le sommet le plus proche de la destination est rajoute au chemin
00524                         chemin.push_back(pVermin) ;
00525                         
00526                         pVertexCour=pVermin; //maj
00527                         
00528                         count++;
00529                         
00530         }
00531         if (count >= 2000)
00532                 std::cout << "*** Warning ***: aucun plus court chemin n'a été trouvé" << std::endl ;
00533         
00534         count=0;
00535         
00536         //  return chemin ;  
00537 }
00538 
00539 
00540 
00541 /*
00542  Structures necessaires pour determiner la local region
00543  Ces structures permettent de selectionner les sommets et facettes qui feront partie de la local region.
00544  */
00545 // Une structure toute bete qui stocke 3 entiers (ces entiers seront des indices de facettes)
00546 class Triangle {
00547 public:
00548         int p1, p2, p3 ;
00549         Triangle(int p1, int p2, int p3) : p1(p1), p2(p2), p3(p3) {};
00550 };
00551 
00552 // operateur d affichage
00553 std::ostream& operator<< (std::ostream& out, const Triangle& T) {
00554         return out << T.p1 << ' ' << T.p2 << ' ' << T.p3;
00555 }
00556 
00557 // classe pour associer un point a un indice
00558 // possibilite d optimiser en etendant la classe Point_3 au lieu de creer une nouvelle classe...
00559 class PtIndex {
00560 public:
00561         Mesh::Point p ;
00562         int i ; 
00563         PtIndex() {}
00564         PtIndex(Mesh::Point p, int i): p(p), i(i) {}
00565 };
00566 
00567 // PtVector rajoute une fonction a la classe vector<PtIndex>
00568 // On aurait pu se servir d'un set plutot qu'un vector, mais les indices des elements d'un set sont susceptibles de changer
00569 class PtVector : public std::vector<PtIndex> {
00570 public:
00571         //isPresent : renvoie -1 si le point p n'existe pas dans le vector, renvoie son indice sinon
00572         int isPresent(const Mesh::Point p) {
00573                 for(std::vector<PtIndex>::iterator i = this->begin() ; i != this->end() ; i++) {
00574                         if (i->p == p) return i->i ;
00575                 }
00576                 return -1 ;
00577         }
00578 };
00579 
00580 //TrVector rajoute une fonction a la classe vector<Triangle>
00581 class TrVector : public std::vector<Triangle> {
00582 public:
00583         //isPresent : si un triangle avec les memes indices de sommets est present dans le vector, renvoie 1, sinon -1. 
00584         int isPresent(const Triangle Tri) {
00585                 for(std::vector<Triangle>::iterator i = this->begin() ; i != this->end() ; i++) {
00586                         if (((i->p1 == Tri.p1) && (i->p2 == Tri.p2) && (i->p3 == Tri.p3)) ||
00587                                 ((i->p1 == Tri.p2) && (i->p2 == Tri.p3) && (i->p3 == Tri.p1)) ||
00588                                 ((i->p1 == Tri.p3) && (i->p2 == Tri.p1) && (i->p3 == Tri.p2)) ||
00589                                 ((i->p1 == Tri.p3) && (i->p2 == Tri.p2) && (i->p3 == Tri.p1)) ||
00590                                 ((i->p1 == Tri.p2) && (i->p2 == Tri.p1) && (i->p3 == Tri.p3)) ||
00591                                 ((i->p1 == Tri.p1) && (i->p2 == Tri.p3) && (i->p3 == Tri.p2)))
00592                                 return 1 ;
00593                 }
00594                 return -1 ;
00595         }
00596 };
00597 
00598 /*
00599  Local_region
00600  calcul de la region locale associee au snake Snake
00601  Selectionne les sommets et facettes du mesh d origine, les stocke en memoire, puis ecrit un fichier au format off.
00602  Ensuite on convertit simplement ce fichier en polyhedron grace a l operateur >>.
00603  Il y a evidemment une perte de performance, et un risque sur la stabilite du programme 
00604  (par ex si le dossier n est pas libre en ecriture, ou si le disque est plein).
00605  /!\ les facettes autres que triangles ne sont pas gerees !!!
00606  */
00607 Mesh::Polyhedron Mesh::Local_region( std::vector< Vertex_chemin >& Snake ) // only first release
00608 {
00609         int vecsize = 0 ;
00610         // parcours de l'ensemble des sommets de la mesh jusqu'a trouver le premier sommet du snake
00611         
00612         PtVector S;
00613         TrVector T ;
00614         PtIndex pind1, pind2, pind3 ;
00615         int indice, ind1, ind2, ind3 ;
00616         
00617         for(std::vector< Vertex_chemin >::const_iterator chem_it=Snake.begin(); chem_it!=Snake.end(); chem_it++)
00618           {
00619                 for(std::vector< Vertex_handle >::const_iterator it=chem_it->begin(); it!=chem_it->end(); it++)
00620                   {
00621                         //std::cout <<  P.size_of_vertices()  <<std::endl;
00622 
00623                         //vertices_circulator
00624                         Halfedge_around_vertex_circulator curr = (*it)->vertex_begin(); // on se place sur la premiere halfedge
00625                         
00626                         Point p1(curr->vertex()->point()); // point du snake
00627                         indice = S.isPresent(p1) ;
00628                         if (indice == -1) 
00629                           {
00630                                 ind1 = vecsize ;
00631                                 pind1 = PtIndex(p1, vecsize++) ;
00632                                 S.push_back(pind1) ;
00633                                 //std::cout<<"SOMMET AJOUTE, ind = "<< vecsize-1 <<std::endl ;
00634                           } 
00635                         else
00636                           {
00637                                 ind1 = indice ;
00638                                 //std::cout<<"SOMMET PRESENT, ind = "<< indice <<std::endl ;
00639                           }
00640                         
00641                         do
00642                           {     
00643                                   
00644                                   Point p2(curr->prev()->vertex()->point()); // un sommet incident
00645                                   indice = S.isPresent(p2) ;
00646                                   if (indice == -1) 
00647                                         {
00648                                           ind2 = vecsize ;
00649                                           pind2 = PtIndex(p2, vecsize++) ;
00650                                           S.push_back(pind2) ;
00651                                           //std::cout<<"SOMMET AJOUTE, ind = "<< vecsize-1 <<std::endl ;
00652                                         } 
00653                                   else
00654                                         {
00655                                           ind2 = indice ;
00656                                           //std::cout<<"SOMMET PRESENT, ind = "<< indice <<std::endl ;
00657                                         }
00658                                   
00659                                   
00660                                   curr++;
00661                                   
00662                                   Point p3(curr->prev()->vertex()->point()); // un autre sommet incident
00663                                   indice = S.isPresent(p3) ;
00664                                   if (indice == -1) 
00665                                         {
00666                                           ind3 = vecsize ;
00667                                           pind3 = PtIndex(p3, vecsize++) ;
00668                                           S.push_back(pind3) ;
00669                                           //std::cout<<"SOMMET AJOUTE, ind = "<< vecsize-1 <<std::endl ;
00670                                         } 
00671                                   else
00672                                         {
00673                                           ind3 = indice ;
00674                                           //std::cout<<"SOMMET PRESENT, ind = "<< indice <<std::endl ;
00675                                         }
00676                                   //si a ce niveau on a encore faceMayBePresent == true, alors la face est deja presente.
00677                                   
00678                                   Triangle facette = Triangle(ind1, ind2, ind3) ;
00679                                   if (T.isPresent(facette) != -1) 
00680                                         {
00681                                           /*
00682                                            std::cout<<"facette deja presente !!"<<std::endl ;
00683                                            std::cout<<"barycentre == "
00684                                            <<(p1.x()+p2.x()+p3.x())/3<<" "
00685                                            <<(p1.y()+p2.y()+p3.y())/3<<" "
00686                                            <<(p1.z()+p2.z()+p3.z())/3<<std::endl ;
00687                                            /**/
00688                                         } 
00689                                            else
00690                                            // le triangle n'est pas present, on peut l'ajouter.
00691                                            T.push_back(Triangle(ind1, ind2, ind3)) ;
00692                                            
00693                                            
00694                           }  while (curr != (*it)->vertex_begin() ); // tant que l'on n'a pas fait un tour complet      
00695                   }
00696           }
00697                                            // On a rempli les structures de stockage des points et des facettes. Maintenant on peut envoyer tout ca dans un fichier
00698                                            
00699                                            const char* filename = "SNAKETEMP.off" ;
00700                                            std::ofstream fichier;
00701                                            
00702                                            fichier.open(filename, std::ios::out | std::ios::trunc);
00703                                            if(fichier.bad()){
00704                                                    std::cout<<"erreur lecture fichier"<<std::endl ;
00705                                                    exit(-1) ;
00706                                            }
00707                                            
00708                                            // Write polyhedron in Object File Format (OFF).
00709                                            CGAL::set_ascii_mode( fichier);
00710                                            fichier << "OFF" << std::endl << S.size() << ' ' 
00711                                            << T.size() << " 0" << std::endl;
00712                                            for(PtVector::iterator ptv = S.begin() ; ptv != S.end() ; ptv++) {
00713                                                    fichier<<ptv->p<<std::endl ;
00714                                            }
00715                                            for (  std::vector<Triangle>::iterator i = T.begin(); i != T.end(); i++) {
00716                                                    // Alors la si jamais la facette n'est pas un triangle, on est mal. 
00717                                                    // Mais c'est plus tot qu'il fallait le verifier.
00718                                                    fichier << '3' << ' ';
00719                                                    
00720                                                    //std::cout << *i << std::endl ;
00721                                                    fichier << *i;
00722                                                    fichier << std::endl;
00723                                            }
00724                                            fichier.close();
00725                                            
00726                                            // lecture du fichier (utilisation de l operateur >> vers Polyhedron)
00727                                            Mesh M(filename) ;
00728                                            return *M._mesh ;
00729 }
00730 
00731 // fonctionne pour des Polyhedron (pas seulement pour des Enriched_polyhedron)
00732 /*
00733  void Mesh::Trace_Local_region( Mesh::Polyhedron P ) // OpenGL 
00734 {
00735         std::cout << "obsolete !!" << std::endl ;
00736 }
00737 /**/

Généré le Thu Jun 15 18:48:52 2006 pour Projet Image 2006 - Vincent Vidal, Florent Paccault - par  doxygen 1.4.7