BWAPI
|
00001 // Copyright (c) 1997 INRIA Sophia-Antipolis (France). 00002 // All rights reserved. 00003 // 00004 // This file is part of CGAL (www.cgal.org); you may redistribute it under 00005 // the terms of the Q Public License version 1.0. 00006 // See the file LICENSE.QPL distributed with CGAL. 00007 // 00008 // Licensees holding a valid commercial license may use this file in 00009 // accordance with the commercial license agreement provided with the software. 00010 // 00011 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 00012 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 00013 // 00014 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/Triangulation_2/include/CGAL/Triangulation_data_structure_2.h $ 00015 // $Id: Triangulation_data_structure_2.h 52618 2009-10-19 15:50:53Z mcaroli $ 00016 // 00017 // 00018 // Author(s) : Mariette Yvinec 00019 00020 #ifndef CGAL_TRIANGULATION_DATA_STRUCTURE_2_H 00021 #define CGAL_TRIANGULATION_DATA_STRUCTURE_2_H 00022 00023 #include <CGAL/basic.h> 00024 #include <iostream> 00025 #include <list> 00026 #include <map> 00027 #include <set> 00028 #include <stack> 00029 #include <vector> 00030 #include <algorithm> 00031 #include <boost/tuple/tuple.hpp> 00032 00033 #include <CGAL/triangulation_assertions.h> 00034 #include <CGAL/Triangulation_utils_2.h> 00035 00036 #include <CGAL/Compact_container.h> 00037 00038 #include <CGAL/Triangulation_ds_face_base_2.h> 00039 #include <CGAL/Triangulation_ds_vertex_base_2.h> 00040 #include <CGAL/Triangulation_ds_iterators_2.h> 00041 #include <CGAL/Triangulation_ds_circulators_2.h> 00042 00043 #include <CGAL/IO/File_header_OFF.h> 00044 #include <CGAL/IO/File_scanner_OFF.h> 00045 00046 CGAL_BEGIN_NAMESPACE 00047 00048 template < class Vb = Triangulation_ds_vertex_base_2<>, 00049 class Fb = Triangulation_ds_face_base_2<> > 00050 class Triangulation_data_structure_2 00051 :public Triangulation_cw_ccw_2 00052 { 00053 typedef Triangulation_data_structure_2<Vb,Fb> Tds; 00054 00055 typedef typename Vb::template Rebind_TDS<Tds>::Other Vertex_base; 00056 typedef typename Fb::template Rebind_TDS<Tds>::Other Face_base; 00057 00058 friend class Triangulation_ds_edge_iterator_2<Tds>; 00059 friend class Triangulation_ds_face_circulator_2<Tds>; 00060 friend class Triangulation_ds_edge_circulator_2<Tds>; 00061 friend class Triangulation_ds_vertex_circulator_2<Tds>; 00062 00063 public: 00064 typedef Vertex_base Vertex; 00065 typedef Face_base Face; 00066 00067 typedef Compact_container<Face> Face_range; 00068 typedef Compact_container<Vertex> Vertex_range; 00069 00070 typedef typename Face_range::size_type size_type; 00071 typedef typename Face_range::difference_type difference_type; 00072 00073 typedef typename Face_range::iterator Face_iterator; 00074 typedef typename Vertex_range::iterator Vertex_iterator; 00075 00076 typedef Triangulation_ds_edge_iterator_2<Tds> Edge_iterator; 00077 00078 typedef Triangulation_ds_face_circulator_2<Tds> Face_circulator; 00079 typedef Triangulation_ds_vertex_circulator_2<Tds> Vertex_circulator; 00080 typedef Triangulation_ds_edge_circulator_2<Tds> Edge_circulator; 00081 00082 typedef Vertex_iterator Vertex_handle; 00083 typedef Face_iterator Face_handle; 00084 00085 typedef std::pair<Face_handle, int> Edge; 00086 typedef std::list<Edge> List_edges; 00087 00088 protected: 00089 int _dimension; 00090 Face_range _faces; 00091 Vertex_range _vertices; 00092 00093 //CREATORS - DESTRUCTORS 00094 public: 00095 Triangulation_data_structure_2(); 00096 Triangulation_data_structure_2(const Tds &tds); 00097 ~Triangulation_data_structure_2(); 00098 Tds& operator= (const Tds &tds); 00099 void swap(Tds &tds); 00100 00101 //ACCESS FUNCTIONS 00102 // We need the const_cast<>s because TDS is not const-correct. 00103 Face_range& faces() { return _faces;} 00104 Face_range& faces() const 00105 { return const_cast<Tds*>(this)->_faces;} 00106 Vertex_range& vertices() {return _vertices;} 00107 Vertex_range& vertices() const 00108 {return const_cast<Tds*>(this)->_vertices;} 00109 00110 int dimension() const { return _dimension; } 00111 size_type number_of_vertices() const {return vertices().size();} 00112 size_type number_of_faces() const ; 00113 size_type number_of_edges() const; 00114 size_type number_of_full_dim_faces() const; //number of faces stored by tds 00115 00116 // TEST FEATURES 00117 bool is_vertex(Vertex_handle v) const; 00118 bool is_edge(Face_handle fh, int i) const; 00119 bool is_edge(Vertex_handle va, Vertex_handle vb) const; 00120 bool is_edge(Vertex_handle va, Vertex_handle vb, 00121 Face_handle& fr, int& i) const; 00122 bool is_face(Face_handle fh) const; 00123 bool is_face(Vertex_handle v1, 00124 Vertex_handle v2, 00125 Vertex_handle v3) const; 00126 bool is_face(Vertex_handle v1, 00127 Vertex_handle v2, 00128 Vertex_handle v3, 00129 Face_handle& fr) const; 00130 00131 // ITERATORS AND CIRCULATORS 00132 public: 00133 // The face_iterator_base_begin gives the possibility to iterate over all 00134 // faces in the container independently of the dimension. 00135 // public for the need of file_ouput() of Constrained triangulation 00136 // should be made private later 00137 00138 Face_iterator face_iterator_base_begin() const { 00139 return faces().begin(); 00140 } 00141 Face_iterator face_iterator_base_end() const { 00142 return faces().end(); 00143 } 00144 00145 public: 00146 Face_iterator faces_begin() const { 00147 if (dimension() < 2) return faces_end(); 00148 return faces().begin(); 00149 } 00150 00151 Face_iterator faces_end() const { 00152 return faces().end(); 00153 } 00154 00155 Vertex_iterator vertices_begin() const { 00156 return vertices().begin(); 00157 } 00158 00159 Vertex_iterator vertices_end() const { 00160 return vertices().end(); 00161 } 00162 00163 Edge_iterator edges_begin() const { 00164 return Edge_iterator(this); 00165 } 00166 00167 Edge_iterator edges_end() const { 00168 return Edge_iterator(this,1); 00169 } 00170 00171 Face_circulator incident_faces(Vertex_handle v, 00172 Face_handle f = Face_handle()) const{ 00173 return Face_circulator(v,f); 00174 } 00175 Vertex_circulator incident_vertices(Vertex_handle v, 00176 Face_handle f = Face_handle()) const 00177 { 00178 return Vertex_circulator(v,f); 00179 } 00180 00181 Edge_circulator incident_edges(Vertex_handle v, 00182 Face_handle f = Face_handle()) const{ 00183 return Edge_circulator(v,f); 00184 } 00185 00186 size_type degree(Vertex_handle v) const { 00187 int count = 0; 00188 Vertex_circulator vc = incident_vertices(v), done(vc); 00189 if ( ! vc.is_empty()) { 00190 do { 00191 count += 1; 00192 } while (++vc != done); 00193 } 00194 return count; 00195 } 00196 00197 00198 Vertex_handle 00199 mirror_vertex(Face_handle f, int i) const 00200 { 00201 CGAL_triangulation_precondition ( f->neighbor(i) != Face_handle() 00202 && f->dimension() >= 1); 00203 return f->neighbor(i)->vertex(mirror_index(f,i)); 00204 } 00205 00206 int 00207 mirror_index(Face_handle f, int i) const 00208 { 00209 // return the index of opposite vertex in neighbor(i); 00210 CGAL_triangulation_precondition (f->neighbor(i) != Face_handle() && 00211 f->dimension() >= 1); 00212 if (f->dimension() == 1) { 00213 return 1 - (f->neighbor(i)->index(f->vertex(1-i))); 00214 } 00215 return ccw( f->neighbor(i)->index(f->vertex(ccw(i)))); 00216 } 00217 00218 // MODIFY 00219 void flip(Face_handle f, int i); 00220 00221 Vertex_handle insert_first(); 00222 Vertex_handle insert_second(); 00223 Vertex_handle insert_in_face(Face_handle f); 00224 Vertex_handle insert_in_edge(Face_handle f, int i); 00225 Vertex_handle insert_dim_up(Vertex_handle w = Vertex_handle(), 00226 bool orient=true); 00227 00228 void remove_degree_3(Vertex_handle v, Face_handle f = Face_handle()); 00229 void remove_1D(Vertex_handle v); 00230 00231 void remove_second(Vertex_handle v); 00232 void remove_first(Vertex_handle v); 00233 void remove_dim_down(Vertex_handle v); 00234 void dim_2D_1D(Face_handle f, int i); 00235 00236 Vertex_handle star_hole(List_edges& hole); 00237 void star_hole(Vertex_handle v, List_edges& hole); 00238 void make_hole(Vertex_handle v, List_edges& hole); 00239 00240 // template< class EdgeIt> 00241 // Vertex_handle star_hole(EdgeIt edge_begin,EdgeIt edge_end); 00242 00243 // template< class EdgeIt> 00244 // void star_hole(Vertex_handle v, EdgeIt edge_begin, EdgeIt edge_end); 00245 00246 // template< class EdgeIt, class FaceIt> 00247 // Vertex_handle star_hole(EdgeIt edge_begin, 00248 // EdgeIt edge_end, 00249 // FaceIt face_begin, 00250 // FaceIt face_end); 00251 00252 // template< class EdgeIt, class FaceIt> 00253 // void star_hole(Vertex_handle v, 00254 // EdgeIt edge_begin, 00255 // EdgeIt edge_end, 00256 // FaceIt face_begin, 00257 // FaceIt face_end); 00258 00259 Vertex_handle create_vertex(const Vertex &v = Vertex()); 00260 Vertex_handle create_vertex(Vertex_handle v); //calls copy constructor 00261 Face_handle create_face(const Face& f = Face()); 00262 Face_handle create_face(Face_handle f); //calls copy constructor 00263 00264 Face_handle create_face(Face_handle f1, int i1, 00265 Face_handle f2, int i2, 00266 Face_handle f3, int i3); 00267 Face_handle create_face(Face_handle f1, int i1, 00268 Face_handle f2, int i2); 00269 Face_handle create_face(Face_handle f1, int i1, Vertex_handle v); 00270 Face_handle create_face(Vertex_handle v1, 00271 Vertex_handle v2, 00272 Vertex_handle v3); 00273 Face_handle create_face(Vertex_handle v1, 00274 Vertex_handle v2, 00275 Vertex_handle v3, 00276 Face_handle f1, 00277 Face_handle f2, 00278 Face_handle f3); 00279 void set_adjacency(Face_handle f0, int i0, Face_handle f1, int i1) const; 00280 void delete_face(Face_handle); 00281 void delete_vertex(Vertex_handle); 00282 00283 // split and join operations 00284 protected: 00285 Vertex_handle join_vertices(Face_handle f, int i, Vertex_handle v); 00286 00287 typedef 00288 boost::tuples::tuple<Vertex_handle,Vertex_handle,Face_handle,Face_handle> 00289 Fourtuple; 00290 00291 public: 00292 Fourtuple split_vertex(Vertex_handle v, Face_handle f1, Face_handle g1); 00293 00294 inline Vertex_handle join_vertices(Face_handle f, int i) { 00295 return join_vertices(f, i, f->vertex( ccw(i) )); 00296 } 00297 00298 inline Vertex_handle join_vertices(Edge e) { 00299 return join_vertices(e.first, e.second); 00300 } 00301 00302 inline Vertex_handle join_vertices(Edge_iterator eit) { 00303 return join_vertices(*eit); 00304 } 00305 00306 inline Vertex_handle join_vertices(Edge_circulator ec) { 00307 return join_vertices(*ec); 00308 } 00309 00310 // insert_degree_2 and remove_degree_2 operations 00311 Vertex_handle insert_degree_2(Face_handle f, int i); 00312 void remove_degree_2(Vertex_handle v); 00313 00314 // CHECKING 00315 bool is_valid(bool verbose = false, int level = 0) const; 00316 00317 // HELPING 00318 private: 00319 typedef std::pair<Vertex_handle,Vertex_handle> Vh_pair; 00320 void set_adjacency(Face_handle fh, 00321 int ih, 00322 std::map< Vh_pair, Edge>& edge_map); 00323 void reorient_faces(); 00324 bool dim_2D_1D_precondition(Face_handle f, int i); 00325 00326 public: 00327 void clear(); 00328 Vertex_handle copy_tds(const Tds &tds, Vertex_handle = Vertex_handle()); 00329 00330 // I/O 00331 Vertex_handle file_input(std::istream& is, bool skip_first=false); 00332 void file_output(std::ostream& os, 00333 Vertex_handle v = Vertex_handle(), 00334 bool skip_first=false) const; 00335 Vertex_handle off_file_input(std::istream& is, bool verbose=false); 00336 void vrml_output(std::ostream& os, 00337 Vertex_handle v = Vertex_handle(), 00338 bool skip_first=false) const; 00339 00340 // SETTING (had to make them public for use in remove from Triangulations) 00341 void set_dimension (int n) {_dimension = n ;} 00342 00343 // template members definition 00344 public: 00345 template< class EdgeIt> 00346 Vertex_handle star_hole(EdgeIt edge_begin, EdgeIt edge_end) 00347 // creates a new vertex 00348 // and stars from it 00349 // the hole described by the range [edge_begin,edge_end[ 00350 // the triangulation is assumed to have dim=2 00351 // hole is supposed to be ccw oriented 00352 { 00353 Vertex_handle newv = create_vertex(); 00354 star_hole(newv, edge_begin, edge_end); 00355 return newv; 00356 } 00357 00358 template< class EdgeIt> 00359 void star_hole(Vertex_handle v, EdgeIt edge_begin, EdgeIt edge_end) 00360 // uses vertex v 00361 // to star the hole described by the range [edge_begin,edge_end[ 00362 // the triangulation is assumed to have dim=2 00363 // the hole is supposed to be ccw oriented 00364 { 00365 std::list<Face_handle> empty_list; 00366 star_hole(v, 00367 edge_begin, 00368 edge_end, 00369 empty_list.begin(), 00370 empty_list.end()); 00371 return; 00372 } 00373 00374 00375 template< class EdgeIt, class FaceIt> 00376 Vertex_handle star_hole(EdgeIt edge_begin, 00377 EdgeIt edge_end, 00378 FaceIt face_begin, 00379 FaceIt face_end) 00380 // creates a new vertex 00381 // and stars from it 00382 // the hole described by the range [edge_begin,edge_end[ 00383 // reusing the faces in the range [face_begin,face_end[ 00384 // the triangulation is assumed to have dim=2 00385 // the hole is supposed to be ccw oriented 00386 { 00387 Vertex_handle newv = create_vertex(); 00388 star_hole(newv, edge_begin, edge_end, face_begin, face_end); 00389 return newv; 00390 } 00391 00392 template< class EdgeIt, class FaceIt> 00393 void star_hole(Vertex_handle newv, 00394 EdgeIt edge_begin, 00395 EdgeIt edge_end, 00396 FaceIt face_begin, 00397 FaceIt face_end) 00398 // uses vertex v 00399 // to star the hole described by the range [edge_begin,edge_end[ 00400 // reusing the faces in the range [face_begin,face_end[ 00401 // the triangulation is assumed to have dim=2 00402 // hole is supposed to be ccw oriented 00403 { 00404 CGAL_triangulation_precondition(dimension() == 2); 00405 EdgeIt eit = edge_begin; 00406 FaceIt fit = face_begin; 00407 00408 Face_handle fn = (*eit).first; 00409 int in = (*eit).second; 00410 fn->vertex(cw(in))->set_face(fn); 00411 Face_handle first_f = reset_or_create_face(fn, in , newv, fit, face_end); 00412 Face_handle previous_f=first_f, next_f; 00413 ++eit; 00414 00415 for( ; eit != edge_end ; eit++) { 00416 fn = (*eit).first; 00417 in = (*eit).second; 00418 fn->vertex(cw(in))->set_face(fn); 00419 next_f = reset_or_create_face(fn, in , newv, fit, face_end); 00420 next_f->set_neighbor(1, previous_f); 00421 previous_f->set_neighbor(0, next_f); 00422 previous_f=next_f; 00423 } 00424 00425 next_f->set_neighbor(0, first_f); 00426 first_f->set_neighbor(1, next_f); 00427 newv->set_face(first_f); 00428 return; 00429 } 00430 00431 private: 00432 template< class FaceIt> 00433 Face_handle reset_or_create_face(Face_handle fn, 00434 int in, 00435 Vertex_handle v, 00436 FaceIt& fit, 00437 const FaceIt& face_end) 00438 { 00439 if (fit == face_end) return create_face(fn, in, v); 00440 (*fit)->set_vertices(fn->vertex(cw(in)), fn->vertex(ccw(in)), v); 00441 (*fit)->set_neighbors(Face_handle(),Face_handle(),fn); 00442 fn->set_neighbor(in, *fit); 00443 return *fit++; 00444 } 00445 00446 }; 00447 00448 //for backward compatibility 00449 template < class Gt , class Vb, class Fb> 00450 class Triangulation_default_data_structure_2 00451 : public Triangulation_data_structure_2<Vb,Fb> 00452 { 00453 public: 00454 typedef Triangulation_data_structure_2<Vb,Fb> Tds; 00455 typedef Triangulation_default_data_structure_2<Gt,Vb,Fb> Tdds; 00456 typedef Gt Geom_traits; 00457 00458 Triangulation_default_data_structure_2(const Geom_traits& = Geom_traits()) 00459 : Tds() {} 00460 00461 Triangulation_default_data_structure_2(const Tdds &tdds) 00462 : Tds(tdds) {} 00463 }; 00464 00465 //for backward compatibility 00466 template <class Vb, class Fb> 00467 class Triangulation_data_structure_using_list_2 00468 :public Triangulation_data_structure_2<Vb, Fb> 00469 { 00470 public: 00471 typedef Triangulation_data_structure_2<Vb,Fb> Tds; 00472 typedef Triangulation_data_structure_using_list_2<Vb,Fb> Tdsul; 00473 00474 Triangulation_data_structure_using_list_2(): Tds() {} 00475 Triangulation_data_structure_using_list_2(const Tdsul &tdsul) 00476 : Tds(tdsul) {} 00477 }; 00478 00479 00480 template < class Vb, class Fb> 00481 Triangulation_data_structure_2<Vb,Fb> :: 00482 Triangulation_data_structure_2() 00483 : _dimension(-2) 00484 { } 00485 00486 template < class Vb, class Fb> 00487 Triangulation_data_structure_2<Vb,Fb> :: 00488 Triangulation_data_structure_2(const Tds &tds) 00489 { 00490 copy_tds(tds); 00491 } 00492 00493 template < class Vb, class Fb> 00494 Triangulation_data_structure_2<Vb,Fb> :: 00495 ~Triangulation_data_structure_2() 00496 { 00497 clear(); 00498 } 00499 00500 //assignement 00501 template < class Vb, class Fb> 00502 Triangulation_data_structure_2<Vb,Fb>& 00503 Triangulation_data_structure_2<Vb,Fb> :: 00504 operator= (const Tds &tds) 00505 { 00506 copy_tds(tds); 00507 return *this; 00508 } 00509 00510 template < class Vb, class Fb> 00511 void 00512 Triangulation_data_structure_2<Vb,Fb>:: 00513 clear() 00514 { 00515 faces().clear(); 00516 vertices().clear(); 00517 set_dimension(-2); 00518 return; 00519 } 00520 00521 template < class Vb, class Fb> 00522 void 00523 Triangulation_data_structure_2<Vb,Fb>:: 00524 swap(Tds &tds) 00525 { 00526 CGAL_triangulation_expensive_precondition(tds.is_valid() && is_valid()); 00527 std::swap(_dimension, tds._dimension); 00528 faces().swap(tds.faces()); 00529 vertices().swap(tds.vertices()); 00530 return; 00531 } 00532 00533 //ACCESS FUNCTIONS 00534 template <class Vb, class Fb> 00535 inline 00536 typename Triangulation_data_structure_2<Vb,Fb>::size_type 00537 Triangulation_data_structure_2<Vb,Fb> :: 00538 number_of_faces() const 00539 { 00540 if (dimension() < 2) return 0; 00541 return faces().size(); 00542 } 00543 00544 template <class Vb, class Fb> 00545 inline 00546 typename Triangulation_data_structure_2<Vb,Fb>::size_type 00547 Triangulation_data_structure_2<Vb,Fb>:: 00548 number_of_edges() const 00549 { 00550 switch (dimension()) { 00551 case 1: return number_of_vertices(); 00552 case 2: return 3*number_of_faces()/2; 00553 default: return 0; 00554 } 00555 } 00556 00557 template <class Vb, class Fb> 00558 typename Triangulation_data_structure_2<Vb,Fb>::size_type 00559 Triangulation_data_structure_2<Vb,Fb>:: 00560 number_of_full_dim_faces() const 00561 { 00562 return faces().size(); 00563 } 00564 00565 template <class Vb, class Fb> 00566 inline bool 00567 Triangulation_data_structure_2<Vb,Fb>:: 00568 is_vertex(Vertex_handle v) const 00569 { 00570 Vertex_iterator vit = vertices_begin(); 00571 while (vit != vertices_end() && v != vit) 00572 ++vit; 00573 return v == vit; 00574 } 00575 00576 template <class Vb, class Fb> 00577 inline bool 00578 Triangulation_data_structure_2<Vb,Fb>:: 00579 is_edge(Face_handle fh, int i) const 00580 { 00581 if ( dimension() == 0 ) return false; 00582 if ( dimension() == 1 && i != 2) return false; 00583 if (i > 2) return false; 00584 Face_iterator fit = face_iterator_base_begin(); 00585 while (fit != face_iterator_base_end() && fh != fit ) ++fit; 00586 return fh == fit; 00587 } 00588 00589 template <class Vb, class Fb> 00590 bool 00591 Triangulation_data_structure_2<Vb,Fb>:: 00592 is_edge(Vertex_handle va, Vertex_handle vb) const 00593 // returns true (false) if the line segment ab is (is not) an edge of t 00594 //It is assumed that va is a vertex of t 00595 { 00596 Vertex_circulator vc = incident_vertices(va), done(vc); 00597 if ( vc == 0) return false; 00598 do { 00599 if( vb == vc ) {return true;} 00600 } while (++vc != done); 00601 return false; 00602 } 00603 00604 00605 template <class Vb, class Fb> 00606 bool 00607 Triangulation_data_structure_2<Vb,Fb>:: 00608 is_edge(Vertex_handle va, Vertex_handle vb, 00609 Face_handle &fr, int & i) const 00610 // assume va is a vertex of t 00611 // returns true (false) if the line segment ab is (is not) an edge of t 00612 // if true is returned (fr,i) is the edge ab 00613 // with face fr on the right of a->b 00614 { 00615 Face_handle fc = va->face(); 00616 Face_handle start = fc; 00617 if (fc == 0) return false; 00618 int inda, indb; 00619 do { 00620 inda=fc->index(va); 00621 indb = (dimension() == 2 ? cw(inda) : 1-inda); 00622 if(fc->vertex(indb) == vb) { 00623 fr=fc; 00624 i = 3 - inda - indb; //works in dim 1 or 2 00625 return true; 00626 } 00627 fc=fc->neighbor(indb); //turns ccw around va 00628 } while (fc != start); 00629 return false; 00630 } 00631 00632 template <class Vb, class Fb> 00633 inline bool 00634 Triangulation_data_structure_2<Vb,Fb>:: 00635 is_face(Face_handle fh) const 00636 { 00637 if (dimension() < 2) return false; 00638 Face_iterator fit = faces_begin(); 00639 while (fit != faces_end() && fh != fit ) ++fit; 00640 return fh == fit; 00641 } 00642 00643 template <class Vb, class Fb> 00644 inline bool 00645 Triangulation_data_structure_2<Vb,Fb>:: 00646 is_face(Vertex_handle v1, 00647 Vertex_handle v2, 00648 Vertex_handle v3) const 00649 { 00650 Face_handle f; 00651 return is_face(v1,v2,v3,f); 00652 } 00653 00654 template <class Vb, class Fb> 00655 bool 00656 Triangulation_data_structure_2<Vb,Fb>:: 00657 is_face(Vertex_handle v1, 00658 Vertex_handle v2, 00659 Vertex_handle v3, 00660 Face_handle &f) const 00661 { 00662 if (dimension() != 2) return false; 00663 int i; 00664 bool b = is_edge(v1,v2,f,i); 00665 if (!b) return false; 00666 else if (v3== f->vertex(i)) return true; 00667 f = f-> neighbor(i); 00668 int ind1= f->index(v1); 00669 int ind2= f->index(v2); 00670 if (v3 == f->vertex(3-ind1-ind2)) { return true;} 00671 return false; 00672 } 00673 00674 template <class Vb, class Fb> 00675 void 00676 Triangulation_data_structure_2<Vb,Fb>:: 00677 flip(Face_handle f, int i) 00678 { 00679 CGAL_triangulation_precondition( dimension()==2); 00680 Face_handle n = f->neighbor(i); 00681 int ni = mirror_index(f,i); //ni = n->index(f); 00682 00683 Vertex_handle v_cw = f->vertex(cw(i)); 00684 Vertex_handle v_ccw = f->vertex(ccw(i)); 00685 00686 // bl == bottom left, tr == top right 00687 Face_handle tr = f->neighbor(ccw(i)); 00688 int tri = mirror_index(f,ccw(i)); 00689 Face_handle bl = n->neighbor(ccw(ni)); 00690 int bli = mirror_index(n,ccw(ni)); 00691 00692 f->set_vertex(cw(i), n->vertex(ni)); 00693 n->set_vertex(cw(ni), f->vertex(i)); 00694 00695 // update the neighborhood relations 00696 f->set_neighbor(i, bl); 00697 bl->set_neighbor(bli, f); 00698 00699 f->set_neighbor(ccw(i), n); 00700 n->set_neighbor(ccw(ni), f); 00701 00702 n->set_neighbor(ni, tr); 00703 tr->set_neighbor(tri, n); 00704 00705 if(v_cw->face() == f) { 00706 v_cw->set_face(n); 00707 } 00708 00709 if(v_ccw->face() == n) { 00710 v_ccw->set_face(f); 00711 } 00712 } 00713 00714 template < class Vb, class Fb> 00715 typename Triangulation_data_structure_2<Vb,Fb>::Vertex_handle 00716 Triangulation_data_structure_2<Vb,Fb>:: 00717 insert_first( ) 00718 { 00719 CGAL_triangulation_precondition( number_of_vertices() == 0 && 00720 dimension()==-2 ); 00721 return insert_dim_up(); 00722 } 00723 00724 template < class Vb, class Fb> 00725 typename Triangulation_data_structure_2<Vb,Fb>::Vertex_handle 00726 Triangulation_data_structure_2<Vb,Fb>:: 00727 insert_second() 00728 { 00729 CGAL_triangulation_precondition( number_of_vertices() == 1 && 00730 dimension()==-1 ); 00731 return insert_dim_up(); 00732 00733 } 00734 00735 00736 template < class Vb, class Fb> 00737 typename Triangulation_data_structure_2<Vb,Fb>::Vertex_handle 00738 Triangulation_data_structure_2<Vb,Fb>:: 00739 insert_in_face(Face_handle f) 00740 // New vertex will replace f->vertex(0) in face f 00741 { 00742 CGAL_triangulation_precondition( f != Face_handle() && dimension()== 2); 00743 Vertex_handle v = create_vertex(); 00744 00745 Vertex_handle v0 = f->vertex(0); 00746 Vertex_handle v2 = f->vertex(2); 00747 Vertex_handle v1 = f->vertex(1); 00748 00749 Face_handle n1 = f->neighbor(1); 00750 Face_handle n2 = f->neighbor(2); 00751 00752 Face_handle f1 = create_face(v0, v, v2, f, n1, Face_handle()); 00753 Face_handle f2 = create_face(v0, v1, v, f, Face_handle(), n2); 00754 00755 f1->set_neighbor(2, f2); 00756 f2->set_neighbor(1, f1); 00757 if (n1 != Face_handle()) { 00758 int i1 = mirror_index(f,1); //int i1 = n1->index(f); 00759 n1->set_neighbor(i1,f1); 00760 } 00761 if (n2 != Face_handle()) { 00762 int i2 = mirror_index(f,2);//int i2 = n2->index(f); 00763 n2->set_neighbor(i2,f2);} 00764 00765 f->set_vertex(0, v); 00766 f->set_neighbor(1, f1); 00767 f->set_neighbor(2, f2); 00768 00769 if( v0->face() == f ) { v0->set_face(f2); } 00770 v->set_face(f); 00771 00772 return v; 00773 } 00774 00775 00776 template < class Vb, class Fb> 00777 typename Triangulation_data_structure_2<Vb,Fb>::Vertex_handle 00778 Triangulation_data_structure_2<Vb,Fb>:: 00779 insert_in_edge(Face_handle f, int i) 00780 //insert in the edge opposite to vertex i of face f 00781 { 00782 CGAL_triangulation_precondition(f != Face_handle() && dimension() >= 1); 00783 if (dimension() == 1) {CGAL_triangulation_precondition(i == 2);} 00784 if (dimension() == 2) {CGAL_triangulation_precondition(i == 0 || 00785 i == 1 || 00786 i == 2);} 00787 Vertex_handle v; 00788 if (dimension() == 1) { 00789 v = create_vertex(); 00790 Face_handle ff = f->neighbor(0); 00791 Vertex_handle vv = f->vertex(1); 00792 Face_handle g = create_face(v,vv,Vertex_handle(),ff, f, Face_handle()); 00793 f->set_vertex(1,v);f->set_neighbor(0,g); 00794 ff->set_neighbor(1,g); 00795 v->set_face(g); 00796 vv->set_face(ff); 00797 } 00798 00799 else { //dimension() ==2 00800 Face_handle n = f->neighbor(i); 00801 int in = mirror_index(f,i); //n->index(f); 00802 v = insert_in_face(f); 00803 flip(n,in); 00804 } 00805 00806 return v; 00807 } 00808 00809 00810 template < class Vb, class Fb> 00811 typename Triangulation_data_structure_2<Vb,Fb>::Vertex_handle 00812 Triangulation_data_structure_2<Vb,Fb>:: 00813 insert_dim_up(Vertex_handle w, bool orient) 00814 { 00815 // the following function insert 00816 // a vertex v which is outside the affine hull of Tds 00817 // The triangulation will be starred from v and w 00818 // ( geometrically w= // the infinite vertex ) 00819 // w=NULL for first and second insertions 00820 // orient governs the orientation of the resulting triangulation 00821 00822 Vertex_handle v = create_vertex(); 00823 set_dimension( dimension() + 1); 00824 Face_handle f1; 00825 Face_handle f2; 00826 00827 const int dim = dimension(); //it is the resulting dimension 00828 00829 switch (dim) { 00830 case -1: 00831 f1 = create_face(v,Vertex_handle(),Vertex_handle()); 00832 v->set_face(f1); 00833 break; 00834 case 0 : 00835 f1 = face_iterator_base_begin(); 00836 f2 = create_face(v,Vertex_handle(),Vertex_handle()); 00837 f1->set_neighbor(0,f2); 00838 f2->set_neighbor(0,f1); 00839 v->set_face(f2); 00840 break; 00841 case 1 : 00842 case 2 : 00843 { 00844 std::list<Face_handle> faces_list; 00845 Face_iterator ib= face_iterator_base_begin(); 00846 Face_iterator ib_end = face_iterator_base_end(); 00847 for (; ib != ib_end ; ++ib){ 00848 faces_list.push_back( ib); 00849 } 00850 00851 std::list<Face_handle> to_delete; 00852 typename std::list<Face_handle>::iterator lfit = faces_list.begin(); 00853 Face_handle f, g; 00854 00855 for ( ; lfit != faces_list.end() ; ++lfit) { 00856 f = * lfit; 00857 g = create_face(f); //calls copy constructor of face 00858 f->set_vertex(dim,v); f->set_neighbor(dim,g); 00859 g->set_vertex(dim,w); g->set_neighbor(dim,f); 00860 if (f->has_vertex(w)) to_delete.push_back(g); // flat face to delete 00861 } 00862 00863 lfit = faces_list.begin(); 00864 for ( ; lfit != faces_list.end() ; ++lfit) { 00865 f = * lfit; 00866 g = f->neighbor(dim); 00867 for(int j = 0; j < dim ; ++j) { 00868 g->set_neighbor(j, f->neighbor(j)->neighbor(dim)); 00869 } 00870 } 00871 00872 // couldn't unify the code for reorientation mater 00873 lfit = faces_list.begin() ; 00874 if (dim == 1){ 00875 if (orient) { 00876 (*lfit)->reorient(); ++lfit ; (*lfit)->neighbor(1)->reorient(); 00877 } 00878 else { 00879 (*lfit)->neighbor(1)->reorient(); ++lfit ; (*lfit)->reorient(); 00880 } 00881 } 00882 else { // dimension == 2 00883 for( ;lfit != faces_list.end(); ++lfit ) { 00884 if (orient) {(*lfit)->neighbor(2)->reorient();} 00885 else { (*lfit)->reorient();} 00886 } 00887 } 00888 00889 lfit = to_delete.begin(); 00890 int i1, i2; 00891 for ( ;lfit != to_delete.end(); ++lfit){ 00892 f = *lfit ; 00893 int j ; 00894 if (f->vertex(0) == w) {j=0;} 00895 else {j=1;} 00896 f1= f->neighbor(dim); i1= mirror_index(f,dim); //f1->index(f); 00897 f2= f->neighbor(j); i2= mirror_index(f,j); //f2->index(f); 00898 f1->set_neighbor(i1,f2); 00899 f2->set_neighbor(i2,f1); 00900 delete_face(f); 00901 } 00902 00903 v->set_face( *(faces_list.begin())); 00904 } 00905 break; 00906 default: 00907 CGAL_triangulation_assertion(false); 00908 break; } 00909 return v; 00910 } 00911 00912 00913 template <class Vb, class Fb> 00914 void 00915 Triangulation_data_structure_2<Vb,Fb>:: 00916 remove_degree_3(Vertex_handle v, Face_handle f) 00917 // remove a vertex of degree 3 00918 { 00919 CGAL_triangulation_precondition(v != Vertex_handle()); 00920 CGAL_triangulation_precondition(degree(v) == 3); 00921 00922 if (f == Face_handle()) {f= v->face();} 00923 else { CGAL_triangulation_assertion( f->has_vertex(v));} 00924 00925 int i = f->index(v); 00926 Face_handle left = f->neighbor(cw(i)); 00927 int li = mirror_index(f,cw(i)); 00928 Face_handle right = f->neighbor(ccw(i)); 00929 int ri = mirror_index(f,ccw(i)); 00930 00931 Face_handle ll, rr; 00932 Vertex_handle q = left->vertex(li); 00933 CGAL_triangulation_assertion( left->vertex(li) == right->vertex(ri)); 00934 00935 ll = left->neighbor(cw(li)); 00936 if(ll != Face_handle()) { 00937 int lli = mirror_index(left,cw(li)); 00938 ll->set_neighbor(lli, f); 00939 } 00940 f->set_neighbor(cw(i), ll); 00941 if (f->vertex(ccw(i))->face() == left) f->vertex(ccw(i))->set_face(f); 00942 00943 rr = right->neighbor(ccw(ri)); 00944 if(rr != Face_handle()) { 00945 int rri = mirror_index(right,ccw(ri)); //rr->index(right); 00946 rr->set_neighbor(rri, f); 00947 } 00948 f->set_neighbor(ccw(i), rr); 00949 if (f->vertex(cw(i))->face() == right) f->vertex(cw(i))->set_face(f); 00950 00951 f->set_vertex(i, q); 00952 if (q->face() == right || q->face() == left) { 00953 q->set_face(f); 00954 } 00955 delete_face(right); 00956 delete_face(left); 00957 00958 delete_vertex(v); 00959 } 00960 00961 template <class Vb, class Fb> 00962 bool 00963 Triangulation_data_structure_2<Vb,Fb>:: 00964 dim_2D_1D_precondition(Face_handle f, int i) { 00965 if(!is_valid()) return false; 00966 if(dimension() != 2) return false; 00967 Vertex_handle v = f->vertex(i); 00968 std::map< Vertex_handle, unsigned > hash_v; 00969 int n_faces = 0; 00970 Face_iterator ib = face_iterator_base_begin(); 00971 for( ; ib != face_iterator_base_end(); ++ib ) { 00972 hash_v[ib->vertex(0)]++; 00973 hash_v[ib->vertex(1)]++; 00974 hash_v[ib->vertex(2)]++; ++n_faces; 00975 } 00976 int n = 0; 00977 Vertex_handle vres[2]; 00978 Vertex_iterator iv = vertices_begin(); 00979 for( ; iv != vertices_end(); ++iv ) { 00980 if(hash_v[iv] == ((number_of_faces()/2) + 1)) { 00981 if(n == 0) vres[n++] = iv; 00982 else if((n == 1) && ((iv == v) || (vres[0] == v))) vres[n++] = iv; 00983 } 00984 } 00985 if(n != 2) return false; 00986 if(!((vres[0] == v) || (vres[1] == v))) return false; 00987 return true; 00988 } 00989 00990 template <class Vb, class Fb> 00991 void 00992 Triangulation_data_structure_2<Vb,Fb>:: 00993 dim_2D_1D(Face_handle f, int i) 00994 { 00995 CGAL_triangulation_precondition(dim_2D_1D_precondition(f, i)); 00996 00997 Vertex_handle v = f->vertex(i); 00998 std::list<Face_handle > to_delete; 00999 std::list<Face_handle> to_downgrade; 01000 Face_iterator ib = face_iterator_base_begin(); 01001 for( ; ib != face_iterator_base_end(); ++ib ){ 01002 if ( ! ib->has_vertex(v) ) { to_delete.push_back(ib);} 01003 else { to_downgrade.push_back(ib);} 01004 } 01005 01006 typename std::list<Face_handle>::iterator lfit = to_downgrade.begin(); 01007 int j; 01008 for( ; lfit != to_downgrade.end() ; ++lfit) { 01009 Face_handle fs = *lfit; j = fs->index(v); 01010 if (j == 0) fs->cw_permute(); 01011 else if(j == 1) fs->ccw_permute(); 01012 fs->set_vertex(2, Vertex_handle()); 01013 fs->set_neighbor(2, Face_handle()); 01014 fs->vertex(0)->set_face(fs); 01015 } 01016 lfit = to_delete.begin(); 01017 for( ; lfit != to_delete.end() ; ++lfit) { 01018 delete_face(*lfit); 01019 } 01020 set_dimension(dimension() -1); 01021 Face_handle n0 = f->neighbor(0); 01022 Face_handle n1 = f->neighbor(1); 01023 Vertex_handle v0 = f->vertex(0); 01024 Vertex_handle v1 = f->vertex(1); 01025 f->set_vertex(1, v); 01026 Face_handle fl = create_face(v, v1, Vertex_handle(), 01027 n0, f, Face_handle()); 01028 f->set_neighbor(0, fl); 01029 n0->set_neighbor(1, fl); 01030 v->set_face(f); 01031 } 01032 01033 template <class Vb, class Fb> 01034 void 01035 Triangulation_data_structure_2<Vb,Fb>:: 01036 remove_dim_down(Vertex_handle v) 01037 { 01038 Face_handle f; 01039 switch( dimension()){ 01040 case -1: 01041 delete_face(v->face()); 01042 break; 01043 case 0: 01044 f = v->face(); 01045 f->neighbor(0)->set_neighbor(0,Face_handle()); 01046 delete_face(v->face()); 01047 break; 01048 case 1: 01049 case 2: 01050 // CGAL_triangulation_precondition ( 01051 // (dimension() == 1 && number_of_vertices() == 3) || 01052 // (dimension() == 2 && number_of_vertices() > 3) ); 01053 // the faces incident to v are down graded one dimension 01054 // the other faces are deleted 01055 std::list<Face_handle > to_delete; 01056 std::list<Face_handle > to_downgrade; 01057 Face_iterator ib = face_iterator_base_begin(); 01058 for( ; ib != face_iterator_base_end(); ++ib ){ 01059 if ( ! ib->has_vertex(v) ) { to_delete.push_back(ib);} 01060 else { to_downgrade.push_back(ib);} 01061 } 01062 01063 typename std::list<Face_handle>::iterator lfit = to_downgrade.begin(); 01064 int j; 01065 for( ; lfit != to_downgrade.end() ; ++lfit) { 01066 f = *lfit; j = f->index(v); 01067 if (dimension() == 1) { 01068 if (j == 0) f->reorient(); 01069 f->set_vertex(1,Vertex_handle()); 01070 f->set_neighbor(1, Face_handle()); 01071 } 01072 else { //dimension() == 2 01073 if (j == 0) f->cw_permute(); 01074 else if(j == 1) f->ccw_permute(); 01075 f->set_vertex(2, Vertex_handle()); 01076 f->set_neighbor(2, Face_handle()); 01077 } 01078 f->vertex(0)->set_face(f); 01079 } 01080 01081 lfit = to_delete.begin(); 01082 for( ; lfit != to_delete.end() ; ++lfit) { 01083 delete_face(*lfit); 01084 } 01085 } 01086 delete_vertex(v); 01087 set_dimension(dimension() -1); 01088 return; 01089 } 01090 01091 template < class Vb, class Fb> 01092 void 01093 Triangulation_data_structure_2<Vb,Fb>:: 01094 remove_1D(Vertex_handle v) 01095 { 01096 CGAL_triangulation_precondition( dimension() == 1 && 01097 number_of_vertices() > 3); 01098 Face_handle f = v->face(); 01099 int i = f->index(v); 01100 if (i==0) {f = f->neighbor(1);} 01101 CGAL_triangulation_assertion( f->index(v) == 1); 01102 Face_handle g= f->neighbor(0); 01103 f->set_vertex(1, g->vertex(1)); 01104 f->set_neighbor(0,g->neighbor(0)); 01105 g->neighbor(0)->set_neighbor(1,f); 01106 g->vertex(1)->set_face(f); 01107 delete_face(g); 01108 delete_vertex(v); 01109 return; 01110 } 01111 01112 01113 01114 template <class Vb, class Fb> 01115 inline void 01116 Triangulation_data_structure_2<Vb,Fb>:: 01117 remove_second(Vertex_handle v) 01118 { 01119 CGAL_triangulation_precondition(number_of_vertices()== 2 && 01120 dimension() == 0); 01121 remove_dim_down(v); 01122 return; 01123 } 01124 01125 01126 template <class Vb, class Fb> 01127 inline void 01128 Triangulation_data_structure_2<Vb,Fb>:: 01129 remove_first(Vertex_handle v) 01130 { 01131 CGAL_triangulation_precondition(number_of_vertices()== 1 && 01132 dimension() == -1); 01133 remove_dim_down(v); 01134 return; 01135 } 01136 01137 template <class Vb, class Fb> 01138 inline 01139 typename Triangulation_data_structure_2<Vb,Fb>::Vertex_handle 01140 Triangulation_data_structure_2<Vb,Fb>:: 01141 star_hole(List_edges& hole) 01142 { 01143 Vertex_handle newv = create_vertex(); 01144 star_hole(newv, hole); 01145 return newv; 01146 } 01147 01148 template <class Vb, class Fb> 01149 void 01150 Triangulation_data_structure_2<Vb,Fb>:: 01151 star_hole(Vertex_handle newv, List_edges& hole) 01152 // star the hole represented by hole around newv 01153 // the triangulation is assumed to have dim=2 01154 // hole is supposed to be ccw oriented 01155 { 01156 01157 star_hole(newv, hole.begin(), hole.end()); 01158 return; 01159 } 01160 01161 template <class Vb, class Fb> 01162 void 01163 Triangulation_data_structure_2<Vb,Fb>:: 01164 make_hole(Vertex_handle v, List_edges& hole) 01165 // delete the faces incident to v and v 01166 // and return the dscription of the hole in hole 01167 { 01168 CGAL_triangulation_precondition(dimension() == 2); 01169 std::list<Face_handle> to_delete; 01170 01171 Face_handle f, fn; 01172 int i =0, in =0; 01173 Vertex_handle vv; 01174 01175 Face_circulator fc = incident_faces(v); 01176 Face_circulator done(fc); 01177 do { 01178 f = fc ; 01179 i = f->index(v); 01180 fn = f->neighbor(i); 01181 in = mirror_index(f,i); //fn->index(f); 01182 vv = f->vertex(cw(i)); 01183 if( vv->face()== f) vv->set_face(fn); 01184 vv = fc->vertex(ccw(i)); 01185 if( vv->face()== f) vv->set_face(fn); 01186 fn->set_neighbor(in, Face_handle()); 01187 hole.push_back(Edge(fn,in)); 01188 to_delete.push_back(f); 01189 } 01190 while(++fc != done); 01191 01192 while (! to_delete.empty()){ 01193 delete_face(to_delete.front()); 01194 to_delete.pop_front(); 01195 } 01196 delete_vertex(v); 01197 return; 01198 } 01199 01200 01201 template <class Vb, class Fb> 01202 inline 01203 typename Triangulation_data_structure_2<Vb,Fb>::Vertex_handle 01204 Triangulation_data_structure_2<Vb,Fb>:: 01205 create_vertex(const Vertex &v) 01206 { 01207 return vertices().insert(v); 01208 } 01209 01210 template <class Vb, class Fb> 01211 inline 01212 typename Triangulation_data_structure_2<Vb,Fb>::Vertex_handle 01213 Triangulation_data_structure_2<Vb,Fb>:: 01214 create_vertex(Vertex_handle vh) 01215 { 01216 return vertices().insert(*vh); 01217 } 01218 01219 template <class Vb, class Fb> 01220 typename Triangulation_data_structure_2<Vb,Fb>::Face_handle 01221 Triangulation_data_structure_2<Vb,Fb>:: 01222 create_face(const Face& f) 01223 { 01224 return faces().insert(f); 01225 } 01226 01227 template <class Vb, class Fb> 01228 typename Triangulation_data_structure_2<Vb,Fb>::Face_handle 01229 Triangulation_data_structure_2<Vb,Fb>:: 01230 create_face( Face_handle fh) 01231 { 01232 return create_face(*fh); 01233 } 01234 01235 01236 template <class Vb, class Fb> 01237 typename Triangulation_data_structure_2<Vb,Fb>::Face_handle 01238 Triangulation_data_structure_2<Vb,Fb>:: 01239 create_face(Face_handle f1, int i1, 01240 Face_handle f2, int i2, 01241 Face_handle f3, int i3) 01242 { 01243 Face_handle newf = faces().emplace(f1->vertex(cw(i1)), 01244 f2->vertex(cw(i2)), 01245 f3->vertex(cw(i3)), 01246 f2, f3, f1); 01247 f1->set_neighbor(i1,newf); 01248 f2->set_neighbor(i2,newf); 01249 f3->set_neighbor(i3,newf); 01250 return newf; 01251 } 01252 01253 template <class Vb, class Fb> 01254 typename Triangulation_data_structure_2<Vb,Fb>::Face_handle 01255 Triangulation_data_structure_2<Vb,Fb>:: 01256 create_face(Face_handle f1, int i1, Face_handle f2, int i2) 01257 { 01258 Face_handle newf = faces().emplace(f1->vertex(cw(i1)), 01259 f2->vertex(cw(i2)), 01260 f2->vertex(ccw(i2)), 01261 f2, Face_handle(), f1); 01262 f1->set_neighbor(i1,newf); 01263 f2->set_neighbor(i2,newf); 01264 return newf; 01265 } 01266 01267 template <class Vb, class Fb> 01268 typename Triangulation_data_structure_2<Vb,Fb>::Face_handle 01269 Triangulation_data_structure_2<Vb,Fb>:: 01270 create_face(Face_handle f1, int i1, Vertex_handle v) 01271 { 01272 Face_handle newf = create_face(); 01273 newf->set_vertices(f1->vertex(cw(i1)), f1->vertex(ccw(i1)), v); 01274 newf->set_neighbors(Face_handle(), Face_handle(), f1); 01275 f1->set_neighbor(i1,newf); 01276 return newf; 01277 } 01278 01279 01280 template <class Vb, class Fb> 01281 typename Triangulation_data_structure_2<Vb,Fb>::Face_handle 01282 Triangulation_data_structure_2<Vb,Fb>:: 01283 create_face(Vertex_handle v1, Vertex_handle v2, Vertex_handle v3) 01284 { 01285 Face_handle newf = faces().emplace(v1, v2, v3); 01286 return newf; 01287 } 01288 01289 template <class Vb, class Fb> 01290 typename Triangulation_data_structure_2<Vb,Fb>::Face_handle 01291 Triangulation_data_structure_2<Vb,Fb>:: 01292 create_face(Vertex_handle v1, Vertex_handle v2, Vertex_handle v3, 01293 Face_handle f1, Face_handle f2, Face_handle f3) 01294 { 01295 Face_handle newf = faces().emplace(v1, v2, v3, f1, f2, f3); 01296 01297 return(newf); 01298 } 01299 01300 template <class Vb, class Fb> 01301 inline void 01302 Triangulation_data_structure_2<Vb,Fb>:: 01303 set_adjacency(Face_handle f0, int i0, Face_handle f1, int i1) const 01304 { 01305 CGAL_triangulation_assertion(i0 >= 0 && i0 <= dimension()); 01306 CGAL_triangulation_assertion(i1 >= 0 && i1 <= dimension()); 01307 CGAL_triangulation_assertion(f0 != f1); 01308 f0->set_neighbor(i0,f1); 01309 f1->set_neighbor(i1,f0); 01310 } 01311 01312 template <class Vb, class Fb> 01313 inline void 01314 Triangulation_data_structure_2<Vb,Fb>:: 01315 delete_face(Face_handle f) 01316 { 01317 CGAL_triangulation_expensive_precondition( dimension() != 2 || is_face(f)); 01318 CGAL_triangulation_expensive_precondition( dimension() != 1 || is_edge(f,2)); 01319 CGAL_triangulation_expensive_precondition( dimension() != 0 || 01320 is_vertex(f->vertex(0)) ); 01321 faces().erase(f); 01322 } 01323 01324 template <class Vb, class Fb> 01325 inline void 01326 Triangulation_data_structure_2<Vb,Fb>:: 01327 delete_vertex(Vertex_handle v) 01328 { 01329 CGAL_triangulation_expensive_precondition( is_vertex(v) ); 01330 vertices().erase(v); 01331 } 01332 01333 // split and join operations 01334 01335 template <class Vb, class Fb> 01336 typename Triangulation_data_structure_2<Vb,Fb>::Fourtuple 01337 Triangulation_data_structure_2<Vb,Fb>:: 01338 split_vertex(Vertex_handle v, Face_handle f1, Face_handle g1) 01339 { 01340 /* 01341 // The following method preforms a split operation of the vertex v 01342 // using the faces f1 and g1. The split operation is shown 01343 // below. 01344 // The names of the variables in the method correspond to the 01345 // quantities in the drawings below 01346 // 01347 // The configuration before the split: 01348 // 01349 // cw(i1) v3 ccw(i2) 01350 // *-----*-----* 01351 // / \ | / \ 01352 // / \ f1|f2 / \ 01353 // / \ | / \ 01354 // / \ | / \ 01355 // / \|/v \ 01356 // *-----------*-----------* 01357 // \ /|\ / 01358 // \ / | \ / 01359 // \ / | \ / 01360 // \ / g2|g1 \ / 01361 // \ / | \ / 01362 // *-----*-----* 01363 // ccw(j2) v4 cw(j1) 01364 // 01365 // 01366 // The configuration after the split: 01367 // 01368 // 01369 // cw(i1) v3 ccw(i2) 01370 // *---------*---------* 01371 // / \ / \ / \ 01372 // / \ f1 / \ f2 / \ 01373 // / \ / f \ / \ 01374 // / \ / v2\ / \ 01375 // *---------*---------*---------* 01376 // \ / \v1 / \ / 01377 // \ / \ g / \ / 01378 // \ / g2 \ / g1 \ / 01379 // \ / \ / \ / 01380 // *---------*---------* 01381 // ccw(j2) v4 cw(j1) 01382 // 01383 */ 01384 01385 CGAL_triangulation_expensive_precondition( is_valid() ); 01386 01387 CGAL_triangulation_precondition( dimension() == 2 ); 01388 CGAL_triangulation_precondition( f1 != Face_handle() && f1->has_vertex(v) ); 01389 CGAL_triangulation_precondition( g1 != Face_handle() && g1->has_vertex(v) ); 01390 01391 // 1. first we read some information that we will need 01392 int i1 = f1->index(v); 01393 int j1 = g1->index(v); 01394 Face_handle f2 = f1->neighbor( cw(i1) ); 01395 Face_handle g2 = g1->neighbor( cw(j1) ); 01396 01397 int i2 = f2->index(v); 01398 int j2 = g2->index(v); 01399 01400 Vertex_handle v3 = f1->vertex( ccw(i1) ); 01401 Vertex_handle v4 = g1->vertex( ccw(j1) ); 01402 01403 // lst is the list of faces adjecent to v stored in 01404 // counterclockwise order from g2 to f1) inclusive. 01405 // the list idx contains the indices of v in the 01406 // faces in lst. 01407 std::list<Face_handle> lst; 01408 std::list<int> idx; 01409 01410 Face_circulator fc(v, g1); 01411 Face_handle ff(fc); 01412 while ( ff != f2 ) { 01413 lst.push_back( ff ); 01414 idx.push_back( ff->index(v) ); 01415 fc++; 01416 ff = Face_handle(fc); 01417 } 01418 lst.push_back( ff ); 01419 idx.push_back( ff->index(v) ); 01420 01421 // 2. we create the new vertices and the two new faces 01422 Vertex_handle v1 = v; 01423 Vertex_handle v2 = create_vertex(); 01424 Face_handle f = create_face(v1, v2, v3); 01425 Face_handle g = create_face(v2, v1, v4); 01426 01427 // 3. we update the adjacency information for the new vertices and 01428 // the new faces 01429 f->set_neighbor(0, f2); 01430 f->set_neighbor(1, f1); 01431 f->set_neighbor(2, g); 01432 g->set_neighbor(0, g2); 01433 g->set_neighbor(1, g1); 01434 g->set_neighbor(2, f); 01435 v1->set_face(f); 01436 v2->set_face(g); 01437 01438 // 4. update the vertex for the faces f2 through g1 in 01439 // counterclockwise order 01440 typename std::list<Face_handle>::iterator fit = lst.begin(); 01441 typename std::list<int>::iterator iit = idx.begin(); 01442 for (; fit != lst.end(); ++fit, ++iit) { 01443 (*fit)->set_vertex(*iit, v2); 01444 } 01445 01446 lst.clear(); 01447 idx.clear(); 01448 01449 // 5. make f and g the new neighbors of f1, f2 and g1, g2 01450 // respectively. 01451 f1->set_neighbor( cw(i1), f ); 01452 f2->set_neighbor( ccw(i2), f ); 01453 g1->set_neighbor( cw(j1), g ); 01454 g2->set_neighbor( ccw(j2), g ); 01455 01456 CGAL_triangulation_expensive_postcondition( is_valid() ); 01457 01458 // 6. return the new stuff 01459 return Fourtuple(v1, v2, f, g); 01460 } 01461 01462 template <class Vb, class Fb> 01463 typename Triangulation_data_structure_2<Vb,Fb>::Vertex_handle 01464 Triangulation_data_structure_2<Vb,Fb>:: 01465 join_vertices(Face_handle f, int i, Vertex_handle v) 01466 { 01467 CGAL_triangulation_expensive_precondition( is_valid() ); 01468 CGAL_triangulation_precondition( f != Face_handle() ); 01469 CGAL_triangulation_precondition( i >= 0 && i <= 2 ); 01470 01471 // this methods does the "join"-operation and preserves 01472 // the vertex v among the two vertices that define the edge (f, i) 01473 01474 Vertex_handle v1 = f->vertex( ccw(i) ); 01475 Vertex_handle v2 = f->vertex( cw(i) ); 01476 01477 CGAL_triangulation_precondition( v == v1 || v == v2 ); 01478 01479 if ( v == v2 ) { 01480 return join_vertices(f->neighbor(i), mirror_index(f,i), v); 01481 } 01482 01483 int deg2 = degree(v2); 01484 01485 CGAL_triangulation_precondition( deg2 >= 3 ); 01486 01487 if ( deg2 == 3 ) { 01488 remove_degree_3(v2, f->neighbor(ccw(i))); 01489 return v1; 01490 } 01491 01492 /* 01493 // The following drawing corrsponds to the variables 01494 // used in this part... 01495 // The vertex v1 is returned... 01496 // 01497 // itl i=v3 itr 01498 // *---------*---------* 01499 // \ / \ / 01500 // \ tl / \ tr / 01501 // \ / f \ / 01502 // \ / \ / 01503 // v1=ccw(i) *---------* cw(i)=v2 01504 // / \ / \ 01505 // / \ g / \ 01506 // / bl \ / br \ 01507 // / \ / \ 01508 // *---------*---------* 01509 // ibl j=v4 ibr 01510 // 01511 // The situation after the "join"-operation is as follows: 01512 // 01513 // i 01514 // *-----*-----* 01515 // \ | / 01516 // \ tl|tr / 01517 // \ | / 01518 // \ | / 01519 // \|/ 01520 // * v1 01521 // /|\ 01522 // / | \ 01523 // / | \ 01524 // / bl|br \ 01525 // / | \ 01526 // *-----*-----* 01527 // 01528 */ 01529 01530 // first we register all the needed info 01531 Face_handle g = f->neighbor(i); 01532 int j = mirror_index(f,i); 01533 01534 Face_handle tl = f->neighbor( cw(i) ); 01535 Face_handle tr = f->neighbor( ccw(i) ); 01536 01537 int itl = mirror_index(f, cw(i) ); 01538 int itr = mirror_index(f, ccw(i) ); 01539 01540 Face_handle bl = g->neighbor( ccw(j) ); 01541 Face_handle br = g->neighbor( cw(j) ); 01542 01543 int ibl = mirror_index(g, ccw(j) ); 01544 int ibr = mirror_index(g, cw(j) ); 01545 01546 // we need to store the faces adjacent to v2 as well as the 01547 // indices of v2 w.r.t. these faces, so that afterwards we can set 01548 // v1 to be the vertex for these faces 01549 std::vector<Face_handle> star_faces_of_v2; 01550 std::vector<int> star_indices_of_v2; 01551 Face_circulator fc_start(v2); 01552 Face_circulator fc = fc_start; 01553 01554 do { 01555 Face_handle ff(fc); 01556 star_faces_of_v2.push_back(ff); 01557 star_indices_of_v2.push_back(ff->index(v2)); 01558 ++fc; 01559 } while ( fc != fc_start ); 01560 01561 CGAL_triangulation_assertion( int(star_faces_of_v2.size()) == deg2 ); 01562 01563 // from this point and on we modify the values 01564 01565 // first set the neighbors 01566 tl->set_neighbor(itl, tr); 01567 tr->set_neighbor(itr, tl); 01568 01569 bl->set_neighbor(ibl, br); 01570 br->set_neighbor(ibr, bl); 01571 01572 // make sure that all the faces containing v2 as a vertex, now 01573 // contain v1 01574 for (unsigned int k = 0; k < star_faces_of_v2.size(); k++) { 01575 int id = star_indices_of_v2[k]; 01576 CGAL_triangulation_assertion( star_faces_of_v2[k]->vertex(id) == v2 ); 01577 star_faces_of_v2[k]->set_vertex( id, v1 ); 01578 } 01579 01580 // then make sure that all the vertices have correct pointers to 01581 // faces 01582 Vertex_handle v3 = f->vertex(i); 01583 Vertex_handle v4 = g->vertex(j); 01584 if ( v3->face() == f ) v3->set_face(tr); 01585 if ( v4->face() == g ) v4->set_face(br); 01586 if ( v1->face() == f || v1->face() == g ) v1->set_face(tl); 01587 01588 01589 #ifndef CGAL_NO_ASSERTIONS 01590 for (Face_iterator fit = faces_begin(); fit != faces_end(); ++fit) { 01591 int id; 01592 CGAL_triangulation_assertion( !fit->has_vertex(v2, id) ); 01593 } 01594 #endif 01595 01596 // memory management 01597 star_faces_of_v2.clear(); 01598 star_indices_of_v2.clear(); 01599 01600 delete_face(f); 01601 delete_face(g); 01602 01603 delete_vertex(v2); 01604 01605 CGAL_triangulation_expensive_postcondition( is_valid() ); 01606 01607 return v1; 01608 } 01609 01610 // insert_degree_2 and remove_degree_2 operations 01611 template <class Vb, class Fb> 01612 typename Triangulation_data_structure_2<Vb,Fb>::Vertex_handle 01613 Triangulation_data_structure_2<Vb,Fb>:: 01614 insert_degree_2(Face_handle f, int i) 01615 { 01616 /* 01617 // This method basically does the following transformation 01618 // The remove_degree_2 method performs the same operation in the 01619 // opposite direction 01620 // 01621 // 01622 // * 01623 // i / \ 01624 // * / \ 01625 // / \ / f \ 01626 // / \ / _____ \ 01627 // / f \ / / f1 \ \ 01628 // / \ |/ v \| 01629 // v0=ccw(i) *---------* v1=cw(i) ===> v0 *----*----* v1 01630 // \ / |\ f2 /| 01631 // \ g / \ \_____/ / 01632 // \ / \ / 01633 // \ / \ g / 01634 // * \ / 01635 // j \ / 01636 // * 01637 // 01638 */ 01639 01640 Face_handle g = f->neighbor(i); 01641 int j = mirror_index(f,i); 01642 01643 Vertex_handle v = create_vertex(); 01644 01645 Vertex_handle v0 = f->vertex( ccw(i) ); 01646 Vertex_handle v1 = f->vertex( cw(i) ); 01647 01648 Face_handle f_undef; 01649 01650 Face_handle f1 = create_face(v0, v, v1, f_undef, f, f_undef); 01651 Face_handle f2 = create_face(v0, v1, v, f_undef, f_undef, g); 01652 01653 f1->set_neighbor(0, f2); 01654 f1->set_neighbor(2, f2); 01655 01656 f2->set_neighbor(0, f1); 01657 f2->set_neighbor(1, f1); 01658 01659 f->set_neighbor(i, f1); 01660 g->set_neighbor(j, f2); 01661 01662 v->set_face(f1); 01663 01664 return v; 01665 } 01666 01667 template <class Vb, class Fb> 01668 void 01669 Triangulation_data_structure_2<Vb,Fb>:: 01670 remove_degree_2(Vertex_handle v) 01671 { 01672 CGAL_precondition( degree(v) == 2 ); 01673 01674 Face_handle f1 = v->face(); 01675 int i = f1->index(v); 01676 01677 Face_handle f2 = f1->neighbor( ccw(i) ); 01678 int j = f2->index(v); 01679 01680 Face_handle ff1 = f1->neighbor( i ); 01681 Face_handle ff2 = f2->neighbor( j ); 01682 01683 int id1 = mirror_index(f1,i); 01684 int id2 = mirror_index(f2,j); 01685 01686 ff1->set_neighbor(id1, ff2); 01687 ff2->set_neighbor(id2, ff1); 01688 01689 Vertex_handle v1 = f1->vertex( ccw(i) ); 01690 // if ( v1->face() == f1 || v1->face() == f2 ) { 01691 v1->set_face(ff1); 01692 // } 01693 01694 Vertex_handle v2 = f1->vertex( cw(i) ); 01695 // if ( v2->face() == f1 || v2->face() == f2 ) { 01696 v2->set_face(ff2); 01697 // } 01698 01699 delete_face(f1); 01700 delete_face(f2); 01701 01702 delete_vertex(v); 01703 } 01704 01705 // CHECKING 01706 template < class Vb, class Fb> 01707 bool 01708 Triangulation_data_structure_2<Vb,Fb>:: 01709 is_valid(bool verbose, int level) const 01710 { 01711 if(number_of_vertices() == 0){ 01712 return (dimension() == -2); 01713 } 01714 01715 01716 bool result = (dimension()>= -1); 01717 CGAL_triangulation_assertion(result); 01718 01719 //count and test the validity of the faces (for positive dimensions) 01720 Face_iterator ib = face_iterator_base_begin(); 01721 Face_iterator ib_end = face_iterator_base_end(); 01722 size_type count_stored_faces =0; 01723 for ( ; ib != ib_end ; ++ib){ 01724 count_stored_faces += 1; 01725 if (dimension()>= 0) { 01726 result = result && ib->is_valid(verbose,level); 01727 CGAL_triangulation_assertion(result); 01728 } 01729 } 01730 01731 result = result && (count_stored_faces == number_of_full_dim_faces()); 01732 CGAL_triangulation_assertion( 01733 count_stored_faces == number_of_full_dim_faces()); 01734 01735 // vertex count 01736 size_type vertex_count = 0; 01737 for(Vertex_iterator vit = vertices_begin(); vit != vertices_end(); 01738 ++vit) { 01739 CGAL_triangulation_assertion( vit->face() != Face_handle()); 01740 result = result && vit->is_valid(verbose,level); 01741 result = result && (vit == vit->face()->vertex( vit->face()->index(vit))); 01742 CGAL_triangulation_assertion( result ); 01743 ++vertex_count; 01744 } 01745 result = result && (number_of_vertices() == vertex_count); 01746 CGAL_triangulation_assertion( number_of_vertices() == vertex_count ); 01747 01748 //edge count 01749 size_type edge_count = 0; 01750 for(Edge_iterator eit = edges_begin(); eit != edges_end(); ++eit) { 01751 ++edge_count; 01752 } 01753 01754 // face count 01755 size_type face_count = 0; 01756 for(Face_iterator fit = faces_begin(); fit != faces_end(); ++fit) { 01757 ++face_count; 01758 } 01759 01760 switch(dimension()) { 01761 case -1: 01762 result = result && vertex_count == 1 && face_count == 0 01763 && edge_count == 0; 01764 CGAL_triangulation_assertion(result); 01765 break; 01766 case 0: 01767 result = result && vertex_count == 2 && face_count == 0 01768 && edge_count == 0; 01769 CGAL_triangulation_assertion(result); 01770 break; 01771 case 1: 01772 result = result && edge_count == vertex_count; 01773 CGAL_triangulation_assertion(result); 01774 result = result && face_count == 0; 01775 CGAL_triangulation_assertion(result); 01776 break; 01777 case 2: 01778 result = result && edge_count == 3*face_count/2 ; 01779 CGAL_triangulation_assertion(edge_count == 3*face_count/2); 01780 break; 01781 default: 01782 result = false; 01783 CGAL_triangulation_assertion(result); 01784 } 01785 return result; 01786 } 01787 01788 template < class Vb, class Fb> 01789 typename Triangulation_data_structure_2<Vb,Fb>::Vertex_handle 01790 Triangulation_data_structure_2<Vb,Fb>:: 01791 copy_tds(const Tds &tds, Vertex_handle vh) 01792 // return the vertex corresponding to vh in the new tds 01793 { 01794 if (this == &tds) return Vertex_handle(); 01795 if (vh != Vertex_handle()) 01796 CGAL_triangulation_precondition( tds.is_vertex(vh)); 01797 01798 clear(); 01799 size_type n = tds.number_of_vertices(); 01800 set_dimension(tds.dimension()); 01801 01802 // Number of pointers to cell/vertex to copy per cell. 01803 int dim = (std::max)(1, dimension() + 1); 01804 01805 if(n == 0) {return Vertex_handle();} 01806 01807 //initializes maps 01808 std::map<Vertex_handle,Vertex_handle> vmap; 01809 std::map<Face_handle,Face_handle> fmap; 01810 01811 // create vertices 01812 Vertex_iterator vit1 = tds.vertices_begin(); 01813 for( ; vit1 != tds.vertices_end(); ++vit1) { 01814 vmap[vit1] = create_vertex(vit1); 01815 } 01816 01817 //create faces 01818 Face_iterator fit1 = tds.faces().begin(); 01819 for( ; fit1 != tds.faces_end(); ++fit1) { 01820 fmap[fit1] = create_face(fit1); 01821 } 01822 01823 //link vertices to a cell 01824 vit1 = tds.vertices_begin(); 01825 for ( ; vit1 != tds.vertices_end(); vit1++) { 01826 vmap[vit1]->set_face(fmap[vit1->face()]); 01827 } 01828 01829 //update vertices and neighbor pointers 01830 fit1 = tds.faces().begin(); 01831 for ( ; fit1 != tds.faces_end(); ++fit1) { 01832 for (int j = 0; j < dim ; ++j) { 01833 fmap[fit1]->set_vertex(j, vmap[fit1->vertex(j)] ); 01834 fmap[fit1]->set_neighbor(j, fmap[fit1->neighbor(j)]); 01835 } 01836 } 01837 01838 // remove the post condition because it is false when copying the 01839 // TDS of a regular triangulation because of hidden vertices 01840 // CGAL_triangulation_postcondition( is_valid() ); 01841 return (vh == Vertex_handle()) ? Vertex_handle() : vmap[vh]; 01842 } 01843 01844 01845 template < class Vb, class Fb> 01846 void 01847 Triangulation_data_structure_2<Vb,Fb>:: 01848 file_output( std::ostream& os, Vertex_handle v, bool skip_first) const 01849 { 01850 // ouput to a file 01851 // if non NULL, v is the vertex to be output first 01852 // if skip_first is true, the point in the first vertex is not output 01853 // (it may be for instance the infinite vertex of the triangulation) 01854 01855 size_type n = number_of_vertices(); 01856 size_type m = number_of_full_dim_faces(); 01857 if(is_ascii(os)) os << n << ' ' << m << ' ' << dimension() << std::endl; 01858 else os << n << m << dimension(); 01859 if (n==0) return; 01860 01861 std::map<Vertex_handle,int> V; 01862 std::map<Face_handle,int> F; 01863 01864 // first vertex 01865 int inum = 0; 01866 if ( v != Vertex_handle()) { 01867 V[v] = inum++; 01868 if( ! skip_first){ 01869 // os << v->point(); 01870 os << *v ; 01871 if(is_ascii(os)) os << std::endl; 01872 } 01873 } 01874 01875 // other vertices 01876 for( Vertex_iterator vit= vertices_begin(); vit != vertices_end() ; ++vit) { 01877 if ( v != vit ) { 01878 V[vit] = inum++; 01879 // os << vit->point(); 01880 os << *vit; 01881 if(is_ascii(os)) os << "\n"; 01882 } 01883 } 01884 if(is_ascii(os)) os << "\n"; 01885 01886 // vertices of the faces 01887 inum = 0; 01888 int dim = (dimension() == -1 ? 1 : dimension() + 1); 01889 for( Face_iterator ib = face_iterator_base_begin(); 01890 ib != face_iterator_base_end(); ++ib) { 01891 F[ib] = inum++; 01892 for(int j = 0; j < dim ; ++j) { 01893 os << V[ib->vertex(j)]; 01894 if(is_ascii(os)) os << " "; 01895 } 01896 os << *ib ; 01897 if(is_ascii(os)) os << "\n"; 01898 } 01899 if(is_ascii(os)) os << "\n"; 01900 01901 // neighbor pointers of the faces 01902 for( Face_iterator it = face_iterator_base_begin(); 01903 it != face_iterator_base_end(); ++it) { 01904 for(int j = 0; j < dimension()+1; ++j){ 01905 os << F[it->neighbor(j)]; 01906 if(is_ascii(os)) os << " "; 01907 } 01908 if(is_ascii(os)) os << "\n"; 01909 } 01910 01911 return ; 01912 } 01913 01914 01915 template < class Vb, class Fb> 01916 typename Triangulation_data_structure_2<Vb,Fb>::Vertex_handle 01917 Triangulation_data_structure_2<Vb,Fb>:: 01918 file_input( std::istream& is, bool skip_first) 01919 { 01920 //input from file 01921 //return a pointer to the first input vertex 01922 // if skip_first is true, a first vertex is added (infinite_vertex) 01923 //set this first vertex as infinite_Vertex 01924 if(number_of_vertices() != 0) clear(); 01925 01926 size_type n, m; 01927 int d; 01928 is >> n >> m >> d; 01929 01930 if (n==0){ return Vertex_handle();} 01931 01932 set_dimension(d); 01933 01934 std::vector<Vertex_handle > V(n); 01935 std::vector<Face_handle> F(m); 01936 01937 // read vertices 01938 size_type i = 0; 01939 if(skip_first){ 01940 V[0] = create_vertex(); 01941 ++i; 01942 } 01943 for( ; i < n; ++i) { 01944 V[i] = create_vertex(); 01945 is >> *(V[i]); 01946 } 01947 01948 // Creation of the faces 01949 int index; 01950 int dim = (dimension() == -1 ? 1 : dimension() + 1); 01951 { 01952 for(i = 0; i < m; ++i) { 01953 F[i] = create_face() ; 01954 for(int j = 0; j < dim ; ++j){ 01955 is >> index; 01956 F[i]->set_vertex(j, V[index]); 01957 // The face pointer of vertices is set too often, 01958 // but otherwise we had to use a further map 01959 V[index]->set_face(F[i]); 01960 } 01961 // read in non combinatorial info of the face 01962 is >> *(F[i]) ; 01963 } 01964 } 01965 01966 // Setting the neighbor pointers 01967 { 01968 for(i = 0; i < m; ++i) { 01969 for(int j = 0; j < dimension()+1; ++j){ 01970 is >> index; 01971 F[i]->set_neighbor(j, F[index]); 01972 } 01973 } 01974 } 01975 01976 return V[0]; 01977 } 01978 01979 01980 template < class Vb, class Fb> 01981 void 01982 Triangulation_data_structure_2<Vb,Fb>:: 01983 vrml_output( std::ostream& os, Vertex_handle v, bool skip_infinite) const 01984 { 01985 // ouput to a vrml file style 01986 // Point are assumed to be 3d points with a stream oprator << 01987 // if non NULL, v is the vertex to be output first 01988 // if skip_inf is true, the point in the first vertex is not output 01989 // and the faces incident to v are not output 01990 // (it may be for instance the infinite vertex of the terrain) 01991 os << "#VRML V2.0 utf8" << std::endl; 01992 os << "Shape {" << std::endl; 01993 os << "\tgeometry IndexedFaceSet {" << std::endl; 01994 os << "\t\tcoord Coordinate {" << std::endl; 01995 os << "\t\t\tpoint [" << std::endl; 01996 01997 std::map<Vertex_handle,int> vmap; 01998 Vertex_iterator vit; 01999 Face_iterator fit; 02000 02001 //first vertex 02002 int inum = 0; 02003 if ( v != Vertex_handle()) { 02004 vmap[v] = inum++; 02005 if( ! skip_infinite) os << "\t\t\t\t" << *v << std::endl; 02006 } 02007 02008 //other vertices 02009 for( vit= vertices_begin(); vit != vertices_end() ; ++vit) { 02010 if ( v != vit) { 02011 vmap[vit] = inum++; 02012 os << "\t\t\t\t" << *vit << std::endl; 02013 } 02014 } 02015 02016 os << "\t\t\t]" << std::endl; 02017 os << "\t\t}" << std::endl; 02018 os << "\t\tcoordIndex [" << std::endl; 02019 02020 // faces 02021 for(fit= faces_begin(); fit != faces_end(); ++fit) { 02022 if (!skip_infinite || !fit->has_vertex(v)) { 02023 os << "\t\t\t"; 02024 os << vmap[(*fit).vertex(0)] << ", "; 02025 os << vmap[(*fit).vertex(1)] << ", "; 02026 os << vmap[(*fit).vertex(2)] << ", "; 02027 os << "-1, " << std::endl; 02028 } 02029 } 02030 os << "\t\t]" << std::endl; 02031 os << "\t}" << std::endl; 02032 os << "}" << std::endl; 02033 return; 02034 } 02035 02036 template < class Vb, class Fb> 02037 typename Triangulation_data_structure_2<Vb,Fb>::Vertex_handle 02038 Triangulation_data_structure_2<Vb,Fb>:: 02039 off_file_input( std::istream& is, bool verbose) 02040 { 02041 // input from an OFF file 02042 // assume a dimension 2 triangulation 02043 // create an infinite-vertex and infinite faces with the 02044 // boundary edges if any. 02045 // return the infinite vertex if created 02046 Vertex_handle vinf; 02047 File_scanner_OFF scanner(is, verbose); 02048 if (! is) { 02049 if (scanner.verbose()) { 02050 std::cerr << " " << std::endl; 02051 std::cerr << "TDS::off_file_input" << std::endl; 02052 std::cerr << " input error: file format is not OFF." << std::endl; 02053 } 02054 return vinf; 02055 } 02056 02057 if(number_of_vertices() != 0) clear(); 02058 int dim = 2; 02059 set_dimension(dim); 02060 02061 std::vector<Vertex_handle > vvh(scanner.size_of_vertices()); 02062 std::map<Vh_pair, Edge> edge_map; 02063 typedef typename Vb::Point Point; 02064 02065 // read vertices 02066 int i; 02067 for ( i = 0; i < scanner.size_of_vertices(); i++) { 02068 Point p; 02069 file_scan_vertex( scanner, p); 02070 vvh[i] = create_vertex(); 02071 vvh[i]->set_point(p); 02072 scanner.skip_to_next_vertex( i); 02073 } 02074 if ( ! is ) { 02075 is.clear( std::ios::badbit); 02076 return vinf; 02077 } 02078 //vinf = vvh[0]; 02079 02080 // create the facets 02081 for ( i = 0; i < scanner.size_of_facets(); i++) { 02082 Face_handle fh = create_face(); 02083 Integer32 no; 02084 scanner.scan_facet( no, i); 02085 if( ! is || no != 3) { 02086 if ( scanner.verbose()) { 02087 std::cerr << " " << std::endl; 02088 std::cerr << "TDS::off_file_input" << std::endl; 02089 std::cerr << "facet " << i << "does not have 3 vertices." 02090 << std::endl; 02091 } 02092 is.clear( std::ios::badbit); 02093 return vinf; 02094 } 02095 02096 for ( int j = 0; j < no; ++j) { 02097 Integer32 index; 02098 scanner.scan_facet_vertex_index( index, i); 02099 fh->set_vertex(j, vvh[index]); 02100 vvh[index]->set_face(fh); 02101 } 02102 02103 for (int ih = 0; ih < no; ++ih) { 02104 set_adjacency(fh, ih, edge_map); 02105 } 02106 } 02107 02108 // deal with boundaries 02109 if ( !edge_map.empty()) { 02110 vinf = create_vertex(); 02111 std::map<Vh_pair, Edge> inf_edge_map; 02112 while (!edge_map.empty()) { 02113 Face_handle fh = edge_map.begin()->second.first; 02114 int ih = edge_map.begin()->second.second; 02115 Face_handle fn = create_face( vinf, 02116 fh->vertex(cw(ih)), 02117 fh->vertex(ccw(ih))); 02118 vinf->set_face(fn); 02119 set_adjacency(fn, 0, fh, ih); 02120 set_adjacency(fn, 1, inf_edge_map); 02121 set_adjacency(fn, 2, inf_edge_map); 02122 edge_map.erase(edge_map.begin()); 02123 } 02124 CGAL_triangulation_assertion(inf_edge_map.empty()); 02125 } 02126 02127 02128 // coherent orientation 02129 reorient_faces(); 02130 return vinf; 02131 } 02132 02133 02134 template < class Vb, class Fb> 02135 void 02136 Triangulation_data_structure_2<Vb,Fb>:: 02137 set_adjacency(Face_handle fh, 02138 int ih, 02139 std::map< Vh_pair, Edge>& edge_map) 02140 { 02141 // set adjacency to (fh,ih) using the the map edge_map 02142 // or insert (fh,ih) in edge map 02143 Vertex_handle vhcw = fh->vertex(cw(ih)); 02144 Vertex_handle vhccw = fh->vertex(ccw(ih)); 02145 Vh_pair vhp = vhcw < vhccw ? 02146 std::make_pair(vhcw, vhccw) 02147 : std::make_pair(vhccw, vhcw) ; 02148 typename std::map<Vh_pair, Edge>::iterator emapit = edge_map.find(vhp); 02149 if (emapit == edge_map.end()) {// not found, insert edge 02150 edge_map.insert(std::make_pair(vhp, Edge(fh,ih))); 02151 } 02152 else { //found set adjacency and erase 02153 Edge e = emapit->second; 02154 set_adjacency( fh,ih, e.first, e.second); 02155 edge_map.erase(emapit); 02156 } 02157 } 02158 02159 02160 02161 template < class Vb, class Fb> 02162 void 02163 Triangulation_data_structure_2<Vb,Fb>:: 02164 reorient_faces() 02165 { 02166 // reorient the faces of a triangulation 02167 // needed for example in off_file_input 02168 // because the genus is not known, the number of faces 02169 std::set<Face_handle> oriented_set; 02170 std::stack<Face_handle> st; 02171 Face_iterator fit = faces_begin(); 02172 int nf = std::distance(faces_begin(),faces_end()); 02173 02174 while (static_cast<int>(oriented_set.size()) != nf) { 02175 while ( oriented_set.find(fit->handle()) != oriented_set.end()){ 02176 ++fit; // find a germ for non oriented components 02177 } 02178 // orient component 02179 oriented_set.insert(fit->handle()); 02180 st.push(fit->handle()); 02181 while ( ! st.empty()) { 02182 Face_handle fh = st.top(); 02183 st.pop(); 02184 for(int ih = 0 ; ih < 3 ; ++ih){ 02185 Face_handle fn = fh->neighbor(ih); 02186 if (oriented_set.find(fn) == oriented_set.end()){ 02187 int in = fn->index(fh); 02188 if (fn->vertex(cw(in)) != fh->vertex(ccw(ih))) fn->reorient(); 02189 oriented_set.insert(fn); 02190 st.push(fn); 02191 } 02192 } 02193 } 02194 02195 } 02196 return; 02197 } 02198 02199 02200 template < class Vb, class Fb> 02201 std::istream& 02202 operator>>(std::istream& is, 02203 Triangulation_data_structure_2<Vb,Fb>& tds) 02204 { 02205 tds.file_input(is); 02206 return is; 02207 } 02208 02209 02210 template < class Vb, class Fb> 02211 std::ostream& 02212 operator<<(std::ostream& os, 02213 const Triangulation_data_structure_2<Vb,Fb> &tds) 02214 { 02215 tds.file_output(os); 02216 return os; 02217 } 02218 02219 02220 CGAL_END_NAMESPACE 02221 02222 #endif //CGAL_TRIANGULATION_DATA_STRUCTURE_2_H