BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Nef_S2/SM_const_decorator.h
Go to the documentation of this file.
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines