BWAPI
|
00001 // Copyright (c) 1997-2002 Max-Planck-Institute Saarbruecken (Germany). 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/Nef_S2/include/CGAL/Nef_S2/SM_const_decorator.h $ 00015 // $Id: SM_const_decorator.h 40851 2007-11-09 15:27:44Z ameyer $ 00016 // 00017 // 00018 // Author(s) : Michael Seel <seel@mpi-sb.mpg.de> 00019 // Miguel Granados <granados@mpi-sb.mpg.de> 00020 // Susan Hert <hert@mpi-sb.mpg.de> 00021 // Lutz Kettner <kettner@mpi-sb.mpg.de> 00022 // Peter Hachenberger <hachenberger@mpi-sb.mpg.de> 00023 #ifndef CGAL_SM_CONST_DECORATOR_H 00024 #define CGAL_SM_CONST_DECORATOR_H 00025 00026 #include <CGAL/basic.h> 00027 #include <CGAL/circulator.h> 00028 #include <CGAL/Unique_hash_map.h> 00029 #include <CGAL/Nef_2/Object_index.h> 00030 #include <CGAL/Nef_S2/SM_iteration.h> 00031 #include <CGAL/Nef_S2/SM_decorator_traits.h> 00032 #include <string> 00033 #include <list> 00034 #include <sstream> 00035 #undef CGAL_NEF_DEBUG 00036 #define CGAL_NEF_DEBUG 67 00037 #include <CGAL/Nef_2/debug.h> 00038 00039 CGAL_BEGIN_NAMESPACE 00040 00041 template <typename Map_> 00042 class SM_const_decorator { 00043 00044 typedef SM_const_decorator<Map_> Self; 00045 public: 00046 00047 typedef Map_ Map; 00048 typedef const Map_ Sphere_map; 00049 typedef SM_decorator_const_traits<Map> Decorator_traits; 00050 00051 /*{\Mdefinition ...}*/ 00052 00053 /*{\Mtypes 5}*/ 00054 00055 typedef typename Map::Sphere_kernel Sphere_kernel; 00056 /*{\Mtypemember spherical geometry.}*/ 00057 00058 typedef typename Map::Sphere_point Sphere_point; 00059 /*{\Mtypemember embedding vertices.}*/ 00060 00061 typedef typename Map::Sphere_segment Sphere_segment; 00062 /*{\Mtypemember embedding edges.}*/ 00063 00064 typedef typename Map::Sphere_circle Sphere_circle; 00065 /*{\Mtypemember embedding loops.}*/ 00066 00067 typedef typename Map::Sphere_direction Sphere_direction; 00068 /*{\Mtypemember embedding directions.}*/ 00069 00070 typedef typename Map::Mark Mark; 00071 /*{\Mtypemember attributes of objects (vertices, edges, faces).}*/ 00072 00073 typedef size_t Size_type; 00074 /*{\Mtypemember size type.}*/ 00075 00076 typedef void* GenPtr; 00077 00078 // typedef typename Map::Constructor_const_parameter Constructor_parameter; 00079 typedef typename Map::SVertex_const_handle SVertex_const_handle; 00080 typedef typename Map::SVertex_const_iterator SVertex_const_iterator; 00081 typedef typename Map::SHalfedge_const_handle SHalfedge_const_handle; 00082 typedef typename Map::SHalfedge_const_iterator SHalfedge_const_iterator; 00083 typedef typename Map::SHalfloop_const_handle SHalfloop_const_handle; 00084 typedef typename Map::SHalfloop_const_iterator SHalfloop_const_iterator; 00085 typedef typename Map::SFace_const_handle SFace_const_handle; 00086 typedef typename Map::SFace_const_iterator SFace_const_iterator; 00087 00088 /*{\Mtext Local types are handles, iterators and circulators of the 00089 following kind: |SVertex_handle|, |SVertex_iterator|, |SHalfedge_handle|, 00090 |SHalfedge_iterator|, |SHalfloop_handle|, |SHalfloop_iterator|, 00091 |SFace_handle|, |SFace_iterator|. Additionally the following 00092 circulators are defined.}*/ 00093 00094 typedef typename Map::SHalfedge_around_svertex_const_circulator 00095 SHalfedge_around_svertex_const_circulator; 00096 /*{\Mtypemember circulating the adjacency list of an vertex |v|.}*/ 00097 00098 typedef typename Map::SHalfedge_around_sface_const_circulator 00099 SHalfedge_around_sface_const_circulator; 00100 /*{\Mtypemember circulating the face cycle of an face |f|.}*/ 00101 00102 typedef typename Map::SFace_cycle_const_iterator 00103 SFace_cycle_const_iterator; 00104 /*{\Mtypemember iterating all sface cycles of an sface |f|. 00105 The iterator has method |bool is_svertex()|, |bool is_shalfedge()|, 00106 |bool is_shalfloop()|, and can be converted to the corresponding 00107 handles |SVertex_const_handle|, |SHalfedge_const_handle|, or 00108 |SHalfloop_const_handle|.}*/ 00109 00110 protected: 00111 const Map* psm_; 00112 00113 void set_sm(const Map* W) { 00114 psm_ = W; 00115 } 00116 00117 public: 00118 00119 /*{\Mcreation 3}*/ 00120 SM_const_decorator() : psm_(0) {} 00121 SM_const_decorator(const Self& D) : psm_(D.psm_) {} 00122 Self& operator=(const Self& D) { psm_=D.psm_; return *this; } 00123 00124 SM_const_decorator(const Map* M) : psm_(M) {} 00125 /*{\Mcreate constructs a plane map decorator exploring |M|.}*/ 00126 00127 /*{\Moperations 4 4}*/ 00128 00129 const Map* sphere_map() const { return psm_; } 00130 00131 bool is_isolated(SVertex_const_handle v) const 00132 /*{\Mop returns |true| when |v| is linked to the interior of a face.}*/ 00133 { return (SHalfedge_const_handle(v->out_sedge()) == SHalfedge_const_handle()); } 00134 00135 SHalfedge_const_handle first_out_edge(SVertex_const_handle v) const 00136 /*{\Mop returns one edge with source |v|. It's the starting point for 00137 the circular iteration over the edges with source |v|. 00138 \precond |!is_isolated(v)|.}*/ 00139 { return v->out_sedge(); } 00140 00141 SHalfedge_const_handle last_out_edge(SVertex_const_handle v) const 00142 /*{\Mop returns one edge with source |v|. \precond |!is_isolated(v)|.}*/ 00143 { return cap(v->out_sedge()); } 00144 00145 SHalfedge_const_handle cyclic_adj_succ(SHalfedge_const_handle e) const 00146 /*{\Mop returns the edge after |e| in the cyclic ordered adjacency list of 00147 |e->source()|.}*/ 00148 { return e->sprev()->twin(); } 00149 00150 SHalfedge_const_handle cyclic_adj_pred(SHalfedge_const_handle e) const 00151 /*{\Mop returns the edge before |e| in the cyclic ordered adjacency list of 00152 |e->source()|.}*/ 00153 { return e->twin()->snext(); } 00154 00155 00156 /*{\Mtext \headerline{Iteration} \setopdims{3.3cm}{0cm}}*/ 00157 00158 SVertex_const_iterator svertices_begin() const 00159 { return psm_->svertices_begin(); } 00160 SVertex_const_iterator svertices_end() const 00161 { return psm_->svertices_end(); } 00162 SHalfedge_const_iterator shalfedges_begin() const 00163 { return psm_->shalfedges_begin(); } 00164 SHalfedge_const_iterator shalfedges_end() const 00165 { return psm_->shalfedges_end(); } 00166 SFace_const_iterator sfaces_begin() const 00167 { return psm_->sfaces_begin(); } 00168 SFace_const_iterator sfaces_end() const 00169 { return psm_->sfaces_end(); } 00170 SHalfloop_const_iterator shalfloops_begin() const 00171 { return psm_->shalfloops_begin(); } 00172 SHalfloop_const_iterator shalfloops_end() const 00173 { return psm_->shalfloops_end(); } 00174 00175 SHalfloop_const_handle shalfloop() const 00176 /*{\Mop returns access to the loop.}*/ 00177 { return psm_->shalfloop(); } 00178 00179 bool has_shalfloop() const 00180 /*{\Mop returns true iff there is a loop.}*/ 00181 { return psm_->has_shalfloop(); } 00182 00183 SHalfedge_around_svertex_const_circulator 00184 out_edges(SVertex_const_handle v) const 00185 /*{\Mop returns a circulator for the cyclic adjacency list of |v|. 00186 \precond the adjacency list is not empty.}*/ 00187 { return SHalfedge_around_svertex_const_circulator(first_out_edge(v)); } 00188 00189 SFace_cycle_const_iterator sface_cycles_begin(SFace_const_handle f) const 00190 /*{\Mop returns an iterator for all bounding face cycles of |f|. 00191 The iterator is is convertable to |SVertex_const_handle|, 00192 |SHalfloop_const_handle|, or |SHalfedge_const_handle|.}*/ 00193 { return f->boundary_entry_objects_.begin(); } 00194 00195 SFace_cycle_const_iterator sface_cycles_end(SFace_const_handle f) const 00196 /*{\Mop returns the past the end iterator of |f|.}*/ 00197 { return f->boundary_entry_objects_.end(); } 00198 00199 /*{\Mtext \headerline{Statistics and Integrity}}*/ 00200 00201 Size_type number_of_svertices() const 00202 /*{\Mop returns the number of vertices.}*/ 00203 { return psm_->number_of_svertices(); } 00204 00205 Size_type number_of_shalfedges() const 00206 /*{\Mop returns the number of halfedges.}*/ 00207 { return psm_->number_of_shalfedges(); } 00208 00209 Size_type number_of_sedges() const 00210 /*{\Mop returns the number of edges.}*/ 00211 { return number_of_shalfedges()/2; } 00212 00213 Size_type number_of_shalfloops() const 00214 /*{\Mop returns the number of halfloops.}*/ 00215 { return psm_->number_of_shalfloops(); } 00216 00217 Size_type number_of_sloops() const 00218 /*{\Mop returns the number of loops.}*/ 00219 { return psm_->number_of_shalfloops()/2; } 00220 00221 Size_type number_of_sfaces() const 00222 /*{\Mop returns the number of faces.}*/ 00223 { return psm_->number_of_sfaces(); } 00224 00225 Size_type number_of_sface_cycles() const; 00226 /*{\Mop returns the number of face cycles.}*/ 00227 00228 Size_type number_of_connected_components() const; 00229 /*{\Mop calculates the number of connected components of |P|.}*/ 00230 00231 void print_statistics(std::ostream& os = std::cout) const 00232 /*{\Mop print the statistics of |P|: the number of vertices, edges, 00233 and faces.}*/ 00234 { 00235 os << "Sphere Map - Statistics\n"; 00236 os << "|V| = " << number_of_svertices() << std::endl; 00237 os << "|E| = " << number_of_shalfedges() << std::endl; 00238 os << "|L| = " << number_of_shalfloops() << std::endl; 00239 os << "|F| = " << number_of_sfaces() << std::endl; 00240 os << "|Fcs| = " << number_of_sface_cycles() << std::endl << std::endl; 00241 } 00242 00243 void check_integrity_and_topological_planarity(bool faces=true) const; 00244 /*{\Mop checks the link structure and the genus of |P|.}*/ 00245 00246 SHalfedge_const_handle cas(SHalfedge_const_handle e) const 00247 { return cyclic_adj_succ(e); } 00248 00249 SHalfedge_const_handle cap(SHalfedge_const_handle e) const 00250 { return cyclic_adj_pred(e); } 00251 00252 template <typename H> 00253 bool is_sm_boundary_object(H h) const 00254 { return psm_->is_sm_boundary_object(h); } 00255 00256 /*{\Mtext \headerline{Associated Information}\restoreopdims}*/ 00257 00258 /*{\Mtext \headerline{Iteration}}*/ 00259 /*{\Mtext The list of all objects can be accessed via iterator ranges. 00260 For comfortable iteration we also provide iterations macros. 00261 The iterator range access operations are of the following kind:\\ 00262 |SVertex_iterator svertices_begin()/svertices_end()|\\ 00263 |SHalfedge_iterator shalfedges_begin()/shalfedges_end()|\\ 00264 |SHalfloop_iterator shalfloops_begin()/shalfloops_end()|\\ 00265 |SFace_iterator sfaces_begin()/sfaces_end()| 00266 00267 The macros are then |CGAL_forall_svertices(v,M)|, 00268 |CGAL_forall_shalfedges(e,M)|, |CGAL_forall_sedges(e,M)|, 00269 |CGAL_forall_sfaces(f,M)|, |CGAL_forall_sface_cycles_of(fc,F)| 00270 where |M| is a sphere map and |F| is a sface.}*/ 00271 00272 }; // SM_const_decorator 00273 00274 00275 00276 template <typename SM_> 00277 void SM_const_decorator<SM_>:: 00278 check_integrity_and_topological_planarity(bool faces) const 00279 { 00280 CGAL_NEF_TRACEN("check_integrity_and_topological_planarity:"); 00281 using CGAL::Object_index; 00282 Object_index<SVertex_const_iterator> 00283 VI(svertices_begin(),svertices_end(),'v'); 00284 Object_index<SHalfedge_const_iterator> 00285 EI(shalfedges_begin(),shalfedges_end(),'e'); 00286 Object_index<SFace_const_iterator> 00287 FI(sfaces_begin(),sfaces_end(),'f'); 00288 typedef SHalfedge_around_svertex_const_circulator hvc_circulator; 00289 typedef SHalfedge_around_sface_const_circulator hfc_circulator; 00290 SVertex_const_handle v; 00291 int iso_vert_num=0; 00292 /* check the source links of out edges and count isolated vertices */ 00293 CGAL_forall_svertices(v,*this) { 00294 if ( is_isolated(v) ) { 00295 if ( faces ) 00296 CGAL_assertion_msg(v->incident_sface() != SFace_const_handle(), VI(v).c_str()); 00297 ++iso_vert_num; 00298 } else { 00299 CGAL_assertion_msg(first_out_edge(v) != SHalfedge_const_handle(), 00300 VI(v).c_str()); 00301 CGAL_NEF_TRACEN(v->point()<<" "<<EI(first_out_edge(v))); 00302 CGAL_assertion_msg(first_out_edge(v)->source() == v, 00303 VI(v).c_str()); 00304 } 00305 } 00306 00307 /* check the bidirected links and the face pointer init */ 00308 SHalfedge_const_iterator e; 00309 CGAL_forall_shalfedges(e,*this) { 00310 CGAL_assertion( e->twin()->twin() == e ); 00311 CGAL_assertion( e->source() != SVertex_const_handle() ); 00312 CGAL_assertion( e->snext() != SHalfedge_const_handle() ); 00313 CGAL_assertion( e->snext()->sprev() == e ); 00314 CGAL_assertion( e->target() == e->snext()->source() ); 00315 CGAL_assertion( e->sprev() != SHalfedge_const_handle() ); 00316 CGAL_assertion( e->sprev()->snext() == e ); 00317 CGAL_assertion( e->sprev()->twin()->source() == e->source() ); 00318 if ( !faces ) continue; 00319 CGAL_assertion( e->incident_sface() != SFace_const_handle() ); 00320 CGAL_assertion( e->snext()->incident_sface() == e->incident_sface() ); 00321 CGAL_assertion( e->sprev()->incident_sface() == e->incident_sface() ); 00322 } 00323 00324 int fc_num(0),iv_num(0); 00325 SFace_const_iterator f; 00326 SFace_cycle_const_iterator fci; 00327 CGAL_forall_sfaces(f,*this) { 00328 CGAL_forall_sface_cycles_of(fci,f) { 00329 if ( fci.is_shalfedge() ) { 00330 CGAL_assertion( SHalfedge_const_handle(fci)->incident_sface() == f ); 00331 ++fc_num; 00332 } else if ( fci.is_svertex() ) { 00333 CGAL_assertion( SVertex_const_handle(fci)->incident_sface() == f ); 00334 ++iv_num; 00335 } else if( fci.is_shalfloop() ) { 00336 CGAL_assertion( SHalfloop_const_handle(fci)->incident_sface() == f ); 00337 ++fc_num; 00338 } else CGAL_error_msg("damn generic handle."); 00339 } 00340 } 00341 00342 CGAL_assertion_code(int v_num = number_of_svertices() - 00343 iso_vert_num + 00344 number_of_shalfloops()); 00345 CGAL_assertion_code(int e_num = number_of_sedges() + 00346 number_of_shalfloops()); 00347 CGAL_assertion_code(int c_num = number_of_connected_components() - 00348 iso_vert_num 00349 + number_of_sloops()); 00350 CGAL_assertion_code(int f_num = number_of_sface_cycles() - c_num + 1); 00351 CGAL_assertion_code(CGAL_NEF_TRACEV(fc_num)); 00352 CGAL_assertion_code(CGAL_NEF_TRACEV(iv_num)); 00353 CGAL_assertion_code(CGAL_NEF_TRACEV(iso_vert_num)); 00354 CGAL_assertion_code(CGAL_NEF_TRACEV(v_num)); 00355 CGAL_assertion_code(CGAL_NEF_TRACEV(e_num)); 00356 CGAL_assertion_code(CGAL_NEF_TRACEV(c_num)); 00357 CGAL_assertion_code(CGAL_NEF_TRACEV(f_num)); 00358 /* this means all face cycles and all isolated vertices are 00359 indeed referenced from a face */ 00360 /* every isolated vertex increases the component count 00361 one face cycle per component is redundent except one 00362 finally check the Euler formula: */ 00363 CGAL_assertion( v_num - e_num + f_num == 1 + c_num ); 00364 } 00365 00366 template <typename SM_> 00367 typename SM_const_decorator<SM_>::Size_type 00368 SM_const_decorator<SM_>:: 00369 number_of_sface_cycles() const 00370 { 00371 unsigned int fc_num=0; 00372 CGAL::Unique_hash_map<SHalfedge_const_handle,bool> visited; 00373 SHalfedge_const_iterator e; 00374 CGAL_forall_shalfedges(e,*this) { 00375 if (visited[e]) continue; 00376 SHalfedge_around_sface_const_circulator hfc(e), hend(hfc); 00377 CGAL_For_all(hfc,hend) visited[hfc]=true; 00378 ++fc_num; 00379 } 00380 if ( has_shalfloop() ) fc_num += 2; 00381 return fc_num; 00382 } 00383 00384 template <typename SM_> 00385 typename SM_const_decorator<SM_>::Size_type 00386 SM_const_decorator<SM_>:: 00387 number_of_connected_components() const 00388 { 00389 int comp_num=0; 00390 CGAL::Unique_hash_map<SVertex_const_iterator,bool> visited(false); 00391 SVertex_const_iterator v; 00392 CGAL_forall_svertices(v,*this) { 00393 if (visited[v]) continue; 00394 std::list<SVertex_const_iterator> L; 00395 L.push_back(v); visited[v]=true; 00396 /* we keep the invariant that all nodes which have been stacked 00397 are marked visited */ 00398 while (!L.empty()) { 00399 SVertex_const_iterator vc = L.front(); L.pop_front(); 00400 if ( is_isolated(vc) ) continue; 00401 SHalfedge_around_svertex_const_circulator 00402 havc(first_out_edge(vc)), hend(havc); 00403 CGAL_For_all(havc,hend) { 00404 if (!visited[havc->target()]) { 00405 L.push_back(havc->target()); visited[havc->target()]=true; 00406 } 00407 } 00408 } 00409 ++comp_num; 00410 } 00411 return comp_num; 00412 } 00413 00414 CGAL_END_NAMESPACE 00415 #endif // CGAL_SM_CONST_DECORATOR_H 00416