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