BWAPI
|
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