diff --git a/Arrangement_on_surface_2/include/CGAL/Arr_topology_traits/Arr_bounded_planar_vert_decomp_helper.h b/Arrangement_on_surface_2/include/CGAL/Arr_topology_traits/Arr_bounded_planar_vert_decomp_helper.h new file mode 100755 index 00000000000..c71ec8f538c --- /dev/null +++ b/Arrangement_on_surface_2/include/CGAL/Arr_topology_traits/Arr_bounded_planar_vert_decomp_helper.h @@ -0,0 +1,106 @@ +// Copyright (c) 2007 Tel-Aviv University (Israel). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Ron Wein + +#ifndef CGAL_ARR_BOUNDED_PLANAR_VERT_DEOCMP_HELPER_H +#define CGAL_ARR_BOUNDED_PLANAR_VERT_DEOCMP_HELPER_H + +/*! \file + * Definition of the Arr_bounded_planar_vert_decomp_helper class-template. + */ + +CGAL_BEGIN_NAMESPACE + +#include + +/*! \class Arr_bounded_planar_vert_decomp_helper + * A helper class for the vertical decomposition sweep-line visitor, suitable + * for an Arrangement_on_surface_2 instantiated with a topology-traits class + * for bounded curves in the plane. + */ +template +class Arr_bounded_planar_vert_decomp_helper +{ +public: + + typedef Traits_ Traits_2; + typedef Arrangement_ Arrangement_2; + + typedef typename Arrangement_2::Face_const_handle Face_const_handle; + + typedef Sweep_line_empty_visitor Base_visitor; + typedef typename Base_visitor::Event Event; + typedef typename Base_visitor::Subcurve Subcurve; + +protected: + + typedef typename Arrangement_2::Topology_traits Topology_traits; + + // Data members: + const Topology_traits *m_top_traits; // The topology-traits class. + Face_const_handle m_unb_face; // The unbounded arrangement face. + +public: + + /*! + * Constructor. + * \param arr The arrangement. + */ + Arr_bounded_planar_vert_decomp_helper (const Arrangement_2 *arr) : + m_top_traits (arr->topology_traits()) + {} + + /// \name Notification functions. + //@{ + + /* A notification issued before the sweep process starts. */ + void before_sweep () + { + // Get the unbounded face. + m_unb_face = Face_const_handle (m_top_traits->unbounded_face()); + } + + /*! + * A notification invoked after the sweep-line finishes handling the given + * event. + */ + void after_handle_event (Event* event) + { + return; + } + //@} + + /*! Get the current top object. */ + CGAL::Object top_object () const + { + // Wrap the unbounded face by a CGAL object. + return (CGAL::make_object (m_unb_face)); + } + + /*! Get the current bottom object. */ + CGAL::Object bottom_object () const + { + // Wrap the unbounded face by a CGAL object. + return (CGAL::make_object (m_unb_face)); + } + +}; + +CGAL_END_NAMESPACE + +#endif diff --git a/Arrangement_on_surface_2/include/CGAL/Arr_topology_traits/Arr_spherical_vert_decomp_helper.h b/Arrangement_on_surface_2/include/CGAL/Arr_topology_traits/Arr_spherical_vert_decomp_helper.h new file mode 100755 index 00000000000..f8bac716107 --- /dev/null +++ b/Arrangement_on_surface_2/include/CGAL/Arr_topology_traits/Arr_spherical_vert_decomp_helper.h @@ -0,0 +1,105 @@ +// Copyright (c) 2007 Tel-Aviv University (Israel). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Ron Wein +// Efi Fogel +// + +#ifndef CGAL_ARR_SPHERICAL_VERT_DECOMP_HELPER_H +#define CGAL_ARR_SPHERICAL_VERT_DECOMP_HELPER_H + +/*! \file + * Definition of the Arr_spherical_vert_decomp_helper class-template. + */ + +CGAL_BEGIN_NAMESPACE + +#include + +/*! \class Arr_spherical_vert_decomp_helper + * A helper class for the vertical decomposition sweep-line visitor, suitable + * for an Arrangement_on_surface_2 instantiated with a topology-traits class + * for bounded curves in the plane. + */ +template +class Arr_spherical_vert_decomp_helper +{ +public: + + typedef Traits_ Traits_2; + typedef Arrangement_ Arrangement_2; + + typedef typename Arrangement_2::Face_const_handle Face_const_handle; + + typedef Sweep_line_empty_visitor Base_visitor; + typedef typename Base_visitor::Event Event; + typedef typename Base_visitor::Subcurve Subcurve; + +protected: + + typedef typename Arrangement_2::Topology_traits Topology_traits; + + const Topology_traits *m_top_traits; // The topology traits. + Face_const_handle m_north_face; // Current north face. + +public: + + /*! Constructor. + * \param arr The arrangement. + */ + Arr_spherical_batched_pl_helper(const Arrangement_2 *arr) : + m_top_traits(arr->topology_traits()) + {} + + /// \name Notification functions. + //@{ + + /*! A notification issued before the sweep process starts. */ + void before_sweep() + { + // Get the spherical face of the arrangement. + m_north_face = Face_handle_red(m_top_traits->spherical_face()); + return; + } + + /*! + * A notification invoked after the sweep-line finishes handling the given + * event. + */ + void after_handle_event(Event * event) + { + return; + } + //@} + + /*! Get the current top object. */ + CGAL::Object top_object () const + { + // Wrap the north face with a CGAL object. + return (m_north_face); + } + + /*! Get the current bottom object. */ + CGAL::Object bottom_object () const + { + // Wrap the north face with a CGAL object. + return (m_north_face); + } +}; + +CGAL_END_NAMESPACE + +#endif diff --git a/Arrangement_on_surface_2/include/CGAL/Arr_topology_traits/Arr_unb_planar_vert_decomp_helper.h b/Arrangement_on_surface_2/include/CGAL/Arr_topology_traits/Arr_unb_planar_vert_decomp_helper.h new file mode 100755 index 00000000000..08c5c81abce --- /dev/null +++ b/Arrangement_on_surface_2/include/CGAL/Arr_topology_traits/Arr_unb_planar_vert_decomp_helper.h @@ -0,0 +1,186 @@ +// Copyright (c) 2007 Tel-Aviv University (Israel). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Ron Wein + +#ifndef CGAL_ARR_UNB_PLANAR_VERT_DECOMP_HELPER_H +#define CGAL_ARR_UNB_PLANAR_VERT_DECOMP_HELPER_H + +/*! \file + * Definition of the Arr_unb_planar_vert_decomp_helper class-template. + */ + +CGAL_BEGIN_NAMESPACE + +#include + +/*! \class Arr_unb_planar_vert_decomp_helper + * A helper class for the vertical decomposition sweep-line visitor, suitable + * for an Arrangement_on_surface_2 instantiated with a topology-traits class + * for unbounded curves in the plane. + */ +template +class Arr_unb_planar_vert_decomp_helper +{ +public: + + typedef Traits_ Traits_2; + typedef Arrangement_ Arrangement_2; + + typedef typename Arrangement_2::Face_const_handle Face_const_handle; + + typedef Sweep_line_empty_visitor Base_visitor; + typedef typename Base_visitor::Event Event; + typedef typename Base_visitor::Subcurve Subcurve; + +protected: + + typedef typename Arrangement_2::Topology_traits Topology_traits; + typedef typename Arrangement_2::Halfedge_const_handle Halfedge_const_handle; + typedef typename Arrangement_2::Vertex_const_handle Vertex_const_handle; + + // Data members: + const Topology_traits *m_top_traits; // The topology-traits class. + Halfedge_const_handle m_top_fict; // The current top fictitious halfedge. + Halfedge_const_handle m_bottom_fict; // The current bottom fictitious + // halfedge. + +public: + + /*! + * Constructor. + * \param arr The arrangement. + */ + Arr_unb_planar_vert_decomp_helper (const Arrangement_2 *arr) : + m_top_traits (arr->topology_traits()) + {} + + /// \name Notification functions. + //@{ + + /* A notification issued before the sweep process starts. */ + void before_sweep (); + + /*! + * A notification invoked after the sweep-line finishes handling the given + * event. + */ + void after_handle_event (Event* event); + //@} + + /*! Get the current top object. */ + CGAL::Object top_object () const + { + // Wrap the top fictitious halfedge by a CGAL object. + return (CGAL::make_object (m_top_fict)); + } + + /*! Get the current bottom object. */ + CGAL::Object bottom_object () const + { + // Wrap the bottom fictitious halfedge by a CGAL object. + return (CGAL::make_object (m_bottom_fict)); + } +}; + +//----------------------------------------------------------------------------- +// Memeber-function definitions: +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// A notification issued before the sweep process starts. +// +template +void Arr_unb_planar_vert_decomp_helper::before_sweep () +{ + // Initialize the fictitious halfedge lying on the top edge of the + // bounding rectangle. We start from the leftmost halfedge, which is + // incident to the top-left vertex and directed from right to left. + Vertex_const_handle v_tl = + Vertex_const_handle (m_top_traits->top_left_vertex()); + + m_top_fict = v_tl->incident_halfedges(); + if (m_top_fict->direction() == LEFT_TO_RIGHT) + m_top_fict = m_top_fict->next()->twin(); + + CGAL_assertion_code ( + Vertex_const_handle v_tr = + Vertex_const_handle (m_top_traits->top_right_vertex()); + ); + CGAL_assertion ((m_top_fict->source() == v_tr) || + (m_top_fict->source()->boundary_in_x() == NO_BOUNDARY && + m_top_fict->source()->boundary_in_y() == PLUS_INFINITY)); + + // Initialize the fictitious halfedge lying on the bottom edge of the + // bounding rectangle. We start from the leftmost halfedge, which is + // incident to the bottom-left vertex and whose source is not at -oo. + Vertex_const_handle v_bl = + Vertex_const_handle (m_top_traits->bottom_left_vertex()); + + m_bottom_fict = v_bl->incident_halfedges(); + if (m_bottom_fict->source()->boundary_in_x() == MINUS_INFINITY) + m_bottom_fict = m_bottom_fict->next()->twin(); + + CGAL_assertion_code ( + Vertex_const_handle v_br = + Vertex_const_handle (m_top_traits->bottom_right_vertex()); + ); + CGAL_assertion ((m_bottom_fict->source() == v_br) || + (m_bottom_fict->source()->boundary_in_x() == NO_BOUNDARY && + m_bottom_fict->source()->boundary_in_y() == MINUS_INFINITY)); + + return; +} + +//----------------------------------------------------------------------------- +// A notification invoked after the sweep-line finishes handling the given +// event. +// +template +void Arr_unb_planar_vert_decomp_helper::after_handle_event + (Event* event) +{ + // If the event is at infinity and occurs on the top edge of the fictitious + // face (namely x is finite and y = +oo), we have to update the fictitious + // halfedges we keep. + if (event->is_finite()) + return; + + if (event->boundary_in_x() != NO_BOUNDARY) + return; + + Boundary_type by = event->boundary_in_y(); + + if (by == PLUS_INFINITY) + { + // Update the fictitious top halfedge. + m_top_fict = m_top_fict->twin()->next()->twin(); + } + else + { + CGAL_assertion (by == PLUS_INFINITY); + + // Update the fictitious bottom halfedge. + m_bottom_fict = m_bottom_fict->prev(); + } + + return; +} + +CGAL_END_NAMESPACE + +#endif diff --git a/Arrangement_on_surface_2/include/CGAL/Sweep_line_2/Arr_vert_decomp_sl_visitor.h b/Arrangement_on_surface_2/include/CGAL/Sweep_line_2/Arr_vert_decomp_sl_visitor.h new file mode 100755 index 00000000000..198367292fd --- /dev/null +++ b/Arrangement_on_surface_2/include/CGAL/Sweep_line_2/Arr_vert_decomp_sl_visitor.h @@ -0,0 +1,328 @@ +// Copyright (c) 2007 Tel-Aviv University (Israel). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Ron Wein + +#ifndef CGAL_ARR_VERT_DECOMP_SL_VISITOR_H +#define CGAL_ARR_VERT_DECOMP_SL_VISITOR_H + +/*! + * Definition of the Arr_vert_decomp_sl_visitor class-template. + */ + +CGAL_BEGIN_NAMESPACE + +#include + +/*! \class Arr_vert_decomp_sl_visitor + * A sweep-line visitor for performing vertical decomposition on an + * arrangement embedded on a surface. + */ +template +class Arr_vert_decomp_sl_visitor : + public Helper_::Base_visitor +{ +public: + + typedef Helper_ Helper; + typedef OutputIterator_ OutputIterator; + + typedef typename Helper::Traits_2 Traits_2; + typedef typename Helper::Arrangement_2 Arrangement_2; + typedef typename Helper::Base_visitor Base; + typedef typename Helper::Event Event; + typedef typename Helper::Subcurve Subcurve; + + typedef typename Arrangement_2::Vertex_const_handle Vertex_const_handle; + + typedef std::pair Vert_pair; + typedef std::pair Vert_entry; + +protected: + + typedef typename Base::Status_line_iterator Status_line_iterator; + typedef typename Arrangement_2::Halfedge_const_handle Halfedge_const_handle; + typedef typename Arrangement_2::Vertex_const_handle Vertex_const_handle; + typedef typename Arrangement_2::Halfedge_around_vertex_const_circulator + Halfedge_around_vertex_const_circulator; + + // Data members: + Helper m_helper; // The helper class. + + const typename Arrangement_2::Geometry_traits_2 *m_traits; + // The traits class. + + const Vertex_const_handle invalid_vh; + // An invalid vertex handle. + + Vertex_const_handle m_prev_vh; // The previous vertex. + CGAL::Object m_prev_obj_below; // The object this vertex sees below it. + CGAL::Object m_prev_obj_above; // The object this vertex sees above it. + + OutputIterator *m_out; // An output iterator for the result. + +public: + + /*! + * Constructor. + * \param arr The arrangement. + * \param oi A pointer to the output iterator that will store the result. + */ + Arr_vert_decomp_sl_visitor (const Arrangement_2 *arr, + OutputIterator *oi) : + m_helper (arr), + m_traits (arr->geometry_traits()), + invalid_vh(), + m_out (oi) + {} + + /* A notification issued before the sweep process starts. */ + void before_sweep (); + + /*! + * A notification invoked after the sweep-line finishes handling the given + * event. + * \param event The event. + * \param above An iterator to the sweep-line subcurves lying right above + * (or on) the event point. + * \param on_above Whether the event is locates on the subcurve above it. + */ + bool after_handle_event (Event* event, + Status_line_iterator above, + bool on_above); + + /*! + * A notification issued when the sweep process is over. + */ + void after_sweep (); +}; + +//----------------------------------------------------------------------------- +// Memeber-function definitions: +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// A notification issued before the sweep process starts. +// +template +void Arr_vert_decomp_sl_visitor::before_sweep () +{ + // Notify the helper that the sweep process now starts. + m_helper.before_sweep(); + + // Set an invalid previous vertex. + m_prev_vh = Vertex_const_handle(); + + return; +} + +//----------------------------------------------------------------------------- +// A notification invoked after the sweep-line finishes handling the given +// event. +// +template +bool Arr_vert_decomp_sl_visitor::after_handle_event + (Event* event, + Status_line_iterator above, bool /* on_above */) +{ + // Notify the helper on the event. + m_helper.after_handle_event (event); + + // We are only interested in events associated with finite points: + if (! event->is_finite()) + return (true); + + // Get the vertex handle associated with the current event (stored with + // the point). + Vertex_const_handle vh = event->point().vertex_handle(); + CGAL::Object obj_above, obj_below; + + // Check the feature from above. + if (above == this->status_line_end()) + { + // There is no concrete subcurve above the current event point, so we use + // the helper class to obtain the object above. + obj_above = m_helper.top_object(); + } + else + { + // We have a valid subcurve above the event: get its halfedge handle + // and associate it with the vertex. + obj_above = + CGAL::make_object((*above)->last_curve().halfedge_handle()); + } + + // Check if the previous vertex we handled has the same x-coordinate + // as the current one (it lies vertically below the current vertex). + const bool prev_same_x = + (m_prev_vh != invalid_vh && + m_traits->compare_x_2_object() (vh->point(), + m_prev_vh->point()) == EQUAL); + + // Decrement the status-line iterator to reach the subcurve below the + // event point. If the number of right subcurves associated with the + // event is n_right, we decrement the iterator n_right times, then + // check if it is possible to further decrement it. + Status_line_iterator below = above; + const int n_right = event->number_of_right_curves(); + int k; + + for (k = 0; k < n_right; k++) + --below; + + if (below == this->status_line_begin()) + { + if (prev_same_x) + { + // The previous vertex is vertically below the current vertex, + // so we update their respective entries in the output map. + // We first check if the two vertices are connected (by a vertical + // segment) - if so, they "see" empty features. + bool vert_connected = false; + + if (! vh->is_isolated()) + { + Halfedge_around_vertex_const_circulator circ, first; + + first = circ = vh->incident_halfedges(); + do + { + if (circ->source() == m_prev_vh) + vert_connected = true; + ++circ; + } while (! vert_connected && circ != first); + } + + if (! vert_connected) + { + obj_below = CGAL::make_object(m_prev_vh); + m_prev_obj_above = CGAL::make_object(vh); + } + else + { + obj_below = CGAL::Object(); + m_prev_obj_above = CGAL::Object(); + } + } + else + { + // There is no concrete subcurve below the current event point, so we + // use the helper class to obtain the object below. + obj_below = m_helper.bottom_object(); + } + } + else + { + // Decrement the iterator once more in order to reach the subcurve below + // the current event. + --below; + + // If the previous event has the same x-coordinate as the current one, + // we check whether it lies below or above the subcurve below. We do this + // to distinguish between the following scenarios: + // + // + // * * + // + // -------- x + // + // x --------- + // + if (prev_same_x && + (m_traits->compare_y_at_x_2_object() + (m_prev_vh->point(), + (*below)->last_curve().base()) != SMALLER)) + { + // The previous vertex is vertically below the current vertex, + // and above the subcurve that lies below vh. We therefore update + // the respective entries in the output map accordingly. + // We first check if the two vertices are connected (by a vertical + // segment) - if so, they "see" empty features. + bool vert_connected = false; + + if (! vh->is_isolated()) + { + Halfedge_around_vertex_const_circulator circ, first; + + first = circ = vh->incident_halfedges(); + do + { + if (circ->source() == m_prev_vh) + vert_connected = true; + ++circ; + } while (! vert_connected && circ != first); + } + + if (! vert_connected) + { + obj_below = CGAL::make_object(m_prev_vh); + m_prev_obj_above = CGAL::make_object(vh); + } + else + { + obj_below = CGAL::Object(); + m_prev_obj_above = CGAL::Object(); + } + } + else + { + // Get the halfedge handle of the subcurve below the current event and + // associate it with its vertex. + obj_below = + CGAL::make_object((*below)->last_curve().halfedge_handle()); + } + } + + // We can now create the entry for the previous vertex, as we are not + // going to change the identity of the features below or above it. + if (m_prev_vh != Vertex_const_handle()) + { + *(*m_out) = Vert_entry (m_prev_vh, Vert_pair (m_prev_obj_below, + m_prev_obj_above)); + ++(*m_out); + } + + // We are done with the current vertex, but we cannot create the entry + // yet - so we store it for the next event. + m_prev_vh = vh; + m_prev_obj_below = obj_below; + m_prev_obj_above = obj_above; + + // It is safe to deallocate the event. + return (true); +} + +//----------------------------------------------------------------------------- +// A notification issued when the sweep process is over. +// +template +void Arr_vert_decomp_sl_visitor::after_sweep () +{ + // Create an entry for the last vertex (the xy-largest one). + if (m_prev_vh != invalid_vh) + { + *(*m_out) = Vert_entry (m_prev_vh, Vert_pair (m_prev_obj_below, + m_prev_obj_above)); + ++(*m_out); + } + + return; +} + +CGAL_END_NAMESPACE + +#endif