BWAPI
|
00001 // Copyright (c) 1997 Tel-Aviv University (Israel). 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/Arrangement_on_surface_2/include/CGAL/Sweep_line_2/Arr_construction_sl_visitor.h $ 00015 // $Id: Arr_construction_sl_visitor.h 49772 2009-06-03 21:25:53Z eric $ 00016 // 00017 // 00018 // Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il> 00019 // Ron Wein <wein@post.tau.ac.il> 00020 00021 #ifndef CGAL_ARR_CONSTRUCTION_SL_VISITOR_H 00022 #define CGAL_ARR_CONSTRUCTION_SL_VISITOR_H 00023 00024 #ifndef CGAL_ARR_CONSTRUCTION_SL_VISITOR_VERBOSE 00025 #define CGAL_ARR_CONSTRUCTION_SL_VISITOR_VERBOSE 0 00026 #endif 00027 00028 #ifndef CGAL_NEW_FACE_SPLIT_STRATEGY 00029 #define CGAL_NEW_FACE_SPLIT_STRATEGY 0 00030 #endif 00031 00036 #include <CGAL/Arr_accessor.h> 00037 #include <CGAL/Unique_hash_map.h> 00038 #include <vector> 00039 00040 CGAL_BEGIN_NAMESPACE 00041 00045 struct Integer_hash_function 00046 { 00047 typedef std::size_t result_type; 00048 00049 std::size_t operator() (unsigned int i) const 00050 { 00051 return i; 00052 } 00053 }; 00054 00058 template <class Helper_> 00059 class Arr_construction_sl_visitor : 00060 public Helper_::Base_visitor 00061 { 00062 public: 00063 00064 typedef Helper_ Helper; 00065 00066 typedef typename Helper::Traits_2 Traits_2; 00067 typedef typename Helper::Arrangement_2 Arrangement_2; 00068 typedef typename Helper::Base_visitor Base; 00069 typedef typename Helper::Event Event; 00070 typedef typename Helper::Subcurve Subcurve; 00071 00072 typedef typename Traits_2::X_monotone_curve_2 X_monotone_curve_2; 00073 typedef typename Traits_2::Point_2 Point_2; 00074 00075 protected: 00076 00077 typedef typename Arrangement_2::Topology_traits Topology_traits; 00078 typedef typename Arrangement_2::Vertex_handle Vertex_handle; 00079 typedef typename Arrangement_2::Halfedge_handle Halfedge_handle; 00080 typedef typename Arrangement_2::Face_handle Face_handle; 00081 00082 typedef typename Base::Event_subcurve_iterator Event_subcurve_iterator; 00083 typedef typename Base::Event_subcurve_reverse_iterator 00084 Event_subcurve_reverse_iterator; 00085 typedef typename Base::Status_line_iterator Status_line_iterator; 00086 00087 typedef typename Helper::Indices_list Indices_list; 00088 typedef typename Helper::Halfedge_indices_map Halfedge_indices_map; 00089 typedef Unique_hash_map<unsigned int, 00090 Vertex_handle, 00091 Integer_hash_function> Iso_vertices_map; 00092 00093 protected: 00094 00095 Helper m_helper; // The helper class. 00096 00097 Arrangement_2 *m_arr; // The arrangement we construct. 00098 Topology_traits *m_top_traits; // The topology-traits class. 00099 Arr_accessor<Arrangement_2> 00100 m_arr_access; // An arrangement accessor. 00101 00102 unsigned int m_sc_counter; // Counter for subcurves that may 00103 // represent a hole (the upper 00104 // subcurves that emarge from event 00105 // points with only right curves). 00106 00107 std::vector<Halfedge_handle> 00108 m_sc_he_table; // A table that maps a subcurve 00109 // index to its halfedge handle, 00110 // directed from right to left. 00111 00112 Iso_vertices_map m_iso_verts_map; // Maps an index to the isolated 00113 // vertex. 00114 00115 Halfedge_indices_map m_he_indices_table; // Maps each halfdge to the 00116 // indices of subcurves that 00117 // lies below it. 00118 00119 const Vertex_handle m_invalid_vertex; // An invalid vertex handle. 00120 00121 public: 00122 00124 Arr_construction_sl_visitor (Arrangement_2 *arr) : 00125 m_helper (arr), 00126 m_arr (arr), 00127 m_top_traits (arr->topology_traits()), 00128 m_arr_access (*arr), 00129 m_sc_counter (0), 00130 m_sc_he_table (1), 00131 m_invalid_vertex () 00132 { 00133 m_helper.set_halfedge_indices_map (m_he_indices_table); 00134 } 00135 00137 virtual ~Arr_construction_sl_visitor() 00138 {} 00139 00141 00142 00143 /* A notification issued before the sweep process starts. */ 00144 inline void before_sweep (); 00145 00150 inline void before_handle_event (Event* event); 00151 00156 bool after_handle_event (Event* event, Status_line_iterator iter, bool flag); 00157 00159 void add_subcurve (const X_monotone_curve_2& cv, Subcurve* sc); 00161 00163 00164 00171 virtual Halfedge_handle 00172 insert_in_face_interior (const X_monotone_curve_2& cv, Subcurve* sc); 00173 00181 virtual Halfedge_handle 00182 insert_from_left_vertex (const X_monotone_curve_2& cv, Halfedge_handle he, 00183 Subcurve* sc); 00184 00192 virtual Halfedge_handle 00193 insert_from_right_vertex (const X_monotone_curve_2& cv, 00194 Halfedge_handle prev, 00195 Subcurve* sc); 00196 00206 virtual Halfedge_handle insert_at_vertices (const X_monotone_curve_2& cv, 00207 Halfedge_handle prev1, 00208 Halfedge_handle prev2, 00209 Subcurve* sc, 00210 bool &new_face_created); 00211 00218 virtual Vertex_handle insert_isolated_vertex (const Point_2& pt, 00219 Status_line_iterator iter); 00220 00227 void relocate_in_new_face(Halfedge_handle he); 00229 00231 Event* last_event_on_subcurve (Subcurve* sc) 00232 { 00233 return (reinterpret_cast<Event*>((sc)->last_event())); 00234 } 00235 00236 private: 00237 00239 00240 00246 inline const typename Arrangement_2::Point_2& _point (const Point_2& p) const 00247 { 00248 return (static_cast<const typename Arrangement_2::Point_2&> (p)); 00249 } 00250 00257 inline const typename Arrangement_2::X_monotone_curve_2& 00258 _curve (const X_monotone_curve_2& cv) const 00259 { 00260 return (static_cast<const typename Arrangement_2::X_monotone_curve_2&>(cv)); 00261 } 00262 00264 void _map_new_halfedge (unsigned int i, Halfedge_handle he); 00266 }; 00267 00268 //----------------------------------------------------------------------------- 00269 // Memeber-function definitions: 00270 //----------------------------------------------------------------------------- 00271 00272 //----------------------------------------------------------------------------- 00273 // A notification issued before the sweep process starts. 00274 // 00275 template <class Hlpr> 00276 void Arr_construction_sl_visitor<Hlpr>::before_sweep () 00277 { 00278 // We just have to notify the helper that the sweep process now starts. 00279 m_helper.before_sweep(); 00280 00281 return; 00282 } 00283 00284 //----------------------------------------------------------------------------- 00285 // A notification invoked before the sweep-line starts handling the given 00286 // event. 00287 // 00288 template <class Hlpr> 00289 void Arr_construction_sl_visitor<Hlpr>::before_handle_event (Event* event) 00290 { 00291 // We just have to notify the helper class on the event. 00292 m_helper.before_handle_event (event); 00293 #if 0 00294 std::cout << "CGAL_CSLV before_handle_event" << std::endl; 00295 #endif 00296 return; 00297 } 00298 00299 //----------------------------------------------------------------------------- 00300 // A notification invoked after the sweep-line finishes handling the given 00301 // event. 00302 // 00303 template <class Hlpr> 00304 bool Arr_construction_sl_visitor<Hlpr>::after_handle_event 00305 (Event* event, Status_line_iterator iter, bool /* flag */) 00306 { 00307 #if 0 00308 std::cout << "CGAL_CSLV after_handle_event" << std::endl; 00309 #endif 00310 00311 // Check if the event represents an isolated vertex. 00312 if (!event->has_left_curves() && !event->has_right_curves()) 00313 { 00314 // There are no incident subcurves, so this event is an isolated vertex. 00315 // We map the current index to this vertex, and add this index to the 00316 // indices list of the curve the vertex "sees" from below. 00317 Vertex_handle v = insert_isolated_vertex(event->point(), iter); 00318 00319 m_sc_counter++; 00320 m_iso_verts_map[m_sc_counter] = v; 00321 _map_new_halfedge(m_sc_counter, Halfedge_handle()); 00322 00323 if (iter != this->status_line_end()) 00324 { 00325 // The isolated vertex "sees" the subcurve of the given position from 00326 // below. 00327 Subcurve *sc_above = *iter; 00328 sc_above->add_halfedge_index(m_sc_counter); 00329 } 00330 else 00331 { 00332 // The vertex is not located below any valid curve, so we use the helper 00333 // class to mark that this index should belong to the current top face. 00334 #if 0 00335 std::cout << "CGAL_CSLV adding a " << m_sc_counter << std::endl; 00336 #endif 00337 m_helper.add_subcurve_in_top_face (m_sc_counter); 00338 } 00339 00340 // The event can now be deallocated. 00341 return (true); 00342 } 00343 00344 // Check if the event has only incident subcurves from its right. 00345 if (!event->has_left_curves() && !event->is_on_boundary()) 00346 { 00347 CGAL_assertion(event->has_right_curves()); 00348 00349 // In case of a finite event that has no incident left curves, it is 00350 // associated with a point that may be the leftmost one in a hole. 00351 // We give index to the topmost subcurve from the right, and add this 00352 // vertex indices list of the curve the event "sees" from below. 00353 m_sc_counter++; 00354 (*(event->right_curves_rbegin()))->set_index (m_sc_counter); 00355 00356 if (iter != this->status_line_end()) 00357 { 00358 // The vertex "sees" the subcurve of the given position from below. 00359 Subcurve *sc_above = *iter; 00360 sc_above->add_halfedge_index(m_sc_counter); 00361 } 00362 else 00363 { 00364 // The vertex is not located below any valid curve, so we use the helper 00365 // class to mark that this index should belong to the current top face. 00366 #if 0 00367 std::cout << "CGAL_CSLV adding b " << m_sc_counter << std::endl; 00368 #endif 00369 m_helper.add_subcurve_in_top_face (m_sc_counter); 00370 } 00371 } 00372 00373 // Set the last event of all left subcurve (thus, this event corresponds 00374 // to their right endpoint). 00375 Event_subcurve_iterator left_it; 00376 for(left_it = event->left_curves_begin(); 00377 left_it != event->left_curves_end(); 00378 ++left_it) 00379 { 00380 (*left_it)->set_last_event(event); 00381 } 00382 00383 // In case there are no right subcurves, the event can be deallocated. 00384 if(event->number_of_right_curves() == 0) 00385 { 00386 // Inform the helper class that the event will soon be deallocated. 00387 m_helper.before_deallocate_event (event); 00388 return (true); 00389 } 00390 00391 // Mark that all right subcurves incident to the current event are not 00392 // in the arrangement yet. 00393 event->init_subcurve_in_arrangement_flags (event->number_of_right_curves()); 00394 00395 // Set the last event of all right subcurve (thus, this event corresponds 00396 // to their left endpoint). 00397 Event_subcurve_iterator right_it; 00398 for(right_it = event->right_curves_begin(); 00399 right_it != event->right_curves_end(); 00400 ++right_it) 00401 { 00402 (*right_it)->set_last_event(event); 00403 } 00404 00405 // Mark that the event cannot be deallocated just yet. 00406 return (false); 00407 } 00408 00409 //----------------------------------------------------------------------------- 00410 // A notification invoked when a new subcurve is created. 00411 // 00412 template <class Hlpr> 00413 void Arr_construction_sl_visitor<Hlpr>:: 00414 add_subcurve (const X_monotone_curve_2& cv, Subcurve* sc) 00415 { 00416 #if CGAL_ARR_CONSTRUCTION_SL_VISITOR_VERBOSE 00417 std::cout << "CGAL_CSLV add_subcurve: " << cv << std::endl; 00418 #endif 00419 00420 // Obtain all information to perform the insertion of the subcurve into 00421 // the arrangement. 00422 Event *last_event = last_event_on_subcurve(sc); 00423 Halfedge_handle res; 00424 Halfedge_handle he_right = this->current_event()->halfedge_handle(); 00425 Halfedge_handle he_left = last_event->halfedge_handle(); 00426 const int jump = last_event->compute_halfedge_jump_count(sc); 00427 00428 const Halfedge_handle invalid_he; 00429 00430 #if CGAL_ARR_CONSTRUCTION_SL_VISITOR_VERBOSE 00431 if (last_event->is_closed()) { 00432 std::cout << "CGAL_CSLG lastevent: " << last_event->point() << std::endl; 00433 } 00434 if (he_left != invalid_he) { 00435 if (!he_left->is_fictitious()) { 00436 std::cout << "he_leftcv : " << he_left->curve() << std::endl; 00437 } else { 00438 std::cout << "he_left : fictitious" << std::endl; 00439 } 00440 std::cout << "he_leftdir : " << he_left->direction() << std::endl; 00441 std::cout << "he_leftfac : " << &(*he_left->face()) << std::endl; 00442 } else { 00443 std::cout << "he_left : invalid" << std::endl; 00444 } 00445 if (he_right != invalid_he) { 00446 if (!he_right->is_fictitious()) { 00447 std::cout << "he_rightcv : " << he_right->curve() << std::endl; 00448 } else { 00449 std::cout << "he_right : fictitious" << std::endl; 00450 } 00451 std::cout << "he_rightdir: " << he_right->direction() << std::endl; 00452 std::cout << "he_rightfac: " << &(*he_right->face()) << std::endl; 00453 } else { 00454 std::cout << "he_right : invalid" << std::endl; 00455 } 00456 #endif 00457 00458 // Check if the previous event on the curve is not in the arrangement yet. 00459 if (he_left == invalid_he) 00460 { 00461 // We do not have a handle from the previous insert. 00462 if (he_right != invalid_he) 00463 { 00464 // We have a handle from the current event, representing the right end 00465 // of the subcurve - use it to insert the subcurve. 00466 #if CGAL_ARR_CONSTRUCTION_SL_VISITOR_VERBOSE 00467 std::cout << "CGAL_CSLV call insert_from_right_vertex" << std::endl; 00468 #endif 00469 res = this->insert_from_right_vertex(cv, he_right, sc); 00470 } 00471 else 00472 { 00473 // We do not have handles for any of the curve end, so we insert it in 00474 // the interior of a face. 00475 #if CGAL_ARR_CONSTRUCTION_SL_VISITOR_VERBOSE 00476 std::cout << "CGAL_CSLV call insert_in_face_interior" << std::endl; 00477 #endif 00478 res = this->insert_in_face_interior(cv, sc); 00479 } 00480 } 00481 else 00482 { 00483 // The previous event on the curve is already in the arrangement, 00484 // therefore we use it to insert the subcurve. 00485 // First, we skip some halfedges around the left vertex to get the true 00486 // predecessor halfedge for the insertion. 00487 for (int i = 0; i < jump; i++) { 00488 he_left = (he_left->next())->twin(); 00489 } 00490 #if CGAL_ARR_CONSTRUCTION_SL_VISITOR_VERBOSE 00491 if (jump != 0) { 00492 std::cout << "CGAL_CSLV JUMP: " << jump << std::endl; 00493 if (!he_left->is_fictitious()) { 00494 std::cout << "he_leftcv : " << he_left->curve() << std::endl; 00495 } else { 00496 std::cout << "he_left : fictitious" << std::endl; 00497 } 00498 std::cout << "he_leftdir : " << he_left->direction() << std::endl; 00499 std::cout << "he_leftfac : " << &(*he_left->face()) << std::endl; 00500 } 00501 #endif 00502 00503 if (he_right != invalid_he) 00504 { 00505 CGAL_assertion (he_left->face() == he_right->face()); 00506 00507 // We also have a handle for the current event, representing the right 00508 // vertex of the subcurve. We insert the subcurve using the two 00509 // predecessor halfedges. 00510 bool dummy; 00511 00512 #if CGAL_ARR_CONSTRUCTION_SL_VISITOR_VERBOSE 00513 std::cout << "CGAL_CSLV call insert_at_vertices" << std::endl; 00514 #endif 00515 res = this->insert_at_vertices (cv, he_right, he_left, sc, dummy); 00516 } 00517 else 00518 { 00519 // We only have a handle for the predecessor halfedge of the left end 00520 // of the subcurve - use it to insert the subcurve. 00521 #if CGAL_ARR_CONSTRUCTION_SL_VISITOR_VERBOSE 00522 std::cout << "CGAL_CSLV call insert_from_left_vertex" << std::endl; 00523 #endif 00524 res = this->insert_from_left_vertex (cv, he_left, sc); 00525 } 00526 } 00527 00528 // Make sure that res is a halfedge that is always directed from left to 00529 // right (thus its twin is directed from right to left). 00530 if (res->direction() != ARR_LEFT_TO_RIGHT) 00531 res = res->twin(); 00532 00533 // Update the last event with the inserted halfegde (if necessary) 00534 // and check if we have to update the auxiliary information on the location 00535 // of holes. 00536 if (last_event->number_of_left_curves() == 0 && 00537 last_event->is_curve_largest((Subcurve*)sc)) 00538 { 00539 if (last_event->vertex_handle() == m_invalid_vertex) 00540 last_event->set_halfedge_handle(res->twin()); 00541 00542 // If sc has valid index, insert its index to m_sc_he_table. 00543 if(sc->has_valid_index()) 00544 { 00545 CGAL_assertion(res->twin()->direction() == ARR_RIGHT_TO_LEFT); 00546 _map_new_halfedge (sc->index(), res->twin()); 00547 } 00548 } 00549 00550 // Update the halfedge handle associated with the current event. 00551 if (this->current_event()->vertex_handle() == m_invalid_vertex) 00552 this->current_event()->set_halfedge_handle(res); 00553 00554 // In case the event has no more right subcurves associated with it, we can 00555 // deallocate it. Note that we inform the helper class before deallocating 00556 // the event. 00557 if (last_event->dec_right_curves_counter() == 0) 00558 { 00559 m_helper.before_deallocate_event (last_event); 00560 this->deallocate_event (last_event); 00561 } 00562 00563 // Clear the list of indices of the subcurve. 00564 sc->clear_halfedge_indices(); 00565 00566 return; 00567 } 00568 00569 //----------------------------------------------------------------------------- 00570 // Insert the given subcurve in the interior of an arrangement face. 00571 // 00572 template <class Hlpr> 00573 typename Arr_construction_sl_visitor<Hlpr>::Halfedge_handle 00574 Arr_construction_sl_visitor<Hlpr>:: 00575 insert_in_face_interior (const X_monotone_curve_2& cv, Subcurve* sc) 00576 { 00577 #if CGAL_ARR_CONSTRUCTION_SL_VISITOR_VERBOSE 00578 std::cout << "CGAL_CSLV insert_in_face_interior\ncurve: " << cv << std::endl; 00579 #endif 00580 00581 // Check if the vertex to be associated with the left end of the curve has 00582 // already been created. 00583 Event *last_event = last_event_on_subcurve(sc); 00584 Vertex_handle v1 = last_event->vertex_handle(); 00585 bool create_v1 = false; 00586 00587 if (v1 == m_invalid_vertex) 00588 { 00589 // Mark that we should create the vertex v1 later on (if we created it 00590 // now, and ended up calling insert_from_right_vertex(), this vertex 00591 // would be constructed twice!) 00592 create_v1 = true; 00593 } 00594 else if (v1->degree() > 0) 00595 { 00596 // In this case the left vertex v1 is a boundary vertex which already has 00597 // some incident halfedges. We look for the predecessor halfedge and 00598 // and insert the curve from this left vertex. 00599 Arr_parameter_space bx = last_event->parameter_space_in_x(); 00600 Arr_parameter_space by = last_event->parameter_space_in_y(); 00601 00602 CGAL_assertion (bx != ARR_INTERIOR || by != ARR_INTERIOR); 00603 00604 Halfedge_handle l_prev = Halfedge_handle 00605 (m_top_traits->locate_around_boundary_vertex (&(*v1), _curve(cv), 00606 ARR_MIN_END, bx, by)); 00607 00608 return (this->insert_from_left_vertex (cv, l_prev, sc)); 00609 } 00610 00611 // Check if the vertex to be associated with the right end of the curve has 00612 // already been created. 00613 Event *curr_event = this->current_event(); 00614 Vertex_handle v2 = curr_event->vertex_handle(); 00615 00616 if (v2 == m_invalid_vertex) 00617 { 00618 // Create the vertex to be associated with the right end of the curve. 00619 v2 = m_arr_access.create_vertex (_point (curr_event->point())); 00620 } 00621 else if (v2->degree() > 0) 00622 { 00623 // In this case the right vertex v2 is a boundary vertex which already has 00624 // some incident halfedges. We look for the predecessor halfedge and 00625 // and insert the curve from this right vertex. 00626 Arr_parameter_space bx = curr_event->parameter_space_in_x(); 00627 Arr_parameter_space by = curr_event->parameter_space_in_y(); 00628 00629 CGAL_assertion (bx != ARR_INTERIOR || by != ARR_INTERIOR); 00630 00631 Halfedge_handle r_prev = Halfedge_handle 00632 (m_top_traits->locate_around_boundary_vertex (&(*v2), _curve(cv), 00633 ARR_MAX_END, bx, by)); 00634 00635 return (this->insert_from_right_vertex (cv, r_prev, sc)); 00636 } 00637 00638 // If necessary, create the vertex to be associated with the left end 00639 // of the curve. 00640 if (create_v1) 00641 v1 = m_arr_access.create_vertex (_point (last_event->point())); 00642 00643 // Perform the insertion between the two (currently isolated) vertices in 00644 // the interior of the current top face, as given by the helper class. 00645 Halfedge_handle res = 00646 m_arr_access.insert_in_face_interior_ex (_curve(cv), m_helper.top_face(), 00647 v1, v2, SMALLER); 00648 00649 // Map the new halfedge to the indices list of all subcurves that lie 00650 // below it. 00651 if (sc->has_halfedge_indices()) 00652 { 00653 CGAL_assertion(res->twin()->direction() == ARR_RIGHT_TO_LEFT); 00654 Indices_list& list_ref = m_he_indices_table[res->twin()]; 00655 list_ref.clear(); 00656 list_ref.splice(list_ref.end(), sc->halfedge_indices_list()); 00657 } 00658 00659 // Notify the helper on the creation of the new halfedge. 00660 m_helper.add_subcurve (res, sc); 00661 00662 return (res); 00663 } 00664 00665 //----------------------------------------------------------------------------- 00666 // Insert the given subcurve using its two end-vertices. 00667 // 00668 template <class Hlpr> 00669 typename Arr_construction_sl_visitor<Hlpr>::Halfedge_handle 00670 Arr_construction_sl_visitor<Hlpr>::insert_at_vertices 00671 (const X_monotone_curve_2& cv, 00672 Halfedge_handle prev1, 00673 Halfedge_handle prev2, 00674 Subcurve* sc, 00675 bool& new_face_created) 00676 { 00677 00678 #if CGAL_ARR_CONSTRUCTION_SL_VISITOR_VERBOSE 00679 std::cout << "CGAL_CSLV insert_at_vertices:\ncurve:" << cv << std::endl; 00680 if (!prev1->is_fictitious()) { 00681 std::cout << "prev1cv : " << prev1->curve() << std::endl; 00682 } else { 00683 std::cout << "prev1 : fictitious" << std::endl; 00684 } 00685 std::cout << "prev1dir : " << prev1->direction() << std::endl; 00686 std::cout << "prev1fac : " << &(*prev1->face()) << std::endl; 00687 if (!prev2->is_fictitious()) { 00688 std::cout << "prev2cv : " << prev2->curve() << std::endl; 00689 } else { 00690 std::cout << "prev2 : fictitious" << std::endl; 00691 } 00692 std::cout << "prev2dir : " << prev2->direction() << std::endl; 00693 std::cout << "prev2fac : " << &(*prev2->face()) << std::endl; 00694 #endif 00695 00696 // Use the helper class to determine whether the order of predecessor 00697 // halfedges should be swaped, to that the edge directed from prev1->target() 00698 // to prev2->target() is incident to the new face (in case a new face is 00699 // created). 00700 Halfedge_handle res; 00701 #if CGAL_NEW_FACE_SPLIT_STRATEGY 00702 // EBEB new strategy for splitting faces. The member also allows 00703 // to decide which prev_i will be on the new outer CCB (if decision needed) 00704 // Here: We use it to decide "swapping", which is actually the decision 00705 // whether prev1 or prev2 is on the new outer CCB ;-) 00706 std::pair< bool, bool > update(false, false); 00707 #if 0 00708 if ((prev1->is_on_inner_ccb() && prev1->is_on_inner_ccb() && 00709 prev1->inner_ccb() == prev2->inner_ccb()) 00710 || 00711 (!prev1->is_on_inner_ccb() && prev1->is_on_inner_ccb())) { 00712 #else 00713 // TODO improve this code! 00714 Halfedge_handle curr1 = prev1->next(); 00715 bool found2 = false; 00716 while (curr1 != prev1) { 00717 if (curr1 == prev2) { 00718 found2 = true; 00719 } 00720 curr1 = curr1->next(); 00721 } 00722 Halfedge_handle curr2 = prev2->next(); 00723 bool found1 = false; 00724 while (curr2 != prev2) { 00725 if (curr2 == prev1) { 00726 found1 = true; 00727 } 00728 curr2 = curr2->next(); 00729 } 00730 if (found1 && found2) { 00731 #endif 00732 update = 00733 m_top_traits->face_update_upon_edge_insertion( 00734 &(*prev1), &(*prev2), cv 00735 ); 00736 } 00737 const bool swap_preds = update.second; 00738 // TODO propagate update.first to _insert_at_vertices! 00739 #else 00740 const bool swap_preds = 00741 m_helper.swap_predecessors (this->current_event()); 00742 #endif 00743 00744 res = (! swap_preds) ? 00745 // usually prev1 is outer of new split face (it it exists) 00746 m_arr_access.insert_at_vertices_ex (_curve(cv), prev1, prev2, 00747 LARGER, new_face_created) : 00748 // if swapping prev2 will becomd outer of new split face (it it exists) 00749 m_arr_access.insert_at_vertices_ex (_curve(cv), prev2, prev1, 00750 SMALLER, new_face_created); 00751 00752 // Map the new halfedge to the indices list of all subcurves that lie 00753 // below it. 00754 if (sc->has_halfedge_indices()) 00755 { 00756 Halfedge_handle he = res; 00757 00758 if (swap_preds) 00759 he = he->twin(); 00760 CGAL_assertion(he->direction() == ARR_RIGHT_TO_LEFT); 00761 00762 Indices_list& list_ref = m_he_indices_table[he]; 00763 list_ref.clear(); 00764 list_ref.splice(list_ref.end(), sc->halfedge_indices_list()); 00765 } 00766 00767 // Notify the helper on the creation of the new halfedge. 00768 // Note that we do this before trying to relocate holes in the new 00769 // face (if one is created). 00770 m_helper.add_subcurve (res, sc); 00771 00772 if (new_face_created) 00773 { 00774 // EBEB: Fixed by checking whether at least one of 00775 // EBEB: res + res->twin() lies on a inner ccb 00776 if (res->is_on_inner_ccb() || res->twin()->is_on_inner_ccb()) { 00777 // In case a new face has been created (pointed by the new halfedge 00778 // we obtained), we have to examine the holes and isolated vertices 00779 // in the existing face (pointed be the twin halfedge) and relocate 00780 // the relevant features in the new face. 00781 CGAL_assertion(res->face() != res->twin()->face()); 00782 this->relocate_in_new_face (res); 00783 } 00784 } 00785 00786 return (res); 00787 } 00788 00789 //----------------------------------------------------------------------------- 00790 // Insert the given subcurve from a vertex that corresponds to its right end. 00791 // 00792 template <class Hlpr> 00793 typename Arr_construction_sl_visitor<Hlpr>::Halfedge_handle 00794 Arr_construction_sl_visitor<Hlpr>::insert_from_right_vertex 00795 (const X_monotone_curve_2& cv, 00796 Halfedge_handle prev, 00797 Subcurve* sc) 00798 { 00799 #if CGAL_ARR_CONSTRUCTION_SL_VISITOR_VERBOSE 00800 std::cout << "CGAL_CSLV insert_from_right_vertex:\ncurve:" << cv << std::endl; 00801 if (!prev->is_fictitious()) { 00802 std::cout << "prevcv : " << prev->curve() << std::endl; 00803 } else { 00804 std::cout << "prev : fictitious" << std::endl; 00805 } 00806 std::cout << "prevdir : " << prev->direction() << std::endl; 00807 std::cout << "prevfac : " << &(*prev->face()) << std::endl; 00808 #endif 00809 00810 // Check if the vertex to be associated with the left end of the curve has 00811 // already been created. 00812 Event *last_event = last_event_on_subcurve(sc); 00813 Vertex_handle v = last_event->vertex_handle(); 00814 00815 if (v == m_invalid_vertex) 00816 { 00817 // Create the vertex to be associated with the left end of the curve. 00818 v = m_arr_access.create_vertex (_point (last_event->point())); 00819 } 00820 else if (v->degree() > 0) 00821 { 00822 // In this case the left vertex v is a boundary vertex which already has 00823 // some incident halfedges. We look for the predecessor halfedge and 00824 // and insert the curve between two existing vertices. 00825 Arr_parameter_space bx = last_event->parameter_space_in_x(); 00826 Arr_parameter_space by = last_event->parameter_space_in_y(); 00827 00828 CGAL_assertion (bx != ARR_INTERIOR || by != ARR_INTERIOR); 00829 00830 Halfedge_handle l_prev = Halfedge_handle 00831 (m_top_traits->locate_around_boundary_vertex (&(*v), _curve(cv), 00832 ARR_MIN_END, bx, by)); 00833 bool dummy; 00834 00835 return (this->insert_at_vertices (cv, prev, l_prev, sc, dummy)); 00836 } 00837 00838 // Insert the curve given its left vertex and the predecessor around the 00839 // right vertex. 00840 Halfedge_handle res = 00841 m_arr_access.insert_from_vertex_ex (_curve(cv), prev, v, LARGER); 00842 00843 // Map the new halfedge to the indices list of all subcurves that lie 00844 // below it. 00845 if (sc->has_halfedge_indices()) 00846 { 00847 CGAL_assertion(res->direction() == ARR_RIGHT_TO_LEFT); 00848 Indices_list& list_ref = m_he_indices_table[res]; 00849 list_ref.clear(); 00850 list_ref.splice(list_ref.end(), sc->halfedge_indices_list()); 00851 } 00852 00853 // Notify the helper on the creation of the new halfedge. 00854 m_helper.add_subcurve (res, sc); 00855 00856 return (res); 00857 } 00858 00859 //----------------------------------------------------------------------------- 00860 // Insert the given subcurve from a vertex that corresponds to its left end. 00861 // 00862 template <class Hlpr> 00863 typename Arr_construction_sl_visitor<Hlpr>::Halfedge_handle 00864 Arr_construction_sl_visitor<Hlpr>:: 00865 insert_from_left_vertex (const X_monotone_curve_2& cv, 00866 Halfedge_handle prev, 00867 Subcurve* sc) 00868 { 00869 #if CGAL_ARR_CONSTRUCTION_SL_VISITOR_VERBOSE 00870 std::cout << "CGAL_CSLV insert_from_left_vertex:\ncurve:" << cv << std::endl; 00871 if (!prev->is_fictitious()) { 00872 std::cout << "prevcv : " << prev->curve() << std::endl; 00873 } else { 00874 std::cout << "prev : fictitious" << std::endl; 00875 } 00876 std::cout << "prevdir : " << prev->direction() << std::endl; 00877 std::cout << "prevfac : " << &(*prev->face()) << std::endl; 00878 #endif 00879 00880 // Check if the vertex to be associated with the right end of the curve has 00881 // already been created. 00882 Event *curr_event = this->current_event(); 00883 Vertex_handle v = curr_event->vertex_handle(); 00884 00885 if (v == m_invalid_vertex) 00886 { 00887 // Create the vertex to be associated with the right end of the curve. 00888 v = m_arr_access.create_vertex (_point (curr_event->point())); 00889 } 00890 else if (v->degree() > 0) 00891 { 00892 // In this case the left vertex v is a boundary vertex which already has 00893 // some incident halfedges. We look for the predecessor halfedge and 00894 // and insert the curve from this right vertex. 00895 Arr_parameter_space bx = curr_event->parameter_space_in_x(); 00896 Arr_parameter_space by = curr_event->parameter_space_in_y(); 00897 00898 CGAL_assertion (bx != ARR_INTERIOR || by != ARR_INTERIOR); 00899 00900 Halfedge_handle r_prev = Halfedge_handle 00901 (m_top_traits->locate_around_boundary_vertex (&(*v), _curve(cv), 00902 ARR_MAX_END, bx, by) 00903 ); 00904 bool dummy; 00905 00906 return (this->insert_at_vertices (cv, r_prev, prev, sc, dummy)); 00907 } 00908 00909 // Insert the curve given its right vertex and the predecessor around the 00910 // left vertex. 00911 Halfedge_handle res = 00912 m_arr_access.insert_from_vertex_ex (_curve(cv), prev, v, SMALLER); 00913 00914 // Map the new halfedge to the indices list of all subcurves that lie 00915 // below it. 00916 if (sc->has_halfedge_indices()) 00917 { 00918 CGAL_assertion(res->twin()->direction() == ARR_RIGHT_TO_LEFT); 00919 Indices_list& list_ref = m_he_indices_table[res->twin()]; 00920 list_ref.clear(); 00921 list_ref.splice(list_ref.end(), sc->halfedge_indices_list()); 00922 } 00923 00924 // Notify the helper on the creation of the new halfedge. 00925 m_helper.add_subcurve (res, sc); 00926 00927 return (res); 00928 } 00929 00930 //----------------------------------------------------------------------------- 00931 // Insert an isolated vertex into the arrangement. 00932 // 00933 template <class Hlpr> 00934 typename Arr_construction_sl_visitor<Hlpr>::Vertex_handle 00935 Arr_construction_sl_visitor<Hlpr>:: 00936 insert_isolated_vertex (const Point_2& pt, 00937 Status_line_iterator /* iter */) 00938 { 00939 #if CGAL_ARR_CONSTRUCTION_SL_VISITOR_VERBOSE 00940 std::cout << "CGAL_CSLV insert_isolated_vertex:\npoint:" << pt << std::endl; 00941 #endif 00942 00943 // Insert the isolated vertex in the interior of the current top face, as 00944 // given by the helper class. 00945 return (m_arr->insert_in_face_interior (_point(pt), 00946 m_helper.top_face())); 00947 } 00948 00949 //----------------------------------------------------------------------------- 00950 // Reloacte holes and isolated vertices inside a newly created face. 00951 // 00952 template <class Hlpr> 00953 void Arr_construction_sl_visitor<Hlpr>:: 00954 relocate_in_new_face (Halfedge_handle he) 00955 { 00956 #if 0 00957 std::cout << "CGAL_CSLV relocate" << std::endl; 00958 std::cout << "HeCv: " << he->curve() << std::endl; 00959 std::cout << "HeDi: " << he->direction() << std::endl; 00960 #endif 00961 00962 // We use a constant indices map so no new entries are added there. 00963 const Halfedge_indices_map& const_he_indices_table = m_he_indices_table; 00964 00965 // Go along the boundary of the new face. 00966 Face_handle new_face = he->face(); 00967 Halfedge_handle curr_he = he; 00968 const Halfedge_handle invalid_he; 00969 Vertex_handle v; 00970 00971 do 00972 { 00973 // We are intreseted only in halfedges directed from right to left. 00974 if (curr_he->direction() == ARR_LEFT_TO_RIGHT) 00975 { 00976 curr_he = curr_he->next(); 00977 continue; 00978 } 00979 00980 // Get the indices list associated with the current halfedges, representing 00981 // the halfedges and isolated vertices that "see" it from above. 00982 const Indices_list& indices_list = const_he_indices_table[curr_he]; 00983 typename Indices_list::const_iterator itr; 00984 00985 for (itr = indices_list.begin(); itr != indices_list.end(); ++itr) 00986 { 00987 CGAL_assertion(*itr != 0); 00988 #if 0 00989 std::cout << "itr: " << *itr << std::endl; 00990 std::cout << "m_sc_counter: " << m_sc_counter << std::endl; 00991 std::cout << "m_sc_he_table: " << m_sc_he_table.size() << std::endl; 00992 #endif 00993 00994 // In case the current subcurve index does not match a valid entry in 00995 // m_sc_he_table, we know that this subcurve matches a halfedge that is 00996 // not yet mapped. This can happen only if this halfedge is he itself. 00997 // As we know that he lies on the outer CCB of the new face, it is 00998 // definately not a hole in the face, therefore we can ignore it. 00999 if (*itr > m_sc_counter || *itr >= m_sc_he_table.size()) 01000 continue; 01001 01002 Halfedge_handle he_on_face = m_sc_he_table[*itr]; 01003 01004 if(he_on_face == invalid_he) 01005 { 01006 // If the halfedge handle is invalis, then we have an index for an 01007 // isolated vertex. Move this vertex to the new face, if necessary. 01008 v = m_iso_verts_map[*itr]; 01009 01010 CGAL_assertion(v != m_invalid_vertex); 01011 if (v->face() != new_face) 01012 { 01013 m_arr_access.move_isolated_vertex (v->face(), 01014 new_face, 01015 v); 01016 } 01017 } 01018 else 01019 { 01020 // If necessary, move the hole that the halfedge belongs to into the 01021 // new face. 01022 if (he_on_face->twin()->face() != new_face && 01023 he_on_face->twin()->is_on_inner_ccb()) 01024 { 01025 m_arr_access.move_inner_ccb (he_on_face->twin()->face(), 01026 new_face, 01027 he_on_face->twin()->ccb()); 01028 01029 // Perform the relocation process recursively: Namely all holes 01030 // and isolated vertices that "see" he_on_face from above should also 01031 // be located inside the new face. 01032 relocate_in_new_face(he_on_face->twin()); 01033 } 01034 } 01035 } 01036 01037 curr_he = curr_he->next(); 01038 01039 } while(curr_he != he); 01040 01041 return; 01042 } 01043 01044 //----------------------------------------------------------------------------- 01045 // Map the given subcurve index to the given halfedge handle. 01046 // 01047 template <class Hlpr> 01048 void Arr_construction_sl_visitor<Hlpr>:: 01049 _map_new_halfedge (unsigned int i, Halfedge_handle he) 01050 { 01051 CGAL_assertion (i != 0); 01052 #if 0 01053 std::cout << "map " << i << " to " << he->curve() << " " 01054 << he->direction() << std::endl; 01055 #endif 01056 if(i >= m_sc_he_table.size()) 01057 // Resize the index table if we reached it capacity. 01058 m_sc_he_table.resize(2*i); 01059 01060 // Map the index to the given halfedge handle. 01061 m_sc_he_table[i] = he; 01062 return; 01063 } 01064 01065 CGAL_END_NAMESPACE 01066 01067 #endif