BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Nef_2/PM_const_decorator.h
Go to the documentation of this file.
00001 // Copyright (c) 1997-2000  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_2/include/CGAL/Nef_2/PM_const_decorator.h $
00015 // $Id: PM_const_decorator.h 28567 2006-02-16 14:30:13Z lsaboret $
00016 // 
00017 //
00018 // Author(s)     : Michael Seel <seel@mpi-sb.mpg.de>
00019 
00020 #ifndef CGAL_PM_CONST_DECORATOR_H
00021 #define CGAL_PM_CONST_DECORATOR_H
00022 
00023 #include <CGAL/basic.h>
00024 #include <CGAL/Unique_hash_map.h>
00025 #include <string>
00026 #include <list>
00027 #include <sstream>
00028 #include <CGAL/Nef_2/Object_index.h>
00029 #include <CGAL/Nef_2/iterator_tools.h>
00030 #undef CGAL_NEF_DEBUG
00031 #define CGAL_NEF_DEBUG 7
00032 #include <CGAL/Nef_2/debug.h>
00033 
00034 CGAL_BEGIN_NAMESPACE
00035 
00036 template <typename Iter, typename Move>
00037 inline CGAL::Circulator_tag  
00038 query_circulator_or_iterator(const CircFromIt<Iter,Move>& )
00039 { return CGAL::Circulator_tag(); }
00040 
00041 
00042 template <typename HE>
00043 class move_halfedge_around_vertex {
00044 public:
00045   void forward(HE& e) const  { e = (e->prev()->opposite()); }
00046   void backward(HE& e) const { e = (e->opposite()->next()); }
00047 };
00048 
00049 template <typename HE>
00050 struct move_halfedge_around_face {
00051   void forward(HE& e)  const { e = (e->next()); }
00052   void backward(HE& e) const { e = (e->prev()); }
00053 };
00054 
00055 
00056 /*{\Moptions print_title=yes}*/ 
00057 /*{\Moptions constref=yes}*/ 
00058 /*{\Msubst 
00059 PM_const_decorator#PMConstDecorator
00060 PM_decorator#PMDecorator
00061 }*/ 
00062 /*{\Moptions outfile=PMConstDecorator.man }*/
00063 /*{\Manpage {PMConstDecorator}{}{Topological plane map exploration}{D}}*/
00064 
00065 template <typename HDS> class PM_decorator;
00066 
00067 template <typename HDS>
00068 class PM_const_decorator 
00069 { typedef PM_const_decorator<HDS> Self;
00070 /*{\Mdefinition An instance |\Mvar| of the data type |\Mname| is a 
00071 decorator for interfacing the topological structure of a plane map |P| 
00072 (read-only).
00073 
00074 A plane map |P| consists of a triple $(V, E, F)$ of vertices, edges, and
00075 faces. We collectively call them objects. An edge |e| is a pair of
00076 vertices |(v,w)| with incidence operations |v = source(e)|, |w =
00077 target(e)|. The list of all edges with source |v| is called the
00078 adjacency list |A(v)|.
00079 
00080 Edges are paired into twins. For each edge |e = (v,w)| there's an edge
00081 |twin(e) = (w,v)| and |twin(twin(e)) == e|\footnote{The existence of 
00082 the edge pairs makes |P| a bidirected graph, the |twin| links make
00083 |P| a map.}.
00084 
00085 An edge |e = (v,w)| knows two adjacent edges |en = next(e)| and |ep
00086 = previous(e)| where |source(en) = w|, |previous(en) = e| and
00087 |target(ep) = v| and |next(ep) = e|. By this symmetric |previous-next|
00088 relationship all edges are partitioned into face cycles.  Two edges
00089 $e$ and $e'$ are in the same face cycle if $e = |next|^*(e')$.  All
00090 edges |e| in the same face cycle have the same incident face $f =
00091 |face|(e)$. The cyclic order on the adjacency list of a vertex |v =
00092 source(e)| is given by |cyclic_adj_succ(e) = twin(previous(e))| and
00093 |cyclic_adj_pred(e) = next(twin(e))|.
00094 
00095 A vertex |v| is embedded via coordinates |point(v)|. By the
00096 embedding of its source and target an edge corresponds to a
00097 segment. |P| has the property that the embedding is always
00098 \emph{order-preserving}.  This means a ray fixed in |point(v)| of a
00099 vertex |v| and swept around counterclockwise meets the embeddings of
00100 |target(e)| ($e \in A(v)$) in the cyclic order defined by the list
00101 order of |A|.
00102 
00103 The embedded face cycles partition the plane into maximal connected
00104 subsets of points. Each such set corresponds to a face. A face is
00105 bounded by its incident face cycles. For all the edges in the
00106 non-trivial face cycles it holds that the face is left of the edges.
00107 There can also be trivial face cycles in form of isolated vertices in
00108 the interior of a face. Each such vertex |v| knows its surrounding
00109 face |f = face(v)|.
00110 
00111 We call the embedded map |(V,E)| also the $1$-skeleton of |P|.
00112 
00113 Plane maps are attributed. To each object $u \in V \cup E \cup F$
00114 we attribute a value |mark(u)| of type |Mark|. |Mark| fits the
00115 concepts assignable, default-constructible, and equal-comparable.}*/
00116 
00117 protected: 
00118 HDS* phds; 
00119 friend class PM_decorator<HDS>;
00120 
00121 public:
00122 /*{\Mtypes 6}*/
00123 typedef HDS Plane_map;
00124 /*{\Mtypemember The underlying plane map type}*/
00125 
00126 typedef typename HDS::Traits Traits;
00127 
00128 typedef typename Traits::Point  Point;
00129 /*{\Mtypemember The point type of vertices.}*/
00130 typedef typename Traits::Mark   Mark;
00131 /*{\Mtypemember All objects (vertices, edges, faces) are attributed by a 
00132 |Mark| object.}*/
00133 typedef size_t Size_type;
00134 /*{\Mtypemember The size type.}*/
00135 typedef void*  GenPtr;
00136 
00137 
00138 typedef typename HDS::Vertex                  Vertex; 
00139 typedef typename HDS::Vertex_base             Vertex_base;
00140 typedef typename HDS::Vertex_handle           Vertex_handle;
00141 typedef typename HDS::Vertex_const_handle     Vertex_const_handle;
00142 typedef typename HDS::Vertex_const_iterator   Vertex_const_iterator;
00143 typedef typename HDS::Halfedge                Halfedge ; 
00144 typedef typename HDS::Halfedge_base           Halfedge_base ;
00145 typedef typename HDS::Halfedge_handle         Halfedge_handle; 
00146 typedef typename HDS::Halfedge_const_handle   Halfedge_const_handle;
00147 typedef typename HDS::Halfedge_const_iterator Halfedge_const_iterator;
00148 typedef typename HDS::Face                    Face;
00149 typedef typename HDS::Face_base               Face_base;
00150 typedef typename HDS::Face_handle             Face_handle;
00151 typedef typename HDS::Face_const_handle       Face_const_handle;
00152 typedef typename HDS::Face_const_iterator     Face_const_iterator;
00153 
00154 
00155 /*{\Mtext Local types are handles, iterators and circulators of the
00156 following kind: |Vertex_const_handle|,
00157 |Vertex_const_iterator|, |Halfedge_const_handle|,
00158 |Halfedge_const_iterator|, |Face_const_handle|, |Face_\-const_\-ite\-rator|.
00159 Additionally the following circulators are defined.}*/
00160 
00161 typedef CircFromIt<
00162         Halfedge_const_iterator, 
00163         move_halfedge_around_vertex<Halfedge_const_iterator> > 
00164         Halfedge_around_vertex_const_circulator;
00165 /*{\Mtypemember circulating the outgoing halfedges in $A(v)$.}*/
00166 
00167 typedef CircFromIt<
00168         Halfedge_const_iterator, 
00169         move_halfedge_around_face<Halfedge_const_iterator> > 
00170         Halfedge_around_face_const_circulator;
00171 /*{\Mtypemember circulating the halfedges in the face cycle of a 
00172 face |f|.}*/
00173 
00174 typedef typename Face::Hole_const_iterator Hole_const_iterator;
00175 /*{\Mtypemember iterating all holes of a face |f|. The type is 
00176 convertible to |Halfedge_const_handle|.}*/
00177 
00178 typedef typename Face::Isolated_vertex_const_iterator 
00179         Isolated_vertex_const_iterator;
00180 /*{\Mtypemember iterating all isolated vertices of a face |f|. 
00181 The type generalizes |Vertex_const_handle|.}*/
00182 
00183 typedef PntItFromVertIt<Vertex_const_iterator,Point> 
00184   Point_const_iterator;
00185 
00186 /*{\Mcreation 3}*/
00187 
00188 PM_const_decorator() : phds(0) {}
00189 PM_const_decorator(const PM_const_decorator<HDS>& D) :
00190     phds(D.phds) {}
00191 PM_const_decorator& operator=(
00192   const PM_const_decorator<HDS>& D)
00193 { phds=D.phds; return *this; }
00194 
00195 PM_const_decorator(const Plane_map& P) 
00196 /*{\Mcreate constructs a plane map decorator exploring |P|.}*/
00197  : phds(const_cast<HDS*>(&P)) {}
00198 
00199 /*{\Moperations 4 4}*/
00200 
00201 Vertex_const_handle source(Halfedge_const_handle e) const
00202 /*{\Mop returns the source of |e|.}*/
00203 { return e->opposite()->vertex(); }
00204 
00205 Vertex_const_handle target(Halfedge_const_handle e) const
00206 /*{\Mop returns the target of |e|.}*/
00207 { return e->vertex(); }
00208 
00209 Halfedge_const_handle twin(Halfedge_const_handle e) const 
00210 /*{\Mop returns the twin of |e|.}*/
00211 { return e->opposite(); }
00212 
00213 bool is_isolated(Vertex_const_handle v) const
00214 /*{\Mop returns |true| iff $A(v) = \emptyset$.}*/
00215 { return v->is_isolated(); }
00216 
00217 Halfedge_const_handle first_out_edge(Vertex_const_handle v) const
00218 /*{\Mop returns one halfedge with source |v|. It's the starting point for
00219   the circular iteration over the halfedges with source |v|.
00220   \precond |!is_isolated(v)|.}*/
00221 { return v->halfedge()->opposite(); }
00222 
00223 Halfedge_const_handle last_out_edge(Vertex_const_handle v) const
00224 /*{\Mop returns the halfedge with source |v| that is the last
00225   in the circular iteration before encountering |first_out_edge(v)| 
00226   again. \precond |!is_isolated(v)|.}*/
00227 { return v->halfedge()->next(); }
00228 
00229 Halfedge_const_handle cyclic_adj_succ(
00230                         Halfedge_const_handle e) const
00231 /*{\Mop returns the edge after |e| in the cyclic ordered adjacency list of
00232   |source(e)|.}*/
00233 { return e->prev()->opposite(); }
00234 
00235 Halfedge_const_handle cyclic_adj_pred(
00236                         Halfedge_const_handle e) const
00237 /*{\Mop returns the edge before |e| in the cyclic ordered adjacency list of
00238   |source(e)|.}*/
00239 { return e->opposite()->next(); }
00240 
00241 
00242 Halfedge_const_handle next(Halfedge_const_handle e) const
00243 /*{\Mop returns the next edge in the face cycle containing |e|.}*/
00244 { return e->next(); }
00245 
00246 Halfedge_const_handle previous(Halfedge_const_handle e) const
00247 /*{\Mop returns the previous edge in the face cycle containing |e|.}*/
00248 { return e->prev(); }
00249 
00250 Face_const_handle face(Halfedge_const_handle e) const
00251 /*{\Mop returns the face incident to |e|.}*/
00252 { return e->face(); }
00253 
00254 Face_const_handle face(Vertex_const_handle v) const
00255 /*{\Mop returns the face incident to |v|.
00256    \precond |is_isolated(v)|.}*/
00257 { return v->face(); }
00258 
00259 Halfedge_const_handle halfedge(Face_const_handle f) const
00260 /*{\Mop returns a halfedge in the bounding face cycle of |f| 
00261 (|Halfedge_const_handle()| if there is no bounding face cycle).}*/
00262 { return f->halfedge(); }
00263 
00264 
00265 /*{\Mtext \headerline{Iteration} \setopdims{7.5cm}{0cm}}*/
00266   
00267 Vertex_const_iterator   vertices_begin() const
00268 { return phds->vertices_begin(); }
00269 Halfedge_const_iterator halfedges_begin() const
00270 { return phds->halfedges_begin(); }
00271 Face_const_iterator     faces_begin() const
00272 { return phds->faces_begin(); }
00273 Vertex_const_iterator   vertices_end() const
00274 { return phds->vertices_end(); }
00275 Halfedge_const_iterator halfedges_end() const
00276 { return phds->halfedges_end(); }
00277 Face_const_iterator     faces_end() const
00278 { return phds->faces_end(); }
00279 Point_const_iterator points_begin() const
00280 { return Point_const_iterator(vertices_begin()); }
00281 Point_const_iterator points_end() const
00282 { return Point_const_iterator(vertices_end()); }
00283 
00284 Halfedge_around_vertex_const_circulator 
00285   out_edges(Vertex_const_handle v) const
00286 /*{\Mop returns a circulator for the cyclic adjacency list of |v|.}*/
00287 { return Halfedge_around_vertex_const_circulator(first_out_edge(v)); }
00288 
00289 Halfedge_around_face_const_circulator 
00290   face_cycle(Face_const_handle f) const
00291 /*{\Mop returns a circulator for the outer face cycle of |f|.}*/
00292 { return Halfedge_around_face_const_circulator(f->halfedge()); }
00293 
00294 Hole_const_iterator  holes_begin(Face_const_handle f) const
00295 /*{\Mop returns an iterator for all holes in the interior of |f|.
00296    A |Hole_iterator| can be assigned to a 
00297    |Halfedge_around_face_const_circulator|.}*/
00298 { return f->fc_begin(); }
00299 
00300 Hole_const_iterator  holes_end(Face_const_handle f) const
00301 /*{\Mop returns the past-the-end iterator of |f|.}*/
00302 { return f->fc_end(); }
00303 
00304 Isolated_vertex_const_iterator 
00305   isolated_vertices_begin(Face_const_handle f) const
00306 /*{\Mop returns an iterator for all isolated vertices in the interior 
00307    of |f|.}*/
00308 { return f->iv_begin(); }
00309 
00310 Isolated_vertex_const_iterator 
00311   isolated_vertices_end(Face_const_handle f) const
00312 /*{\Mop returns the past the end iterator of |f|.}*/
00313 { return f->iv_end(); }
00314 
00315 
00316 /*{\Mtext \headerline{Associated Information}\setopdims{2.5cm}{4cm}
00317 The type |Mark| is the general attribute of an object. The type
00318 |GenPtr| is equal to type |void*|.}*/
00319 
00320 const Point& point(Vertex_const_handle v) const
00321 /*{\Mop returns the embedding of |v|.}*/
00322 { return v->point(); }
00323 
00324 const Mark& mark(Vertex_const_handle v) const  
00325 /*{\Mop returns the mark of |v|.}*/
00326 { return v->mark(); }
00327 
00328 const Mark& mark(Halfedge_const_handle e) const 
00329 /*{\Mop returns the mark of |e|.}*/
00330 { if (&*e < &*(e->opposite())) return e->mark();
00331   else return e->opposite()->mark();
00332 } // we store the mark in the container with smaller memory address !
00333 
00334 const Mark& mark(Face_const_handle f) const
00335 /*{\Mop returns the mark of |f|.}*/
00336 { return f->mark(); }
00337 
00338 const GenPtr& info(Vertex_const_handle v) const
00339 /*{\Mop returns a generic information slot.}*/
00340 { return v->info(); }
00341 
00342 const GenPtr& info(Halfedge_const_handle e) const
00343 /*{\Mop returns a generic information slot.}*/
00344 { return e->info(); }
00345 
00346 const GenPtr& info(Face_const_handle f) const
00347 /*{\Mop returns a generic information slot.}*/
00348 { return f->info(); }
00349 
00350 
00351 /*{\Mtext \headerline{Statistics and Integrity}}*/
00352 
00353 Size_type number_of_vertices() const 
00354 /*{\Mop returns the number of vertices.}*/
00355 { return phds->size_of_vertices(); }
00356 
00357 Size_type number_of_halfedges() const 
00358 /*{\Mop returns the number of halfedges.}*/
00359 { return phds->size_of_halfedges(); }
00360 
00361 Size_type number_of_edges() const    
00362 /*{\Mop returns the number of halfedge pairs.}*/
00363 { return phds->size_of_halfedges()/2; }
00364 
00365 Size_type number_of_faces() const    
00366 /*{\Mop returns the number of faces.}*/
00367 { return phds->size_of_faces(); }
00368 
00369 Size_type number_of_face_cycles() const;
00370 /*{\Mop returns the number of face cycles.}*/
00371 
00372 Size_type number_of_connected_components() const;
00373 /*{\Mop calculates the number of connected components of |P|.}*/
00374 
00375 void print_statistics(std::ostream& os = std::cout) const
00376 /*{\Mop print the statistics of |P|: the number of vertices, edges, and 
00377    faces.}*/
00378 {
00379   os << "Plane Map - Statistics\n";
00380   os << "|V| = " << number_of_vertices() << std::endl;
00381   os << "|E| = " << number_of_edges() 
00382   << " (" << 2*number_of_edges() << ")" << std::endl;
00383   os << "|F| = " << number_of_faces() << std::endl;
00384   os << "|Fcs| = " << number_of_face_cycles() << std::endl << std::endl;
00385 }
00386  
00387 void check_integrity_and_topological_planarity(bool faces=true) const;
00388 /*{\Mop checks the link structure and the genus of |P|.}*/
00389 
00390 }; // PM_const_decorator
00391 
00392 template <class VH>
00393 std::string PV(VH v)
00394 { std::ostringstream os; CGAL::set_pretty_mode(os);
00395   if (v != VH()) os << v->point();
00396   else           os << "nil";
00397   return os.str();
00398 }
00399 
00400 template <class HH>
00401 std::string PE(HH e)
00402 { std::ostringstream os;
00403   if (e==HH()) return "nil";
00404   os << "[" << PV(e->opposite()->vertex()) << ","
00405             << PV(e->vertex()) << " " << e->info() << "]";
00406   return os.str();
00407 }
00408 
00409 template <typename HDS>
00410 void PM_const_decorator<HDS>::
00411 check_integrity_and_topological_planarity(bool faces) const
00412 {
00413   CGAL_NEF_TRACEN("check_integrity_and_topological_planarity:");
00414   using CGAL::Object_index;
00415   Object_index<Vertex_const_iterator>   
00416     VI(vertices_begin(),vertices_end(),'v');
00417   Object_index<Halfedge_const_iterator> 
00418     EI(halfedges_begin(),halfedges_end(),'e');
00419   Object_index<Face_const_iterator> 
00420     FI(faces_begin(),faces_end(),'f');
00421   typedef Halfedge_around_vertex_const_circulator hvc_circulator;
00422   typedef Halfedge_around_face_const_circulator   hfc_circulator;
00423   Vertex_const_handle vit, vend = phds->vertices_end();
00424   int iso_vert_num=0;
00425   /* check the source links of out edges and count isolated vertices */
00426   for (vit = vertices_begin() ; vit != vend; ++vit) {
00427     if ( is_isolated(vit) ) {
00428       if ( faces )
00429         CGAL_assertion_msg( vit->face() != Face_const_handle(),
00430                             VI(vit).c_str());
00431       ++iso_vert_num;
00432     } else {
00433       CGAL_assertion_msg( vit->halfedge() != Halfedge_const_handle(),
00434       VI(vit).c_str());
00435       CGAL_assertion_msg( vit->halfedge()->vertex() == vit ,VI(vit).c_str());
00436     }
00437   }
00438 
00439   /* check the bidirected links and the face pointer init */
00440   Halfedge_const_iterator eit, eend = phds->halfedges_end();
00441   for (eit = phds->halfedges_begin() ; eit != eend; ++eit) {
00442     CGAL_assertion( twin(twin(eit)) == eit );
00443     CGAL_assertion( eit->vertex() != Vertex_const_handle() );
00444     CGAL_assertion( next(eit) != Halfedge_const_handle() );
00445     CGAL_assertion( previous(next(eit)) == eit );
00446     CGAL_assertion( target(eit) == source(next(eit)) );
00447     CGAL_assertion( previous(eit) != Halfedge_const_handle() );
00448     CGAL_assertion( next(previous(eit)) == eit );
00449     CGAL_assertion( target(previous(eit)) == source(eit) );
00450     if ( !faces ) continue;
00451     CGAL_assertion( face(eit) != Face_const_handle() );
00452     CGAL_assertion( face(next(eit)) == face(eit) );
00453     CGAL_assertion( face(previous(eit)) == face(eit) );
00454   }
00455 
00456   bool first=true;
00457   int fc_num(0),iv_num(0);
00458   Face_const_iterator fit;
00459   for (fit = faces_begin(); fit != faces_end(); ++fit) {
00460     if (!first) {
00461       CGAL_assertion( face(halfedge(fit))==fit ); ++fc_num;
00462     }
00463     Hole_const_iterator fcit;
00464     for( fcit = holes_begin(fit); fcit != holes_end(fit); ++fcit) {
00465       CGAL_assertion( face(fcit)==fit ); ++fc_num;
00466     }
00467     Isolated_vertex_const_iterator ivit;
00468     for(ivit = isolated_vertices_begin(fit); 
00469         ivit != isolated_vertices_end(fit); ++ivit) {
00470       CGAL_assertion( face(ivit)==fit ); ++iv_num;
00471     }
00472     first=false;
00473   }
00474 
00475   int v_num = number_of_vertices() - iso_vert_num;
00476   int e_num = number_of_edges();
00477   int c_num = number_of_connected_components() - iso_vert_num;
00478   int f_num = number_of_face_cycles() - c_num + 1;
00479   CGAL_NEF_TRACEV(fc_num);CGAL_NEF_TRACEV(iv_num);CGAL_NEF_TRACEV(iso_vert_num);
00480   CGAL_NEF_TRACEV(v_num);CGAL_NEF_TRACEV(e_num);CGAL_NEF_TRACEV(c_num);CGAL_NEF_TRACEV(f_num);
00481   // CGAL_assertion(fc_num == f_num && iv_num == iso_vert_num);
00482   /* this means all face cycles and all isolated vertices are 
00483      indeed referenced from a face */
00484   /* every isolated vertex increases the component count
00485        one face cycle per component is redundent except one
00486        finally check the Euler formula: */
00487   CGAL_assertion( v_num - e_num + f_num == 1 + c_num );
00488 }
00489 
00490 template <typename HDS>
00491 typename PM_const_decorator<HDS>::Size_type 
00492 PM_const_decorator<HDS>::
00493 number_of_face_cycles() const
00494 {
00495   unsigned int fc_num=0;
00496   CGAL::Unique_hash_map<Halfedge_const_handle,bool> visited; 
00497     // init with bool() == false
00498   Halfedge_const_iterator eit =  phds->halfedges_begin();
00499   Halfedge_const_iterator eend = phds->halfedges_end();
00500   for ( ; eit != eend; ++eit) {
00501     if (visited[eit]) continue;
00502     Halfedge_around_face_const_circulator hfc(eit), hend(hfc);
00503     CGAL_For_all(hfc,hend) visited[hfc]=true;
00504     ++fc_num;
00505   }
00506   return fc_num;
00507 }
00508 
00509 template <typename HDS>
00510 size_t PM_const_decorator<HDS>::
00511 number_of_connected_components() const
00512 {
00513   typedef Vertex_const_iterator vc_handle;
00514   typedef Halfedge_around_vertex_const_circulator hvc_circulator;
00515   int comp_num=0;
00516   CGAL::Unique_hash_map< vc_handle, bool> handled(false); 
00517   vc_handle vit = vertices_begin(), vend = vertices_end();
00518   for ( ; vit != vend; ++vit) {
00519     if (handled[vit]) continue;
00520     std::list<vc_handle> L;
00521     L.push_back(vit); handled[vit]=true; 
00522     /* we keep the invariant that all nodes which have been stacked
00523        are marked handled */
00524     while (!L.empty()) {
00525       vc_handle v=L.front(); L.pop_front();
00526       if ( is_isolated(v) ) continue;
00527       hvc_circulator havc(first_out_edge(v)), hend(havc);
00528       CGAL_For_all(havc,hend) {
00529         if (!handled[target(havc)]) {
00530           L.push_back(target(havc)); handled[target(havc)]=true; 
00531         }
00532       }
00533     }
00534     ++comp_num;
00535   }
00536   return comp_num;   
00537 }
00538 
00539 struct KERNELPNT {
00540   template <typename PNT>
00541   std::string operator() (const PNT& p) const
00542   { std::ostringstream os;
00543     os << "(" << CGAL::to_double(p.x()) << ","
00544               << CGAL::to_double(p.y()) << ")";
00545     return os.str();
00546   }
00547 };
00548 
00549 template <typename PMCDEC, typename POINTDA>
00550 void print_as_leda_graph(std::ostream& os, const PMCDEC& D, 
00551   const POINTDA& P)
00552 {
00553   typedef typename PMCDEC::Vertex_const_iterator   
00554   Vertex_const_iterator;
00555   typedef typename PMCDEC::Halfedge_const_iterator 
00556   Halfedge_const_iterator;
00557   int vn(1), en(1);  
00558   CGAL::Unique_hash_map<Vertex_const_iterator,int>   v_num;
00559   CGAL::Unique_hash_map<Halfedge_const_iterator,int> e_num;
00560   os << "LEDA.GRAPH\n" << "point\n" << "int\n";
00561   os << D.number_of_vertices() << std::endl;
00562   Vertex_const_iterator vit;
00563   for (vit = D.vertices_begin(); vit != D.vertices_end(); ++vit) {
00564     v_num[vit] = vn++;
00565     os << "|{(" << P(D.point(vit)) << ")}|\n";
00566      typename PMCDEC::Halfedge_around_vertex_const_circulator
00567        ecirc(D.first_out_edge(vit)),ecend(ecirc);
00568     int l=0;
00569     CGAL_For_all(ecirc,ecend) e_num[ecirc]=l++;
00570   }
00571   os << 2* D.number_of_edges() << std::endl;
00572   Halfedge_const_iterator eit;
00573   for (eit = D.halfedges_begin(); eit != D.halfedges_end(); ++eit) {
00574     e_num[eit] = en++;
00575   }
00576   for (eit = D.halfedges_begin(); eit != D.halfedges_end(); ++eit) {
00577     os << v_num[D.source(eit)] << " "
00578        << v_num[D.target(eit)] << " "
00579        << e_num[D.twin(eit)]   << " ";
00580     os << "|{" << e_num[eit] << "}|\n";
00581   }
00582   os << std::flush;
00583 }
00584 
00585 
00586 
00587 CGAL_END_NAMESPACE
00588 #endif // CGAL_PM_CONST_DECORATOR_H
00589 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines