BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Nef_2/PM_overlayer.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_overlayer.h $
00015 // $Id: PM_overlayer.h 39791 2007-08-09 09:48:44Z spion $
00016 // 
00017 //
00018 // Author(s)     : Michael Seel <seel@mpi-sb.mpg.de>
00019 
00020 #ifndef CGAL_PM_OVERLAYER_H
00021 #define CGAL_PM_OVERLAYER_H
00022 
00023 #include <CGAL/basic.h>
00024 #include <CGAL/Unique_hash_map.h>
00025 #include <CGAL/Union_find.h>
00026 #include <CGAL/Nef_2/Segment_overlay_traits.h>
00027 #include <CGAL/Nef_2/geninfo.h>
00028 #undef CGAL_NEF_DEBUG
00029 #define CGAL_NEF_DEBUG 13
00030 #include <CGAL/Nef_2/debug.h>
00031 
00032 #ifndef CGAL_USE_LEDA
00033 #define LEDA_MEMORY(t) 
00034 #endif
00035 
00036 CGAL_BEGIN_NAMESPACE
00037 
00038 template <typename PMD, typename I, typename DA>
00039 struct PMO_from_segs {
00040   typedef PMD Decorator;
00041   typedef typename Decorator::Vertex_handle   Vertex_handle;
00042   typedef typename Decorator::Halfedge_handle Halfedge_handle;
00043   typedef typename Decorator::Point           Point;
00044   const Decorator& G;
00045   DA& D; 
00046   PMO_from_segs(const Decorator& Gi, DA& Di) : 
00047     G(Gi),D(Di) {}
00048 
00049   Vertex_handle new_vertex(const Point& p)
00050   { Vertex_handle v = G.new_vertex(p); 
00051     geninfo<Halfedge_handle>::create(G.info(v));
00052     return v;
00053   }
00054 
00055   void link_as_target_and_append(Vertex_handle v, Halfedge_handle e) 
00056   { G.link_as_target_and_append(v,e); }
00057 
00058   Halfedge_handle new_halfedge_pair_at_source(Vertex_handle v)
00059   { Halfedge_handle e = 
00060     G.new_halfedge_pair_at_source(v,Decorator::BEFORE); 
00061     return e;
00062   }
00063 
00064   void supporting_segment(Halfedge_handle e, I it) const
00065   { D.supporting_segment(e,it); }
00066 
00067   void trivial_segment(Vertex_handle v, I it) const
00068   { D.trivial_segment(v,it); }
00069 
00070   void starting_segment(Vertex_handle v, I it) const
00071   { D.starting_segment(v,it); }
00072 
00073   void passing_segment(Vertex_handle v, I it) const
00074   { D.passing_segment(v,it); }
00075 
00076   void ending_segment(Vertex_handle v, I it) const
00077   { D.ending_segment(v,it); }
00078 
00079   void halfedge_below(Vertex_handle v, Halfedge_handle e) const
00080   { geninfo<Halfedge_handle>::access(G.info(v)) = e; }
00081 
00082   Halfedge_handle halfedge_below(Vertex_handle v) const
00083   { return geninfo<Halfedge_handle>::access(G.info(v)); }
00084 
00085   void clear_temporary_vertex_info() const
00086   { Vertex_handle v;
00087     for(v = G.vertices_begin(); v!= G.vertices_end(); ++v)
00088       geninfo<Halfedge_handle>::clear(G.info(v));
00089   }
00090 
00091 
00092 }; // PMO_from_segs
00093 
00094 
00095 template <typename PMD, typename IT, typename INFO>
00096 struct PMO_from_pm {
00097   typedef PMD Decorator;
00098   typedef typename PMD::Const_decorator Const_decorator;
00099   typedef typename Decorator::Vertex_handle Vertex_handle;
00100   typedef typename Decorator::Halfedge_handle Halfedge_handle;
00101   typedef typename Decorator::Vertex_const_handle Vertex_const_handle;
00102   typedef typename Decorator::Halfedge_const_handle Halfedge_const_handle;
00103   typedef typename Decorator::Point Point;
00104 
00105   const Decorator& G;
00106   const Const_decorator* pGI[2];
00107   CGAL::Unique_hash_map<IT,INFO>& M;
00108   PMO_from_pm(const Decorator& Gi, 
00109               const Const_decorator* pG0, 
00110               const Const_decorator* pG1,
00111               CGAL::Unique_hash_map<IT,INFO>& Mi) : G(Gi),M(Mi) 
00112  { pGI[0]=pG0; pGI[1]=pG1; }
00113 
00114  Vertex_handle new_vertex(const Point& p) const
00115  { Vertex_handle v = G.new_vertex(p);
00116    G.assoc_info(v);
00117    return v;
00118  }
00119 
00120  void link_as_target_and_append(Vertex_handle v, Halfedge_handle e) const
00121  { G.link_as_target_and_append(v,e); }
00122 
00123  Halfedge_handle new_halfedge_pair_at_source(Vertex_handle v) const
00124  { Halfedge_handle e = 
00125    G.new_halfedge_pair_at_source(v,Decorator::BEFORE); 
00126    G.assoc_info(e);
00127    return e;
00128  }
00129 
00130  void halfedge_below(Vertex_handle v, Halfedge_handle e) const
00131  { G.halfedge_below(v) = e; }
00132 
00133  void supporting_segment(Halfedge_handle e, IT it) const
00134  { INFO& si = M[it];
00135    CGAL_assertion( si.e != Halfedge_const_handle() );
00136    G.supp_halfedge(e,si.i) = si.e;
00137    G.is_forward(e) = true;
00138  }
00139 
00140 
00141  void trivial_segment(Vertex_handle v, IT it) const
00142  { INFO& si = M[it];
00143    CGAL_assertion( si.v != Vertex_const_handle() );
00144    G.supp_vertex(v,si.i) = si.v; 
00145  }
00146 
00147  void starting_segment(Vertex_handle v, IT it) const
00148  { INFO& si = M[it];
00149    G.supp_vertex(v,si.i) = pGI[si.i]->source(si.e);
00150  }
00151 
00152  void ending_segment(Vertex_handle v, IT it) const
00153  { INFO& si = M[it];
00154    G.supp_vertex(v,si.i) = pGI[si.i]->target(si.e);
00155  }
00156 
00157  void passing_segment(Vertex_handle v, IT it) const
00158  { INFO& si = M[it];
00159    G.supp_halfedge(v,si.i) = si.e; 
00160  }
00161 
00162  Halfedge_handle halfedge_below(Vertex_handle v) const
00163  { return G.halfedge_below(v); }
00164 
00165 
00166 }; // PMO_from_pm
00167 
00168 /*{\Moptions print_title=yes }*/ 
00169 /*{\Msubst 
00170 PM_decorator_#PMD
00171 Geometry_#GEO
00172 }*/
00173 /*{\Manpage {PM_overlayer}{PMD,GEO}{Plane Map Overlay}{O}}*/
00174 template <typename PM_decorator_, typename Geometry_>
00175 class PM_overlayer : public PM_decorator_ {
00176   typedef PM_decorator_ Base;
00177   typedef PM_overlayer<PM_decorator_,Geometry_>  Self;
00178   const Geometry_& K; // geometry reference
00179 
00180 /*{\Mdefinition An instance |\Mvar| of data type |\Mname| is a
00181 decorator object offering plane map overlay calculation. Overlay is
00182 either calculated from two plane maps or from a set of segments.  The
00183 result is stored in a plane map |P| that carries the geometry and the
00184 topology of the overlay.
00185 
00186 The two template parameters allow to adapt the overlay calculation
00187 to different scenarios.  The template parameter |PM_decorator_| has to
00188 be a model conforming to our plane map decorator concept
00189 |PMDecorator|.  The concept describes the interface how the
00190 topological information stored in |P| can be extracted.  The geometry
00191 |Geometry_| has to be a model conforming to the concept 
00192 |OverlayerGeometry_2|.
00193 
00194 The overlay of a set of segments $S$ is stored in a plane map $P =
00195 (V,E,F)$. Vertices are either the endpoints of segments (trivial
00196 segments are allowed) or the result of a non-degenerate internal
00197 intersection of two segments. Between two vertices there is an edge if
00198 there is a segment that supports the straight line embedding of $e$ and
00199 if there is no vertex in the relative interior of the embedding of $e$.
00200 
00201 The faces refer to the maximal connected open point sets of the
00202 planar subdivision implied by the embedding of the vertices and edges.
00203 Faces are bounded by possibly several face cycles\footnote{For the
00204 definition of plane maps and their concepts see the manual page of
00205 |PMConstDecorator|.} including isolated vertices. The overlay process
00206 in the method |create| creates the objects, the topology of the result
00207 and allows to link the plane map objects to input segments by means of
00208 a data accessor. The method starts from zero- and one-dimensional
00209 geometric objects in $S$ and produces a plane map |P| where each point
00210 of the plane can be assigned to an object (vertex, edge, or face) of
00211 |P|.
00212 
00213 The overlay of two plane maps $P_i = (V_i, E_i, F_i)$ has the
00214 additional aspect that we already start from two planar subdivisions.
00215 We use the index $i=0,1$ defining the reference to $P_i$, unindexed
00216 variables refer to the resulting plane map $P$.  The $1$-skeleta of
00217 the two maps subdivide the edges and faces of the complementary
00218 structure into smaller units. This means vertices and edges of $P_i$
00219 can split edges of $P_{1-i}$ and face cycles of $P_i$ subdivide faces
00220 of $P_{1-i}$. The 1-skeleton $P'$ of $P$ is defined by the overlay of
00221 the embedding of the 1-skeleta of $P_0$ and $P_1$ (Take a trivial
00222 segment for each vertex and a segment for each edge and use the
00223 overlay definition of a set of segments above). The faces of $P$ refer
00224 to the maximal connected open point sets of the planar subdivision
00225 implied by the embedding of $P'$. Each object from the output tuple
00226 $(V,E,F)$ has a \emph{supporting} object $u_i$ in each of the two
00227 input structures.  Imagine the two maps to be transparencies, which we
00228 stack. Then each point of the plane is covered by an object from each
00229 of the input structures.  This support relation from the input
00230 structures to the output structure defines an information flow. Each
00231 supporting object $u_i$ of $u$ $(i=0,1)$ carries an attribute
00232 $|mark|(u_i)$. After the subdivision operation this attribute
00233 is associated to the output object $u$ by $|mark|(u,i)$.}*/
00234 
00235 /*{\Mgeneralization PM_decorator_}*/
00236 
00237 public:
00238 /*{\Mtypes 8}*/
00239   typedef PM_decorator_                 Decorator;
00240   /*{\Mtypemember the plane map decorator |PM_decorator_|.}*/
00241   typedef typename Decorator::Plane_map Plane_map;
00242   /*{\Mtypemember the plane map type decorated by |PM_decorator_|.}*/
00243   typedef Geometry_                     Geometry;
00244   /*{\Mtypemember the geometry kernel |Geometry_|.}*/
00245   typedef typename Geometry::Point_2    Point;
00246   /*{\Mtypemember the point type of the geometric kernel, 
00247      \precond |Point| equals |Plane_map::Point|.}*/
00248   typedef typename Geometry::Segment_2  Segment;
00249   /*{\Mtypemember the segment type of the geometric kernel.}*/
00250   typedef typename Decorator::Mark      Mark;
00251   /*{\Mtypemember the attribute type of plane map objects.}*/
00252 
00253 
00254   typedef typename Decorator::Base Const_decorator;
00255   typedef typename Decorator::Halfedge_handle Halfedge_handle;
00256   typedef typename Decorator::Vertex_handle Vertex_handle;
00257   typedef typename Decorator::Face_handle Face_handle;
00258   typedef typename Decorator::Vertex_iterator Vertex_iterator;
00259   typedef typename Decorator::Halfedge_iterator Halfedge_iterator;
00260   typedef typename Decorator::Face_iterator Face_iterator;
00261   typedef typename Decorator::Halfedge_const_handle Halfedge_const_handle;
00262   typedef typename Decorator::Vertex_const_handle Vertex_const_handle;
00263   typedef typename Decorator::Face_const_handle Face_const_handle;
00264   typedef typename Decorator::Halfedge_const_iterator Halfedge_const_iterator;
00265   typedef typename Decorator::Vertex_const_iterator Vertex_const_iterator;
00266   typedef typename Decorator::Face_const_iterator Face_const_iterator;
00267   typedef typename Decorator::Halfedge_around_vertex_circulator 
00268     Halfedge_around_vertex_circulator;
00269   typedef typename Decorator::Halfedge_around_face_circulator 
00270     Halfedge_around_face_circulator;
00271   typedef typename Decorator::Hole_iterator Hole_iterator;
00272   typedef typename Decorator::Isolated_vertex_iterator Isolated_vertex_iterator;
00273 
00274   using Base::clear;
00275   using Base::vertices_begin;
00276   using Base::vertices_end;
00277   using Base::halfedges_begin;
00278   using Base::halfedges_end;
00279   using Base::faces_begin;
00280   using Base::faces_end;
00281   using Base::number_of_vertices;
00282   using Base::number_of_halfedges;
00283   using Base::number_of_faces;
00284   using Base::new_vertex;
00285   using Base::new_face;
00286 
00287   // C++ is really friendly:
00288   #define USECMARK(t) const Mark& mark(t h) const { return Base::mark(h); }
00289   #define USEMARK(t)  Mark& mark(t h) const { return Base::mark(h); }
00290   USEMARK(Vertex_handle)
00291   USEMARK(Halfedge_handle)
00292   USEMARK(Face_handle)
00293   USECMARK(Vertex_const_handle)
00294   USECMARK(Halfedge_const_handle)
00295   USECMARK(Face_const_handle)
00296   #undef USEMARK
00297   #undef USECMARK
00298 
00299     enum Creation {POLYGON=0, POLYLINE=1};
00300 
00301   /*{\Moperations 1.1 1}*/
00302 
00303   struct Seg_info { // to transport information from input to output
00304     Halfedge_const_handle e;
00305     Vertex_const_handle   v;
00306     int                   i;
00307 
00308     Seg_info() : i(-1) {}
00309     Seg_info(Halfedge_const_handle e_, int i_) 
00310     { e=e_; i=i_; }
00311     Seg_info(Vertex_const_handle v_, int i_) 
00312     { v=v_; i=i_; }
00313     Seg_info(const Seg_info& si) 
00314     { e=si.e; v=si.v; i=si.i; }
00315     Seg_info& operator=(const Seg_info& si) 
00316     { e=si.e; v=si.v; i=si.i; return *this; }
00317     LEDA_MEMORY(Seg_info)
00318   };
00319 
00320   typedef std::list<Segment>                   Seg_list;
00321   typedef typename Seg_list::const_iterator    Seg_iterator;
00322   typedef std::pair<Seg_iterator,Seg_iterator> Seg_it_pair;
00323 
00324 
00325 /*{\Mcreation 6}*/
00326 PM_overlayer(Plane_map& P, const Geometry& g = Geometry()) : 
00327 /*{\Mcreate |\Mvar| is a decorator object manipulating |P|.}*/
00328   Base(P), K(g) {}
00329 
00330 
00331 template <typename Forward_iterator, typename Object_data_accessor>
00332 void create(Forward_iterator start, Forward_iterator end, 
00333             Object_data_accessor& A, Creation cr = POLYGON) const
00334 /*{\Mop produces in |P| the plane map consistent with the overlay
00335 of the segments from the iterator range |[start,end)|. The data accessor 
00336 |A| allows to initialize created vertices and edges with respect to the
00337 segments in the iterator range. |A| requires the following methods:\\
00338 [[void supporting_segment(Halfedge_handle e, Forward_iterator it)]]\\
00339 [[void trivial_segment(Vertex_handle v, Forward_iterator it)]]\\
00340 [[void starting_segment(Vertex_handle v, Forward_iterator it)]]\\
00341 [[void passing_segment(Vertex_handle v, Forward_iterator it)]]\\
00342 [[void ending_segment(Vertex_handle v, Forward_iterator it)]]\\
00343 where |supporting_segment| is called for each non-trivial segment |*it|
00344 supporting a newly created edge |e|, |trivial_segment| is called for
00345 each trivial segment |*it| supporting a newly created vertex |v|, and
00346 the three last operations are called for each non-trivial segment
00347 |*it| starting at/passing through/ending at the embedding of a newly
00348 created vertex |v|. 
00349 \precond |Forward_iterator| has value type |Segment|.}*/
00350 {
00351   CGAL_NEF_TRACEN("creating from iterator range");
00352   CGAL_assertion(cr == POLYGON || cr == POLYLINE);
00353   typedef PMO_from_segs<Self,Forward_iterator,Object_data_accessor> 
00354     Output_from_segments;
00355   typedef Segment_overlay_traits<
00356     Forward_iterator, Output_from_segments, Geometry> seg_overlay;
00357   typedef generic_sweep< seg_overlay > seg_overlay_sweep;
00358   typedef typename seg_overlay::INPUT input_range;
00359   Output_from_segments Out(*this, A);
00360   seg_overlay_sweep SOS( input_range(start, end), Out, K);
00361   SOS.sweep();
00362   if(cr==POLYGON)
00363     create_face_objects(Out);
00364   else
00365     create_face_objects_pl(Out);
00366   Out.clear_temporary_vertex_info();
00367 }
00368 
00369 void subdivide(const Plane_map& P0, const Plane_map& P1) const
00370 /*{\Mop constructs the overlay of the plane maps |P0| and |P1| in
00371 |P|, where all objects (vertices, halfedges, faces) of |P| are
00372 \emph{enriched} by the marks of the supporting objects of the two
00373 input structures: e.g. let |v| be a vertex supported by a node |v0| in
00374 |P0| and by a face |f1| in |P1| and |D0|, |D1| be decorators of
00375 type |PM_decorator| on |P0|,|P1|. Then |\Mvar.mark(v,0) = D0.mark(v0)|
00376 and |\Mvar.mark(v,1) = D1.mark(f1)|.}*/
00377 {
00378   Const_decorator PI[2];
00379   PI[0] = Const_decorator(P0); PI[1] = Const_decorator(P1);
00380   Seg_list Segments; int i;
00381   CGAL::Unique_hash_map<Seg_iterator,Seg_info> From;
00382   for (i=0; i<2; ++i) {
00383     Vertex_const_iterator v;
00384     for(v = PI[i].vertices_begin(); v != PI[i].vertices_end(); ++v)
00385       if ( PI[i].is_isolated(v) ) {
00386         Segments.push_back(segment(PI[i],v));
00387         From[--Segments.end()] = Seg_info(v,i);
00388       }
00389     Halfedge_const_iterator e;
00390     for(e = PI[i].halfedges_begin(); e != PI[i].halfedges_end(); ++e)
00391       if ( is_forward_edge(PI[i],e) ) {
00392         Segments.push_back(segment(PI[i],e));
00393         From[--Segments.end()] = Seg_info(e,i);
00394       }
00395   }
00396 
00397 
00398   typedef PMO_from_pm<Self,Seg_iterator,Seg_info> Output_from_plane_maps;
00399   typedef Segment_overlay_traits<
00400     Seg_iterator, Output_from_plane_maps, Geometry> pm_overlay;
00401   typedef generic_sweep< pm_overlay > pm_overlay_sweep;
00402   Output_from_plane_maps Out(*this,&PI[0],&PI[1],From);
00403   pm_overlay_sweep SOS(Seg_it_pair(Segments.begin(),Segments.end()),Out,K);
00404   SOS.sweep();
00405   create_face_objects(Out);
00406 
00407 
00408   CGAL_NEF_TRACEN("transfering marks");
00409   Face_iterator f = this->faces_begin(); assoc_info(f);
00410   for (i=0; i<2; ++i) mark(f,i) = PI[i].mark(PI[i].faces_begin());
00411 
00412   Vertex_iterator v, vend = this->vertices_end();
00413   for (v = this->vertices_begin(); v != vend; ++v) {
00414     CGAL_NEF_TRACEN("mark at "<<PV(v));
00415     Halfedge_handle e_below = halfedge_below(v);
00416     Mark m_below[2];
00417     if ( e_below != Halfedge_handle() ) {
00418       for (int i=0; i<2; ++i) {
00419         m_below[i] = incident_mark(e_below,i); 
00420       }
00421     } else { // e_below does not exist
00422       for (int i=0; i<2; ++i) 
00423         m_below[i] = PI[i].mark(PI[i].faces_begin());
00424     }
00425 
00426     for (i=0; i<2; ++i) 
00427       if ( supp_halfedge(v,i) != Halfedge_const_handle() ) {
00428         mark(v,i) = PI[i].mark(supp_halfedge(v,i));
00429       } else if ( supp_vertex(v,i) != Vertex_const_handle() ) {
00430         mark(v,i) = PI[i].mark(supp_vertex(v,i));
00431       } else {
00432         mark(v,i) = m_below[i];
00433       }
00434 
00435     if ( is_isolated(v) ) continue;
00436     Halfedge_around_vertex_circulator 
00437       e(first_out_edge(v)), hend(e);
00438     CGAL_For_all(e,hend) {
00439       if ( is_forward(e) ) {
00440         CGAL_NEF_TRACEN("   halfedge "<<PE(e));
00441         Halfedge_const_handle ei;
00442         bool supported;
00443         for (int i=0; i<2; ++i) {
00444           supported = ( supp_halfedge(e,i) != Halfedge_const_handle() );
00445           if ( supported ) {
00446             ei = supp_halfedge(e,i);
00447             CGAL_NEF_TRACEN("   supp halfedge "<<i<<" "<<PE(ei));
00448             incident_mark(twin(e),i) = 
00449               PI[i].mark(PI[i].face(PI[i].twin(ei)));
00450             mark(e,i) = PI[i].mark(ei);
00451             incident_mark(e,i) = m_below[i] =
00452               PI[i].mark(PI[i].face(ei));
00453           } else { // no support from input PI[i]
00454             incident_mark(twin(e),i) = mark(e,i) = incident_mark(e,i) = 
00455               m_below[i];
00456           }
00457         }
00458       } else break;
00459     }
00460 
00461   }
00462   for (f = ++this->faces_begin(); f != this->faces_end(); ++f) { // skip first face
00463     assoc_info(f);
00464     for (i=0; i<2; ++i) mark(f,i) = incident_mark(halfedge(f),i);
00465   }
00466 
00467 
00468 }
00469 
00470 
00471 
00472 template <typename Selection>
00473 void select(Selection& predicate) const
00474 /*{\Mop sets the marks of all objects according to the selection
00475 predicate |predicate|. |Selection| has to be a function object type
00476 with a function operator\\ [[Mark operator()(Mark m0, Mark m1)]]\\ For
00477 each object |u| of |P| enriched by the marks of the supporting objects
00478 according to the previous procedure |subdivide|, after this operation
00479 |\Mvar.mark(u) = predicate ( \Mvar.mark(u,0),\Mvar.mark(u,1) )|. The
00480 additional marks are invalidated afterwards. }*/
00481 { 
00482   Vertex_iterator vit = this->vertices_begin(),
00483                   vend = this->vertices_end();
00484   for( ; vit != vend; ++vit) {
00485     mark(vit) = predicate(mark(vit,0),mark(vit,1));
00486     discard_info(vit); 
00487   }
00488   Halfedge_iterator hit = this->halfedges_begin(),
00489                     hend = this->halfedges_end();
00490   for(; hit != hend; ++(++hit)) {
00491     mark(hit) = predicate(mark(hit,0),mark(hit,1));
00492     discard_info(hit);
00493   }
00494   Face_iterator fit = this->faces_begin(),
00495                 fend = this->faces_end();
00496   for(; fit != fend; ++fit) {
00497     mark(fit) = predicate(mark(fit,0),mark(fit,1));
00498     discard_info(fit);
00499   }
00500 }
00501 
00502 
00503 template <typename Keep_edge>
00504 void simplify(const Keep_edge& keep) const
00505 /*{\Mop simplifies the structure of |P| according to the marks of
00506 its objects. An edge |e| separating two faces |f1| and |f2| and equal
00507 marks |mark(e) == mark(f1) == mark(f2)| is removed and the faces are
00508 unified.  An isolated vertex |v| in a face |f| with |mark(v)==mark(f)|
00509 is removed.  A vertex |v| with outdegree two, two collinear out-edges
00510 |e1|,|e2| and equal marks |mark(v) == mark(e1) == mark(e2)| is removed
00511 and the edges are unified. The data accessor |keep| requires the function
00512 call operator\\[[bool operator()(Halfedge_handle e)]]\\that allows to
00513 avoid the simplification for edge pairs referenced by |e|.}*/
00514 {
00515   CGAL_NEF_TRACEN("simplifying"); 
00516   typedef typename CGAL::Union_find<Face_handle>::handle Union_find_handle;
00517   CGAL::Unique_hash_map< Face_iterator, Union_find_handle> Pitem;
00518   CGAL::Union_find<Face_handle> unify_faces;
00519 
00520   Face_iterator f, fend = this->faces_end();
00521   for (f = this->faces_begin(); f!= fend; ++f) { 
00522      Pitem[f] = unify_faces.make_set(f);
00523      clear_face_cycle_entries(f);
00524   }
00525 
00526 
00527   Halfedge_iterator e = this->halfedges_begin(), en,
00528                     eend = this->halfedges_end();
00529   for(; en=e, ++(++en), e != eend; e=en) { 
00530     if ( keep(e) ) continue;
00531     if ( mark(e) == mark(face(e)) &&
00532          mark(e) == mark(face(twin(e))) ) {
00533         CGAL_NEF_TRACEN("deleting "<<PE(e));
00534       if ( !unify_faces.same_set(Pitem[face(e)],
00535                                  Pitem[face(twin(e))]) ) {
00536         unify_faces.unify_sets( Pitem[face(e)],
00537                                 Pitem[face(twin(e))] );
00538         CGAL_NEF_TRACEN("unioning disjoint faces");
00539       }
00540       if ( is_closed_at_source(e) )       set_face(source(e),face(e));
00541       if ( is_closed_at_source(twin(e)) ) set_face(target(e),face(e));
00542       delete_halfedge_pair(e);
00543     }
00544   }
00545   
00546   CGAL::Unique_hash_map<Halfedge_handle,bool> linked(false);
00547   for (e = this->halfedges_begin(); e != eend; ++e) {
00548     if ( linked[e] ) continue;
00549     Halfedge_around_face_circulator hfc(e),hend(hfc);
00550     Halfedge_handle e_min = e;
00551     Face_handle f = *(unify_faces.find(Pitem[face(e)]));
00552     CGAL_For_all(hfc,hend) {
00553       set_face(hfc,f);
00554       if(target(hfc) == target(e_min)) {
00555         Point p1 = point(source(hfc)), 
00556           p2 = point(target(hfc)), 
00557           p3 = point(target(next(hfc)));
00558         if (!K.left_turn(p1,p2,p3) )
00559           e_min = hfc;
00560       } else if ( K.compare_xy(point(target(hfc)), point(target(e_min))) < 0 )
00561         e_min = hfc;
00562       linked[hfc]=true;
00563     }
00564     Point p1 = point(source(e_min)),
00565           p2 = point(target(e_min)),
00566           p3 = point(target(next(e_min)));
00567     if ( K.orientation(p1,p2,p3) > 0 ) set_halfedge(f,e_min); // outer
00568     else set_hole(f,e_min); // store as inner
00569   }
00570 
00571 
00572   Vertex_iterator v, vn, vend = this->vertices_end();
00573   for(v = this->vertices_begin(); v != vend; v=vn) { CGAL_NEF_TRACEN("at vertex "<<PV(v));
00574     vn=v; ++vn;
00575     if ( is_isolated(v) ) {
00576       if ( mark(v) == mark(face(v)) ) delete_vertex_only(v);
00577       else set_isolated_vertex(face(v),v); 
00578     } else { // v not isolated
00579       Halfedge_handle e2 = first_out_edge(v), e1 = previous(e2);
00580       Point p1 = point(source(e1)), p2 = point(v), 
00581             p3 = point(target(e2));
00582       if ( has_outdeg_two(v) &&
00583            mark(v) == mark(e1) && mark(v) == mark(e2) &&
00584            (K.orientation(p1,p2,p3) == 0) ) 
00585         merge_halfedge_pairs_at_target(e1); 
00586     }
00587   }
00588 
00589   Face_iterator fn;
00590   for (f = this->faces_begin(); f != fend; f=fn) {
00591     fn=f; ++fn;
00592     Union_find_handle pit = Pitem[f];
00593     if ( unify_faces.find(pit) != pit ) delete_face(f);
00594   }
00595 
00596 
00597 }
00598 
00599 struct vertex_info {
00600   Mark                  m[2];
00601   Vertex_const_handle   v_supp[2];
00602   Halfedge_const_handle e_supp[2];
00603   Halfedge_handle       e_below;
00604   vertex_info() 
00605   { v_supp[0]=v_supp[1]=Vertex_const_handle(); 
00606     e_supp[0]=e_supp[1]=Halfedge_const_handle(); }
00607   LEDA_MEMORY(vertex_info)
00608 };
00609 
00610 void assoc_info(Vertex_handle v) const
00611 { geninfo<vertex_info>::create(info(v)); }
00612 
00613 void discard_info(Vertex_handle v) const
00614 { geninfo<vertex_info>::clear(info(v)); }
00615 
00616 vertex_info& ginfo(Vertex_handle v) const
00617 { return geninfo<vertex_info>::access(info(v)); }
00618 
00619 Mark& mark(Vertex_handle v, int i) const
00620 { return ginfo(v).m[i]; }
00621 
00622 Vertex_const_handle& supp_vertex(Vertex_handle v, int i) const
00623 { return ginfo(v).v_supp[i]; }
00624 
00625 Halfedge_const_handle& supp_halfedge(Vertex_handle v, int i) const
00626 { return ginfo(v).e_supp[i]; }
00627 
00628 Halfedge_handle& halfedge_below(Vertex_handle v) const
00629 { return ginfo(v).e_below; }
00630 
00631 struct halfedge_info {
00632   Mark                  m[2];
00633   Mark                  mf[2];
00634   Halfedge_const_handle e_supp[2];
00635   bool                  forw;
00636   halfedge_info()
00637   { m[0]=m[1]=mf[0]=mf[1]=Mark(); 
00638     e_supp[0]=e_supp[1]=Halfedge_const_handle(); 
00639     forw=false; }
00640   LEDA_MEMORY(halfedge_info)
00641 };
00642 
00643 void assoc_info(Halfedge_handle e)  const
00644 { geninfo<halfedge_info>::create(info(e)); 
00645   geninfo<halfedge_info>::create(info(twin(e))); }
00646 
00647 void discard_info(Halfedge_handle e)  const
00648 { geninfo<halfedge_info>::clear(info(e)); 
00649   geninfo<halfedge_info>::clear(info(twin(e))); }
00650 
00651 halfedge_info& ginfo(Halfedge_handle e)  const
00652 { return geninfo<halfedge_info>::access(info(e)); }
00653 
00654 Mark& mark(Halfedge_handle e, int i)  const
00655 // uedge information we store in the smaller one 
00656 { if (&*e < &*(twin(e))) return ginfo(e).m[i]; 
00657   else                   return ginfo(twin(e)).m[i]; }
00658 
00659 Halfedge_const_handle& supp_halfedge(Halfedge_handle e, int i) const
00660 // uedge information we store in the smaller one 
00661 { if (&*e < &*(twin(e))) return ginfo(e).e_supp[i]; 
00662   else                   return ginfo(twin(e)).e_supp[i]; }
00663 
00664 Mark& incident_mark(Halfedge_handle e, int i)  const
00665 // biedge information we store in the halfedge
00666 { return ginfo(e).mf[i]; }
00667 
00668 bool& is_forward(Halfedge_handle e) const
00669 // biedge information we store in the halfedge
00670 { return ginfo(e).forw; }
00671 
00672 struct face_info {
00673   Mark m[2];
00674   face_info() { m[0]=m[1]=Mark(); }
00675   LEDA_MEMORY(face_info)
00676 };
00677 
00678 void assoc_info(Face_handle f)  const
00679 { geninfo<face_info>::create(info(f)); }
00680 
00681 void discard_info(Face_handle f)  const
00682 { geninfo<face_info>::clear(info(f)); }
00683 
00684 face_info& ginfo(Face_handle f)  const
00685 { return geninfo<face_info>::access(info(f)); }
00686 
00687 Mark& mark(Face_handle f, int i)  const
00688 { return ginfo(f).m[i]; }
00689 
00690 void clear_associated_info_of_all_objects() const 
00691 {
00692   Vertex_iterator vit;
00693   for (vit = this->vertices_begin(); vit != this->vertices_end(); ++vit)
00694     discard_info(vit);
00695   Halfedge_iterator hit;
00696   for (hit = this->halfedges_begin(); hit != this->halfedges_end(); ++hit) 
00697     discard_info(hit);
00698   Face_iterator fit;
00699   for (fit = this->faces_begin(); fit != this->faces_end(); ++fit) 
00700     discard_info(fit);
00701 }
00702 
00703 template <typename Below_info>
00704 void create_face_objects(const Below_info& D) const
00705 {
00706   CGAL_NEF_TRACEN("create_face_objects()");
00707   CGAL::Unique_hash_map<Halfedge_handle,int> FaceCycle(-1);
00708   std::vector<Halfedge_handle>  MinimalHalfedge;
00709   int i=0;
00710   Halfedge_iterator e, eend = this->halfedges_end();
00711   for (e=this->halfedges_begin(); e != eend; ++e) {
00712     if ( FaceCycle[e] >= 0 ) continue; // already assigned
00713     Halfedge_around_face_circulator hfc(e),hend(hfc);
00714     Halfedge_handle e_min = e;
00715     CGAL_NEF_TRACE("face cycle "<<i<<"\n");
00716     CGAL_For_all(hfc,hend) {
00717       FaceCycle[hfc]=i; // assign face cycle number
00718       if(target(hfc) == target(e_min)) {
00719         Point p1 = point(source(hfc)), 
00720           p2 = point(target(hfc)), 
00721           p3 = point(target(next(hfc)));
00722         if (!K.left_turn(p1,p2,p3) )
00723           e_min = hfc;
00724       } else if ( K.compare_xy(point(target(hfc)), point(target(e_min))) < 0 )
00725         e_min = hfc;
00726       CGAL_NEF_TRACE(PE(hfc));
00727     } 
00728     CGAL_NEF_TRACEN("");
00729     MinimalHalfedge.push_back(e_min); ++i;
00730   }
00731 
00732   Face_handle f_outer = this->new_face();
00733   for (int j=0; j<i; ++j) {
00734     Halfedge_handle e = MinimalHalfedge[j];
00735       CGAL_NEF_TRACEN("  face cycle "<<j);CGAL_NEF_TRACEN("  minimal halfedge "<<PE(e));
00736     Point p1 = point(source(e)), 
00737           p2 = point(target(e)), 
00738           p3 = point(target(next(e)));
00739     if ( K.left_turn(p1,p2,p3) ) { // left_turn => outer face cycle
00740       CGAL_NEF_TRACEN("  creating new face object");
00741       Face_handle f = this->new_face();
00742       link_as_outer_face_cycle(f,e);
00743     }
00744   }
00745 
00746   for (e = this->halfedges_begin(); e != eend; ++e) {
00747     if ( face(e) != Face_handle() ) continue;
00748     CGAL_NEF_TRACEN("linking hole "<<PE(e));
00749     Face_handle f = determine_face(e,MinimalHalfedge,FaceCycle,D);
00750     link_as_hole(f,e);
00751   }
00752   Vertex_iterator v, v_end = this->vertices_end();
00753   for (v = this->vertices_begin(); v != v_end; ++v) {
00754     if ( !is_isolated(v) ) continue;
00755     Halfedge_handle e_below = D.halfedge_below(v);
00756     if ( e_below == Halfedge_handle() ) 
00757       link_as_isolated_vertex(f_outer,v);
00758     else
00759       link_as_isolated_vertex(face(e_below),v);    
00760   }
00761 
00762 }
00763 
00764 template <typename Below_info>
00765 void create_face_objects_pl(const Below_info& D) const
00766 {
00767   CGAL_NEF_TRACEN("create_face_objects_pl()");
00768   CGAL::Unique_hash_map<Halfedge_handle,int> FaceCycle(-1);
00769   std::vector<Halfedge_handle>  MinimalHalfedge;
00770   int i=0;
00771   Halfedge_iterator e, eend = this->halfedges_end();
00772   for (e=this->halfedges_begin(); e != eend; ++e) {
00773     if ( FaceCycle[e] >= 0 ) continue; // already assigned
00774     Halfedge_around_face_circulator hfc(e),hend(hfc);
00775     Halfedge_handle e_min = e;
00776     CGAL_NEF_TRACE("face cycle "<<i<<"\n");
00777     CGAL_For_all(hfc,hend) {
00778       FaceCycle[hfc]=i; // assign face cycle number
00779       if(target(hfc) == target(e_min)) {
00780         Point p1 = point(source(hfc)), 
00781           p2 = point(target(hfc)), 
00782           p3 = point(target(next(hfc)));
00783         if (!K.left_turn(p1,p2,p3) )
00784           e_min = hfc;
00785       } else if ( K.compare_xy(point(target(hfc)), point(target(e_min))) < 0 )
00786         e_min = hfc;
00787       CGAL_NEF_TRACE(PE(hfc));
00788     } 
00789     CGAL_NEF_TRACEN("");
00790     MinimalHalfedge.push_back(e_min); ++i;
00791   }
00792 
00793   Face_handle f_outer = this->new_face();
00794   for (int j=0; j<i; ++j) {
00795     Halfedge_handle e = MinimalHalfedge[j];
00796       CGAL_NEF_TRACEN("  face cycle "<<j);CGAL_NEF_TRACEN("  minimal halfedge "<<PE(e));
00797     Point p1 = point(source(e)), 
00798           p2 = point(target(e)), 
00799           p3 = point(target(next(e)));
00800     if ( K.left_turn(p1,p2,p3) ) { // left_turn => outer face cycle
00801       CGAL_NEF_TRACEN("  creating new face object");
00802       Halfedge_around_face_circulator hfc(e),hend(hfc);
00803       Face_handle f = this->new_face();
00804       link_as_outer_face_cycle(f,e);
00805     }
00806   }
00807 
00808   for (e = this->halfedges_begin(); e != eend; ++e) {
00809     if ( face(e) != Face_handle() ) continue;
00810     CGAL_NEF_TRACEN("linking hole "<<PE(e));
00811     Face_handle f = determine_face(e,MinimalHalfedge,FaceCycle,D);
00812     link_as_hole(f,e);
00813   }
00814 }
00815 
00816 template <typename Below_info>
00817 Face_handle determine_face(Halfedge_handle e, 
00818   const std::vector<Halfedge_handle>& MinimalHalfedge,
00819   const CGAL::Unique_hash_map<Halfedge_handle,int>& FaceCycle,
00820   const Below_info& D) const
00821 { CGAL_NEF_TRACEN("determine_face "<<PE(e));
00822   Halfedge_handle e_min = MinimalHalfedge[FaceCycle[e]];
00823   Halfedge_handle e_below = D.halfedge_below(target(e_min));
00824   if ( e_below == Halfedge_handle() ) // below is nirwana
00825     return this->faces_begin();
00826   Face_handle f = face(e_below);
00827   if (f != Face_handle()) return f; // has face already
00828   f = determine_face(e_below, MinimalHalfedge, FaceCycle,D);
00829   link_as_hole(f,e_below);
00830   return f;
00831 }
00832 
00833 Segment segment(const Const_decorator& N, 
00834                 Halfedge_const_handle e) const
00835 { return K.construct_segment(
00836     N.point(N.source(e)),N.point(N.target(e))); }
00837 
00838 Segment segment(const Const_decorator& N, 
00839                 Vertex_const_handle v) const
00840 { Point p = N.point(v); 
00841   return K.construct_segment(p,p); }
00842 
00843 bool is_forward_edge(const Const_decorator& N, 
00844                      Halfedge_const_iterator hit) const
00845 { Point p1 = N.point(N.source(hit));
00846   Point p2 = N.point(N.target(hit));
00847   return (K.compare_xy(p1,p2) < 0); }
00848 
00849 void assert_type_precondition() const
00850 { typename PM_decorator_::Point p1; Point p2;
00851   assert_equal_types(p1,p2); }
00852 
00853 
00854 
00855 }; // PM_overlayer<PM_decorator_,Geometry_>
00856 
00857 
00858 
00859 CGAL_END_NAMESPACE
00860 #endif // CGAL_PM_OVERLAYER_H
00861 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines