BWAPI
|
00001 // Copyright (c) 1997-2002 Max-Planck-Institute Saarbruecken (Germany). 00002 // All rights reserved. 00003 // 00004 // This file is part of CGAL (www.cgal.org); you may redistribute it under 00005 // the terms of the Q Public License version 1.0. 00006 // See the file LICENSE.QPL distributed with CGAL. 00007 // 00008 // Licensees holding a valid commercial license may use this file in 00009 // accordance with the commercial license agreement provided with the software. 00010 // 00011 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 00012 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 00013 // 00014 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/Nef_S2/include/CGAL/Nef_S2/SM_decorator.h $ 00015 // $Id: SM_decorator.h 45448 2008-09-09 16:03:25Z spion $ 00016 // 00017 // 00018 // Author(s) : Michael Seel <seel@mpi-sb.mpg.de> 00019 // Miguel Granados <granados@mpi-sb.mpg.de> 00020 // Susan Hert <hert@mpi-sb.mpg.de> 00021 // Lutz Kettner <kettner@mpi-sb.mpg.de> 00022 // Peter Hachenberger <hachenberger@mpi-sb.mpg.de> 00023 #ifndef CGAL_SM_DECORATOR_H 00024 #define CGAL_SM_DECORATOR_H 00025 00026 #include <CGAL/basic.h> 00027 #include <CGAL/Nef_S2/SM_const_decorator.h> 00028 00029 #undef CGAL_NEF_DEBUG 00030 #define CGAL_NEF_DEBUG 23 00031 #include <CGAL/Nef_2/debug.h> 00032 #include <CGAL/Nef_S2/SM_decorator_traits.h> 00033 #include <CGAL/Nef_S2/Sphere_map.h> 00034 #include <CGAL/Nef_S2/Normalizing.h> 00035 #include <CGAL/Unique_hash_map.h> 00036 #include <CGAL/IO/Verbose_ostream.h> 00037 00038 CGAL_BEGIN_NAMESPACE 00039 00040 /*{\Moptions print_title=yes }*/ 00041 /*{\Moptions outfile=SM_decorator.man }*/ 00042 /*{\Manpage {SM_decorator}{Sphere_map} 00043 {Topological sphere map decorator}{D}}*/ 00044 00045 template <typename Map_> 00046 class SM_decorator 00047 { 00048 public: 00049 typedef Map_ Map; 00050 typedef Map_ Sphere_map; 00051 typedef SM_decorator<Map> Self; 00052 typedef SM_decorator_traits<Map> Decorator_traits; 00053 /*{\Mdefinition ...}*/ 00054 00055 /*{\Mtypes 5}*/ 00056 00057 typedef CGAL::SM_const_decorator<Map> SM_const_decorator; 00058 00059 typedef typename Map::Sphere_kernel Sphere_kernel; 00060 /*{\Mtypemember spherical geometry.}*/ 00061 00062 typedef typename Map::Sphere_point Sphere_point; 00063 /*{\Mtypemember embedding vertices.}*/ 00064 00065 typedef typename Map::Sphere_segment Sphere_segment; 00066 /*{\Mtypemember embedding edges.}*/ 00067 00068 typedef typename Map::Sphere_circle Sphere_circle; 00069 /*{\Mtypemember embedding loops.}*/ 00070 00071 typedef typename Map::Sphere_direction Sphere_direction; 00072 /*{\Mtypemember embedding directions.}*/ 00073 00074 typedef typename Map::Mark Mark; 00075 /*{\Mtypemember attributes of objects (vertices, edges, faces).}*/ 00076 00077 typedef size_t Size_type; 00078 /*{\Mtypemember size type.}*/ 00079 00080 enum { BEFORE = -1, AFTER = 1 }; 00081 /*{\Menum insertion order labels.}*/ 00082 00083 typedef typename Sphere_kernel::Aff_transformation_3 Aff_transformation_3; 00084 00085 typedef void* GenPtr; 00086 typedef typename Map::SVertex SVertex; 00087 typedef typename Map::SVertex_handle SVertex_handle; 00088 typedef typename Map::SVertex_iterator SVertex_iterator; 00089 typedef typename Map::SVertex_const_handle SVertex_const_handle; 00090 typedef typename Map::SVertex_const_iterator SVertex_const_iterator; 00091 typedef typename Map::SHalfedge SHalfedge; 00092 typedef typename Map::SHalfedge_handle SHalfedge_handle; 00093 typedef typename Map::SHalfedge_iterator SHalfedge_iterator; 00094 typedef typename Map::SHalfedge_const_handle SHalfedge_const_handle; 00095 typedef typename Map::SHalfedge_const_iterator SHalfedge_const_iterator; 00096 typedef typename Map::SFace SFace; 00097 typedef typename Map::SFace_handle SFace_handle; 00098 typedef typename Map::SFace_iterator SFace_iterator; 00099 typedef typename Map::SFace_const_handle SFace_const_handle; 00100 typedef typename Map::SFace_const_iterator SFace_const_iterator; 00101 typedef typename Map::SHalfloop SHalfloop; 00102 typedef typename Map::SHalfloop_handle SHalfloop_handle; 00103 typedef typename Map::SHalfloop_iterator SHalfloop_iterator; 00104 typedef typename Map::SHalfloop_const_handle SHalfloop_const_handle; 00105 typedef typename Map::SHalfloop_const_iterator SHalfloop_const_iterator; 00106 typedef typename Map::Object_handle Object_handle; 00107 typedef typename Map::SHalfedge_around_svertex_circulator 00108 SHalfedge_around_svertex_circulator; 00109 typedef typename Map::SHalfedge_around_sface_circulator 00110 SHalfedge_around_sface_circulator; 00111 typedef typename Map::SFace_cycle_iterator SFace_cycle_iterator; 00112 00113 /*{\Mtypemember iterating all face cycles of an face |f|. 00114 The iterator has method |bool is_svertex()|, |bool is_shalfedge()|, 00115 |bool is_shalfloop()|, and can be converted to the corresponding 00116 handles |SVertex_handle|, |SHalfedge_handle|, or 00117 |SHalfloop_handle|.}*/ 00118 00119 protected: 00120 Map* psm_; 00121 00122 public: 00123 /*{\Mcreation 3}*/ 00124 SM_decorator() : psm_(0) {} 00125 SM_decorator(const Self& D) : psm_(D.psm_) {} 00126 Self& operator=(const Self& D) { psm_=D.psm_; return *this; } 00127 00128 SM_decorator(Map* M) : psm_(M) {} 00129 00130 /*{\Moperations 4 4}*/ 00131 00132 Map* sphere_map() const { return psm_; } 00133 00134 Map* map() { return psm_; } 00135 const Map* map() const { return psm_; } 00136 00137 bool is_isolated(SVertex_const_handle v) const 00138 { return (v->out_sedge() == SHalfedge_handle()); } 00139 00140 bool is_isolated(SVertex_handle v) const 00141 /*{\Mop returns |true| when |v| is linked to the interior of a face.}*/ 00142 { return (v->out_sedge() == SHalfedge_handle()); } 00143 00144 SHalfedge_const_handle first_out_edge(SVertex_const_handle v) const 00145 { return v->out_sedge(); } 00146 SHalfedge_const_handle last_out_edge(SVertex_const_handle v) const 00147 { return cap(v->out_sedge()); } 00148 00149 SHalfedge_handle first_out_edge(SVertex_handle v) const 00150 /*{\Mop returns one edge with source |v|. It's the starting point for 00151 the circular iteration over the edges with source |v|. 00152 \precond |!is_isolated(v)|.}*/ 00153 { return v->out_sedge(); } 00154 00155 SHalfedge_handle last_out_edge(SVertex_handle v) const 00156 /*{\Mop returns one edge with source |v|. \precond |!is_isolated(v)|.}*/ 00157 { return cap(v->out_sedge()); } 00158 00159 SHalfedge_const_handle cyclic_adj_succ(SHalfedge_const_handle e) const 00160 { return e->sprev()->twin(); } 00161 SHalfedge_const_handle cyclic_adj_pred(SHalfedge_const_handle e) const 00162 { return e->twin()->snext(); } 00163 00164 SHalfedge_handle cyclic_adj_succ(SHalfedge_handle e) const 00165 /*{\Mop returns the edge after |e| in the cyclic ordered adjacency list of 00166 |e->source()|.}*/ 00167 { return e->sprev()->twin(); } 00168 00169 SHalfedge_handle cyclic_adj_pred(SHalfedge_handle e) const 00170 /*{\Mop returns the edge before |e| in the cyclic ordered adjacency list of 00171 |e->source()|.}*/ 00172 { return e->twin()->snext(); } 00173 00174 bool has_shalfloop() const 00175 /*{\Mop returns true iff there is a loop.}*/ 00176 { return psm_->has_shalfloop(); } 00177 00178 /*{\Mtext \headerline{Iteration} \setopdims{3.3cm}{0cm}}*/ 00179 00180 SVertex_iterator svertices_begin() const 00181 { return psm_->svertices_begin(); } 00182 SVertex_iterator svertices_end() const 00183 { return psm_->svertices_end(); } 00184 SHalfedge_iterator shalfedges_begin() const 00185 { return psm_->shalfedges_begin(); } 00186 SHalfedge_iterator shalfedges_end() const 00187 { return psm_->shalfedges_end(); } 00188 SFace_iterator sfaces_begin() const 00189 { return psm_->sfaces_begin(); } 00190 SFace_iterator sfaces_end() const 00191 { return psm_->sfaces_end(); } 00192 SHalfloop_iterator shalfloops_begin() const 00193 { return psm_->shalfloops_begin(); } 00194 SHalfloop_iterator shalfloops_end() const 00195 { return psm_->shalfloops_end(); } 00196 00197 SHalfloop_handle& shalfloop() 00198 { return psm_->shalfloop(); } 00199 SHalfloop_const_handle shalfloop() const 00200 { return psm_->shalfloop(); } 00201 00202 Size_type number_of_svertices() const 00203 /*{\Mop returns the number of vertices.}*/ 00204 { return psm_->number_of_svertices(); } 00205 00206 Size_type number_of_shalfedges() const 00207 /*{\Mop returns the number of halfedges.}*/ 00208 { return psm_->number_of_shalfedges(); } 00209 00210 Size_type number_of_sedges() const 00211 /*{\Mop returns the number of edges.}*/ 00212 { return number_of_shalfedges()/2; } 00213 00214 Size_type number_of_shalfloops() const 00215 /*{\Mop returns the number of halfloops.}*/ 00216 { return psm_->number_of_shalfloops(); } 00217 00218 Size_type number_of_sloops() const 00219 /*{\Mop returns the number of loops.}*/ 00220 { return psm_->number_of_shalfloops()/2; } 00221 00222 Size_type number_of_sfaces() const 00223 /*{\Mop returns the number of faces.}*/ 00224 { return psm_->number_of_sfaces(); } 00225 00226 SFace_cycle_iterator sface_cycles_begin(SFace_handle f) const 00227 /*{\Mop returns an iterator for all bounding face cycles of |f|. 00228 The iterator is is convertable to |SVertex_handle|, 00229 |SHalfloop_handle|, or |SHalfedge_handle|.}*/ 00230 { return f->boundary_entry_objects().begin(); } 00231 00232 SFace_cycle_iterator sface_cycles_end(SFace_handle f) const 00233 /*{\Mop returns the past the end iterator of |f|.}*/ 00234 { return f->boundary_entry_objects_.end(); } 00235 00236 SHalfedge_around_svertex_circulator 00237 out_edges(SVertex_handle v) const 00238 /*{\Mop returns a circulator for the cyclic adjacency list of |v|. 00239 \precond the adjacency list is not empty.}*/ 00240 { return SHalfedge_around_svertex_circulator(first_out_edge(v)); } 00241 00242 /*{\Mtext \headerline{Update Operations}}*/ 00243 00244 void clear() const 00245 /*{\Mop reintializes |P| to the empty map.}*/ 00246 { psm_->clear(); } 00247 00248 bool is_closed_at_source(SHalfedge_handle e) const 00249 /*{\Mop returns |true| when |e->sprev() == e->twin()|.}*/ 00250 { return e->sprev() == e->twin(); } 00251 00252 bool is_closed_at_target(SHalfedge_handle e) const 00253 /*{\Mop returns |true| when |e->snext() == e->twin()|.}*/ 00254 { return e->snext() == e->twin(); } 00255 00256 SHalfedge_handle cas(SHalfedge_handle e) const 00257 { return cyclic_adj_succ(e); } 00258 SHalfedge_handle cap(SHalfedge_handle e) const 00259 { return cyclic_adj_pred(e); } 00260 00261 template <typename H> 00262 void make_twins(H h1, H h2) const 00263 { h1->twin() = h2; h2->twin() = h1; } 00264 00265 SVertex_handle new_svertex(const Sphere_point& p = Sphere_point()) 00266 /*{\Mop creates a new vertex.}*/ 00267 { return map()->new_svertex(p); } 00268 00269 SHalfedge_handle new_shalfedge_pair() { 00270 /*{\Xop creates a new edge pair. No connectivity is provided.}*/ 00271 return map()->new_shalfedge_pair(); 00272 } 00273 00274 SHalfloop_handle new_shalfloop_pair() 00275 /*{\Mop creates a new loop pair. 00276 \precond No sloop pair exists in the local graph.}*/ 00277 { CGAL_assertion(!has_shalfloop()); 00278 return map()->new_shalfloop_pair(); 00279 } 00280 00281 SFace_handle new_sface() 00282 /*{\Mop creates a new face.}*/ 00283 { return map()->new_sface(); } 00284 00285 void delete_vertex_only(SVertex_handle v) 00286 /*{\Mop deletes |v| without any connectivity update.}*/ 00287 { map()->delete_svertex(v); } 00288 00289 void delete_edge_pair_only(SHalfedge_handle e) 00290 /*{\Mop deletes |e| and its twin without any connectivity update.}*/ 00291 { map()->delete_shalfedge_pair(e); } 00292 00293 void delete_halfedge_only(SHalfedge_handle e) 00294 /*{\Mop deletes |e| without its twin and without any connectivity update.}*/ 00295 { map()->delete_shalfedge(e); } 00296 00297 void delete_face_only(SFace_handle f) 00298 /*{\Mop deletes |f| without any connectivity update.}*/ 00299 { map()->delete_sface(f); } 00300 00301 void delete_loop_only() 00302 /*{\Mop deletes the loop and its twin without any connectivity update.}*/ 00303 { map()->delete_shalfloop_pair(); } 00304 00305 template <typename H> 00306 bool is_sm_boundary_object(H h) const 00307 { return map()->is_sm_boundary_object(h); } 00308 00309 template <typename H> 00310 void store_sm_boundary_object(H h, SFace_handle f) { 00311 CGAL_assertion(!map()->is_sm_boundary_object(h)); 00312 f->boundary_entry_objects().push_back(make_object(h)); 00313 map()->store_sm_boundary_item(h, --(f->sface_cycles_end())); 00314 } 00315 00316 template <typename H> 00317 void undo_sm_boundary_object(H h, SFace_handle f) 00318 { CGAL_assertion(map()->is_sm_boundary_object(h)); 00319 SFace_cycle_iterator it = map()->sm_boundary_item(h); 00320 map()->undef_sm_boundary_item(h); 00321 f->boundary_entry_objects().erase(it); 00322 } 00323 00324 void link_as_face_cycle(SHalfedge_handle e, SFace_handle f) 00325 /*{\Mop creates a new face cycle of |f| and 00326 makes |e| the entry point of it.}*/ 00327 { 00328 SHalfedge_around_sface_circulator hfc(e), hend(hfc); 00329 CGAL_For_all(hfc,hend) hfc->incident_sface() = f; 00330 store_sm_boundary_object(e,f); 00331 } 00332 00333 void link_as_loop(SHalfloop_handle l, SFace_handle f) 00334 /*{\Mop creates a new trivial face cycle of |f| and 00335 makes |l| the singular object of it.}*/ 00336 { store_sm_boundary_object(l,f); l->incident_sface() = f; } 00337 00338 void link_as_isolated_vertex(SVertex_handle v, SFace_handle f) 00339 /*{\Mop creates a new trivial face cycle of |f|. 00340 (makes |v| an isolated vertex within |f|).}*/ 00341 { store_sm_boundary_object(v,f); v->incident_sface() = f; } 00342 00343 void unlink_as_face_cycle(SHalfedge_handle e) 00344 /*{\Mop removes the face cycle defined by |e| from |e->incident_sface()|. 00345 Does not update the face links of the corresponding face cycle 00346 edges. \precond |e| is the entry object of the face cycle.}*/ 00347 { undo_sm_boundary_object(e,e->incident_sface()); } 00348 00349 void unlink_as_loop(SHalfloop_handle l) 00350 /*{\Mop removes the trivial face cycle defined by |l| from 00351 |l->incident_sface()|. Does not update |l|'s face link.}*/ 00352 { undo_sm_boundary_object(l,l->incident_sface()); } 00353 00354 void unlink_as_isolated_vertex(SVertex_handle v) 00355 /*{\Mop removes the trivial face cycle defined by |v| from 00356 |v->incident_sface()|. Does not update |v|'s face link. 00357 \precond |v| is a trivial face cycle of |v->incident_sface()|.}*/ 00358 { undo_sm_boundary_object(v,v->incident_sface()); } 00359 00360 void clear_face_cycle_entries(SFace_handle f) 00361 { map()->reset_sm_object_list(f->boundary_entry_objects()); 00362 // removes entries of list and the hashed membership 00363 } 00364 00365 SHalfedge_handle new_shalfedge_pair(SVertex_handle v1, 00366 SVertex_handle v2) 00367 /*{\Mop creates a new pair of edges |(e1,e2)| representing |(v1,v2)| 00368 by appending the |ei| to |A(vi)| $(i=1,2)$.}*/ 00369 { SHalfedge_handle e1 = new_shalfedge_pair(); 00370 SHalfedge_handle e2 = e1->twin(); 00371 if (!is_isolated(v1)) 00372 set_adjacency_at_source_between(cap(first_out_edge(v1)),e1, 00373 first_out_edge(v1)); 00374 else 00375 close_tip_at_source(e1,v1); 00376 if (!is_isolated(v2)) 00377 set_adjacency_at_source_between(cap(first_out_edge(v2)),e2, 00378 first_out_edge(v2)); 00379 else 00380 close_tip_at_source(e2,v2); 00381 return e1; 00382 } 00383 00384 00385 SHalfedge_handle new_shalfedge_pair(SHalfedge_handle e1, 00386 SHalfedge_handle e2, 00387 int pos1 = AFTER, int pos2 = AFTER) 00388 /*{\Mop creates a new pair of edges |(es1,es2)| representing the uedge 00389 |\{e1->source(),e2->source()\}| by inserting the |esi| before or after |ei| 00390 into the cyclic adjacency list of |ei->source()| depending on |posi| 00391 $(i=1,2)$ from |\Mname::BEFORE|, |\Mname::AFTER|.}*/ 00392 { 00393 SHalfedge_handle er = new_shalfedge_pair(); 00394 SHalfedge_handle ero = er->twin(); 00395 if (pos1 < 0) { // before e1 00396 set_adjacency_at_source_between(cap(e1),er,e1); 00397 if ( e1 == first_out_edge(e1->source()) ) 00398 set_first_out_edge(e1->source(),er); 00399 } else { // after e1 00400 set_adjacency_at_source_between(e1,er,cas(e1)); 00401 } 00402 if (pos2 < 0) { // before e2 00403 set_adjacency_at_source_between(cap(e2),ero,e2); 00404 if ( e2 == first_out_edge(e2->source()) ) 00405 set_first_out_edge(e2->source(),ero); 00406 } else { // after e2 00407 set_adjacency_at_source_between(e2,ero,cas(e2)); 00408 } 00409 return er; 00410 } 00411 00412 SHalfedge_handle new_shalfedge_pair(SHalfedge_handle e, SVertex_handle v, 00413 int pos = AFTER) 00414 /*{\Mop creates a new pair of edges |(e1,e2)| representing the uedge 00415 |\{e->source(),v\}| by inserting |e1| before or after |e| into cyclic 00416 adjacency list of |e->source()| depending on |pos| from |\Mname::BEFORE|, 00417 |\Mname::AFTER| and appending |e2| at |A(v)|.}*/ 00418 { 00419 SHalfedge_handle e_new = new_shalfedge_pair(); 00420 SHalfedge_handle e_opp = e_new->twin(); 00421 if (pos < 0) { // before e 00422 set_adjacency_at_source_between(cap(e),e_new,e); 00423 if ( e == first_out_edge(e->source()) ) 00424 set_first_out_edge(e->source(),e_new); 00425 } else // after e 00426 set_adjacency_at_source_between(e,e_new,cas(e)); 00427 00428 if (!is_isolated(v)) { 00429 SHalfedge_handle e_first = first_out_edge(v); 00430 set_adjacency_at_source_between(cap(e_first),e_opp,e_first); 00431 } else 00432 close_tip_at_source(e_opp,v); 00433 return e_new; 00434 } 00435 00436 00437 SHalfedge_handle new_shalfedge_pair(SVertex_handle v, SHalfedge_handle e, 00438 int pos = AFTER) 00439 /*{\Mop symmetric to the previous one.}*/ 00440 { return new_shalfedge_pair(e,v,pos)->twin(); } 00441 00442 void delete_edge_pair(SHalfedge_handle e) 00443 /*{\Mop deletes |e| and its twin and maintains the adjacency at its source 00444 and its target.}*/ 00445 { remove_from_adj_list_at_source(e); 00446 remove_from_adj_list_at_source(e->twin()); 00447 delete_edge_pair_only(e); 00448 } 00449 00450 SHalfedge_handle split_at(SHalfedge_handle e, Sphere_point sp) 00451 { 00452 CGAL_assertion(sp != e->source()->point()); 00453 CGAL_assertion(sp != e->twin()->source()->point()); 00454 CGAL_assertion(Sphere_segment(e->source()->point(), 00455 e->twin()->source()->point(), 00456 e->circle()).has_on(sp)); 00457 SVertex_handle v_new = new_svertex(sp); 00458 v_new->mark() = e->mark(); 00459 return split_at(e, v_new); 00460 } 00461 00462 SHalfedge_handle split_at(SHalfedge_handle e, SVertex_handle v) 00463 { 00464 CGAL_assertion(v->point() != e->source()->point()); 00465 CGAL_assertion(v->point() != e->twin()->source()->point()); 00466 CGAL_assertion(Sphere_segment(e->source()->point(), 00467 e->twin()->source()->point(), 00468 e->circle()).has_on(v->point())); 00469 00470 SHalfedge_handle e_new = new_shalfedge_pair(v, e->twin()); 00471 e_new->mark() = e_new->twin()->mark() = e->mark(); 00472 e_new->circle() = e->circle(); 00473 e_new->twin()->circle() = e->twin()->circle(); 00474 if(e->twin()->source()->out_sedge() == e->twin()) 00475 e->twin()->source()->out_sedge() = e_new->twin(); 00476 e->twin()->source() = v; 00477 e->snext()->sprev() = e_new; 00478 e_new->snext() = e->snext(); 00479 e_new->sprev() = e; 00480 e->snext() = e_new; 00481 e_new->twin()->snext() = e->twin(); 00482 e->twin()->sprev() = e_new->twin(); 00483 e_new->incident_sface() = e->incident_sface(); 00484 e_new->twin()->incident_sface() = e->twin()->incident_sface(); 00485 return e_new; 00486 } 00487 00488 void delete_vertex(SVertex_handle v) 00489 /*{\Mop deletes |v| and all outgoing edges |A(v)| as well as their twins. 00490 Updates the adjacency at the targets of the edges in |A(v)|.}*/ 00491 { 00492 if (!is_isolated(v)) { 00493 SHalfedge_handle e = first_out_edge(v); 00494 while ( e != cap(e) ) 00495 delete_edge_pair(cap(e)); 00496 delete_edge_pair(e); 00497 } 00498 delete_vertex_only(v); 00499 } 00500 00501 void delete_face(SFace_handle f) 00502 /*{\Mop deletes the face |f| without consideration of topological 00503 linkage.}*/ 00504 { clear_face_cycle_entries(f); delete_face_only(f); } 00505 00506 bool has_outdeg_two(SVertex_handle v) const 00507 /*{\Mop return true when |v| has outdegree two.}*/ 00508 // does this work for looping edges? 00509 { if (is_isolated(v)) return false; 00510 SHalfedge_handle e1 = first_out_edge(v); 00511 SHalfedge_handle e2 = last_out_edge(v); 00512 return (e1!=e2 && e2==cas(e1)); 00513 } 00514 00515 void link_as_prev_next_pair(SHalfedge_handle e1, SHalfedge_handle e2) 00516 /*{\Xop makes |e1| and |e2| adjacent in the face cycle 00517 $\ldots-|e1-e2|-\ldots$. 00518 Afterwards |e1 = e2->sprev()| and |e2 = e1->snext()|.}*/ 00519 { e1->snext() = e2; e2->sprev() = e1; } 00520 00521 void merge_edge_pairs_at_target(SHalfedge_handle e) 00522 /*{\Mop merges the edge pairs at |v = e->target()|. |e| and |twin(e)| 00523 are preserved, |e->snext()|, |twin(e->snext())| and |v| are deleted 00524 in the merger. \precond |v| has outdegree two. The adjacency at 00525 |e->source()| and |target(e->snext())| is kept consistent. 00526 If |e->snext()| was entry point of |e->incident_sface()| then |e| takes this role. 00527 The same holds for |twin(e->snext())| and |face(twin(e))|.}*/ 00528 { 00529 CGAL_NEF_TRACEN("merge_edge_pairs_at_target "<<PH(e)); 00530 SHalfedge_handle en = e->snext(), eno = en->twin(), enn, enno, 00531 eo = e->twin() ; 00532 if ( is_closed_at_target(en) ) { enn = eo; enno=e; } 00533 else { enn = en->snext(), enno = eno->sprev(); } 00534 SVertex_handle v = e->target(), vn = en->target(); 00535 CGAL_assertion(has_outdeg_two(v)); 00536 SFace_handle f1 = en->incident_sface(), f2 = eno->incident_sface(); 00537 // transfer the opposite face cycles e-en-enn to e-enn 00538 if ( enn != eno ) { 00539 link_as_prev_next_pair(e,enn); 00540 link_as_prev_next_pair(enno,eo); 00541 } else { 00542 link_as_prev_next_pair(e,eo); 00543 } 00544 // set vertex of e and deal with vertex-halfedge incidence 00545 eo->source() = vn; 00546 00547 if ( first_out_edge(vn) == eno ) set_first_out_edge(vn,eo); 00548 if ( is_sm_boundary_object(en) ) 00549 { undo_sm_boundary_object(en,f1); store_sm_boundary_object(e,f1); } 00550 if ( is_sm_boundary_object(eno) ) 00551 { undo_sm_boundary_object(eno,f2); store_sm_boundary_object(eo,f2); } 00552 delete_vertex_only(v); 00553 delete_edge_pair_only(en); 00554 CGAL_NEF_TRACEN("END "<<PH(e->sprev())<<PH(e)<<PH(e->snext())); 00555 } 00556 00557 void convert_edge_to_loop(SHalfedge_handle e) 00558 /*{\Mop converts the edge at |v = e->target()| to the unique 00559 loop |l| of |\Mvar|. |e|, |e->twin()| and |v| are deleted 00560 in the conversion. \precond there was no loop in |\Mvar|. 00561 As |e| was entry point of |e->incident_sface()| then |l| takes this role.}*/ 00562 { CGAL_NEF_TRACEN("convert_edge_to_loop "<<PH(e)); 00563 CGAL_assertion( e->source()==e->target() ); 00564 CGAL_assertion( !has_shalfloop() ); 00565 SHalfloop_handle l = new_shalfloop_pair(); 00566 SVertex_handle v = e->target(); 00567 SFace_handle f1 = e->incident_sface(), f2 = e->twin()->incident_sface(); 00568 if( is_sm_boundary_object(e)) { 00569 CGAL_assertion( is_sm_boundary_object(e->twin())); 00570 undo_sm_boundary_object(e,f1); undo_sm_boundary_object(e->twin(),f2); 00571 } 00572 link_as_loop(l,f1), link_as_loop(l->twin(),f2); 00573 l->circle() = e->circle(); l->twin()->circle() = e->twin()->circle(); 00574 l->mark() = l->twin()->mark() = e->mark(); 00575 delete_vertex_only(v); 00576 delete_edge_pair_only(e); 00577 } 00578 00579 void flip_diagonal(SHalfedge_handle e) 00580 { SHalfedge_handle r = e->twin(); 00581 SHalfedge_handle en = e->snext(), enn= en->snext(); 00582 SHalfedge_handle rn = r->snext(), rnn= rn->snext(); 00583 CGAL_NEF_TRACEN(PH(e)<<PH(en)<<PH(enn)); 00584 CGAL_NEF_TRACEN(PH(r)<<PH(rn)<<PH(rnn)); 00585 CGAL_assertion( enn->snext()==e && rnn->snext()==r ); 00586 remove_from_adj_list_at_source(e); 00587 remove_from_adj_list_at_source(r); 00588 set_adjacency_at_source_between(enn,e,en->twin()); 00589 set_adjacency_at_source_between(rnn,r,rn->twin()); 00590 } 00591 00592 00593 /*{\Mtext \headerline{Incomplete topological update primitives}}*/ 00594 00595 SHalfedge_handle new_shalfedge_pair_at_source 00596 (SHalfedge_handle e, int pos = AFTER) const 00597 /*{\Xop creates a new pair of edges |(e1,e2)| representing |(e->source(),())| 00598 by inserting |e1| before or after |e| into cyclic adjacency list of 00599 |e->source()| depending on |pos| from |\Mname::BEFORE, \Mname::AFTER|.}*/ 00600 { SHalfedge_handle e_new = new_shalfedge_pair(); 00601 if (pos < 0) set_adjacency_at_source_between(cap(e),e_new,e); 00602 else set_adjacency_at_source_between(e,e_new,cas(e)); 00603 return e_new; 00604 } 00605 00606 SHalfedge_handle new_shalfedge_pair_at_source 00607 (SVertex_handle v, int pos = AFTER) 00608 /*{\Mop creates a new pair of edges |(e1,e2)| representing |(v,())| 00609 by inserting |e1| at the beginning (BEFORE) or end (AFTER) 00610 of adjacency list of |v|.}*/ 00611 { SHalfedge_handle e1 = new_shalfedge_pair(); 00612 if (!is_isolated(v)) { 00613 SHalfedge_handle ef = first_out_edge(v); 00614 if (pos < 0) { // before e1 00615 set_adjacency_at_source_between(cap(ef),e1,ef); 00616 set_first_out_edge(v,e1); 00617 } else { 00618 set_adjacency_at_source_between(cap(ef),e1,ef); 00619 } 00620 } else 00621 close_tip_at_source(e1,v); 00622 return e1; 00623 } 00624 00625 void delete_edge_pair_at_source(SHalfedge_handle e) const 00626 /*{\Mop deletes |e| and its twin and maintains the adjacency at its 00627 source.}*/ 00628 { remove_from_adj_list_at_source(e); 00629 delete_edge_pair_only(e); 00630 } 00631 00632 void link_as_target_and_append(SVertex_handle v, SHalfedge_handle e, int pos = AFTER) 00633 /*{\Mop makes |v| the target of |e| appends |e->twin()| to the adjacency list 00634 of |v|.}*/ 00635 { if (!is_isolated(v)) { 00636 SHalfedge_handle ef = first_out_edge(v); 00637 set_adjacency_at_source_between(cap(ef), e->twin(), ef); 00638 if(pos<0) 00639 set_first_out_edge(v,e->twin()); 00640 } else 00641 close_tip_at_target(e,v); 00642 } 00643 00644 void link_as_source_of(SHalfedge_handle e, SVertex_handle v) const 00645 /*{\Mop makes |e->source() = v| and sets |e| as the first 00646 out edge if |v| was isolated before.}*/ 00647 { e->source() = v; 00648 if (v->out_sedge() == SHalfedge_handle()) v->out_sedge() = e; } 00649 00650 void link_as_target_of(SHalfedge_handle e, SVertex_handle v) const 00651 /*{\Mop makes |e->target() = v| and sets |e| as the first 00652 in edge if |v| was isolated before.}*/ 00653 { link_as_source_of(e->twin(),v); } 00654 00655 void set_adjacency_at_source_between(SHalfedge_handle e, SHalfedge_handle en) 00656 /*{\Mop makes |e| and |en| neigbors in the cyclic ordered adjacency list 00657 around |v=e->source()|. \precond |e->source()==en->source()|.}*/ 00658 { CGAL_assertion(e->source()==en->source()); 00659 link_as_prev_next_pair(en->twin(),e); 00660 } 00661 00662 void set_adjacency_at_source_between(SHalfedge_handle e1, 00663 SHalfedge_handle e_between, 00664 SHalfedge_handle e2) 00665 /*{\Mop inserts |e_between| into the adjacency list around |e1->source()| 00666 between |e1| and |e2| and makes |e1->source()| the source of |e_between|. 00667 \precond |e1->source()==e2->source()|.}*/ 00668 { 00669 e_between->source() = e1->source(); 00670 set_adjacency_at_source_between(e1,e_between); 00671 set_adjacency_at_source_between(e_between,e2); 00672 } 00673 00674 void close_tip_at_source(SHalfedge_handle e, SVertex_handle v) 00675 /*{\Mop sets |v| as source of |e| and closes the tip by setting the 00676 corresponding pointers such that |prev(e) == e->twin()| and 00677 |next(e->twin()) == e|.}*/ 00678 { link_as_source_of(e,v); 00679 link_as_prev_next_pair(e->twin(),e); } 00680 00681 void close_tip_at_target(SHalfedge_handle e, SVertex_handle v) 00682 /*{\Mop sets |v| as target of |e| and closes the tip by setting the 00683 corresponding pointers such that |prev(e->twin()) == e| and 00684 |e->snext() == e->twin()|.}*/ 00685 { link_as_target_of(e,v); 00686 link_as_prev_next_pair(e,e->twin()); } 00687 00688 00689 void remove_from_adj_list_at_source(SHalfedge_handle e) 00690 /*{\Mop removes a halfedge pair |(e,e->twin()| from the adjacency list 00691 of |e->source()|. Afterwards |next(prev(e))==next(e->twin())| and 00692 |first_out_edge(e->source())| is valid if |degree(v->source())>1| before 00693 the operation.}*/ 00694 { 00695 SVertex_handle v = e->source(); 00696 if ( is_closed_at_source(e) ) { // last outgoing 00697 v->out_sedge() = SHalfedge_handle(); 00698 } else { 00699 if (e == first_out_edge(v)) v->out_sedge() = cap(e); 00700 set_adjacency_at_source_between(cap(e),cas(e)); 00701 } 00702 } 00703 00704 void set_face(SHalfedge_handle e, SFace_handle f) const 00705 { e->incident_sface() = f; } 00706 void set_face(SHalfloop_handle l, SFace_handle f) const 00707 { l->incident_sface() = f; } 00708 void set_face(SVertex_handle v, SFace_handle f) const 00709 { v->incident_sface() = f; } 00710 void set_first_out_edge(SVertex_handle v, SHalfedge_handle e) const 00711 { v->out_sedge() = e; } 00712 void set_prev(SHalfedge_handle e, SHalfedge_handle ep) const 00713 { e->sprev() = ep; } 00714 void set_next(SHalfedge_handle e, SHalfedge_handle en) const 00715 { e->snext() = en; } 00716 void set_source(SHalfedge_handle e, SVertex_handle v) const 00717 { e->source() = v; } 00718 00719 /*{\Mtext \headerline{Associated Information}\restoreopdims}*/ 00720 00721 void set_marks_in_face_cycle(SHalfedge_handle e, Mark m) const 00722 { SHalfedge_around_sface_circulator hfc(e), hend(hfc); 00723 CGAL_For_all(hfc,hend) hfc->mark() = hfc->target()->mark() = m; 00724 } 00725 00726 GenPtr& info(SVertex_handle v) const 00727 { return v->info(); } 00728 GenPtr& info(SHalfedge_handle e) const 00729 { return e->info(); } 00730 GenPtr& info(SFace_handle f) const 00731 { return f->info(); } 00732 00733 const GenPtr& info(SVertex_const_handle v) const 00734 { return v->info(); } 00735 const GenPtr& info(SHalfedge_const_handle e) const 00736 { return e->info(); } 00737 const GenPtr& info(SFace_const_handle f) const 00738 { return f->info(); } 00739 00740 00741 /*{\Mtext \headerline{Iteration}}*/ 00742 /*{\Mtext The list of all objects can be accessed via iterator ranges. 00743 For comfortable iteration we also provide iterations macros. 00744 The iterator range access operations are of the following kind:\\ 00745 |SVertex_iterator svertices_begin()/svertices_end()|\\ 00746 |SHalfedge_iterator shalfedges_begin()/shalfedges_end()|\\ 00747 |SHalfedge_iterator sedges_begin()/sedges_end()|\\ 00748 |SFace_iterator sfaces_begin()/sfaces_end()| 00749 00750 The macros are then |CGAL_forall_svertices_of(v,V)|, 00751 |CGAL_forall_shalfedges_of(e,V)|, |CGAL_forall_sedges_of(e,V)|, 00752 |CGAL_forall_sfaces_of(f,V)|, |CGAL_forall_sface_cycles_of(fc,F)|.}*/ 00753 00754 void transform( const Aff_transformation_3& linear) { 00755 // CGAL_NEF_TRACEN("transform sphere map of vertex" << center_vertex()->point()); 00756 // The affine transformation is linear, i.e., no translation part. 00757 CGAL_precondition( linear.hm(0,3) == 0 && 00758 linear.hm(1,3) == 0 && 00759 linear.hm(2,3) == 0); 00760 00761 // CGAL_NEF_TRACEN(linear); 00762 for (SVertex_iterator i = svertices_begin(); i != svertices_end(); ++i) 00763 i->point() = normalized(Sphere_point( i->point().transform( linear))); 00764 for (SHalfedge_iterator i = shalfedges_begin(); i !=shalfedges_end(); ++i) 00765 i->circle() = Sphere_circle( i->circle().transform( linear)); 00766 if ( has_shalfloop()) { 00767 shalfloop()->circle() = Sphere_circle(shalfloop()->circle() 00768 .transform( linear)); 00769 shalfloop()->twin()->circle() 00770 = Sphere_circle(shalfloop()->twin()->circle().transform( linear)); 00771 } 00772 } 00773 00774 void extract_complement() { 00775 00776 SVertex_handle sv; 00777 CGAL_forall_svertices(sv,*this) sv->mark() = !sv->mark(); 00778 SHalfedge_handle she; 00779 CGAL_forall_shalfedges(she,*this) she->mark() = !she->mark(); 00780 SHalfloop_handle shl; 00781 if(has_shalfloop()) { 00782 shl = shalfloop(); 00783 shl->mark() = shl->twin()->mark() = !shl->mark(); 00784 } 00785 SFace_handle sf; 00786 CGAL_forall_sfaces(sf,*this) 00787 sf->mark() = !sf->mark(); 00788 } 00789 00790 void extract_interior() { 00791 00792 SVertex_handle sv; 00793 CGAL_forall_svertices(sv,*this) sv->mark() = false; 00794 SHalfedge_handle she; 00795 CGAL_forall_shalfedges(she,*this) she->mark() = false; 00796 SHalfloop_handle shl; 00797 if(has_shalfloop()) { 00798 shl = shalfloop(); 00799 shl->mark() = shl->twin()->mark() = false; 00800 } 00801 } 00802 00803 void extract_boundary() { 00804 00805 SVertex_handle sv; 00806 CGAL_forall_svertices(sv,*this) sv->mark() = true; 00807 SHalfedge_handle she; 00808 CGAL_forall_shalfedges(she,*this) she->mark() = true; 00809 SHalfloop_handle shl; 00810 if(has_shalfloop()) { 00811 shl = shalfloop(); 00812 shl->mark() = shl->twin()->mark() = true; 00813 } 00814 SFace_handle sf; 00815 CGAL_forall_sfaces(sf,*this) sf->mark() = false; 00816 } 00817 00818 bool is_valid( Unique_hash_map<SVertex_handle,bool>& sv_hash, 00819 Unique_hash_map<SHalfedge_handle,bool>& se_hash, 00820 Unique_hash_map<SFace_handle,bool>& sf_hash, 00821 bool verb = false, int level = 0) { 00822 00823 Verbose_ostream verr(verb); 00824 verr << "begin CGAL::SNC_SM_decorator<...>::is_valid( verb=true, " 00825 "level = " << level << "):" << std::endl; 00826 00827 bool valid = true; 00828 00829 int count = 0; 00830 int max = 2 * number_of_svertices() 00831 + 2 * number_of_shalfedges() 00832 + number_of_sfaces() 00833 + 2; 00834 00835 SVertex_handle sv; 00836 int isolated_vertices_found = 0; 00837 CGAL_forall_svertices(sv,*this) { 00838 valid = valid && (!sv_hash[sv]); 00839 sv_hash[sv] = true; 00840 if(is_isolated(sv)) 00841 isolated_vertices_found++; 00842 valid = valid && (++count <= max); 00843 } 00844 00845 SHalfedge_iterator she; 00846 CGAL_forall_shalfedges(she,*this) { 00847 valid = valid && she->is_valid(verb, level); 00848 00849 valid = valid && (she->twin() != she); 00850 valid = valid && (she->twin()->twin() == she); 00851 valid = valid && (she->snext()->sprev() == she); 00852 valid = valid && ((she->sprev() != she && she->snext() != she) || 00853 (she->sprev() == she && she->snext() == she)); 00854 valid = valid && (she->incident_sface() == she->snext()->incident_sface()); 00855 valid = valid && (she->incident_sface() == she->sprev()->incident_sface()); 00856 00857 valid = valid && (!se_hash[she]); 00858 00859 // Plane_3 pl(point(she->source()),point(she->target()),Point_3(0,0,0)); 00860 // Sphere_point vct(pl.orthogonal_vector()); 00861 // valid = valid && (normalized(Sphere_point(she->circle().orthogonal_vector())) == normalized(vct) || 00862 // normalized(Sphere_point(she->circle().opposite().orthogonal_vector())) == normalized(vct)); 00863 00864 se_hash[she] = true; 00865 valid = valid && (++count <= max); 00866 } 00867 00868 if(has_shalfloop()) { 00869 SHalfloop_handle shl = shalfloop(); 00870 valid = valid && shl->is_valid(); 00871 valid = valid && shl->twin()->is_valid(); 00872 valid = valid && (shl->twin() != shl); 00873 valid = valid && (shl->twin()->twin() == shl); 00874 } 00875 00876 SFace_iterator sf; 00877 SFace_cycle_iterator sfc; 00878 int loop_entries_found = 0; 00879 int edge_entries_found = 0; 00880 int vertex_entries_found = 0; 00881 CGAL_forall_sfaces(sf,*this) { 00882 valid = valid && sf->is_valid(verb, level); 00883 valid = valid && (!sf_hash[sf]); 00884 sf_hash[sf] = true; 00885 00886 CGAL_forall_sface_cycles_of(sfc,sf) { 00887 if (sfc.is_shalfloop()) 00888 loop_entries_found++; 00889 else if(sfc.is_shalfedge()) 00890 edge_entries_found++; 00891 else if(sfc.is_svertex()) 00892 vertex_entries_found++; 00893 valid = valid && (++count <= max); 00894 } 00895 00896 valid = valid && (++count <= max); 00897 } 00898 00899 if(has_shalfloop()) 00900 valid = valid && (loop_entries_found == 2); 00901 else 00902 valid = valid && (loop_entries_found == 0); 00903 00904 if(number_of_shalfedges() > 0) 00905 valid = valid && (edge_entries_found > 0); 00906 else 00907 valid = valid && (edge_entries_found == 0); 00908 00909 valid = valid && (vertex_entries_found == isolated_vertices_found); 00910 00911 verr << "end of CGAL::SNC_SM_decorator<...>::is_valid(): structure is " 00912 << ( valid ? "valid." : "NOT VALID.") << std::endl; 00913 00914 return valid; 00915 } 00916 00917 template <typename Selection> 00918 void change_marks(const Mark& m, const Selection& SP) { 00919 00920 psm_->mark() = SP(m, psm_->mark()); 00921 00922 SVertex_iterator v; 00923 CGAL_forall_svertices(v,*this) 00924 v->mark() = SP(m, v->mark()); 00925 00926 SHalfedge_iterator e; 00927 CGAL_forall_shalfedges(e,*this) 00928 e->mark() = SP(m, e->mark()); 00929 00930 SFace_iterator f; 00931 CGAL_forall_sfaces(f,*this) 00932 f->mark() = SP(m, f->mark()); 00933 } 00934 00935 template <typename Selection> 00936 void change_marks(const Selection& SP, const Mark& m) { 00937 00938 psm_->mark() = SP(psm_->mark(), m); 00939 00940 SVertex_iterator v; 00941 CGAL_forall_svertices(v,*this) 00942 v->mark() = SP(v->mark(),m); 00943 00944 SHalfedge_iterator e; 00945 CGAL_forall_shalfedges(e,*this) 00946 e->mark() = SP(e->mark(),m); 00947 00948 SFace_iterator f; 00949 CGAL_forall_sfaces(f,*this) 00950 f->mark() = SP(f->mark(),m); 00951 } 00952 00953 void check_integrity_and_topological_planarity(bool faces=true) const { 00954 SM_const_decorator C(psm_); 00955 C.check_integrity_and_topological_planarity(faces); 00956 } 00957 00958 }; // SM_decorator 00959 00960 00961 CGAL_END_NAMESPACE 00962 #endif // CGAL_SM_DECORATOR_H 00963 00964