BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Sweep_line_2/Arr_overlay_sl_visitor.h
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines