BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Arrangement_2/Arrangement_on_surface_2_global.h
Go to the documentation of this file.
00001 
00002 // Copyright (c) 2005  Tel-Aviv University (Israel).
00003 // All rights reserved.
00004 //
00005 // This file is part of CGAL (www.cgal.org); you may redistribute it under
00006 // the terms of the Q Public License version 1.0.
00007 // See the file LICENSE.QPL distributed with CGAL.
00008 //
00009 // Licensees holding a valid commercial license may use this file in
00010 // accordance with the commercial license agreement provided with the software.
00011 //
00012 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00013 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00014 //
00015 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/Arrangement_on_surface_2/include/CGAL/Arrangement_2/Arrangement_on_surface_2_global.h $
00016 // $Id: Arrangement_on_surface_2_global.h 50366 2009-07-05 12:56:48Z efif $
00017 // 
00018 //
00019 // Author(s)     : Ron Wein          <wein@post.tau.ac.il>
00020 //                 Baruch Zukerman   <baruchzu@post.tau.ac.il>
00021 //                 Efi Fogel         <efif@post.tau.ac.il>
00022 //
00023 #ifndef CGAL_ARRANGEMENT_ON_SURFACE_2_GLOBAL_H
00024 #define CGAL_ARRANGEMENT_ON_SURFACE_2_GLOBAL_H
00025 
00030 #include <boost/type_traits.hpp>
00031 #include <boost/mpl/if.hpp>
00032 
00033 #include <CGAL/Arrangement_on_surface_2.h>
00034 #include <CGAL/Arr_accessor.h>
00035 #include <CGAL/Basic_sweep_line_2.h>
00036 #include <CGAL/Sweep_line_2.h>
00037 #include <CGAL/Arrangement_zone_2.h>
00038 #include <CGAL/Arrangement_2/Arr_compute_zone_visitor.h>
00039 #include <CGAL/Arrangement_2/Arr_do_intersect_zone_visitor.h>
00040 #include <CGAL/Arrangement_2/Arr_traits_adaptor_2.h>
00041 #include <CGAL/Sweep_line_2/Sweep_line_2_utils.h>
00042 #include <CGAL/Sweep_line_2/Sweep_line_2_visitors.h>
00043 
00044 #include <boost/type_traits.hpp>
00045 
00046 #include <list>
00047 
00048 CGAL_BEGIN_NAMESPACE
00049 
00050 //-----------------------------------------------------------------------------
00051 // Insert a curve into the arrangement (incremental insertion).
00052 // The inserted curve may intersect the existing arrangement.
00053 //
00054 // The last parameter is used to resolve ambiguity between this function and 
00055 // do_intersect of X_monotone_curve_2 in case that X_monotone_curve_2 and 
00056 // Curve_2 are the same class. 
00057 // The last parameter should be boost::false_type but we used a 
00058 // workaround since it didn't compile in FC3_g++-3.4.4 with the error of:
00059 //
00060 // error: no matching function for call to `do_intersect(Arrangement_2<>&, 
00061 // const Arr_segment_2&, const Arr_walk_along_line_point_location<>&, 
00062 // mpl_::bool_< true>)'
00063 //
00064 template <class GeomTraits, class TopTraits, class PointLocation, 
00065   class ZoneVisitor>
00066 void insert (Arrangement_on_surface_2<GeomTraits, TopTraits>& arr, 
00067              const typename GeomTraits::Curve_2& c,
00068              const PointLocation& pl, ZoneVisitor &visitor, 
00069              boost::is_same<int, double>::type)
00070 {
00071   typedef Arrangement_on_surface_2<GeomTraits, TopTraits>  Arr;
00072   typedef ZoneVisitor                                      Zone_visitor;
00073 
00074   // Obtain an arrangement accessor.
00075   Arr_accessor<Arr>                      arr_access (arr);
00076 
00077   // Initialize a zone-computation object an a visitor that performs the
00078   // incremental insertion.
00079   Arrangement_zone_2<Arr, Zone_visitor>  arr_zone (arr, &visitor);
00080 
00081   // Break the input curve into x-monotone subcurves and isolated points.
00082   std::list<CGAL::Object>                         x_objects;
00083   std::list<CGAL::Object>::const_iterator         obj_iter;
00084   const typename GeomTraits::X_monotone_curve_2  *x_curve;
00085   const typename GeomTraits::Point_2             *iso_p;
00086 
00087   arr.geometry_traits()->make_x_monotone_2_object()
00088     (c, std::back_inserter (x_objects));
00089 
00090   // Insert each x-monotone curve into the arrangement.
00091   for (obj_iter = x_objects.begin(); obj_iter != x_objects.end(); ++obj_iter)
00092   {
00093     // Act according to the type of the current object.
00094     x_curve =
00095       object_cast<typename GeomTraits::X_monotone_curve_2> (&(*obj_iter));
00096 
00097     if (x_curve != NULL)
00098     {
00099       // Inserting an x-monotone curve:
00100       // Initialize the zone-computation object with the given curve.
00101       arr_zone.init (*x_curve, pl);
00102 
00103       // Notify the arrangement observers that a global operation is about to 
00104       // take place.
00105       arr_access.notify_before_global_change();
00106 
00107       // Insert the current x-monotone curve into the arrangement.
00108       arr_zone.compute_zone();
00109 
00110       // Notify the arrangement observers that the global operation has been
00111       // completed.
00112       arr_access.notify_after_global_change();
00113     }
00114     else
00115     {
00116       iso_p = object_cast<typename GeomTraits::Point_2> (&(*obj_iter));
00117       CGAL_assertion (iso_p != NULL);
00118 
00119       // Inserting a point into the arrangement:
00120       insert_point (arr, *iso_p, pl);
00121     }
00122   }
00123 }
00124 
00125 //-----------------------------------------------------------------------------
00126 // Insert an x-monotone curve into the arrangement (incremental insertion).
00127 // The inserted x-monotone curve may intersect the existing arrangement.
00128 //
00129 // The last parameter is used to resolve ambiguity between this function and 
00130 // do_intersect of Curve_2 in case that X_monotone_curve_2 and Curve_2 are the 
00131 // same class. The last parameter should be boost::true_type but we used a 
00132 // workaround since it didn't compile in FC3_g++-3.4.4 with the error of:
00133 //
00134 // error: no matching function for call to `do_intersect(Arrangement_2<>&, 
00135 // const Arr_segment_2&, const Arr_walk_along_line_point_location<>&, 
00136 // mpl_::bool_< true>)'
00137 //
00138 //
00139 template <class GeomTraits, class TopTraits, class PointLocation, 
00140   class ZoneVisitor>
00141 void insert(Arrangement_on_surface_2<GeomTraits, TopTraits>& arr,
00142             const typename GeomTraits::X_monotone_curve_2& c,
00143             const PointLocation& pl, ZoneVisitor &visitor, 
00144             boost::is_same<int, int>::type)
00145 {
00146   typedef Arrangement_on_surface_2<GeomTraits, TopTraits>  Arr;
00147   typedef ZoneVisitor                                      Zone_visitor;
00148 
00149   // Obtain an arrangement accessor.
00150   Arr_accessor<Arr>                      arr_access (arr);
00151 
00152   // Initialize a zone-computation object an a visitor that performs the
00153   // incremental insertion.
00154   Arrangement_zone_2<Arr, Zone_visitor>  arr_zone (arr, &visitor);
00155 
00156   // Initialize the zone-computation object with the given curve.
00157 
00158 /*  Needs to be deleted!!!
00159     {
00160     std::cout << std::endl;
00161     std::cout << "xxxxxxxxxxxx" << std::endl;
00162     std::cout << "c: " << c << std::endl;
00163     std::cout << std::endl;
00164     typename Arr::Vertex_const_iterator  vit;
00165     std::cout << arr.number_of_vertices() << " vertices:" << std::endl;
00166     for (vit = arr.vertices_begin(); vit != arr.vertices_end(); ++vit)
00167     {
00168       std::cout << "(" << vit->point() << ")";
00169       if (vit->is_isolated())
00170         std::cout << " - Isolated." << std::endl;
00171       else
00172         std::cout << " - degree " << vit->degree() << std::endl;
00173     }
00174     std::cout << std::endl;
00175     std::cout << "xxxxxxxxxxxx" << std::endl;
00176   }  
00177 */
00178   arr_zone.init (c, pl);
00179 
00180   // Notify the arrangement observers that a global operation is about to 
00181   // take place.
00182   arr_access.notify_before_global_change();
00183 
00184   // Insert the x-monotone curve into the arrangement.
00185   arr_zone.compute_zone();
00186 
00187   // Notify the arrangement observers that the global operation has been
00188   // completed.
00189   arr_access.notify_after_global_change();
00190 }
00191 
00192 //-----------------------------------------------------------------------------
00193 // Common interface for the insert of the Curve_2 and X_monotone_curve_2
00194 template <class GeomTraits, class TopTraits, class Curve, class PointLocation, 
00195   class ZoneVisitor>
00196 void insert (Arrangement_on_surface_2<GeomTraits, TopTraits>& arr,
00197              const Curve& c, const PointLocation& pl, ZoneVisitor &visitor)
00198 {
00199   typedef typename GeomTraits::X_monotone_curve_2       X_monotone_curve_2;
00200   
00201   typedef typename boost::is_same<Curve, X_monotone_curve_2>::type
00202     Is_x_monotone;
00203   
00204   insert(arr, c, pl, visitor, Is_x_monotone());
00205 }
00206 
00207 // In some compilers there is a template deduction disambiguity between this
00208 // function and the function receiving two InputIterator.
00209 // For now the solution is to add a dummy variable at the end (referring
00210 // to point-location). Maybe the proper solution is to use boost::enable_if
00211 // together with appropriate tag.
00212 template <class GeomTraits, class TopTraits, class Curve, class PointLocation>
00213 void insert (Arrangement_on_surface_2<GeomTraits, TopTraits>& arr,
00214              const Curve& c, const PointLocation& pl,
00215              typename PointLocation::Point_2*)
00216 {
00217   typedef Arrangement_on_surface_2<GeomTraits, TopTraits>  Arr;
00218   typedef typename TopTraits::Zone_insertion_visitor       Zone_visitor;
00219   
00220   Zone_visitor visitor;
00221   insert (arr, c, pl, visitor);
00222 }
00223 
00224 //-----------------------------------------------------------------------------
00225 // Insert a curve/x-monotone curve into the arrangement (incremental 
00226 // insertion).
00227 // The inserted x-monotone curve may intersect the existing arrangement.
00228 // Overloaded version with no point location object - using the default point
00229 // location.
00230 //
00231 template <class GeomTraits, class TopTraits, class Curve>
00232 void insert(Arrangement_on_surface_2<GeomTraits, TopTraits>& arr,
00233             const Curve& c)
00234 {
00235   // Create a default point-location object and use it to insert the curve.
00236   typename TopTraits::Default_point_location_strategy    def_pl (arr);
00237 
00238   insert (arr, c, def_pl);
00239 }
00240 
00246 template <typename GeomTraits, typename TopTraits, typename InputIterator>
00247 void insert_empty(Arrangement_on_surface_2<GeomTraits, TopTraits>& arr,
00248                   InputIterator begin_xcurves, InputIterator end_xcurves)
00249 {
00250   typedef typename TopTraits::Sweep_line_construction_visitor
00251                                                         Construct_visitor;
00252   typedef typename Construct_visitor::Traits_2          Construct_traits;
00253 
00254   const GeomTraits * geom_traits = arr.geometry_traits();
00255   Construct_visitor visitor(&arr);
00256 
00257   /* We would like to avoid copy construction of the geometry traits class.
00258    * Copy construction is undesired, because it may results with data
00259    * duplication or even data loss.
00260    *
00261    * If the type Construct_visitor::Traits_2 is the same as the type
00262    * GeomTraits, use a reference to GeomTraits to avoid constructing a new one.
00263    * Otherwise, instantiate a local variable of the former and provide
00264    * the later as a single parameter to the constructor.
00265    * 
00266    * Use the form 'A a(*b);' and not ''A a = b;' to handle the case where A has
00267    * only an implicit constructor, (which takes *b as a parameter).
00268    */
00269   typename boost::mpl::if_<boost::is_same<GeomTraits, Construct_traits>,
00270                            const Construct_traits&, Construct_traits>::type
00271     traits(*geom_traits);
00272 
00273   // Define a sweep-line instance and perform the sweep:
00274   Sweep_line_2<typename Construct_visitor::Traits_2, Construct_visitor,
00275                typename Construct_visitor::Subcurve,
00276                typename Construct_visitor::Event>
00277     sweep_line(&traits, &visitor);
00278   sweep_line.sweep(begin_xcurves, end_xcurves);
00279 }
00280 
00289 template <typename GeomTraits, typename TopTraits,
00290           typename XcInputIterator, typename PInputIterator>
00291 void insert_empty(Arrangement_on_surface_2<GeomTraits, TopTraits>& arr,
00292                   XcInputIterator begin_xcurves, XcInputIterator end_xcurves,
00293                   PInputIterator begin_points, PInputIterator end_points)
00294 {
00295   typedef typename TopTraits::Sweep_line_construction_visitor
00296                                                         Construct_visitor;
00297   typedef typename Construct_visitor::Traits_2          Construct_traits;
00298   
00299   const GeomTraits * geom_traits = arr.geometry_traits();
00300   Construct_visitor visitor(&arr);
00301 
00302   /* We would like to avoid copy construction of the geometry traits class.
00303    * Copy construction is undesired, because it may results with data
00304    * duplication or even data loss.
00305    *
00306    * If the type Construct_visitor::Traits_2 is the same as the type
00307    * GeomTraits, use a reference to GeomTraits to avoid constructing a new one.
00308    * Otherwise, instantiate a local variable of the former and provide
00309    * the later as a single parameter to the constructor.
00310    * 
00311    * Use the form 'A a(*b);' and not ''A a = b;' to handle the case where A has
00312    * only an implicit constructor, (which takes *b as a parameter).
00313    */
00314   typename boost::mpl::if_<boost::is_same<GeomTraits, Construct_traits>,
00315                            const Construct_traits&, Construct_traits>::type
00316     traits(*geom_traits);
00317     
00318   // Define a sweep-line instance and perform the sweep.
00319   Sweep_line_2<typename Construct_visitor::Traits_2, Construct_visitor,
00320                typename Construct_visitor::Subcurve,
00321                typename Construct_visitor::Event>
00322     sweep_line(&traits, &visitor);
00323   sweep_line.sweep(begin_xcurves, end_xcurves, begin_points, end_points);
00324 }
00325 
00331 template <typename GeomTraits, typename TopTraits,
00332           typename XcInputIterator, typename PInputIterator>
00333 void insert_non_empty(Arrangement_on_surface_2<GeomTraits, TopTraits>& arr,
00334                       XcInputIterator begin_xcurves,
00335                       XcInputIterator end_xcurves,
00336                       PInputIterator begin_points, PInputIterator end_points)
00337 {
00338   typedef typename TopTraits::Sweep_line_insertion_visitor
00339                                                         Insert_visitor;
00340   typedef typename Insert_visitor::Traits_2             Insert_traits;
00341   typedef typename Insert_visitor::Traits_2::X_monotone_curve_2
00342                                                         Ex_x_monotone_curve_2;
00343   typedef typename Insert_visitor::Traits_2::Point_2    Ex_point_2;
00344   
00345   const GeomTraits * geom_traits = arr.geometry_traits();
00346   Insert_visitor visitor(&arr);
00347 
00348   /* We would like to avoid copy construction of the geometry traits class.
00349    * Copy construction is undesired, because it may results with data
00350    * duplication or even data loss.
00351    *
00352    * If the type Construct_visitor::Traits_2 is the same as the type
00353    * GeomTraits, use a reference to GeomTraits to avoid constructing a new one.
00354    * Otherwise, instantiate a local variable of the former and provide
00355    * the later as a single parameter to the constructor.
00356    * 
00357    * Use the form 'A a(*b);' and not ''A a = b;' to handle the case where A has
00358    * only an implicit constructor, (which takes *b as a parameter).
00359    */
00360   typename boost::mpl::if_<boost::is_same<GeomTraits, Insert_traits>,
00361                            const Insert_traits&, Insert_traits>::type
00362     traits(*geom_traits);
00363 
00364   // Create a set of existing as well as new curves and points.
00365   std::list<Ex_x_monotone_curve_2> ex_cvs;
00366   std::list<Ex_point_2> ex_pts;
00367     
00368   prepare_for_sweep(arr,
00369                     begin_xcurves, end_xcurves,   // the x-monotone curves
00370                     begin_points, end_points,     // the points (if any)
00371                     std::back_inserter(ex_cvs),
00372                     std::back_inserter(ex_pts),
00373                     &traits);
00374 
00375   // Define a basic sweep-line instance and perform the sweep.
00376   Sweep_line_2<typename Insert_visitor::Traits_2, Insert_visitor,
00377                typename Insert_visitor::Subcurve,
00378                typename Insert_visitor::Event>
00379     sweep_line(&traits, &visitor);
00380   sweep_line.sweep(ex_cvs.begin(), ex_cvs.end(),ex_pts.begin(), ex_pts.end());
00381 };
00382 
00383 //-----------------------------------------------------------------------------
00384 // Insert a range of curves into the arrangement (aggregated insertion). 
00385 // The inserted curves may intersect one another and may also intersect the 
00386 // existing arrangement.
00387 //
00388 // The last parameter is used to resolve ambiguity between this function and 
00389 // do_intersect of X_monotone_curve_2 in case that X_monotone_curve_2 and 
00390 // Curve_2 are the same class. 
00391 // The last parameter should be boost::false_type but we used a 
00392 // workaround since it didn't compile in FC3_g++-3.4.4 with the error of:
00393 //
00394 // error: no matching function for call to `do_intersect(Arrangement_2<>&, 
00395 // const Arr_segment_2&, const Arr_walk_along_line_point_location<>&, 
00396 // mpl_::bool_< true>)'
00397 //
00398 template <class GeomTraits, class TopTraits, class InputIterator>
00399 void insert (Arrangement_on_surface_2<GeomTraits, TopTraits>& arr,
00400              InputIterator begin, InputIterator end,
00401              boost::is_same<int, double>::type)
00402 {
00403   typedef Arrangement_on_surface_2<GeomTraits, TopTraits>   Arr;
00404   typedef typename GeomTraits::Point_2                      Point_2;
00405   typedef typename GeomTraits::X_monotone_curve_2           X_monotone_curve_2;
00406 
00407   // Obtain an arrangement accessor.
00408   Arr_accessor<Arr>                  arr_access (arr);
00409 
00410   // Notify the arrangement observers that a global operation is about to 
00411   // take place.
00412   arr_access.notify_before_global_change();
00413 
00414   // Subdivide the input curves into x-monotone subcurves and isolated points.
00415   const GeomTraits * geom_traits = arr.geometry_traits();
00416   std::list<X_monotone_curve_2>      xcurves;
00417   std::list<Point_2>                 iso_points;
00418 
00419   make_x_monotone(begin, end,
00420                   std::back_inserter(xcurves), std::back_inserter(iso_points),
00421                   geom_traits);
00422 
00423   if (arr.is_empty())
00424     insert_empty(arr, xcurves.begin(), xcurves.end(),
00425                  iso_points.begin(), iso_points.end());
00426   else
00427     insert_non_empty(arr, xcurves.begin(), xcurves.end(),
00428                      iso_points.begin(), iso_points.end());
00429 
00430   // Notify the arrangement observers that the global operation has been
00431   // completed.
00432   arr_access.notify_after_global_change();
00433 }
00434 
00435 //-----------------------------------------------------------------------------
00436 // Insert a range of x-monotone curves into the arrangement (aggregated
00437 // insertion). The inserted x-monotone curves may intersect one another and
00438 // may also intersect the existing arrangement.
00439 //
00440 // The last parameter is used to resolve ambiguity between this function and 
00441 // insert of Curve_2 in case that X_monotone_curve_2 and Curve_2 are the 
00442 // same class. The last parameter should be boost::true_type but we used a 
00443 // workaround since it didn't compile in FC3_g++-3.4.4 with the error of:
00444 //
00445 // error: no matching function for call to `do_intersect(Arrangement_2<>&, 
00446 // const Arr_segment_2&, const Arr_walk_along_line_point_location<>&, 
00447 // mpl_::bool_< true>)'
00448 //
00449 template <class GeomTraits, class TopTraits, class InputIterator>
00450 void insert(Arrangement_on_surface_2<GeomTraits, TopTraits>& arr,
00451             InputIterator begin, InputIterator end, 
00452             boost::is_same<int, int>::type)
00453 {
00454   typedef Arrangement_on_surface_2<GeomTraits, TopTraits>   Arr;
00455 
00456   // Obtain an arrangement accessor.
00457   Arr_accessor<Arr>                  arr_access (arr);
00458 
00459   // Notify the arrangement observers that a global operation is about to 
00460   // take place.
00461   arr_access.notify_before_global_change();
00462 
00463   // Choose the operation depending on whether the input arrangement is
00464   // empty (then we construct it from scratch), or not (where we just insert
00465   // the new curves).
00466   if (arr.is_empty())
00467     insert_empty(arr, begin, end);
00468   else {
00469     // The arrangement is not empty: use the insertion visitor.
00470     std::list<typename GeomTraits::Point_2> empty;
00471     insert_non_empty(arr, begin, end, empty.begin(), empty.end());
00472   }
00473 
00474   // Notify the arrangement observers that the global operation has been
00475   // completed.
00476   arr_access.notify_after_global_change();
00477 }
00478 
00479 //-----------------------------------------------------------------------------
00480 // Common interface for the inserts of the Curve_2 and X_monotone_curve_2
00481 template <class GeomTraits, class TopTraits, class InputIterator>
00482 void insert (Arrangement_on_surface_2<GeomTraits,TopTraits>& arr,
00483              InputIterator begin, InputIterator end)
00484 {
00485   typedef typename GeomTraits::X_monotone_curve_2       X_monotone_curve_2;
00486   typedef typename std::iterator_traits<InputIterator>::value_type 
00487     Iterator_value_type;
00488 
00489   typedef typename boost::is_same<Iterator_value_type,X_monotone_curve_2>::type
00490     Is_x_monotone;
00491   
00492   return insert (arr, begin, end, Is_x_monotone());
00493 }
00494 
00495 //-----------------------------------------------------------------------------
00496 // Insert an x-monotone curve into the arrangement (incremental insertion)
00497 // when the location of the left endpoint of the curve is known and is
00498 // given as an isertion hint.
00499 // The inserted x-monotone curve may intersect the existing arrangement.
00500 //
00501 template <class GeomTraits, class TopTraits>
00502 void insert (Arrangement_on_surface_2<GeomTraits, TopTraits>& arr,
00503              const typename GeomTraits::X_monotone_curve_2& c,
00504              const Object& obj)
00505 {
00506   typedef Arrangement_on_surface_2<GeomTraits, TopTraits>  Arr;
00507   typedef typename TopTraits::Zone_insertion_visitor       Zone_visitor;
00508 
00509   // Obtain an arrangement accessor.
00510   Arr_accessor<Arr>                      arr_access (arr);
00511 
00512   // Define a zone-computation object an a visitor that performs the
00513   // incremental insertion.
00514   Zone_visitor                           visitor;
00515   Arrangement_zone_2<Arr, Zone_visitor>  arr_zone (arr, &visitor);
00516 
00517   // Initialize the zone-computation object with the given curve.
00518   arr_zone.init_with_hint (c, obj);
00519 
00520   // Notify the arrangement observers that a global operation is about to 
00521   // take place.
00522   arr_access.notify_before_global_change();
00523 
00524   // Insert the x-monotone curve into the arrangement.
00525   arr_zone.compute_zone();
00526 
00527   // Notify the arrangement observers that the global operation has been
00528   // completed.
00529   arr_access.notify_after_global_change();
00530 }
00531 
00532 // ----------------------------------------------------------------------------
00533 // backward compatibility functions.
00534 /* DEPRECATED use insert() instead */
00535 template <class GeomTraits, class TopTraits, class PointLocation>
00536 CGAL_DEPRECATED void insert_x_monotone_curve
00537 (Arrangement_on_surface_2<GeomTraits, TopTraits>& arr,
00538  const typename GeomTraits::X_monotone_curve_2& c,
00539  const PointLocation& pl)
00540 {
00541   insert(arr, c, pl);
00542 }
00543 
00544 /* DEPRECATED use insert() instead */
00545 template <class GeomTraits, class TopTraits>
00546 CGAL_DEPRECATED void insert_x_monotone_curve
00547 (Arrangement_on_surface_2<GeomTraits, TopTraits>& arr,
00548  const typename GeomTraits::X_monotone_curve_2& c)
00549 {
00550   insert(arr, c);
00551 }
00552 
00553 /* DEPRECATED use insert() instead */
00554 template <class GeomTraits, class TopTraits, class InputIterator>
00555 CGAL_DEPRECATED void insert_x_monotone_curves 
00556 (Arrangement_on_surface_2<GeomTraits, TopTraits>& arr,
00557  InputIterator begin, InputIterator end)
00558 {
00559   insert(arr, begin, end);
00560 }
00561 
00562 /* DEPRECATED use insert() instead */
00563 template <class GeomTraits, class TopTraits>
00564 CGAL_DEPRECATED void insert_x_monotone_curve
00565 (Arrangement_on_surface_2<GeomTraits, TopTraits>& arr,
00566  const typename GeomTraits::X_monotone_curve_2& c,
00567  const Object& obj)
00568 {
00569   insert(arr, c, obj);
00570 }
00571 
00572 /* DEPRECATED use insert() instead */
00573 template <class GeomTraits, class TopTraits, class PointLocation>
00574 CGAL_DEPRECATED
00575 void insert_curve(Arrangement_on_surface_2<GeomTraits, TopTraits>& arr,
00576                   const typename GeomTraits::Curve_2& c,
00577                   const PointLocation& pl)
00578 {
00579   insert(arr, c, pl);
00580 }
00581 
00582 /* DEPRECATED use insert() instead */
00583 template <class GeomTraits, class TopTraits>
00584 CGAL_DEPRECATED
00585 void insert_curve(Arrangement_on_surface_2<GeomTraits, TopTraits>& arr,
00586                   const typename GeomTraits::Curve_2& c)
00587 {
00588   insert(arr, c);
00589 }
00590 
00591 /* DEPRECATED use insert() instead */
00592 template <class GeomTraits, class TopTraits, class InputIterator>
00593 CGAL_DEPRECATED
00594 void insert_curves (Arrangement_on_surface_2<GeomTraits, TopTraits>& arr,
00595                     InputIterator begin, InputIterator end)
00596 {
00597   insert(arr, begin, end);
00598 }
00599 
00600 //-----------------------------------------------------------------------------
00601 // Insert an x-monotone curve into the arrangement, such that the curve
00602 // interior does not intersect with any existing edge or vertex in the
00603 // arragement (incremental insertion).
00604 //
00605 template <class GeomTraits, class TopTraits, class PointLocation>
00606 typename Arrangement_on_surface_2<GeomTraits, TopTraits>::Halfedge_handle
00607 insert_non_intersecting_curve
00608     (Arrangement_on_surface_2<GeomTraits, TopTraits>& arr,
00609      const typename GeomTraits::X_monotone_curve_2& c,
00610      const PointLocation& pl)
00611 {
00612   typedef Arrangement_on_surface_2<GeomTraits, TopTraits>  Arr;
00613 
00614   typedef Arr_traits_basic_adaptor_2<typename Arr::Geometry_traits_2>
00615                                                          Traits_adaptor_2;
00616   typedef typename Arr::Vertex_const_handle              Vertex_const_handle;
00617   typedef typename Arr::Halfedge_const_handle            Halfedge_const_handle;
00618 
00619   const Traits_adaptor_2 * geom_traits =
00620     static_cast<const Traits_adaptor_2*> (arr.geometry_traits());
00621   Arr_accessor<Arr>                 arr_access (arr);
00622 
00623   // Check whether the left end has boundary conditions, and locate it in the
00624   // arrangement accordingly.
00625   const Arr_parameter_space  bx1 =
00626     geom_traits->parameter_space_in_x_2_object()(c, ARR_MIN_END);
00627   const Arr_parameter_space  by1 =
00628     geom_traits->parameter_space_in_y_2_object()(c, ARR_MIN_END);
00629   CGAL::Object                 obj1;
00630   const Vertex_const_handle   *vh1 = NULL;
00631 
00632   if (bx1 == ARR_INTERIOR && by1 == ARR_INTERIOR)
00633   {
00634     // We have a normal left endpoint with no boundary conditions:
00635     // use a point-location query.
00636     obj1 = pl.locate (geom_traits->construct_min_vertex_2_object() (c));
00637 
00638     // The endpoint must not lie on an existing edge, but may coincide with
00639     // and existing vertex vh1.
00640     CGAL_precondition_msg
00641       (object_cast<Halfedge_const_handle> (&obj1) == NULL,
00642        "The curve must not intersect an existing edge.");
00643 
00644     vh1 = object_cast<Vertex_const_handle> (&obj1);
00645   }
00646   else
00647   {
00648     // We have a left end with boundary conditions. Use the accessor to locate
00649     // the feature that contains it.
00650     obj1 = arr_access.locate_curve_end (c, ARR_MIN_END, bx1, by1);
00651 
00652     CGAL_precondition_msg
00653       (object_cast<Halfedge_const_handle> (&obj1) == NULL,
00654        "The curve must not overlap an existing edge.");
00655 
00656     vh1 = object_cast<Vertex_const_handle> (&obj1);
00657   }
00658 
00659   // Check whether the right end has boundary conditions, and locate it in the
00660   // arrangement accordingly.
00661   const Arr_parameter_space  bx2 =
00662     geom_traits->parameter_space_in_x_2_object()(c, ARR_MAX_END);
00663   const Arr_parameter_space  by2 =
00664     geom_traits->parameter_space_in_y_2_object()(c, ARR_MAX_END);
00665   CGAL::Object                 obj2;
00666   const Vertex_const_handle   *vh2 = NULL;
00667 
00668   if (bx2 == ARR_INTERIOR && by2 == ARR_INTERIOR)
00669   {
00670     // We have a normal right endpoint with no boundary conditions:
00671     // use a point-location query.
00672     obj2 = pl.locate (geom_traits->construct_max_vertex_2_object() (c));
00673 
00674     // The endpoint must not lie on an existing edge, but may coincide with
00675     // and existing vertex vh2.
00676     CGAL_precondition_msg
00677       (object_cast<Halfedge_const_handle> (&obj2) == NULL,
00678        "The curve must not intersect an existing edge.");
00679 
00680     vh2 = object_cast<Vertex_const_handle> (&obj2);
00681   }
00682   else
00683   {
00684     // We have a right end with boundary conditions. Use the accessor to locate
00685     // the feature that contains it.
00686     obj2 = arr_access.locate_curve_end (c, ARR_MAX_END, bx2, by2);
00687 
00688     CGAL_precondition_msg
00689       (object_cast<Halfedge_const_handle> (&obj2) == NULL,
00690        "The curve must not overlap an existing edge.");
00691 
00692     vh2 = object_cast<Vertex_const_handle> (&obj2);
00693   }
00694 
00695   // Notify the arrangement observers that a global operation is about to 
00696   // take place.  
00697   arr_access.notify_before_global_change();
00698 
00699   // Check whether the located features containing the curve endpoints
00700   // are vertices or faces, and use the proper specialized insertion function
00701   // accordingly.
00702   typename Arr::Halfedge_handle   new_he;
00703 
00704   if (vh1 != NULL)
00705   {
00706     if (vh2 != NULL)
00707     {
00708       // Both endpoints are associated with a existing vertices.
00709       // In this case insert_at_vertices() already returns a halfedge
00710       // directed from left to right.
00711       new_he = arr.insert_at_vertices (c,
00712                                        arr.non_const_handle (*vh1),
00713                                        arr.non_const_handle (*vh2));
00714     }
00715     else
00716     {
00717       // Only the left endpoint is associated with an existing vertex.
00718       // In this case insert_from_left_vertex() returns a halfedge directed
00719       // to the new vertex it creates, so it is already directed from left to
00720       // right.
00721       new_he = arr.insert_from_left_vertex (c, arr.non_const_handle (*vh1));
00722     }
00723   }
00724   else
00725   {
00726     if (vh2 != NULL)
00727     {
00728       // Only the right endpoint is associated with an existing vertex.
00729       // In this case insert_from_left_vertex() returns a halfedge directed
00730       // to the new vertex it creates, so it is directed from right to left
00731       // and we take its twin halfedge instead.
00732       new_he = arr.insert_from_right_vertex (c, arr.non_const_handle (*vh2));
00733       new_he = new_he->twin();
00734     }
00735     else
00736     {
00737       // Both endpoints are not associated with existing vertices, so
00738       // we must insert the curve in the interior of a face.
00739       // In this case insert_in_face_interior() already returns a halfedge
00740       // directed from left to right.
00741       const typename Arr::Face_const_handle  *fh1;
00742       const typename Arr::Face_const_handle  *fh2;
00743 
00744       fh1 = object_cast<typename Arr::Face_const_handle> (&obj1);
00745       fh2 = object_cast<typename Arr::Face_const_handle> (&obj2);
00746 
00747       CGAL_assertion_msg 
00748         (fh1 != NULL && fh2 != NULL && *fh1 == *fh2,
00749          "The curve intersects the interior of existing edges.");
00750 
00751       if (fh1 != NULL && fh2 != NULL && *fh1 == *fh2)
00752       {
00753         new_he = arr.insert_in_face_interior (c, arr.non_const_handle (*fh1));
00754       }
00755     }
00756   }
00757 
00758   // Notify the arrangement observers that the global operation has been
00759   // completed.
00760   arr_access.notify_after_global_change();
00761 
00762   // Return the resulting halfedge from the insertion operation.
00763   return (new_he);
00764 }
00765 
00766 //-----------------------------------------------------------------------------
00767 // Insert an x-monotone curve into the arrangement, such that the curve
00768 // interior does not intersect with any existing edge or vertex in the
00769 // arragement (incremental insertion).
00770 // Overloaded version with no point location object.
00771 //
00772 template <class GeomTraits, class TopTraits>
00773 typename Arrangement_on_surface_2<GeomTraits, TopTraits>::Halfedge_handle
00774 insert_non_intersecting_curve
00775     (Arrangement_on_surface_2<GeomTraits, TopTraits>& arr,
00776      const typename GeomTraits::X_monotone_curve_2& c)
00777 {
00778   // Create a default point-location object and use it to insert the curve.
00779   typename TopTraits::Default_point_location_strategy  def_pl (arr);
00780 
00781   return (insert_non_intersecting_curve (arr, c, def_pl));
00782 }
00783 
00789 template <typename GeomTraits, typename TopTraits, typename InputIterator>
00790 void non_intersecting_insert_empty(Arrangement_on_surface_2<GeomTraits,
00791                                                             TopTraits>& arr,
00792                                    InputIterator begin_xcurves,
00793                                    InputIterator end_xcurves)
00794 {
00795   const GeomTraits * geom_traits = arr.geometry_traits();
00796   typedef typename TopTraits::Sweep_line_non_intersecting_construction_visitor
00797                                                             Construct_visitor;
00798   Construct_visitor visitor(&arr);
00799   typename Construct_visitor::Traits_2 traits(*geom_traits);
00800   
00801   // Define a basic sweep-line instance (which is not supposed to handle
00802   // insersections) and perform the sweep.
00803   Basic_sweep_line_2<typename Construct_visitor::Traits_2, Construct_visitor,
00804                      typename Construct_visitor::Subcurve,
00805                      typename Construct_visitor::Event>
00806     sweep_line(&traits, &visitor);
00807   sweep_line.sweep(begin_xcurves, end_xcurves);
00808 }
00809 
00815 template <typename GeomTraits, typename TopTraits,
00816           typename XcInputIterator, typename PInputIterator>
00817 void non_intersecting_insert_empty(Arrangement_on_surface_2<GeomTraits,
00818                                                             TopTraits>& arr,
00819                                    XcInputIterator begin_xcurves,
00820                                    XcInputIterator end_xcurves,
00821                                    PInputIterator begin_points,
00822                                    PInputIterator end_points)
00823 {
00824   typedef typename TopTraits::Sweep_line_non_intersecting_construction_visitor
00825                                                         Construct_visitor;
00826   typedef typename Construct_visitor::Traits_2          Construct_traits;
00827 
00828   const GeomTraits * geom_traits = arr.geometry_traits();
00829   Construct_visitor visitor(&arr);
00830 
00831   /* We would like to avoid copy construction of the geometry traits class.
00832    * Copy construction is undesired, because it may results with data
00833    * duplication or even data loss.
00834    *
00835    * If the type Construct_visitor::Traits_2 is the same as the type
00836    * GeomTraits, use a reference to GeomTraits to avoid constructing a new one.
00837    * Otherwise, instantiate a local variable of the former and provide
00838    * the later as a single parameter to the constructor.
00839    * 
00840    * Use the form 'A a(*b);' and not ''A a = b;' to handle the case where A has
00841    * only an implicit constructor, (which takes *b as a parameter).
00842    */
00843   typename boost::mpl::if_<boost::is_same<GeomTraits, Construct_traits>,
00844                            const Construct_traits&, Construct_traits>::type
00845     traits(*geom_traits);
00846 
00847   // Define a basic sweep-line instance (which is not supposed to handle
00848   // insersections) and perform the sweep.
00849   Basic_sweep_line_2<typename Construct_visitor::Traits_2, Construct_visitor,
00850                      typename Construct_visitor::Subcurve,
00851                      typename Construct_visitor::Event>
00852     sweep_line(&traits, &visitor);
00853   sweep_line.sweep(begin_xcurves, end_xcurves, begin_points, end_points);
00854 }
00855 
00861 template <typename GeomTraits, typename TopTraits,
00862           typename XcInputIterator, typename PInputIterator>
00863 void non_intersecting_insert_non_empty(Arrangement_on_surface_2<GeomTraits,
00864                                                                 TopTraits>& arr,
00865                                        XcInputIterator begin_xcurves,
00866                                        XcInputIterator end_xcurves,
00867                                        PInputIterator begin_points,
00868                                        PInputIterator end_points)
00869 {
00870   typedef typename TopTraits::Sweep_line_non_intersecting_insertion_visitor
00871                                                         Insert_visitor;
00872   typedef typename Insert_visitor::Traits_2             Insert_traits;
00873   typedef typename Insert_visitor::Traits_2::X_monotone_curve_2
00874                                                         Ex_x_monotone_curve_2;
00875   typedef typename Insert_visitor::Traits_2::Point_2    Ex_point_2;
00876 
00877   const GeomTraits * geom_traits = arr.geometry_traits();
00878   Insert_visitor visitor(&arr);
00879 
00880   /* We would like to avoid copy construction of the geometry traits class.
00881    * Copy construction is undesired, because it may results with data
00882    * duplication or even data loss.
00883    *
00884    * If the type Construct_visitor::Traits_2 is the same as the type
00885    * GeomTraits, use a reference to GeomTraits to avoid constructing a new one.
00886    * Otherwise, instantiate a local variable of the former and provide
00887    * the later as a single parameter to the constructor.
00888    * 
00889    * Use the form 'A a(*b);' and not ''A a = b;' to handle the case where A has
00890    * only an implicit constructor, (which takes *b as a parameter).
00891    */
00892   typename boost::mpl::if_<boost::is_same<GeomTraits, Insert_traits>,
00893                            const Insert_traits&, Insert_traits>::type
00894     traits(*geom_traits);
00895     
00896   // Create a set of existing as well as new curves and points.
00897   std::list<Ex_x_monotone_curve_2> ex_cvs;
00898   std::list<Ex_point_2> ex_pts;
00899     
00900   prepare_for_sweep(arr,
00901                     begin_xcurves, end_xcurves,   // the x-monotone curves
00902                     begin_points, end_points,     // the points (if any)
00903                     std::back_inserter(ex_cvs),
00904                     std::back_inserter(ex_pts),
00905                     &traits);
00906 
00907   // Define a basic sweep-line instance and perform the sweep.
00908   Basic_sweep_line_2<typename Insert_visitor::Traits_2, Insert_visitor,
00909                      typename Insert_visitor::Subcurve,
00910                        typename Insert_visitor::Event>
00911     sweep_line(&traits, &visitor);
00912   sweep_line.sweep(ex_cvs.begin(), ex_cvs.end(), ex_pts.begin(), ex_pts.end());
00913 }
00914 
00915 //-----------------------------------------------------------------------------
00916 // Insert a range of pairwise interior-disjoint x-monotone curves into
00917 // the arrangement, such that the curve interiors do not intersect with
00918 // any existing edge or vertex in the arragement (aggregated insertion).
00919 //
00920 template <class GeomTraits, class TopTraits, class InputIterator>
00921 void insert_non_intersecting_curves
00922   (Arrangement_on_surface_2<GeomTraits, TopTraits>& arr,
00923    InputIterator begin, InputIterator end)
00924 {
00925   typedef Arrangement_on_surface_2<GeomTraits, TopTraits>   Arr;
00926 
00927   // Obtain an arrangement accessor.
00928   Arr_accessor<Arr>                  arr_access (arr);
00929 
00930   // Notify the arrangement observers that a global operation is about to 
00931   // take place.
00932   arr_access.notify_before_global_change();
00933 
00934   // Choose the operation depending on whether the input arrangement is
00935   // empty (then we construct it from scratch), or not (where we just insert
00936   // the new curves).
00937   if (arr.is_empty())
00938     non_intersecting_insert_empty(arr, begin, end);
00939   else {
00940     std::list<typename GeomTraits::Point_2> empty;
00941     non_intersecting_insert_non_empty(arr, begin, end,
00942                                       empty.begin(), empty.end());
00943   }
00944 
00945   // Notify the arrangement observers that the global operation has been
00946   // completed.
00947   arr_access.notify_after_global_change();
00948 }
00949 
00950 //-----------------------------------------------------------------------------
00951 // Remove an edge from the arrangement. In case it is possible to merge
00952 // the edges incident to the end-vertices of the removed edge after its
00953 // deletion, the function performs these merges as well.
00954 //
00955 template <class GeomTraits, class TopTraits>
00956 typename Arrangement_on_surface_2<GeomTraits, TopTraits>::Face_handle
00957 remove_edge
00958 (Arrangement_on_surface_2<GeomTraits, TopTraits>& arr,
00959  typename Arrangement_on_surface_2<GeomTraits, TopTraits>::Halfedge_handle e)
00960 {
00961   typedef Arrangement_on_surface_2<GeomTraits, TopTraits>   Arr;
00962   typedef Arr_traits_adaptor_2<GeomTraits>                  Traits_adaptor_2;
00963 
00964   // Notify the arrangement observers that a global operation is about to 
00965   // take place.
00966   Arr_accessor<Arr>    arr_access (arr);
00967 
00968   arr_access.notify_before_global_change();
00969 
00970   // Keep track of the end-vertices of the edge we are about to remove.
00971   typename Arr::Vertex_handle  v_ends[2];
00972   bool                         is_removed[2];
00973 
00974   v_ends[0] = e->source();
00975   is_removed[0] = 
00976       (v_ends[0]->is_at_open_boundary() || v_ends[0]->degree() == 1);
00977   v_ends[1] = e->target();
00978   is_removed[1] = 
00979       (v_ends[1]->is_at_open_boundary() || v_ends[1]->degree() == 1);
00980 
00981   // Remove the edge from the arrangement.
00982   typename Arr::Face_handle    face = arr.remove_edge (e);
00983 
00984   // Examine the end-vertices: If a vertex has now two incident edges, and the
00985   // curves associated with these edges can be merged, merge the two edges and
00986   // remove the vertex.
00987 
00988   const Traits_adaptor_2 * traits = 
00989     static_cast<const Traits_adaptor_2*> (arr.geometry_traits());
00990 
00991   typename Arr::Halfedge_around_vertex_circulator  circ;
00992   typename Arr::Halfedge_handle                    e1, e2;
00993   int                                              i;
00994 
00995   for (i = 0; i < 2; i++)
00996   {
00997     if (! is_removed[i] && v_ends[i]->degree() == 2)
00998     {
00999       // Get the two edges incident to the end-vertex.
01000       circ = v_ends[i]->incident_halfedges();
01001       e1 = circ;
01002       ++circ;
01003       e2 = circ;
01004 
01005       // Check if it is possible to merge the two edges.
01006       if (traits->are_mergeable_2_object() (e1->curve(), e2->curve()))
01007       {
01008         // Merge the two curves.
01009         typename GeomTraits::X_monotone_curve_2   cv;
01010         traits->merge_2_object() (e1->curve(), e2->curve(),
01011                                   cv);
01012 
01013         // Merge the two edges in the arrangement.
01014          arr.merge_edge (e1, e2, cv);
01015       }
01016     }
01017   }
01018 
01019   // Notify the arrangement observers that the global operation has been
01020   // completed.
01021   arr_access.notify_after_global_change();
01022   
01023   // Return the face remaining after the removal of the edge.
01024   return (face);
01025 }
01026 
01027 //-----------------------------------------------------------------------------
01028 // Insert a vertex that corresponds to a given point into the arrangement.
01029 // The inserted point may lie on any existing arrangement feature.
01030 //
01031 template <class GeomTraits, class TopTraits, class PointLocation>
01032 typename Arrangement_on_surface_2<GeomTraits, TopTraits>::Vertex_handle
01033 insert_point (Arrangement_on_surface_2<GeomTraits, TopTraits>& arr,
01034               const typename GeomTraits::Point_2& p,
01035               const PointLocation& pl)
01036 {
01037   typedef Arrangement_on_surface_2<GeomTraits, TopTraits>   Arr;
01038 
01039   // Act according to the type of arrangement feature that contains the point.
01040   const typename Arr::Face_const_handle      *fh;
01041   const typename Arr::Halfedge_const_handle  *hh;
01042   const typename Arr::Vertex_const_handle    *vh;
01043   typename Arr::Vertex_handle                 vh_for_p;
01044 
01045   // Locate the given point in the arrangement.
01046   CGAL::Object        obj = pl.locate (p);
01047 
01048   // Notify the arrangement observers that a global operation is about to 
01049   // take place.
01050   Arr_accessor<Arr>    arr_access (arr);
01051 
01052   arr_access.notify_before_global_change();
01053 
01054   if ((fh = object_cast<typename Arr::Face_const_handle>(&obj)) != NULL) 
01055   {
01056     // p lies inside a face: Insert it as an isolated vertex it the interior of
01057     // this face.
01058     vh_for_p = arr.insert_in_face_interior (p,
01059                                             arr.non_const_handle (*fh));
01060   }
01061   else if ((hh = 
01062             object_cast<typename Arr::Halfedge_const_handle>(&obj)) != NULL) 
01063   {
01064     // p lies in the interior of an edge: Split this edge to create a new
01065     // vertex associated with p.
01066     typename GeomTraits::X_monotone_curve_2   sub_cv1, sub_cv2;
01067     typename Arr::Halfedge_handle             split_he;
01068    
01069     arr.geometry_traits()->split_2_object() ((*hh)->curve(), p,
01070                                              sub_cv1, sub_cv2);
01071 
01072     split_he = arr.split_edge (arr.non_const_handle (*hh),
01073                                sub_cv1, sub_cv2);
01074 
01075     // The new vertex is the target of the returned halfedge.
01076     vh_for_p = split_he->target();
01077   }
01078   else
01079   {
01080     // In this case p lies on an existing vertex, so we just update this
01081     // vertex.
01082     vh = object_cast<typename Arr::Vertex_const_handle>(&obj);
01083     CGAL_assertion (vh != NULL);
01084     
01085     vh_for_p = arr.modify_vertex (arr.non_const_handle (*vh), p);
01086   }
01087 
01088   // Notify the arrangement observers that the global operation has been
01089   // completed.
01090   arr_access.notify_after_global_change();
01091 
01092   // Return a handle for the vertex associated with p. 
01093   return (vh_for_p);
01094 }
01095 
01096 //-----------------------------------------------------------------------------
01097 // Insert a vertex that corresponds to a given point into the arrangement.
01098 // The inserted point may lie on any existing arrangement feature.
01099 //
01100 template <class GeomTraits, class TopTraits>
01101 typename Arrangement_on_surface_2<GeomTraits, TopTraits>::Vertex_handle
01102 insert_point (Arrangement_on_surface_2<GeomTraits, TopTraits>& arr,
01103               const typename GeomTraits::Point_2& p)
01104 {
01105   // Create a default point-location object and use it to insert the point.
01106   typename TopTraits::Default_point_location_strategy    def_pl (arr);
01107   
01108   return (insert_point (arr, p, def_pl));
01109 }
01110 
01111 //-----------------------------------------------------------------------------
01112 // Remove a vertex from the arrangement.
01113 //
01114 template <class GeomTraits, class TopTraits>
01115 bool remove_vertex
01116     (Arrangement_on_surface_2<GeomTraits, TopTraits>& arr,
01117      typename Arrangement_on_surface_2<GeomTraits, TopTraits>::Vertex_handle v)
01118 {
01119   typedef Arrangement_on_surface_2<GeomTraits, TopTraits>   Arr;
01120   typedef Arr_traits_adaptor_2<GeomTraits>                  Traits_adaptor_2;
01121 
01122   // Notify the arrangement observers that a global operation is about to 
01123   // take place.
01124   Arr_accessor<Arr>    arr_access (arr);
01125 
01126   arr_access.notify_before_global_change();
01127 
01128   // Act according to the number of edges incident to v.
01129   bool      removed = false;
01130 
01131   if (v->is_isolated())
01132   {
01133     // In case v is an isolated vertex, simply remove it.
01134     arr.remove_isolated_vertex (v);
01135     removed = true;
01136   }
01137   else if (v->degree() == 2)
01138   {
01139     // If the vertex has now two incident edges, and the curves associated
01140     // with these edges can be merged, merge the two edges and remove the
01141     // vertex.
01142     const Traits_adaptor_2 * traits =
01143       static_cast<const Traits_adaptor_2*>(arr.geometry_traits());
01144     typename Arr::Halfedge_around_vertex_circulator  circ;
01145     typename Arr::Halfedge_handle                    e1, e2;
01146 
01147     circ = v->incident_halfedges();
01148     e1 = circ;
01149     ++circ;
01150     e2 = circ;
01151 
01152     if (traits->are_mergeable_2_object() (e1->curve(), e2->curve()))
01153     {
01154       // Merge the two curves.
01155       typename GeomTraits::X_monotone_curve_2   cv;
01156       traits->merge_2_object() (e1->curve(), e2->curve(),
01157                                 cv);
01158 
01159       // Merge the two edges in the arrangement.
01160       arr.merge_edge (e1, e2, cv);
01161       removed = true;
01162     }
01163   }
01164 
01165   // Notify the arrangement observers that the global operation has been
01166   // completed.
01167   arr_access.notify_after_global_change();
01168 
01169   // Return an indication whether the vertex has been removed or not.
01170   return (removed);
01171 }
01172 
01173 //-----------------------------------------------------------------------------
01174 // Check the validity of the arrangement. In particular, check that the
01175 // edegs are disjoint-interior, and the holes are located in their proper
01176 // position.
01177 //
01178 template <class GeomTraits, class TopTraits>
01179 bool is_valid (const Arrangement_on_surface_2<GeomTraits, TopTraits>& arr)
01180 {
01181   // First use the internal validity check.
01182   if(!arr.is_valid())
01183     return (false);
01184 
01185   typedef Arrangement_on_surface_2<GeomTraits, TopTraits>   Arr;
01186   typedef GeomTraits                                        Geometry_traits_2;
01187   typedef typename Geometry_traits_2::Point_2               Point_2;
01188   typedef typename Geometry_traits_2::X_monotone_curve_2    X_monotone_curve_2;
01189   
01190   // Define the sweep-line types:
01191   typedef Sweep_line_do_curves_x_visitor<Geometry_traits_2> Visitor;
01192   typedef Sweep_line_2<Geometry_traits_2, Visitor>          Sweep_line_2;
01193 
01194   // Define the arrangement iterator and circulator types:
01195   typedef typename Arr::Edge_const_iterator           Edge_const_iterator;
01196   typedef typename Arr::Halfedge_const_handle         Halfedge_const_handle;
01197   typedef typename Arr::Inner_ccb_const_iterator      Inner_ccb_const_iterator;
01198   typedef typename Arr::Face_const_iterator           Face_const_iterator;
01199   typedef typename Arr::Face_const_handle             Face_const_handle;
01200   typedef typename Arr::Vertex_const_handle           Vertex_const_handle;
01201   typedef typename Arr::Isolated_vertex_const_iterator
01202                                        Isolated_vertex_const_iterator;
01203   typedef typename Arr::Ccb_halfedge_const_circulator 
01204                                        Ccb_halfedge_const_circulator;
01205   typedef typename Arr::Halfedge_around_vertex_const_circulator 
01206                                        Halfedge_around_vertex_const_circulator;
01207   
01208   // Perform a sweep over all subcurves associated with arrangement edges.
01209   std::vector<X_monotone_curve_2>   curves_vec (arr.number_of_edges());
01210   Edge_const_iterator               eit;
01211   unsigned int                      i = 0;
01212   
01213   for (eit = arr.edges_begin(); eit != arr.edges_end(); ++eit, i++)
01214     curves_vec[i] = eit->curve();
01215 
01216   Visitor            visitor;
01217   const Geometry_traits_2 *traits = arr.geometry_traits();
01218   Sweep_line_2       sweep_line (traits, &visitor);
01219 
01220   visitor.sweep_xcurves (curves_vec.begin(), curves_vec.end());
01221   
01222   bool               are_edges_disjoint = (! visitor.found_intersection());
01223 
01224   if (!are_edges_disjoint)
01225   {
01226     CGAL_warning_msg (are_edges_disjoint,
01227                       "Arrangement edges are not disjoint in their interior.");
01228     return (false);
01229   }
01230 
01231   // Check that the holes and isolated vertices are located where they should.
01232   // At the same time, we prepare a vector that consists of all isolated
01233   // vertices and all leftmost vertices from every hole. 
01234   std::list<std::pair<Vertex_const_handle, Face_const_handle> >  vf_list;
01235 
01236   typename Geometry_traits_2::Compare_xy_2  compare_xy = 
01237     traits->compare_xy_2_object();
01238   Face_const_iterator               fit;
01239   Face_const_handle                 fh;
01240   Inner_ccb_const_iterator          ic_it;
01241   Halfedge_const_handle             ccb;
01242   Isolated_vertex_const_iterator    iv_it;
01243   Vertex_const_handle               left_v;
01244   bool                              is_first;
01245 
01246   for (fit = arr.faces_begin(); fit != arr.faces_end(); ++fit)
01247   {
01248     // Check all holes in the current face.
01249     fh = fit;
01250     for (ic_it = fh->inner_ccbs_begin();
01251          ic_it != fh->inner_ccbs_end(); ++ic_it)
01252     {
01253       ccb = *ic_it;
01254       is_first = true;
01255 
01256       do
01257       {
01258         if (ccb->face() != fit)
01259           return (false);
01260 
01261         if (is_first ||
01262             compare_xy (ccb->target()->point(), left_v->point()) == SMALLER)
01263         {
01264           left_v = ccb->target();
01265           is_first = false;
01266         }
01267 
01268         ccb = ccb->next();
01269 
01270       } while (ccb != *ic_it);
01271 
01272       vf_list.push_back (std::make_pair (left_v, fh));
01273     }
01274 
01275     // Check all isolated vertices in the current face.
01276     for (iv_it = fh->isolated_vertices_begin();
01277          iv_it != fh->isolated_vertices_end(); ++iv_it)
01278     {
01279       if (iv_it->face() != fit)
01280         return (false);
01281 
01282       vf_list.push_back (std::make_pair (Vertex_const_handle(iv_it), fh));
01283     }
01284   }
01285 
01286   // Shoot a vertical ray from each vertex we have collected downward, and
01287   // check that this vertex is really contained in the proper face.
01288   typename Geometry_traits_2::Compare_y_at_x_right_2  comp_y_at_x_right =
01289                                       traits->compare_y_at_x_right_2_object();
01290   typename Geometry_traits_2::Compare_y_at_x_left_2   comp_y_at_x_left =
01291                                       traits->compare_y_at_x_left_2_object();
01292 
01293   typename std::list<std::pair<Vertex_const_handle,
01294                                Face_const_handle> >::iterator    vf_iter;
01295   typename TopTraits::Default_point_location_strategy            def_pl (arr);
01296   Vertex_const_handle                                            curr_v;
01297   Object                                                         obj;
01298   Halfedge_const_handle                                          he_below;
01299   Vertex_const_handle                                            v_below;
01300   Face_const_handle                                              in_face;
01301   Halfedge_around_vertex_const_circulator                        first, circ;
01302   bool                                                           assign_ok;
01303   const Halfedge_const_handle                                    invalid_he;
01304 
01305   for (vf_iter = vf_list.begin(); vf_iter != vf_list.end(); ++vf_iter)
01306   {
01307     // Perform ray-shooting from the current vertex.
01308     curr_v = vf_iter->first;
01309     obj = def_pl.ray_shoot_down(curr_v->point());
01310 
01311     if (CGAL::assign(he_below, obj))
01312     {
01313       // Hit an edge - take the incident face of the halfedge directed to the
01314       // right.
01315       if (he_below->direction() == ARR_RIGHT_TO_LEFT)
01316         he_below = he_below->twin();
01317       
01318       in_face = he_below->face();
01319     }
01320     else if (CGAL::assign(v_below, obj))
01321     {
01322       // Hit a vertex.
01323       if(v_below->is_isolated())
01324       {
01325         in_face = v_below->face();
01326       }
01327       else
01328       {    
01329         // Get the first halfedge aroung v_below that is directed from left to
01330         // right and the first halfedge that is directed from right to left.
01331         first = circ = v_below->incident_halfedges();
01332         Halfedge_const_handle he_left;  // A halfedge to the left of v_below.
01333         Halfedge_const_handle he_right; // A halfedge to the right of v_below.
01334 
01335         do
01336         {
01337           if (circ->direction() == ARR_LEFT_TO_RIGHT)
01338           {
01339             he_left = circ;
01340           }
01341           else
01342           {
01343             he_right = circ;
01344             if (he_left != invalid_he && he_right != invalid_he)
01345               break;
01346           }
01347           ++circ;
01348         
01349         } while(circ != first);
01350 
01351         CGAL_assertion (he_left != invalid_he || he_right != invalid_he); 
01352 
01353         if (he_left != invalid_he && he_right != invalid_he)
01354         {
01355           while (he_left->direction() == ARR_LEFT_TO_RIGHT)
01356             he_left = he_left->next()->twin();
01357           
01358           he_left = he_left->twin()->prev();
01359           CGAL_assertion (he_left->direction() == ARR_LEFT_TO_RIGHT);
01360           in_face = he_left->face();
01361         }
01362         else if (he_left != invalid_he)
01363         {
01364           Comparison_result     res;
01365           Halfedge_const_handle he_curr = he_left;
01366              
01367           do // as long as we have next he_left halfedge which is above
01368           {
01369             he_left = he_curr;
01370             he_curr = he_left->next()->twin();
01371             res = comp_y_at_x_left (he_curr->curve(),
01372                                     he_left->curve(),
01373                                     v_below->point());
01374           } while(res == LARGER);
01375           in_face = he_left->face();           
01376         }
01377         else
01378         {
01379           Comparison_result     res;
01380           Halfedge_const_handle he_curr = he_right;
01381           
01382           do // as long as we have he_right halfedge which is below
01383           {
01384             he_right = he_curr;
01385             he_curr = he_right->next()->twin();
01386             res = comp_y_at_x_right (he_curr->curve(),
01387                                      he_right->curve(),
01388                                      v_below->point());
01389           } while(res == SMALLER);
01390           in_face = he_right->face();  
01391         } 
01392       }
01393     }
01394     else
01395     {
01396       // Hit nothing (an unbounded face is returned).
01397       assign_ok = CGAL::assign(in_face, obj);
01398 
01399       CGAL_assertion (assign_ok && in_face->is_unbounded());
01400 
01401       if (! assign_ok)
01402         return (false);
01403     }
01404 
01405     if (vf_iter->second != in_face)
01406     {
01407       CGAL_warning_msg (false,
01408                         "An inner component is located in the wrong face.");
01409       return (false);
01410     }
01411   }
01412 
01413   // If we reached here, the arrangement is valid:
01414   return (true);
01415 }
01416 
01417 //-----------------------------------------------------------------------------
01418 // Compute the zone of the given x-monotone curve in the existing arrangement.
01419 // Meaning, it output the arrangment's vertices, edges and faces that the 
01420 // x-monotone curve intersects.
01421 template <class GeomTraits, class TopTraits, 
01422   class OutputIterator, class PointLocation>
01423 OutputIterator zone (Arrangement_on_surface_2<GeomTraits, TopTraits>& arr, 
01424                      const typename GeomTraits::X_monotone_curve_2& c,
01425                      OutputIterator oi,
01426                      const PointLocation& pl)
01427 {
01428   // Obtain an arrangement accessor.
01429   typedef Arrangement_on_surface_2<GeomTraits,TopTraits>      
01430     Arrangement_on_surface_2;
01431 
01432   // Define a zone-computation object an a visitor that performs the
01433   // intersection check.
01434   typedef Arr_compute_zone_visitor<Arrangement_on_surface_2, OutputIterator>  
01435     Zone_visitor;
01436   
01437   Zone_visitor                                     visitor (oi);
01438   Arrangement_zone_2<Arrangement_on_surface_2, Zone_visitor>  
01439     arr_zone (arr, &visitor);
01440 
01441   arr_zone.init (c, pl);
01442   arr_zone.compute_zone();
01443 
01444   return (oi);
01445 }
01446 
01447 //-----------------------------------------------------------------------------
01448 // Compute the zone of the given x-monotone curve in the existing arrangement.b
01449 // Overloaded version with no point location object - the walk point-location
01450 // strategy is used as default.
01451 //
01452 template <class GeomTraits, class TopTraits, class OutputIterator>
01453 OutputIterator zone (Arrangement_on_surface_2<GeomTraits, TopTraits>& arr, 
01454                      const typename GeomTraits::X_monotone_curve_2& c,
01455                      OutputIterator oi)
01456 {
01457   typedef Arrangement_on_surface_2<GeomTraits, TopTraits>
01458     Arrangement_on_surface_2;
01459 
01460   // Create a default point-location object and use it to insert the curve.
01461   typename TopTraits::Default_point_location_strategy    def_pl (arr);
01462 
01463   //insert the curve using the walk point location
01464   zone (arr, c, oi, def_pl);
01465   return oi;
01466 }
01467 
01468 
01469 //-----------------------------------------------------------------------------
01470 // Checks if the given x-monotone curve intersects the existing arrangement.
01471 // The last parameter is used to resolve ambiguity between this function and 
01472 // do_intersect of Curve_2 in case that X_monotone_curve_2 and Curve_2 are the 
01473 // same class. The last parameter should be boost::true_type but we used a 
01474 // workaround since it didn't compile in FC3_g++-3.4.4 with the error of:
01475 //
01476 // error: no matching function for call to `do_intersect(Arrangement_on_surface_2<>&, 
01477 // const Arr_segment_2&, const Arr_walk_along_line_point_location<>&, mpl_::bool_< true>)'
01478 //
01479 template <class GeomTraits, class TopTraits, class PointLocation>
01480 bool do_intersect (Arrangement_on_surface_2<GeomTraits, TopTraits>& arr, 
01481                    const typename GeomTraits::X_monotone_curve_2& c,
01482                    const PointLocation& pl, boost::is_same<int, int>::type)
01483 {
01484   // Obtain an arrangement accessor.
01485   typedef Arrangement_on_surface_2<GeomTraits,TopTraits>
01486     Arrangement_on_surface_2;
01487 
01488   // Define a zone-computation object an a visitor that performs the
01489   // intersection check.
01490   typedef Arr_do_intersect_zone_visitor<Arrangement_on_surface_2>  Zone_visitor;
01491   
01492   Zone_visitor                                     visitor;
01493   Arrangement_zone_2<Arrangement_on_surface_2, Zone_visitor>  
01494     arr_zone (arr, &visitor);
01495 
01496   arr_zone.init (c, pl);
01497   arr_zone.compute_zone();
01498 
01499   return (visitor.do_intersect());
01500 }
01501 
01502 //-----------------------------------------------------------------------------
01503 // Checks if the given curve intersects the existing arrangement.
01504 // The last parameter is used to resolve ambiguity between this function and 
01505 // do_intersect of X_monotone_curve_2 in case that X_monotone_curve_2 and 
01506 // Curve_2 are the same class. 
01507 // The last parameter should be boost::false_type but we used a 
01508 // workaround since it didn't compile in FC3_g++-3.4.4 with the error of:
01509 //
01510 // error: no matching function for call to `do_intersect(Arrangement_on_surface_2<>&, 
01511 // const Arr_segment_2&, const Arr_walk_along_line_point_location<>&, mpl_::bool_< true>)'
01512 //
01513 template <class GeomTraits, class TopTraits, class PointLocation>
01514 bool do_intersect (Arrangement_on_surface_2<GeomTraits, TopTraits>& arr, 
01515                    const typename GeomTraits::X_monotone_curve_2& c,
01516                    const PointLocation& pl, boost::is_same<int, double>::type)
01517 {
01518   // Obtain an arrangement accessor.
01519   typedef Arrangement_on_surface_2<GeomTraits,TopTraits>
01520     Arrangement_on_surface_2;
01521 
01522   // Break the input curve into x-monotone subcurves and isolated points.
01523   typedef Arr_traits_adaptor_2<GeomTraits>                   Traits_adaptor_2;
01524 
01525   const Traits_adaptor_2 * traits =
01526     static_cast<const Traits_adaptor_2*> (arr.traits());
01527 
01528   std::list<CGAL::Object>                        x_objects;
01529   std::list<CGAL::Object>::const_iterator        obj_iter;
01530   const typename GeomTraits::X_monotone_curve_2  *x_curve;
01531   const typename GeomTraits::Point_2             *iso_p;
01532 
01533   traits->make_x_monotone_2_object() (c,
01534                                       std::back_inserter (x_objects));
01535 
01536   // Insert each x-monotone curve into the arrangement.
01537   for (obj_iter = x_objects.begin(); obj_iter != x_objects.end(); ++obj_iter)
01538   {
01539     // Act according to the type of the current object.
01540     x_curve = object_cast<typename GeomTraits::X_monotone_curve_2> 
01541       (&(*obj_iter));
01542     if (x_curve != NULL)
01543     {
01544       // Check if the x-monotone subcurve intersects the arrangement.
01545       if (do_intersect(arr, *x_curve, pl) == true)
01546         return true;
01547     }
01548     else
01549     {
01550       iso_p = object_cast<typename GeomTraits::Point_2> (&(*obj_iter));
01551       CGAL_assertion (iso_p != NULL);
01552       
01553       // Check whether the isolated point lies inside a face (otherwise,
01554       // it conincides with a vertex or an edge).
01555       CGAL::Object  obj = pl.locate (*iso_p);
01556       
01557       return (object_cast<typename 
01558               Arrangement_on_surface_2::Face_const_handle>(&obj) != NULL);
01559     }
01560   }
01561 
01562   // If we reached here, the curve does not intersect the arrangement.
01563   return (false);
01564 }
01565 
01566 //-----------------------------------------------------------------------------
01567 // Common interface for the do_intersect of the Curve_2 and X_monotone_curve_2
01568 template <class GeomTraits, class TopTraits, class Curve, class PointLocation>
01569 bool do_intersect (Arrangement_on_surface_2<GeomTraits, TopTraits>& arr, 
01570                    const Curve& c, const PointLocation& pl)
01571 {
01572   typedef typename GeomTraits::X_monotone_curve_2       X_monotone_curve_2;
01573   
01574   typedef typename boost::is_same<Curve, X_monotone_curve_2>::type
01575     Is_x_monotone;
01576   
01577   return do_intersect(arr, c, pl, Is_x_monotone());
01578 }
01579 
01580 //-----------------------------------------------------------------------------
01581 // Checks if the given curve intersects the existing arrangement.
01582 // Overloaded version with no point location object - the walk point-location
01583 // strategy is used as default.
01584 template <class GeomTraits, class TopTraits, class Curve>
01585 bool do_intersect (Arrangement_on_surface_2<GeomTraits, TopTraits>& arr, 
01586                    const Curve& c)
01587 {
01588   typedef Arrangement_on_surface_2<GeomTraits, TopTraits>
01589     Arrangement_on_surface_2;
01590 
01591   // Create a default point-location object and use it to insert the curve.
01592   typename TopTraits::Default_point_location_strategy    def_pl (arr);
01593   
01594   // check if the curve intersects the arrangement using the walk point 
01595   // location.
01596   return do_intersect (arr, c, def_pl);
01597 }
01598 
01599 
01600 CGAL_END_NAMESPACE
01601 
01602 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines