BWAPI
|
00001 // Copyright (c) 2005 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_overlay_sl_visitor.h $ 00015 // $Id: Arr_overlay_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 // Efi Fogel <efif@post.tau.ac.il> 00021 00022 #ifndef CGAL_ARR_OVERLAY_SL_VISITOR_H 00023 #define CGAL_ARR_OVERLAY_SL_VISITOR_H 00024 00029 #include <CGAL/Sweep_line_2/Arr_construction_sl_visitor.h> 00030 #include <CGAL/Unique_hash_map.h> 00031 00032 CGAL_BEGIN_NAMESPACE 00033 00039 template <class OverlayHelper_, class OverlayTraits_> 00040 class Arr_overlay_sl_visitor : public 00041 Arr_construction_sl_visitor<typename OverlayHelper_::Construction_helper> 00042 { 00043 public: 00044 00045 typedef OverlayHelper_ Overlay_helper; 00046 typedef OverlayTraits_ Overlay_traits; 00047 00048 typedef typename Overlay_helper::Traits_2 Traits_2; 00049 typedef typename Overlay_helper::Event Event; 00050 typedef typename Overlay_helper::Subcurve Subcurve; 00051 00052 typedef typename Traits_2::X_monotone_curve_2 X_monotone_curve_2; 00053 typedef typename Traits_2::Point_2 Point_2; 00054 00055 // The input arrangements (the "red" and the "blue" one): 00056 typedef typename Overlay_helper::Arrangement_red_2 Arrangement_red_2; 00057 typedef typename Arrangement_red_2::Halfedge_const_handle 00058 Halfedge_handle_red; 00059 typedef typename Arrangement_red_2::Face_const_handle Face_handle_red; 00060 typedef typename Arrangement_red_2::Vertex_const_handle Vertex_handle_red; 00061 00062 typedef typename Overlay_helper::Arrangement_blue_2 Arrangement_blue_2; 00063 typedef typename Arrangement_blue_2::Halfedge_const_handle 00064 Halfedge_handle_blue; 00065 typedef typename Arrangement_blue_2::Face_const_handle Face_handle_blue; 00066 typedef typename Arrangement_blue_2::Vertex_const_handle 00067 Vertex_handle_blue; 00068 00069 // The resulting arrangement: 00070 typedef typename Overlay_helper::Arrangement_2 Arrangement_2; 00071 typedef typename Arrangement_2::Halfedge_handle Halfedge_handle; 00072 typedef typename Arrangement_2::Face_handle Face_handle; 00073 typedef typename Arrangement_2::Vertex_handle Vertex_handle; 00074 typedef typename Arrangement_2::Ccb_halfedge_circulator 00075 Ccb_halfedge_circulator; 00076 typedef typename Arrangement_2::Outer_ccb_iterator Outer_ccb_iterator; 00077 00078 // The base construction visitor: 00079 typedef typename Overlay_helper::Construction_helper Construction_helper; 00080 typedef Arr_construction_sl_visitor<Construction_helper> 00081 Base; 00082 00083 typedef typename Base::Event_subcurve_iterator Event_subcurve_iterator; 00084 typedef typename Base::Event_subcurve_reverse_iterator 00085 Event_subcurve_reverse_iterator; 00086 typedef typename Base::Status_line_iterator Status_line_iterator; 00087 00088 protected: 00089 00090 typedef std::pair<Halfedge_handle_red, 00091 Halfedge_handle_blue> Halfedge_info; 00092 typedef Unique_hash_map<Halfedge_handle, 00093 Halfedge_info> Halfedge_hash_map; 00094 00095 // Data members: 00096 Overlay_helper m_overlay_helper; // The overlay-helper class 00097 // (note that the base class stores 00098 // an additional helper class used 00099 // for constructing the result). 00100 00101 Halfedge_hash_map m_halfedges_map; // Mapping of each halfedge in the 00102 // result arrangement to the red 00103 // and blue halfedges that induce it. 00104 00105 Overlay_traits* m_overlay_traits; // The overlay traits object. 00106 00107 public: 00108 00110 Arr_overlay_sl_visitor (const Arrangement_red_2 *red_arr, 00111 const Arrangement_blue_2 *blue_arr, 00112 Arrangement_2 *res_arr, 00113 Overlay_traits *overlay_traits): 00114 Base (res_arr), 00115 m_overlay_helper (red_arr, blue_arr), 00116 m_halfedges_map (Halfedge_info(), 00117 // Give an initial size for the hash table 00118 red_arr->number_of_halfedges() + 00119 blue_arr->number_of_halfedges()), 00120 m_overlay_traits (overlay_traits) 00121 {} 00122 00124 virtual ~Arr_overlay_sl_visitor() 00125 {} 00126 00128 00129 00130 /* A notification issued before the sweep process starts. */ 00131 void before_sweep (); 00132 00137 void before_handle_event (Event *event); 00138 00143 bool after_handle_event (Event *event, 00144 Status_line_iterator iter, bool flag); 00145 00147 void update_event (Event* e, 00148 const Point_2& end_point, 00149 const X_monotone_curve_2& cv, 00150 Arr_curve_end cv_end, 00151 bool is_new); 00152 00153 void update_event (Event* /* e */, 00154 const X_monotone_curve_2& /* cv */, 00155 Arr_curve_end /* cv_end */, 00156 bool /* is_new */) 00157 {} 00158 00160 void update_event (Event* /* e */, 00161 Subcurve* /* c1 */, 00162 Subcurve* /* c2 */, 00163 bool CGAL_assertion_code(is_new)) 00164 { 00165 CGAL_assertion(is_new == true); 00166 } 00167 00169 void update_event (Event *e, Subcurve* sc); 00170 00172 void update_event(Event* e, const Point_2& p, bool is_new); 00173 00174 /* A notification issued when the sweep process has ended. */ 00175 void after_sweep (); 00177 00179 00180 00187 virtual Halfedge_handle insert_in_face_interior 00188 (const X_monotone_curve_2& cv, 00189 Subcurve* sc); 00190 00198 virtual Halfedge_handle insert_from_right_vertex 00199 (const X_monotone_curve_2& cv, 00200 Halfedge_handle prev, 00201 Subcurve* sc); 00202 00210 virtual Halfedge_handle insert_from_left_vertex 00211 (const X_monotone_curve_2& cv, 00212 Halfedge_handle prev, 00213 Subcurve* sc); 00214 00224 virtual Halfedge_handle insert_at_vertices (const X_monotone_curve_2& cv, 00225 Halfedge_handle prev1, 00226 Halfedge_handle prev2, 00227 Subcurve* sc, 00228 bool &new_face_created); 00229 00236 virtual Vertex_handle insert_isolated_vertex (const Point_2& pt, 00237 Status_line_iterator iter); 00239 00240 protected: 00241 00243 00244 00253 void _map_halfedge_and_twin (Halfedge_handle he, 00254 Halfedge_handle_red red_he, 00255 Halfedge_handle_blue blue_he); 00256 00263 void _create_vertex (Event *event, Vertex_handle res_v, Subcurve* sc); 00264 00270 void _create_edge (Subcurve *sc, Halfedge_handle res_he); 00271 }; 00272 00273 //----------------------------------------------------------------------------- 00274 // Memeber-function definitions: 00275 //----------------------------------------------------------------------------- 00276 00277 //----------------------------------------------------------------------------- 00278 // A notification issued before the sweep process starts. 00279 // 00280 template <class OvlHlpr, class OvlTr> 00281 void Arr_overlay_sl_visitor<OvlHlpr, OvlTr>::before_sweep () 00282 { 00283 // Initialize the necessary fields in the base construction visitor. 00284 // Note that the construction visitor also informs its helper class that 00285 // the sweep process is about to start. 00286 Base::before_sweep(); 00287 00288 // Notify the overlay helper that the sweep process now starts. 00289 m_overlay_helper.before_sweep (); 00290 00291 return; 00292 } 00293 00294 //----------------------------------------------------------------------------- 00295 // A notification invoked before the sweep-line starts handling the given 00296 // event. 00297 // 00298 template <class OvlHlpr, class OvlTr> 00299 void Arr_overlay_sl_visitor<OvlHlpr, OvlTr>:: 00300 before_handle_event (Event* event) 00301 { 00302 // Let the base construction visitor do the work (and also inform its helper 00303 // class on the event). 00304 Base::before_handle_event (event); 00305 00306 // Notify the overlay helper class on the event. 00307 m_overlay_helper.before_handle_event (event); 00308 00309 return; 00310 } 00311 00312 //----------------------------------------------------------------------------- 00313 // A notification invoked after the sweep-line finishes handling the given 00314 // event. 00315 // 00316 template <class OvlHlpr, class OvlTr> 00317 bool Arr_overlay_sl_visitor<OvlHlpr, OvlTr>:: 00318 after_handle_event (Event *event, Status_line_iterator iter, bool flag) 00319 { 00320 // Let the base construction visitor handle the event. 00321 bool res = Base::after_handle_event(event, iter, flag); 00322 00323 // In case there are no subcurves in the status line above the given event 00324 // point, we update the top fictitious halfedges for all subcurves incident 00325 // to this event. 00326 Event_subcurve_reverse_iterator rev_iter = event->right_curves_rbegin(); 00327 Subcurve *sc_above = NULL; 00328 00329 if (iter != this->status_line_end()) 00330 sc_above = (*iter); 00331 00332 if (sc_above == NULL) 00333 { 00334 if (rev_iter != event->right_curves_rend()) 00335 { 00336 if((*rev_iter)->color() == Traits_2::BLUE) 00337 (*rev_iter)->set_red_top_face (m_overlay_helper.red_top_face()); 00338 else if((*rev_iter)->color() == Traits_2::RED) 00339 (*rev_iter)->set_blue_top_face (m_overlay_helper.blue_top_face()); 00340 00341 (*rev_iter)->set_subcurve_above(NULL); 00342 sc_above = *rev_iter; 00343 ++rev_iter; 00344 } 00345 else 00346 { 00347 // Nothing else to do. 00348 return res; 00349 } 00350 } 00351 00352 // For each subcurve, try to locate a subcurve lying above it in the status 00353 // line that has a different color. 00354 for ( ; rev_iter != event->right_curves_rend(); ++rev_iter ) 00355 { 00356 Subcurve* curr_sc = *rev_iter; 00357 00358 if (! curr_sc->has_same_color(sc_above)) 00359 { 00360 curr_sc->set_subcurve_above(sc_above); 00361 } 00362 else 00363 { 00364 if (sc_above->subcurve_above() != NULL) 00365 curr_sc->set_subcurve_above (sc_above->subcurve_above()); 00366 else 00367 curr_sc->set_top_face (sc_above); 00368 } 00369 00370 sc_above = curr_sc; 00371 } 00372 return (res); 00373 } 00374 00375 //----------------------------------------------------------------------------- 00376 // Update an event that corresponds to a curve endpoint. 00377 // 00378 template <class OvlHlpr, class OvlTr> 00379 void Arr_overlay_sl_visitor<OvlHlpr, OvlTr>:: 00380 update_event (Event *e, 00381 const Point_2& end_point, 00382 const X_monotone_curve_2& /* cv */, 00383 Arr_curve_end /* cv_end */, 00384 bool /* is_new */) 00385 { 00386 // Nothing to do in case of an event at infinity. 00387 CGAL_assertion(e->is_closed()); 00388 00389 // Update the red and blue objects associated with the point as necessary. 00390 Point_2& pt = e->point(); 00391 00392 if (pt.is_red_object_empty()) 00393 { 00394 pt.set_red_object (end_point.red_object()); 00395 } 00396 else if (pt.is_blue_object_empty()) 00397 { 00398 pt.set_blue_object(end_point.blue_object()); 00399 } 00400 00401 return; 00402 } 00403 00404 //----------------------------------------------------------------------------- 00405 // Update an event. 00406 // 00407 template <class OvlHlpr, class OvlTr> 00408 void Arr_overlay_sl_visitor<OvlHlpr, OvlTr>:: 00409 update_event (Event *e, Subcurve *sc) 00410 { 00411 // Update the red and blue halfedges associated with the point as necessary. 00412 Point_2& pt = e->point(); 00413 00414 if (pt.is_red_object_empty()) 00415 { 00416 CGAL_assertion (! pt.is_blue_object_empty()); 00417 CGAL_assertion (sc->color() == Traits_2::RED); 00418 00419 Halfedge_handle_red red_he = sc->red_halfedge_handle(); 00420 pt.set_red_object (CGAL::make_object(red_he)); 00421 } 00422 else if (pt.is_blue_object_empty()) 00423 { 00424 Halfedge_handle_blue blue_he = sc->blue_halfedge_handle(); 00425 pt.set_blue_object(CGAL::make_object(blue_he)); 00426 } 00427 00428 return; 00429 } 00430 00431 //----------------------------------------------------------------------------- 00432 // Update an event. 00433 // 00434 template <class OvlHlpr, class OvlTr> 00435 void Arr_overlay_sl_visitor<OvlHlpr, OvlTr>::update_event (Event *e, 00436 const Point_2& p, 00437 bool /* is_new */) 00438 { 00439 // Update the red and blue objects associated with the point as necessary. 00440 Point_2& pt = e->point(); 00441 00442 if(pt.is_red_object_empty()) 00443 { 00444 pt.set_red_object(p.red_object()); 00445 } 00446 else if(pt.is_blue_object_empty()) 00447 { 00448 pt.set_blue_object(p.blue_object()); 00449 } 00450 00451 return; 00452 } 00453 00454 //----------------------------------------------------------------------------- 00455 // A notification issued when the sweep process has ended. 00456 // 00457 template <class OvlHlpr, class OvlTr> 00458 void Arr_overlay_sl_visitor<OvlHlpr, OvlTr>:: 00459 after_sweep() 00460 { 00461 // When the sweep-line process is over, the remaining arrangement face 00462 // (the current top face of the result arrangement) should be updated such 00463 // that it is the overlay of the two remaining red and blue unbounded face 00464 // (the current "red" and "blue" top faces, as given by the helper class). 00465 m_overlay_traits->create_face (m_overlay_helper.red_top_face(), 00466 m_overlay_helper.blue_top_face(), 00467 this->m_helper.top_face()); 00468 00469 return; 00470 } 00471 00472 //----------------------------------------------------------------------------- 00473 // Insert the given subcurve in the interior of an arrangement face. 00474 // 00475 template <class OvlHlpr, class OvlTr> 00476 typename Arr_overlay_sl_visitor<OvlHlpr, OvlTr>:: 00477 Halfedge_handle 00478 Arr_overlay_sl_visitor<OvlHlpr, OvlTr>:: 00479 insert_in_face_interior (const X_monotone_curve_2& cv, 00480 Subcurve* sc) 00481 { 00482 // Insert the halfedge using the base construction visitor. Note that the 00483 // resulting halfedge is directed from left to right. 00484 Halfedge_handle new_he = Base::insert_in_face_interior(cv,sc); 00485 00486 if (new_he->direction() == ARR_LEFT_TO_RIGHT) 00487 new_he = new_he->twin(); 00488 _map_halfedge_and_twin (new_he, 00489 cv.red_halfedge_handle(), cv.blue_halfedge_handle()); 00490 00491 // Update the newly created left vertex using the overlay traits. 00492 Vertex_handle new_v_left = 00493 (new_he->direction() == ARR_LEFT_TO_RIGHT ? 00494 new_he->source() : 00495 new_he->target()); 00496 00497 _create_vertex (this->last_event_on_subcurve(sc), new_v_left, sc); 00498 00499 // Update the newly created right vertex using the overlay traits. 00500 Vertex_handle new_v_right = 00501 (new_he->direction() == ARR_LEFT_TO_RIGHT ? 00502 new_he->target() : 00503 new_he->source()); 00504 00505 _create_vertex (this->current_event(), new_v_right, sc); 00506 00507 // Update the newly created edge using the overlay traits. 00508 _create_edge (sc, new_he); 00509 00510 return (new_he); 00511 } 00512 00513 //----------------------------------------------------------------------------- 00514 // Insert the given subcurve given its left end-vertex. 00515 // 00516 template <class OvlHlpr, class OvlTr> 00517 typename Arr_overlay_sl_visitor<OvlHlpr, OvlTr>:: 00518 Halfedge_handle 00519 Arr_overlay_sl_visitor<OvlHlpr, OvlTr>:: 00520 insert_from_left_vertex (const X_monotone_curve_2& cv, 00521 Halfedge_handle prev, 00522 Subcurve* sc) 00523 { 00524 // Insert the halfedge using the base construction visitor. Note that the 00525 // resulting halfedge is directed from left to right. 00526 Halfedge_handle new_he = Base::insert_from_left_vertex (cv, prev, sc); 00527 00528 if (new_he->direction() == ARR_LEFT_TO_RIGHT) 00529 new_he = new_he->twin(); 00530 _map_halfedge_and_twin (new_he, 00531 cv.red_halfedge_handle(), cv.blue_halfedge_handle()); 00532 00533 // Update the newly created right vertex (the newly created one) using the 00534 // overlay traits. 00535 Vertex_handle new_v_right = 00536 (new_he->direction() == ARR_LEFT_TO_RIGHT ? 00537 new_he->target() : 00538 new_he->source()); 00539 00540 _create_vertex (this->current_event(), new_v_right, sc); 00541 00542 // Update the newly created edge using the overlay traits. 00543 _create_edge (sc, new_he); 00544 00545 return (new_he); 00546 } 00547 00548 //----------------------------------------------------------------------------- 00549 // Insert the given subcurve given its right end-vertex. 00550 // 00551 template <class OvlHlpr, class OvlTr> 00552 typename Arr_overlay_sl_visitor<OvlHlpr, OvlTr>:: 00553 Halfedge_handle 00554 Arr_overlay_sl_visitor<OvlHlpr, OvlTr>:: 00555 insert_from_right_vertex (const X_monotone_curve_2& cv, 00556 Halfedge_handle prev, 00557 Subcurve *sc) 00558 { 00559 // Insert the halfedge using the base construction visitor. Note that the 00560 // resulting halfedge is directed from right to left. 00561 Halfedge_handle new_he = Base::insert_from_right_vertex (cv, prev, sc); 00562 00563 if (new_he->direction() == ARR_LEFT_TO_RIGHT) 00564 new_he = new_he->twin(); 00565 _map_halfedge_and_twin (new_he, 00566 cv.red_halfedge_handle(), cv.blue_halfedge_handle()); 00567 00568 // Update the newly created left vertex (the newly created one) using the 00569 // overlay traits. 00570 Vertex_handle new_v_left = 00571 (new_he->direction() == ARR_LEFT_TO_RIGHT ? 00572 new_he->source() : 00573 new_he->target()); 00574 00575 _create_vertex (this->last_event_on_subcurve(sc), new_v_left, sc); 00576 00577 // Update the newly created edge using the overlay traits. 00578 _create_edge (sc, new_he); 00579 00580 return (new_he); 00581 } 00582 00583 //----------------------------------------------------------------------------- 00584 // Insert the given subcurve given its two end-vertices. 00585 // 00586 template <class OvlHlpr, class OvlTr> 00587 typename Arr_overlay_sl_visitor<OvlHlpr, OvlTr>:: 00588 Halfedge_handle 00589 Arr_overlay_sl_visitor<OvlHlpr, OvlTr>:: 00590 insert_at_vertices (const X_monotone_curve_2& cv, 00591 Halfedge_handle prev1, 00592 Halfedge_handle prev2, 00593 Subcurve *sc, 00594 bool& new_face_created) 00595 { 00596 // Insert the halfedge using the base construction visitor. Note that the 00597 // resulting halfedge is always incident to the new face (if one created). 00598 Halfedge_handle new_he = Base::insert_at_vertices (cv, prev1, prev2, sc, 00599 new_face_created); 00600 bool flipped_he = false; 00601 00602 if (new_he->direction() == ARR_LEFT_TO_RIGHT) 00603 { 00604 new_he = new_he->twin(); 00605 flipped_he = true; 00606 } 00607 00608 _map_halfedge_and_twin (new_he, 00609 cv.red_halfedge_handle(), cv.blue_halfedge_handle()); 00610 00611 // Update the newly created edge using the overlay traits. 00612 _create_edge (sc, new_he); 00613 00614 // If a new face was created, we have to updated the newly created face 00615 // using the overlay traits. 00616 if (new_face_created) 00617 { 00618 // Obtain the new face, which is incident to new_he (note that in case 00619 // the construction helper indicates that the predecessor halfedges have 00620 // been swapped, we have to take the incident face of the twin). 00621 Face_handle new_face = (! flipped_he) ? 00622 new_he->face() : 00623 new_he->twin()->face(); 00624 Halfedge_handle he; 00625 00626 // Traverse the boundary of the new face, and locate halfedge originated 00627 // by red or by blue halfedges along its boundary. 00628 // We stop the traversal earlier if we locate a red and a blue halfedge. 00629 const Halfedge_handle_red invalid_red_he; 00630 const Halfedge_handle_blue invalid_blue_he; 00631 00632 Halfedge_handle_red red_he; 00633 Halfedge_handle_blue blue_he; 00634 00635 // msvc CL requires the breakdown to the following 2 statements: 00636 Outer_ccb_iterator occb_it = new_face->outer_ccbs_begin(); 00637 Ccb_halfedge_circulator ccb_first = *occb_it; 00638 Ccb_halfedge_circulator ccb_circ = ccb_first; 00639 00640 do 00641 { 00642 // Get the current halfedge on the face boundary and obtain its 00643 // originating halfedges. 00644 he = ccb_circ; 00645 00646 if (! m_halfedges_map.is_defined (he)) 00647 { 00648 // The mapping is not available for fictitious halfedges ... 00649 ++ccb_circ; 00650 continue; 00651 } 00652 00653 // The halfedge info is a pair of red and blue halfedges, one of them 00654 // may be invalid. 00655 const Halfedge_info& he_info = m_halfedges_map[he]; 00656 00657 if (he_info.first != invalid_red_he) 00658 { 00659 red_he = he_info.first; 00660 if (blue_he != invalid_blue_he) 00661 break; 00662 } 00663 00664 if (he_info.second != invalid_blue_he) 00665 { 00666 blue_he = he_info.second; 00667 if (red_he != invalid_red_he) 00668 break; 00669 } 00670 00671 ++ccb_circ; 00672 } while(ccb_circ != ccb_first); 00673 00674 // Determine the relation between the red and blue face that originate 00675 // our new overlay face and update it accordingly. 00676 Face_handle_red red_face; 00677 Face_handle_blue blue_face; 00678 00679 if (red_he != invalid_red_he && blue_he != invalid_blue_he) 00680 { 00681 // The red face and the blue face intersect (or overlap). 00682 red_face = red_he->face(); 00683 blue_face = blue_he->face(); 00684 } 00685 else if (red_he != invalid_red_he) 00686 { 00687 // The new overlay face is an entirely red face contained inside a blue 00688 // face. We have to find the identity of this containing blue face. 00689 Subcurve *sc_above = sc->subcurve_above(); 00690 00691 red_face = red_he->face(); 00692 00693 if (sc_above != NULL) 00694 blue_face = sc_above->blue_halfedge_handle()->face(); 00695 else 00696 blue_face = sc->blue_top_face(); 00697 } 00698 else 00699 { 00700 CGAL_assertion (blue_he != invalid_blue_he); 00701 00702 // The new overlay face is an entirely blue face contained inside a red 00703 // face. We have to find the identity of this containing red face. 00704 Subcurve *sc_above = sc->subcurve_above(); 00705 00706 blue_face = blue_he->face(); 00707 00708 if (sc_above != NULL) 00709 red_face = sc_above->red_halfedge_handle()->face(); 00710 else 00711 red_face = sc->red_top_face(); 00712 } 00713 00714 // Use the overlay traits to update the information of the newly created 00715 // face. 00716 m_overlay_traits->create_face (red_face, blue_face, 00717 new_face); 00718 } 00719 00720 return (new_he); 00721 } 00722 00723 //----------------------------------------------------------------------------- 00724 // Insert an isolated vertex into the arrangement. 00725 // 00726 template <class OvlHlpr, class OvlTr> 00727 typename Arr_overlay_sl_visitor<OvlHlpr, OvlTr>:: 00728 Vertex_handle 00729 Arr_overlay_sl_visitor<OvlHlpr, OvlTr>:: 00730 insert_isolated_vertex (const Point_2& pt, 00731 Status_line_iterator iter) 00732 { 00733 // Insert the isolated vertex using the base construction visitor. 00734 Vertex_handle new_v = Base::insert_isolated_vertex (pt, iter); 00735 00736 // Get the red and blue objects that originated the isolated point. 00737 // Note that as this point is isolated, both objects must be vertices 00738 // (in case they are not empty). 00739 const bool is_red_empty = pt.is_red_object_empty(); 00740 const bool is_blue_empty = pt.is_blue_object_empty(); 00741 00742 CGAL_assertion (! is_red_empty || ! is_blue_empty); 00743 00744 if (! is_red_empty && ! is_blue_empty) 00745 { 00746 // The vertex is created by two coincident isolated vertices. 00747 Vertex_handle_red red_v; 00748 Vertex_handle_blue blue_v; 00749 00750 CGAL::assign (red_v, pt.red_object()); 00751 CGAL::assign (blue_v, pt.blue_object()); 00752 00753 // Use the overlay traits to update the newly created isolated vertex. 00754 m_overlay_traits->create_vertex (red_v, blue_v, 00755 new_v); 00756 } 00757 else if (is_red_empty) 00758 { 00759 // We have an isolated blue vertex inside a red face. 00760 Vertex_handle_blue blue_v; 00761 Face_handle_red red_face; 00762 00763 CGAL::assign (blue_v, pt.blue_object()); 00764 00765 // Obtain the red face containing the isolated vertex. 00766 if (iter == this->status_line_end()) 00767 { 00768 // There is nothing above the vertex - use the current red top face. 00769 red_face = m_overlay_helper.red_top_face(); 00770 } 00771 else 00772 { 00773 // Go up the status line until we find a red halfedge. 00774 // Note that the subcurve above is always of an opposite color. However, 00775 // above the blue isolated vertex there may be one blue subcurve, but 00776 // the subcruve above it must be red in this case. This is why it is 00777 // sufficient to go at most two steps up. 00778 // There is nothing above the vertex - use the current red top face. 00779 Subcurve *sc_above = *iter; 00780 00781 if (sc_above == NULL) 00782 { 00783 red_face = m_overlay_helper.red_top_face(); 00784 } 00785 else 00786 { 00787 if (sc_above->color() != Traits_2::BLUE) 00788 { 00789 red_face = sc_above->red_halfedge_handle()->face(); 00790 } 00791 else 00792 { 00793 sc_above = sc_above->subcurve_above(); 00794 if (sc_above != NULL) 00795 red_face = sc_above->red_halfedge_handle()->face(); 00796 else 00797 red_face = m_overlay_helper.red_top_face(); 00798 } 00799 } 00800 } 00801 00802 // Use the overlay traits to update the newly created isolated vertex. 00803 m_overlay_traits->create_vertex (red_face, blue_v, 00804 new_v); 00805 } 00806 else 00807 { 00808 // We have an isolated red vertex inside a blue face. 00809 Vertex_handle_red red_v; 00810 Face_handle_blue blue_face; 00811 00812 CGAL::assign (red_v, pt.red_object()); 00813 00814 // Obtain the blue face containing the isolated vertex. 00815 if (iter == this->status_line_end()) 00816 { 00817 // There is nothing above the vertex - use the current blue top face. 00818 blue_face = m_overlay_helper.blue_top_face(); 00819 } 00820 else 00821 { 00822 // Go up the status line until we find a blue halfedge. 00823 // Note that the subcurve above is always of an opposite color. However, 00824 // above the red isolated vertex there may be one red subcurve, but 00825 // the subcruve above it must be blue in this case. This is why it is 00826 // sufficient to go at most two steps up. 00827 // If we do not find a blue halfedge, we use the current red top face. 00828 Subcurve *sc_above = *iter; 00829 00830 if (sc_above == NULL) 00831 { 00832 blue_face = m_overlay_helper.blue_top_face(); 00833 } 00834 else 00835 { 00836 if(sc_above->color() != Traits_2::RED) 00837 { 00838 blue_face = sc_above->blue_halfedge_handle()->face(); 00839 } 00840 else 00841 { 00842 sc_above = sc_above->subcurve_above(); 00843 if (sc_above != NULL) 00844 blue_face = sc_above->blue_halfedge_handle()->face(); 00845 else 00846 blue_face = m_overlay_helper.blue_top_face(); 00847 } 00848 } 00849 } 00850 00851 // Use the overlay traits to update the newly created isolated vertex. 00852 m_overlay_traits->create_vertex (red_v, blue_face, 00853 new_v); 00854 } 00855 00856 return (new_v); 00857 } 00858 00859 //----------------------------------------------------------------------------- 00860 // Map a newly created halfedge in the result arrangement to its originator 00861 // red and blue halfedges. 00862 // 00863 template <class OvlHlpr, class OvlTr> 00864 void Arr_overlay_sl_visitor<OvlHlpr, OvlTr>:: 00865 _map_halfedge_and_twin (Halfedge_handle he, 00866 Halfedge_handle_red red_he, 00867 Halfedge_handle_blue blue_he) 00868 { 00869 // Obtain the twin red and blue halfedges (if they are valid). Note that 00870 // the original halfedges are always directed from right to left. 00871 Halfedge_handle_red red_he_twin; 00872 Halfedge_handle_blue blue_he_twin; 00873 00874 if (red_he != Halfedge_handle_red()) 00875 red_he_twin = red_he->twin(); 00876 00877 if (blue_he != Halfedge_handle_blue()) 00878 blue_he_twin = blue_he->twin(); 00879 00880 // Create the halfedge-information pairs and store them in the map. 00881 Halfedge_info he_info = std::make_pair (red_he, blue_he); 00882 Halfedge_info he_twin_info = std::make_pair (red_he_twin, blue_he_twin); 00883 00884 m_halfedges_map[he] = he_info; 00885 m_halfedges_map[he->twin()] = he_twin_info; 00886 00887 return; 00888 } 00889 00890 //----------------------------------------------------------------------------- 00891 // Update a newly created result vertex using the overlay traits. 00892 // 00893 template <class OvlHlpr, class OvlTr> 00894 void Arr_overlay_sl_visitor<OvlHlpr, OvlTr>:: 00895 _create_vertex (Event *event, Vertex_handle new_v, Subcurve *sc) 00896 { 00897 // Get the red and blue objects that originate the vertex. 00898 const Point_2& pt = event->point(); 00899 CGAL_assertion (! pt.is_red_object_empty() || ! pt.is_blue_object_empty()); 00900 00901 const CGAL::Object& red_obj = pt.red_object(); 00902 const CGAL::Object& blue_obj = pt.blue_object(); 00903 Subcurve *sc_above = sc->subcurve_above(); 00904 00905 // Check if the red object is a vertex. 00906 Vertex_handle_red red_v; 00907 if (CGAL::assign(red_v, red_obj)) 00908 { 00909 Vertex_handle_blue blue_v; 00910 00911 if (CGAL::assign (blue_v, blue_obj)) 00912 { 00913 // We have a red vertex on a blue vertex. 00914 m_overlay_traits->create_vertex (red_v, blue_v, 00915 new_v); 00916 } 00917 else 00918 { 00919 Halfedge_handle_blue blue_he; 00920 00921 if (CGAL::assign (blue_he, blue_obj)) 00922 { 00923 // We have a red vertex on a blue halfedge. 00924 m_overlay_traits->create_vertex (red_v, blue_he, 00925 new_v); 00926 } 00927 else 00928 { 00929 CGAL_assertion(blue_obj.is_empty()); 00930 00931 // We have a red vertex inside blue face. We obtain the blue face 00932 // by looking for a subcurve above. 00933 Face_handle_blue blue_f; 00934 00935 if (sc_above != NULL) 00936 blue_f = sc_above->blue_halfedge_handle()->face(); 00937 else 00938 blue_f = sc->blue_top_face(); 00939 00940 m_overlay_traits->create_vertex (red_v, blue_f, 00941 new_v); 00942 } 00943 } 00944 } 00945 else 00946 { 00947 // Check if the red object is a halfedge. 00948 Halfedge_handle_red red_he; 00949 if (CGAL::assign (red_he, red_obj)) 00950 { 00951 Halfedge_handle_blue blue_he; 00952 00953 if (CGAL::assign (blue_he, blue_obj)) 00954 { 00955 // We have an itersection between a red halfedge and a blue halfedge. 00956 m_overlay_traits->create_vertex (red_he, blue_he, 00957 new_v); 00958 } 00959 else 00960 { 00961 // We have a blue vertex on a red halfedge. 00962 Vertex_handle_blue blue_v; 00963 00964 CGAL::assign (blue_v, blue_obj); 00965 00966 m_overlay_traits->create_vertex (red_he, blue_v, 00967 new_v); 00968 } 00969 } 00970 else 00971 { 00972 CGAL_assertion(red_obj.is_empty()); 00973 00974 // We have a blue vertex inside a red face. We obtain the red face 00975 // by looking for a subcurve above. 00976 Vertex_handle_blue blue_v; 00977 Face_handle_red red_f; 00978 00979 CGAL::assign(blue_v, blue_obj); 00980 00981 if (sc_above != NULL) 00982 red_f = sc_above ->red_halfedge_handle()->face(); 00983 else 00984 red_f = sc->red_top_face(); 00985 00986 m_overlay_traits->create_vertex(red_f, blue_v, new_v); 00987 } 00988 } 00989 00990 return; 00991 } 00992 00993 //----------------------------------------------------------------------------- 00994 // Update a newly created result edge using the overlay traits. 00995 // 00996 template <class OvlHlpr, class OvlTr> 00997 void Arr_overlay_sl_visitor<OvlHlpr, OvlTr>:: 00998 _create_edge (Subcurve *sc, Halfedge_handle new_he) 00999 { 01000 // Note that the "red" and "blue" halfedges are always directed from right 01001 // to left, so we make sure the overlaid halfedge is also directed from 01002 // right to left. 01003 if (new_he->direction() != ARR_RIGHT_TO_LEFT) 01004 new_he = new_he->twin(); 01005 01006 // Examine the various cases for the creation of a new edge. 01007 if (sc->color() == Traits_2::RB_OVERLAP) 01008 { 01009 // The new edge represents an overlap between a red halfedge and a blue 01010 // halfedge. 01011 Halfedge_handle_red red_he = sc->red_halfedge_handle(); 01012 Halfedge_handle_blue blue_he = sc->blue_halfedge_handle(); 01013 01014 m_overlay_traits->create_edge (red_he, blue_he, 01015 new_he); 01016 } 01017 else if(sc->color() == Traits_2::RED) 01018 { 01019 // We have a red edge on a blue face. 01020 Halfedge_handle_red red_he = sc->red_halfedge_handle(); 01021 Face_handle_blue blue_f; 01022 Subcurve *sc_above = sc->subcurve_above(); 01023 01024 if (sc_above != NULL) 01025 blue_f = sc_above->blue_halfedge_handle()->face(); 01026 else 01027 blue_f = sc->blue_top_face(); 01028 01029 m_overlay_traits ->create_edge (red_he, blue_f, 01030 new_he); 01031 } 01032 else 01033 { 01034 CGAL_assertion(sc->color() == Traits_2::BLUE); 01035 01036 // We have a blue edge on a red face. 01037 Halfedge_handle_blue blue_he = sc->blue_halfedge_handle(); 01038 Face_handle_red red_f; 01039 Subcurve *sc_above = sc->subcurve_above(); 01040 01041 if (sc_above != NULL) 01042 red_f = sc_above->red_halfedge_handle()->face(); 01043 else 01044 red_f = sc->red_top_face(); 01045 01046 m_overlay_traits->create_edge(red_f, blue_he, new_he); 01047 } 01048 01049 return; 01050 } 01051 01052 CGAL_END_NAMESPACE 01053 01054 #endif