diff --git a/Arrangement_on_surface_2/include/CGAL/Arr_do_intersect_overlay_2.h b/Arrangement_on_surface_2/include/CGAL/Arr_do_intersect_overlay_2.h new file mode 100644 index 00000000000..f35e8b10b19 --- /dev/null +++ b/Arrangement_on_surface_2/include/CGAL/Arr_do_intersect_overlay_2.h @@ -0,0 +1,236 @@ +// Copyright (c) 2025 Tel-Aviv University (Israel). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s): Efi Fogel + +#ifndef CGAL_ARR_DO_INTERSECT_OVERLAY_2_H +#define CGAL_ARR_DO_INTERSECT_OVERLAY_2_H + +#include + +#include + +/*! \file + * + * Definition of the global do_intersect_overlay_2() function. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace CGAL { + +/*! Compute the overlay of two input arrangements. + * \tparam GeometryTraitsA_2 the geometry traits of the first arrangement. + * \tparam GeometryTraitsB_2 the geometry traits of the second arrangement. + * \tparam GeometryTraitsRes_2 the geometry traits of the resulting arrangement. + * \tparam TopologyTraitsA the topology traits of the first arrangement. + * \tparam TopologyTraitsB the topology traits of the second arrangement. + * \tparam TopologyTraitsRes the topology traits of the resulting arrangement. + * \tparam OverlayTraits An overlay-traits class. As arr1, arr2 and res can be + * templated with different geometry-traits class and + * different DCELs (encapsulated in the various topology-traits + * classes). The geometry-traits of the result arrangement is + * used to construct the result arrangement. This means that all + * the types (e.g., Point_2, Curve_2 and X_monotone_2) of both + * arr1 and arr2 have to be convertible to the types + * in the result geometry-traits. + * The overlay-traits class defines the various + * overlay operations of pairs of DCEL features from + * TopologyTraitsA and TopologyTraitsB to the resulting ResDcel. + */ +template +bool do_intersect_overlay(const Arrangement_on_surface_2& arr1, + const Arrangement_on_surface_2& arr2, + Arrangement_on_surface_2& arr, + OverlayTraits& ovl_tr, + bool ignore_isolated_vertices = true) { + using Agt2 = GeometryTraitsA_2; + using Bgt2 = GeometryTraitsB_2; + using Rgt2 = GeometryTraitsRes_2; + using Att = TopologyTraitsA; + using Btt = TopologyTraitsB; + using Rtt = TopologyTraitsRes; + using Overlay_traits = OverlayTraits; + + using Arr_a = Arrangement_on_surface_2; + using Arr_b = Arrangement_on_surface_2; + using Arr_res = Arrangement_on_surface_2; + using Allocator = typename Arr_res::Allocator; + + // some type assertions (not all, but better than nothing). + using A_point = typename Agt2::Point_2; + using B_point = typename Bgt2::Point_2; + using Res_point = typename Rgt2::Point_2; + static_assert(std::is_convertible::value); + static_assert(std::is_convertible::value); + + using A_xcv = typename Agt2::X_monotone_curve_2; + using B_xcv = typename Bgt2::X_monotone_curve_2; + using Res_xcv = typename Rgt2::X_monotone_curve_2; + static_assert(std::is_convertible::value); + static_assert(std::is_convertible::value); + + using Gt_adaptor_2 = Arr_traits_basic_adaptor_2; + using Ovl_gt2 = Arr_overlay_traits_2; + using Ovl_event = Arr_overlay_event; + using Ovl_curve = Arr_overlay_subcurve; + using Ovl_helper = typename TopologyTraitsRes::template Overlay_helper; + using Diovl_visitor = Arr_do_intersect_overlay_ss_visitor; + + using Ovl_x_monotone_curve_2 = typename Ovl_gt2::X_monotone_curve_2; + using Ovl_point_2 = typename Ovl_gt2::Point_2; + using Cell_handle_red = typename Ovl_gt2::Cell_handle_red; + using Optional_cell_red = typename Ovl_gt2::Optional_cell_red; + using Cell_handle_blue = typename Ovl_gt2::Cell_handle_blue; + using Optional_cell_blue = typename Ovl_gt2::Optional_cell_blue; + + CGAL_USE_TYPE(Optional_cell_red); + CGAL_USE_TYPE(Optional_cell_blue); + + // The result arrangement cannot be on of the input arrangements. + CGAL_precondition(((void*)(&arr) != (void*)(&arr1)) && ((void*)(&arr) != (void*)(&arr2))); + + // Prepare a vector of extended x-monotone curves that represent all edges + // in both input arrangements. Each curve is associated with a halfedge + // directed from right to left. + typename Arr_a::Halfedge_const_handle invalid_he1; + typename Arr_b::Halfedge_const_handle invalid_he2; + std::vector xcvs(arr1.number_of_edges() + arr2.number_of_edges()); + std::size_t i = 0; + + for (auto eit1 = arr1.edges_begin(); eit1 != arr1.edges_end(); ++eit1, ++i) { + typename Arr_a::Halfedge_const_handle he1 = eit1; + if (he1->direction() != ARR_RIGHT_TO_LEFT) he1 = he1->twin(); + xcvs[i] = Ovl_x_monotone_curve_2(eit1->curve(), he1, invalid_he2); + } + + for (auto eit2 = arr2.edges_begin(); eit2 != arr2.edges_end(); ++eit2, ++i) { + typename Arr_b::Halfedge_const_handle he2 = eit2; + if (he2->direction() != ARR_RIGHT_TO_LEFT) he2 = he2->twin(); + xcvs[i] = Ovl_x_monotone_curve_2(eit2->curve(), invalid_he1, he2); + } + + // Obtain an extended traits-class object and define the sweep-line visitor. + const typename Arr_res::Traits_adaptor_2* traits_adaptor = arr.traits_adaptor(); + + /* We would like to avoid copy construction of the geometry traits class. + * Copy construction is undesired, because it may results with data + * duplication or even data loss. + * + * If the type Ovl_gt2 is the same as the type + * GeomTraits, use a reference to GeomTraits to avoid constructing a new one. + * Otherwise, instantiate a local variable of the former and provide + * the latter as a single parameter to the constructor. + * + * Use the form 'A a(*b);' and not ''A a = b;' to handle the case where A has + * only an implicit constructor, (which takes *b as a parameter). + */ + std::conditional_t, const Ovl_gt2&, Ovl_gt2> ex_traits(*traits_adaptor); + + Diovl_visitor visitor(&arr1, &arr2, &arr, &ovl_tr); + Ss2::Surface_sweep_2 surface_sweep(&ex_traits, &visitor); + + // In case both arrangement do not contain isolated vertices, go on and overlay them. + if (ignore_isolated_vertices || + ((arr1.number_of_isolated_vertices() == 0) && (arr2.number_of_isolated_vertices() == 0))) { + // Clear the result arrangement and perform the sweep to construct it. + arr.clear(); + if (std::is_same::value) { + surface_sweep.sweep(xcvs.begin(), xcvs.end()); + xcvs.clear(); + return visitor.found_intersection(); + } + surface_sweep.indexed_sweep(xcvs, Indexed_sweep_accessor(arr1, arr2)); + xcvs.clear(); + return visitor.found_intersection(); + } + + // Prepare a vector of extended points that represent all isolated vertices + // in both input arrangements. + std::vector pts_vec(arr1.number_of_isolated_vertices() + arr2.number_of_isolated_vertices()); + + i = 0; + for (auto vit1 = arr1.vertices_begin(); vit1 != arr1.vertices_end(); ++vit1) { + if (vit1->is_isolated()) { + typename Arr_a::Vertex_const_handle v1 = vit1; + pts_vec[i++] = Ovl_point_2(vit1->point(), std::make_optional(Cell_handle_red(v1)), + std::optional()); + } + } + + for (auto vit2 = arr2.vertices_begin(); vit2 != arr2.vertices_end(); ++vit2) { + if (vit2->is_isolated()) { + typename Arr_b::Vertex_const_handle v2 = vit2; + pts_vec[i++] = Ovl_point_2(vit2->point(), std::optional(), + std::make_optional(Cell_handle_blue(v2))); + } + } + + // Clear the result arrangement and perform the sweep to construct it. + arr.clear(); + if (std::is_same::value) { + surface_sweep.sweep(xcvs.begin(), xcvs.end(), pts_vec.begin(), pts_vec.end()); + xcvs.clear(); + pts_vec.clear(); + return visitor.found_intersection(); + } + surface_sweep.indexed_sweep(xcvs, Indexed_sweep_accessor(arr1, arr2), + pts_vec.begin(), pts_vec.end()); + xcvs.clear(); + pts_vec.clear(); + return visitor.found_intersection(); +} + +/*! Compute the (simple) overlay of two input arrangements. + * \param[in] arr1 the first arrangement. + * \param[in] arr2 the second arrangement. + * \param[out] arr the resulting arrangement. + */ +template +bool do_intersect_overlay(const Arrangement_on_surface_2& arr1, + const Arrangement_on_surface_2& arr2, + Arrangement_on_surface_2& arr) { + using Agt2 = GeometryTraitsA_2; + using Bgt2 = GeometryTraitsB_2; + using Rgt2 = GeometryTraitsRes_2; + using Att = TopologyTraitsA; + using Btt = TopologyTraitsB; + using Rtt = TopologyTraitsRes; + using Arr_a = Arrangement_on_surface_2; + using Arr_b = Arrangement_on_surface_2; + using Arr_res = Arrangement_on_surface_2; + + _Arr_default_overlay_traits_base ovl_traits; + return do_intersect_overlay(arr1, arr2, arr, ovl_traits); +} + +} // namespace CGAL + +#include + +#endif diff --git a/Arrangement_on_surface_2/include/CGAL/Arr_overlay_2.h b/Arrangement_on_surface_2/include/CGAL/Arr_overlay_2.h index 4d518c96961..03f105b5c0d 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arr_overlay_2.h +++ b/Arrangement_on_surface_2/include/CGAL/Arr_overlay_2.h @@ -8,8 +8,8 @@ // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // // -// Author(s) : Baruch Zukerman -// Efi Fogel +// Author(s) : Baruch Zukerman +// Efi Fogel #ifndef CGAL_ARR_OVERLAY_2_H #define CGAL_ARR_OVERLAY_2_H @@ -40,24 +40,18 @@ namespace CGAL { template -class Indexed_sweep_accessor -{ - const Arr1& arr1; - const Arr2& arr2; - mutable std::vector backup_inc; +class Indexed_sweep_accessor { +private: + const Arr1& m_arr1; + const Arr2& m_arr2; + mutable std::vector m_backup_inc; public: + Indexed_sweep_accessor(const Arr1& arr1, const Arr2& arr2) : m_arr1(arr1), m_arr2(arr2) {} - Indexed_sweep_accessor (const Arr1& arr1, const Arr2& arr2) - : arr1(arr1), arr2(arr2) { } + std::size_t nb_vertices() const { return m_arr1.number_of_vertices() + m_arr2.number_of_vertices(); } - std::size_t nb_vertices() const - { - return arr1.number_of_vertices() + arr2.number_of_vertices(); - } - - std::size_t min_end_index (const Curve& c) const - { + std::size_t min_end_index(const Curve& c) const { if (c.red_halfedge_handle() != typename Curve::HH_red()) return reinterpret_cast(c.red_halfedge_handle()->target()->inc()); // else @@ -65,8 +59,7 @@ public: return reinterpret_cast(c.blue_halfedge_handle()->target()->inc()); } - std::size_t max_end_index (const Curve& c) const - { + std::size_t max_end_index(const Curve& c) const { if (c.red_halfedge_handle() != typename Curve::HH_red()) return reinterpret_cast(c.red_halfedge_handle()->source()->inc()); // else @@ -74,52 +67,36 @@ public: return reinterpret_cast(c.blue_halfedge_handle()->source()->inc()); } - const Curve& curve (const Curve& c) const - { - return c; - } + const Curve& curve(const Curve& c) const { return c; } // Initializes indices by squatting Vertex::inc(); - void before_init() const - { + void before_init() const { std::size_t idx = 0; - backup_inc.resize (nb_vertices()); - for (typename Arr1::Vertex_const_iterator vit = arr1.vertices_begin(); - vit != arr1.vertices_end(); ++vit, ++idx) - { - CGAL_assertion (idx < backup_inc.size()); - backup_inc[idx] = vit->inc(); - vit->set_inc (reinterpret_cast(idx)); + m_backup_inc.resize (nb_vertices()); + for (auto vit = m_arr1.vertices_begin(); vit != m_arr1.vertices_end(); ++vit, ++idx) { + CGAL_assertion(idx < m_backup_inc.size()); + m_backup_inc[idx] = vit->inc(); + vit->set_inc(reinterpret_cast(idx)); } - for (typename Arr2::Vertex_const_iterator vit = arr2.vertices_begin(); - vit != arr2.vertices_end(); ++vit, ++idx) - { - CGAL_assertion (idx < backup_inc.size()); - backup_inc[idx] = vit->inc(); - vit->set_inc (reinterpret_cast(idx)); + for (auto vit = m_arr2.vertices_begin(); vit != m_arr2.vertices_end(); ++vit, ++idx) { + CGAL_assertion(idx < m_backup_inc.size()); + m_backup_inc[idx] = vit->inc(); + vit->set_inc(reinterpret_cast(idx)); } } // Restores state of arrangements before index squatting - void after_init() const - { + void after_init() const { std::size_t idx = 0; - for (typename Arr1::Vertex_const_iterator vit = arr1.vertices_begin(); - vit != arr1.vertices_end(); ++vit, ++idx) - { - CGAL_assertion (idx < backup_inc.size()); - vit->set_inc (backup_inc[idx]); + for (auto vit = m_arr1.vertices_begin(); vit != m_arr1.vertices_end(); ++vit, ++idx) { + CGAL_assertion(idx < m_backup_inc.size()); + vit->set_inc(m_backup_inc[idx]); } - for (typename Arr2::Vertex_const_iterator vit = arr2.vertices_begin(); - vit != arr2.vertices_end(); ++vit, ++idx) - { - CGAL_assertion (idx < backup_inc.size()); - vit->set_inc (backup_inc[idx]); + for (auto vit = m_arr2.vertices_begin(); vit != m_arr2.vertices_end(); ++vit, ++idx) { + CGAL_assertion(idx < m_backup_inc.size()); + vit->set_inc(m_backup_inc[idx]); } } - -private: - }; /*! Compute the overlay of two input arrangements. @@ -148,64 +125,55 @@ template -void -overlay(const Arrangement_on_surface_2& arr1, - const Arrangement_on_surface_2& arr2, - Arrangement_on_surface_2& arr, - OverlayTraits& ovl_tr) -{ - typedef GeometryTraitsA_2 Agt2; - typedef GeometryTraitsB_2 Bgt2; - typedef GeometryTraitsRes_2 Rgt2; - typedef TopologyTraitsA Att; - typedef TopologyTraitsB Btt; - typedef TopologyTraitsRes Rtt; - typedef OverlayTraits Overlay_traits; +void overlay(const Arrangement_on_surface_2& arr1, + const Arrangement_on_surface_2& arr2, + Arrangement_on_surface_2& arr, + OverlayTraits& ovl_tr) { + using Agt2 = GeometryTraitsA_2; + using Bgt2 = GeometryTraitsB_2; + using Rgt2 = GeometryTraitsRes_2; + using Att = TopologyTraitsA; + using Btt = TopologyTraitsB; + using Rtt = TopologyTraitsRes; + using Overlay_traits = OverlayTraits; - typedef Arrangement_on_surface_2 Arr_a; - typedef Arrangement_on_surface_2 Arr_b; - typedef Arrangement_on_surface_2 Arr_res; - typedef typename Arr_res::Allocator Allocator; + using Arr_a = Arrangement_on_surface_2; + using Arr_b = Arrangement_on_surface_2; + using Arr_res = Arrangement_on_surface_2; + using Allocator = typename Arr_res::Allocator; // some type assertions (not all, but better than nothing). - typedef typename Agt2::Point_2 A_point; - typedef typename Bgt2::Point_2 B_point; - typedef typename Rgt2::Point_2 Res_point; + using A_point = typename Agt2::Point_2; + using B_point = typename Bgt2::Point_2; + using Res_point = typename Rgt2::Point_2; static_assert(std::is_convertible::value); static_assert(std::is_convertible::value); - typedef typename Agt2::X_monotone_curve_2 A_xcv; - typedef typename Bgt2::X_monotone_curve_2 B_xcv; - typedef typename Rgt2::X_monotone_curve_2 Res_xcv; + using A_xcv = typename Agt2::X_monotone_curve_2; + using B_xcv = typename Bgt2::X_monotone_curve_2; + using Res_xcv = typename Rgt2::X_monotone_curve_2; static_assert(std::is_convertible::value); static_assert(std::is_convertible::value); - typedef Arr_traits_basic_adaptor_2 Gt_adaptor_2; - typedef Arr_overlay_traits_2 - Ovl_gt2; - typedef Arr_overlay_event - Ovl_event; - typedef Arr_overlay_subcurve - Ovl_curve; - typedef typename TopologyTraitsRes::template - Overlay_helper - Ovl_helper; - typedef Arr_overlay_ss_visitor - Ovl_visitor; + using Gt_adaptor_2 = Arr_traits_basic_adaptor_2; + using Ovl_gt2 = Arr_overlay_traits_2; + using Ovl_event = Arr_overlay_event; + using Ovl_curve = Arr_overlay_subcurve; + using Ovl_helper = typename TopologyTraitsRes::template Overlay_helper; + using Ovl_visitor = Arr_overlay_ss_visitor; - typedef typename Ovl_gt2::X_monotone_curve_2 Ovl_x_monotone_curve_2; - typedef typename Ovl_gt2::Point_2 Ovl_point_2; - typedef typename Ovl_gt2::Cell_handle_red Cell_handle_red; - typedef typename Ovl_gt2::Optional_cell_red Optional_cell_red; - typedef typename Ovl_gt2::Cell_handle_blue Cell_handle_blue; - typedef typename Ovl_gt2::Optional_cell_blue Optional_cell_blue; + using Ovl_x_monotone_curve_2 = typename Ovl_gt2::X_monotone_curve_2; + using Ovl_point_2 = typename Ovl_gt2::Point_2; + using Cell_handle_red = typename Ovl_gt2::Cell_handle_red; + using Optional_cell_red = typename Ovl_gt2::Optional_cell_red; + using Cell_handle_blue = typename Ovl_gt2::Cell_handle_blue; + using Optional_cell_blue = typename Ovl_gt2::Optional_cell_blue; CGAL_USE_TYPE(Optional_cell_red); CGAL_USE_TYPE(Optional_cell_blue); // The result arrangement cannot be on of the input arrangements. - CGAL_precondition(((void*)(&arr) != (void*)(&arr1)) && - ((void*)(&arr) != (void*)(&arr2))); + CGAL_precondition(((void*)(&arr) != (void*)(&arr1)) && ((void*)(&arr) != (void*)(&arr2))); // Prepare a vector of extended x-monotone curves that represent all edges // in both input arrangements. Each curve is associated with a halfedge @@ -216,23 +184,20 @@ overlay(const Arrangement_on_surface_2& arr1 xcvs_vec(arr1.number_of_edges() + arr2.number_of_edges()); unsigned int i = 0; - typename Arr_a::Edge_const_iterator eit1; - for (eit1 = arr1.edges_begin(); eit1 != arr1.edges_end(); ++eit1, ++i) { + for (auto eit1 = arr1.edges_begin(); eit1 != arr1.edges_end(); ++eit1, ++i) { typename Arr_a::Halfedge_const_handle he1 = eit1; if (he1->direction() != ARR_RIGHT_TO_LEFT) he1 = he1->twin(); xcvs_vec[i] = Ovl_x_monotone_curve_2(eit1->curve(), he1, invalid_he2); } - typename Arr_b::Edge_const_iterator eit2; - for (eit2 = arr2.edges_begin(); eit2 != arr2.edges_end(); ++eit2, ++i) { + for (auto eit2 = arr2.edges_begin(); eit2 != arr2.edges_end(); ++eit2, ++i) { typename Arr_b::Halfedge_const_handle he2 = eit2; if (he2->direction() != ARR_RIGHT_TO_LEFT) he2 = he2->twin(); xcvs_vec[i] = Ovl_x_monotone_curve_2(eit2->curve(), invalid_he1, he2); } // Obtain an extended traits-class object and define the sweep-line visitor. - const typename Arr_res::Traits_adaptor_2* traits_adaptor = - arr.traits_adaptor(); + const typename Arr_res::Traits_adaptor_2* traits_adaptor = arr.traits_adaptor(); /* We would like to avoid copy construction of the geometry traits class. * Copy construction is undesired, because it may results with data @@ -246,29 +211,22 @@ overlay(const Arrangement_on_surface_2& arr1 * Use the form 'A a(*b);' and not ''A a = b;' to handle the case where A has * only an implicit constructor, (which takes *b as a parameter). */ - std::conditional_t, - const Ovl_gt2&, Ovl_gt2> - ex_traits(*traits_adaptor); + std::conditional_t, const Ovl_gt2&, Ovl_gt2> ex_traits(*traits_adaptor); Ovl_visitor visitor(&arr1, &arr2, &arr, &ovl_tr); Ss2::Surface_sweep_2 surface_sweep(&ex_traits, &visitor); // In case both arrangement do not contain isolated vertices, go on and // overlay them. - const std::size_t total_iso_verts = - arr1.number_of_isolated_vertices() + arr2.number_of_isolated_vertices(); + const std::size_t total_iso_verts = arr1.number_of_isolated_vertices() + arr2.number_of_isolated_vertices(); if (total_iso_verts == 0) { // Clear the result arrangement and perform the sweep to construct it. arr.clear(); - if (std::is_same::value) - surface_sweep.sweep (xcvs_vec.begin(), xcvs_vec.end()); + if (std::is_same::value) + surface_sweep.sweep(xcvs_vec.begin(), xcvs_vec.end()); else - surface_sweep.indexed_sweep (xcvs_vec, - Indexed_sweep_accessor - - (arr1, arr2)); + surface_sweep.indexed_sweep(xcvs_vec, Indexed_sweep_accessor(arr1, arr2)); xcvs_vec.clear(); return; } @@ -278,38 +236,29 @@ overlay(const Arrangement_on_surface_2& arr1 std::vector pts_vec(total_iso_verts); i = 0; - typename Arr_a::Vertex_const_iterator vit1; - for (vit1 = arr1.vertices_begin(); vit1 != arr1.vertices_end(); ++vit1) { + for (auto vit1 = arr1.vertices_begin(); vit1 != arr1.vertices_end(); ++vit1) { if (vit1->is_isolated()) { typename Arr_a::Vertex_const_handle v1 = vit1; - pts_vec[i++] = - Ovl_point_2(vit1->point(), std::make_optional(Cell_handle_red(v1)), - std::optional()); + pts_vec[i++] = Ovl_point_2(vit1->point(), std::make_optional(Cell_handle_red(v1)), + std::optional()); } } - typename Arr_b::Vertex_const_iterator vit2; - for (vit2 = arr2.vertices_begin(); vit2 != arr2.vertices_end(); ++vit2) { + for (auto vit2 = arr2.vertices_begin(); vit2 != arr2.vertices_end(); ++vit2) { if (vit2->is_isolated()) { typename Arr_b::Vertex_const_handle v2 = vit2; - pts_vec[i++] = - Ovl_point_2(vit2->point(), std::optional(), - std::make_optional(Cell_handle_blue(v2))); + pts_vec[i++] = Ovl_point_2(vit2->point(), std::optional(), + std::make_optional(Cell_handle_blue(v2))); } } // Clear the result arrangement and perform the sweep to construct it. arr.clear(); - if (std::is_same::value) - surface_sweep.sweep(xcvs_vec.begin(), xcvs_vec.end(), - pts_vec.begin(), pts_vec.end()); + if (std::is_same::value) + surface_sweep.sweep(xcvs_vec.begin(), xcvs_vec.end(), pts_vec.begin(), pts_vec.end()); else - surface_sweep.indexed_sweep (xcvs_vec, - Indexed_sweep_accessor - - (arr1, arr2), - pts_vec.begin(), pts_vec.end()); + surface_sweep.indexed_sweep(xcvs_vec, Indexed_sweep_accessor(arr1, arr2), + pts_vec.begin(), pts_vec.end()); xcvs_vec.clear(); pts_vec.clear(); } @@ -325,20 +274,18 @@ template -void -overlay(const Arrangement_on_surface_2& arr1, - const Arrangement_on_surface_2& arr2, - Arrangement_on_surface_2& arr) -{ - typedef GeometryTraitsA_2 Agt2; - typedef GeometryTraitsB_2 Bgt2; - typedef GeometryTraitsRes_2 Rgt2; - typedef TopologyTraitsA Att; - typedef TopologyTraitsB Btt; - typedef TopologyTraitsRes Rtt; - typedef Arrangement_on_surface_2 Arr_a; - typedef Arrangement_on_surface_2 Arr_b; - typedef Arrangement_on_surface_2 Arr_res; +void overlay(const Arrangement_on_surface_2& arr1, + const Arrangement_on_surface_2& arr2, + Arrangement_on_surface_2& arr) { + using Agt2 = GeometryTraitsA_2; + using Bgt2 = GeometryTraitsB_2; + using Rgt2 = GeometryTraitsRes_2; + using Att = TopologyTraitsA; + using Btt = TopologyTraitsB; + using Rtt = TopologyTraitsRes; + using Arr_a = Arrangement_on_surface_2; + using Arr_b = Arrangement_on_surface_2; + using Arr_res = Arrangement_on_surface_2; _Arr_default_overlay_traits_base ovl_traits; overlay(arr1, arr2, arr, ovl_traits); diff --git a/Arrangement_on_surface_2/include/CGAL/Surface_sweep_2/Arr_do_intersect_overlay_ss_visitor.h b/Arrangement_on_surface_2/include/CGAL/Surface_sweep_2/Arr_do_intersect_overlay_ss_visitor.h new file mode 100644 index 00000000000..105e42ea513 --- /dev/null +++ b/Arrangement_on_surface_2/include/CGAL/Surface_sweep_2/Arr_do_intersect_overlay_ss_visitor.h @@ -0,0 +1,110 @@ +// Copyright (c) 2006,2007,2009,2010,2011,2025 Tel-Aviv University (Israel). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Efi Fogel + +#ifndef CGAL_DO_INTERSECT_ARR_OVERLAY_SS_VISITOR_H +#define CGAL_DO_INTERSECT_ARR_OVERLAY_SS_VISITOR_H + +#include + +/*! \file + * + * Definition of the Arr_do_intersect_overlay_ss_visitor class-template. + */ + +#include +#include + +namespace CGAL { + +/*! \class Arr_do_intersect_overlay_ss_visitor + * + * A sweep-line visitor for overlaying a "red" arrangement and a "blue" + * arrangement as long as the edges do not intersect in their interiors. If + * there are no intersections, the overlay arrangement is constructed. All three + * arrangements are embedded on the same type of surface and use the same + * geometry traits. Otherwise, the process is terminated without any delay (that + * is, once an intersection is detected). + */ +template +class Arr_do_intersect_overlay_ss_visitor : + public Arr_overlay_ss_visitor< + OverlayHelper, OverlayTraits, + typename Default::Get >::type> { +private: + using Overlay_helper = OverlayHelper; + using Overlay_traits = OverlayTraits; + + using Self = Arr_do_intersect_overlay_ss_visitor; + using Visitor = typename Default::Get::type; + using Base = Arr_overlay_ss_visitor; + +protected: + bool m_found_x; + +public: + using Arrangement_red_2 = typename Base::Arrangement_red_2; + using Arrangement_blue_2 = typename Base::Arrangement_blue_2; + using Arrangement_2 = typename Base::Arrangement_2; + using Event = typename Base::Event; + using Subcurve = typename Base::Subcurve; + using Status_line_iterator = typename Base::Status_line_iterator; + using X_monotone_curve_2 = typename Base::X_monotone_curve_2; + using Point_2 = typename Base::Point_2; + using Multiplicity = typename Base::Multiplicity; + + /*! Constructor */ + Arr_do_intersect_overlay_ss_visitor(const Arrangement_red_2* red_arr, + const Arrangement_blue_2* blue_arr, + Arrangement_2* res_arr, + Overlay_traits* overlay_traits) : + Base(red_arr, blue_arr, res_arr, overlay_traits), + m_found_x(false) + {} + + /*! Destructor */ + virtual ~Arr_do_intersect_overlay_ss_visitor() {} + + /*! Update an event that corresponds to a curve endpoint. */ + void update_event(Event* e, const Point_2& end_point, const X_monotone_curve_2& cv, Arr_curve_end cv_end, bool is_new) + { return Base::update_event(e, end_point, cv, cv_end, is_new); } + + /*! Update an event that corresponds to a curve endpoint */ + void update_event(Event* e, const X_monotone_curve_2& cv, Arr_curve_end cv_end, bool is_new ) + { return Base::update_event(e, cv, cv_end, is_new); } + + /*! Update an event that corresponds to a curve endpoint */ + void update_event(Event* e, const Point_2& p, bool is_new) + { return Base::update_event(e, p, is_new); } + + /*! Update an event that corresponds to an intersection */ + void update_event(Event* e, Subcurve* sc) { return Base::update_event(e, sc); } + + /*! Update an event that corresponds to an intersection between curves */ + void update_event(Event* e, Subcurve* sc1, Subcurve* sc2, bool is_new, Multiplicity multiplicity) { + if ((multiplicity % 2) == 1) m_found_x = true; + Base::update_event(e, sc1, sc2, is_new, multiplicity); + } + + bool after_handle_event(Event* e, Status_line_iterator iter, bool flag) { + auto res = Base::after_handle_event(e, iter, flag); + if (m_found_x) this->surface_sweep()->stop_sweep(); + return res; + } + + /*! Getter */ + bool found_intersection() { return m_found_x; } +}; + +} // namespace CGAL + +#endif diff --git a/Arrangement_on_surface_2/include/CGAL/Surface_sweep_2/Arr_no_intersection_insertion_ss_visitor.h b/Arrangement_on_surface_2/include/CGAL/Surface_sweep_2/Arr_no_intersection_insertion_ss_visitor.h index e82e28b3164..8e2ed4ef9b5 100644 --- a/Arrangement_on_surface_2/include/CGAL/Surface_sweep_2/Arr_no_intersection_insertion_ss_visitor.h +++ b/Arrangement_on_surface_2/include/CGAL/Surface_sweep_2/Arr_no_intersection_insertion_ss_visitor.h @@ -8,9 +8,9 @@ // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // // -// Author(s): Baruch Zukerman -// Ron Wein -// Efi Fogel +// Author(s) : Baruch Zukerman +// Ron Wein +// Efi Fogel #ifndef CGAL_ARR_NO_INTERSECTION_INSERTION_SS_VISITOR_H #define CGAL_ARR_NO_INTERSECTION_INSERTION_SS_VISITOR_H @@ -42,35 +42,33 @@ class Arr_no_intersection_insertion_ss_visitor : public Arr_construction_ss_visitor< Helper_, typename Default::Get >::type> -{ + Helper_, Visitor_> >::type> { public: - typedef Helper_ Helper; + using Helper = Helper_; - typedef typename Helper::Geometry_traits_2 Geometry_traits_2; - typedef typename Helper::Event Event; - typedef typename Helper::Subcurve Subcurve; + using Geometry_traits_2 = typename Helper::Geometry_traits_2; + using Event = typename Helper::Event; + using Subcurve = typename Helper::Subcurve; private: - typedef Geometry_traits_2 Gt2; - typedef Arr_no_intersection_insertion_ss_visitor - Self; - typedef typename Default::Get::type Visitor; - typedef Arr_construction_ss_visitor Base; + using Gt2 = Geometry_traits_2; + using Self = Arr_no_intersection_insertion_ss_visitor; + using Visitor = typename Default::Get::type; + using Base = Arr_construction_ss_visitor; public: - typedef typename Gt2::X_monotone_curve_2 X_monotone_curve_2; - typedef typename Gt2::Point_2 Point_2; + using X_monotone_curve_2 = typename Gt2::X_monotone_curve_2; + using Point_2 = typename Gt2::Point_2; + using Multiplicity = typename Gt2::Multiplicity; protected: - typedef typename Subcurve::Status_line_iterator Status_line_iterator; - typedef typename Base::Event_subcurve_reverse_iterator - Event_subcurve_reverse_iterator; + using Status_line_iterator = typename Subcurve::Status_line_iterator; + using Event_subcurve_reverse_iterator = typename Base::Event_subcurve_reverse_iterator; - typedef typename Helper::Arrangement_2 Arrangement_2; - typedef typename Arrangement_2::Vertex_handle Vertex_handle; - typedef typename Arrangement_2::Halfedge_handle Halfedge_handle; - typedef typename Arrangement_2::Face_handle Face_handle; + using Arrangement_2 = typename Helper::Arrangement_2; + using Vertex_handle = typename Arrangement_2::Vertex_handle; + using Halfedge_handle = typename Arrangement_2::Halfedge_handle; + using Face_handle = typename Arrangement_2::Face_handle; public: /*! Constructor. */ @@ -103,13 +101,12 @@ public: {} void update_event(Event* /* e */, Subcurve* /* sc1 */, Subcurve* /* sc2 */, - bool /* is_new */) + bool /* is_new */, Multiplicity /* multiplicity */) {} void update_event(Event* /* e */, Subcurve* /* sc1 */) {} - void update_event(Event* e, const Point_2& pt, bool /* is_new */) - { + void update_event(Event* e, const Point_2& pt, bool /* is_new */) { Vertex_handle invalid_v; if (e->point().vertex_handle() == invalid_v) e->point().set_vertex_handle(pt.vertex_handle()); @@ -241,8 +238,7 @@ void Arr_no_intersection_insertion_ss_visitor::before_sweep() // template void Arr_no_intersection_insertion_ss_visitor:: -before_handle_event(Event* event) -{ +before_handle_event(Event* event) { // First we notify the helper class on the event. this->m_helper.before_handle_event(event); @@ -330,8 +326,7 @@ before_handle_event(Event* event) // template bool Arr_no_intersection_insertion_ss_visitor:: -add_subcurve_(const X_monotone_curve_2& cv, Subcurve* sc) -{ +add_subcurve_(const X_monotone_curve_2& cv, Subcurve* sc) { const Halfedge_handle invalid_he; if (cv.halfedge_handle() != invalid_he) return false; // Insert the curve into the arrangement @@ -344,8 +339,7 @@ add_subcurve_(const X_monotone_curve_2& cv, Subcurve* sc) // template void Arr_no_intersection_insertion_ss_visitor:: -add_subcurve(const X_monotone_curve_2& cv, Subcurve* sc) -{ +add_subcurve(const X_monotone_curve_2& cv, Subcurve* sc) { if (add_subcurve_(cv, sc)) return; Halfedge_handle next_ccw_he = @@ -359,8 +353,7 @@ add_subcurve(const X_monotone_curve_2& cv, Subcurve* sc) template typename Arr_no_intersection_insertion_ss_visitor::Halfedge_handle Arr_no_intersection_insertion_ss_visitor:: -insert_in_face_interior(const X_monotone_curve_2& cv, Subcurve* sc) -{ +insert_in_face_interior(const X_monotone_curve_2& cv, Subcurve* sc) { Event* last_event = this->last_event_on_subcurve(sc); Vertex_handle last_v = last_event->point().vertex_handle(); Vertex_handle curr_v = this->current_event()->point().vertex_handle(); @@ -385,8 +378,7 @@ template typename Arr_no_intersection_insertion_ss_visitor::Halfedge_handle Arr_no_intersection_insertion_ss_visitor:: insert_from_left_vertex(const X_monotone_curve_2& cv, Halfedge_handle he, - Subcurve* sc) -{ + Subcurve* sc) { Vertex_handle curr_v = this->current_event()->point().vertex_handle(); if (curr_v != Vertex_handle()) return (this->m_arr->insert_at_vertices(cv.base(), he, curr_v)); @@ -400,8 +392,7 @@ template typename Arr_no_intersection_insertion_ss_visitor::Halfedge_handle Arr_no_intersection_insertion_ss_visitor:: insert_from_right_vertex(const X_monotone_curve_2& cv, Halfedge_handle he, - Subcurve* sc) -{ + Subcurve* sc) { Event* last_event = this->last_event_on_subcurve(sc); Vertex_handle last_v = last_event->point().vertex_handle(); if (last_v != Vertex_handle()) @@ -426,8 +417,7 @@ insert_at_vertices(const X_monotone_curve_2& cv, template typename Arr_no_intersection_insertion_ss_visitor::Vertex_handle Arr_no_intersection_insertion_ss_visitor:: -insert_isolated_vertex(const Point_2& pt, Status_line_iterator iter) -{ +insert_isolated_vertex(const Point_2& pt, Status_line_iterator iter) { // If the isolated vertex is already at the arrangement, return: if (pt.vertex_handle() != Vertex_handle()) return Vertex_handle(); @@ -443,8 +433,7 @@ insert_isolated_vertex(const Point_2& pt, Status_line_iterator iter) template typename Arr_no_intersection_insertion_ss_visitor::Halfedge_handle Arr_no_intersection_insertion_ss_visitor:: -_insert_in_face_interior(const X_monotone_curve_2& cv, Subcurve* sc) -{ +_insert_in_face_interior(const X_monotone_curve_2& cv, Subcurve* sc) { // Check if the vertex to be associated with the left end of the curve has // already been created. Event* last_event = this->last_event_on_subcurve(sc); @@ -514,8 +503,7 @@ template typename Arr_no_intersection_insertion_ss_visitor::Halfedge_handle Arr_no_intersection_insertion_ss_visitor:: _insert_from_left_vertex(const X_monotone_curve_2& cv, - Halfedge_handle prev, Subcurve* sc) -{ + Halfedge_handle prev, Subcurve* sc) { // Check if the vertex to be associated with the right end of the curve has // already been created. Event* curr_event = this->current_event(); @@ -551,8 +539,7 @@ template typename Arr_no_intersection_insertion_ss_visitor::Halfedge_handle Arr_no_intersection_insertion_ss_visitor:: _insert_from_right_vertex(const X_monotone_curve_2& cv, Halfedge_handle prev, - Subcurve* sc) -{ + Subcurve* sc) { // Check if the vertex to be associated with the left end of the curve has // already been created. Event* last_event = this->last_event_on_subcurve(sc); @@ -589,8 +576,7 @@ typename Arr_no_intersection_insertion_ss_visitor::Halfedge_handle Arr_no_intersection_insertion_ss_visitor:: _insert_at_vertices(const X_monotone_curve_2& cv, Halfedge_handle prev1, Halfedge_handle prev2, - Subcurve* sc, bool& new_face_created) -{ + Subcurve* sc, bool& new_face_created) { // Perform the insertion. new_face_created = false; bool swapped_predecessors = false; @@ -632,8 +618,7 @@ _insert_at_vertices(const X_monotone_curve_2& cv, template typename Arr_no_intersection_insertion_ss_visitor::Face_handle Arr_no_intersection_insertion_ss_visitor:: -_ray_shoot_up(Status_line_iterator iter) -{ +_ray_shoot_up(Status_line_iterator iter) { // Go up the status line and try to locate a curve which is associated // with a valid arrangement halfedge. const Halfedge_handle invalid_he; diff --git a/Arrangement_on_surface_2/include/CGAL/Surface_sweep_2/Arr_overlay_ss_visitor.h b/Arrangement_on_surface_2/include/CGAL/Surface_sweep_2/Arr_overlay_ss_visitor.h index 06052a8f19d..6c3cea30646 100644 --- a/Arrangement_on_surface_2/include/CGAL/Surface_sweep_2/Arr_overlay_ss_visitor.h +++ b/Arrangement_on_surface_2/include/CGAL/Surface_sweep_2/Arr_overlay_ss_visitor.h @@ -8,9 +8,9 @@ // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // // -// Author(s) : Baruch Zukerman -// Ron Wein -// Efi Fogel +// Author(s) : Baruch Zukerman +// Ron Wein +// Efi Fogel #ifndef CGAL_ARR_OVERLAY_SS_VISITOR_H #define CGAL_ARR_OVERLAY_SS_VISITOR_H @@ -40,92 +40,80 @@ namespace CGAL { * arrangement, creating a result arrangement. All three arrangements are * embedded on the same type of surface and use the same geometry traits. */ -template +template class Arr_overlay_ss_visitor : public Arr_construction_ss_visitor< typename OverlayHelper::Construction_helper, typename Default::Get >::type> -{ + Arr_overlay_ss_visitor >::type> { public: - typedef OverlayHelper Overlay_helper; - typedef OverlayTraits Overlay_traits; + using Overlay_helper = OverlayHelper; + using Overlay_traits = OverlayTraits; - typedef typename Overlay_helper::Geometry_traits_2 Geometry_traits_2; - typedef typename Overlay_helper::Event Event; - typedef typename Overlay_helper::Subcurve Subcurve; + using Geometry_traits_2 = typename Overlay_helper::Geometry_traits_2; + using Event = typename Overlay_helper::Event; + using Subcurve = typename Overlay_helper::Subcurve; - typedef typename Overlay_helper::Arrangement_red_2 Arrangement_red_2; - typedef typename Overlay_helper::Arrangement_blue_2 Arrangement_blue_2; - - typedef typename Overlay_helper::Construction_helper Construction_helper; + using Arrangement_red_2 = typename Overlay_helper::Arrangement_red_2; + using Arrangement_blue_2 = typename Overlay_helper::Arrangement_blue_2; + using Construction_helper = typename Overlay_helper::Construction_helper; private: - typedef Geometry_traits_2 Gt2; - typedef Arrangement_red_2 Ar2; - typedef Arrangement_blue_2 Ab2; + using Gt2 = Geometry_traits_2; + using Ar2 = Arrangement_red_2; + using Ab2 = Arrangement_blue_2; - typedef Arr_overlay_ss_visitor - Self; - typedef typename Default::Get::type Visitor; - typedef Arr_construction_ss_visitor - Base; + using Self = Arr_overlay_ss_visitor; + using Visitor = typename Default::Get::type; + using Base = Arr_construction_ss_visitor; public: - typedef typename Gt2::X_monotone_curve_2 X_monotone_curve_2; - typedef typename Gt2::Point_2 Point_2; + using X_monotone_curve_2 = typename Gt2::X_monotone_curve_2; + using Point_2 = typename Gt2::Point_2; + using Multiplicity = typename Gt2::Multiplicity; // The input arrangements (the "red" and the "blue" one): - typedef typename Ar2::Halfedge_const_handle Halfedge_handle_red; - typedef typename Ar2::Face_const_handle Face_handle_red; - typedef typename Ar2::Vertex_const_handle Vertex_handle_red; + using Halfedge_handle_red = typename Ar2::Halfedge_const_handle; + using Face_handle_red = typename Ar2::Face_const_handle; + using Vertex_handle_red = typename Ar2::Vertex_const_handle; - typedef typename Ab2::Halfedge_const_handle Halfedge_handle_blue; - typedef typename Ab2::Face_const_handle Face_handle_blue; - typedef typename Ab2::Vertex_const_handle Vertex_handle_blue; + using Halfedge_handle_blue = typename Ab2::Halfedge_const_handle; + using Face_handle_blue = typename Ab2::Face_const_handle; + using Vertex_handle_blue = typename Ab2::Vertex_const_handle; // The resulting arrangement: - typedef typename Overlay_helper::Arrangement_2 Arrangement_2; - typedef typename Arrangement_2::Halfedge_handle Halfedge_handle; - typedef typename Arrangement_2::Face_handle Face_handle; - typedef typename Arrangement_2::Vertex_handle Vertex_handle; - typedef typename Arrangement_2::Ccb_halfedge_circulator - Ccb_halfedge_circulator; - typedef typename Arrangement_2::Outer_ccb_iterator Outer_ccb_iterator; + using Arrangement_2 = typename Overlay_helper::Arrangement_2; + using Halfedge_handle = typename Arrangement_2::Halfedge_handle; + using Face_handle = typename Arrangement_2::Face_handle; + using Vertex_handle = typename Arrangement_2::Vertex_handle; + using Ccb_halfedge_circulator = typename Arrangement_2::Ccb_halfedge_circulator; + using Outer_ccb_iterator = typename Arrangement_2::Outer_ccb_iterator; - typedef typename Base::Event_subcurve_iterator - Event_subcurve_iterator; - typedef typename Base::Event_subcurve_reverse_iterator - Event_subcurve_reverse_iterator; - typedef typename Base::Status_line_iterator Status_line_iterator; + using Event_subcurve_iterator = typename Base::Event_subcurve_iterator; + using Event_subcurve_reverse_iterator = typename Base::Event_subcurve_reverse_iterator; + using Status_line_iterator = typename Base::Status_line_iterator; protected: - typedef typename Gt2::Cell_handle_red Cell_handle_red; - typedef typename Gt2::Optional_cell_red Optional_cell_red; - typedef typename Gt2::Cell_handle_blue Cell_handle_blue; - typedef typename Gt2::Optional_cell_blue Optional_cell_blue; + using Cell_handle_red = typename Gt2::Cell_handle_red; + using Optional_cell_red = typename Gt2::Optional_cell_red; + using Cell_handle_blue = typename Gt2::Cell_handle_blue; + using Optional_cell_blue = typename Gt2::Optional_cell_blue; - typedef std::pair - Halfedge_info; - typedef Unique_hash_map - Halfedge_map; + using Halfedge_info = std::pair; + using Halfedge_map = Unique_hash_map; - typedef std::pair Handle_info; - typedef std::unordered_map - Vertex_map; + using Handle_info = std::pair; + using Vertex_map = std::unordered_map; // Side categoties: - typedef typename Gt2::Left_side_category Left_side_category; - typedef typename Gt2::Bottom_side_category Bottom_side_category; - typedef typename Gt2::Top_side_category Top_side_category; - typedef typename Gt2::Right_side_category Right_side_category; + using Left_side_category = typename Gt2::Left_side_category; + using Bottom_side_category = typename Gt2::Bottom_side_category; + using Top_side_category = typename Gt2::Top_side_category; + using Right_side_category = typename Gt2::Right_side_category; - typedef typename Arr_has_identified_sides::result - Has_identified_sides_category; + using Has_identified_sides_category = + typename Arr_has_identified_sides::result; // Data members: Overlay_traits* m_overlay_traits; // The overlay traits object. @@ -195,10 +183,9 @@ public: void update_event(Event* /* e */, Subcurve* /* c1 */, Subcurve* /* c2 */, - bool CGAL_assertion_code(is_new)) - { - CGAL_assertion(is_new == true); - } + bool CGAL_assertion_code(is_new), + Multiplicity /* multiplicity */) + { CGAL_assertion(is_new == true); } /*! Update an event. */ void update_event(Event* e, Subcurve* sc); @@ -407,9 +394,8 @@ protected: //----------------------------------------------------------------------------- // A notification issued before the sweep process starts. // - template - void Arr_overlay_ss_visitor::before_sweep() -{ +template +void Arr_overlay_ss_visitor::before_sweep() { // Initialize the necessary fields in the base construction visitor. // Note that the construction visitor also informs its helper class that // the sweep process is about to start. @@ -425,8 +411,7 @@ protected: // template void -Arr_overlay_ss_visitor::before_handle_event(Event* event) -{ +Arr_overlay_ss_visitor::before_handle_event(Event* event) { // Let the base construction visitor do the work (and also inform its helper // class on the event). Base::before_handle_event(event); @@ -441,8 +426,7 @@ Arr_overlay_ss_visitor::before_handle_event(Event* event) // template bool Arr_overlay_ss_visitor:: -after_handle_event(Event* event, Status_line_iterator iter, bool flag) -{ +after_handle_event(Event* event, Status_line_iterator iter, bool flag) { // Let the base construction visitor handle the event. bool res = Base::after_handle_event(event, iter, flag); @@ -497,8 +481,7 @@ update_event(Event* e, const Point_2& end_point, const X_monotone_curve_2& /* cv */, Arr_curve_end /* cv_end */, - bool /* is_new */) -{ + bool /* is_new */) { // Nothing to do in case of an event at infinity. CGAL_assertion(e->is_closed()); @@ -513,8 +496,7 @@ update_event(Event* e, // template void Arr_overlay_ss_visitor::update_event(Event* e, - Subcurve* sc) -{ + Subcurve* sc) { // Update the red and blue halfedges associated with the point as necessary. Point_2& pt = e->point(); @@ -538,8 +520,7 @@ template void Arr_overlay_ss_visitor::update_event(Event* e, const Point_2& p, - bool /* is_new */) -{ + bool /* is_new */) { // Update the red and blue objects associated with the point as necessary. Point_2& pt = e->point(); if (pt.is_red_cell_empty()) pt.set_red_cell(p.red_cell()); @@ -550,8 +531,7 @@ Arr_overlay_ss_visitor::update_event(Event* e, // A notification issued when the sweep process has ended. // template -void Arr_overlay_ss_visitor::after_sweep() -{ +void Arr_overlay_ss_visitor::after_sweep() { Base::after_sweep(); // Notify boundary vertices: @@ -580,8 +560,7 @@ void Arr_overlay_ss_visitor::after_sweep() template typename Arr_overlay_ss_visitor::Halfedge_handle Arr_overlay_ss_visitor:: -insert_in_face_interior(const X_monotone_curve_2& cv, Subcurve* sc) -{ +insert_in_face_interior(const X_monotone_curve_2& cv, Subcurve* sc) { // Insert the halfedge using the base construction visitor. Halfedge_handle new_he = Base::insert_in_face_interior(cv, sc); _map_halfedge_and_twin(new_he, @@ -615,8 +594,7 @@ typename Arr_overlay_ss_visitor::Halfedge_handle Arr_overlay_ss_visitor:: insert_from_left_vertex(const X_monotone_curve_2& cv, Halfedge_handle prev, - Subcurve* sc) -{ + Subcurve* sc) { _map_boundary_vertices(this->last_event_on_subcurve(sc), prev->target(), Has_identified_sides_category()); @@ -647,8 +625,7 @@ typename Arr_overlay_ss_visitor::Halfedge_handle Arr_overlay_ss_visitor:: insert_from_right_vertex(const X_monotone_curve_2& cv, Halfedge_handle prev, - Subcurve* sc) -{ + Subcurve* sc) { _map_boundary_vertices(this->current_event(), prev->target(), Has_identified_sides_category()); @@ -680,8 +657,7 @@ insert_at_vertices(const X_monotone_curve_2& cv, Halfedge_handle prev1, Halfedge_handle prev2, Subcurve* sc, - bool& new_face_created) -{ + bool& new_face_created) { // Insert the halfedge using the base construction visitor. Note that the // resulting halfedge is always incident to the new face (if one created). Halfedge_handle new_he = @@ -795,8 +771,7 @@ template typename Arr_overlay_ss_visitor::Vertex_handle Arr_overlay_ss_visitor:: insert_isolated_vertex(const Point_2& pt, - Status_line_iterator iter) -{ + Status_line_iterator iter) { // Insert the isolated vertex using the base construction visitor. Vertex_handle new_v = Base::insert_isolated_vertex(pt, iter); @@ -897,14 +872,13 @@ template void Arr_overlay_ss_visitor:: _map_halfedge_and_twin(Halfedge_handle he, Halfedge_handle_red red_he, - Halfedge_handle_blue blue_he) -{ + Halfedge_handle_blue blue_he) { if (he->direction() == ARR_LEFT_TO_RIGHT) he = he->twin(); // Obtain the twin red and blue halfedges (if they are valid). Note that // the original halfedges are always directed from right to left. - Halfedge_handle_red red_he_twin; - Halfedge_handle_blue blue_he_twin; + Halfedge_handle_red red_he_twin; + Halfedge_handle_blue blue_he_twin; if (red_he != Halfedge_handle_red()) red_he_twin = red_he->twin(); if (blue_he != Halfedge_handle_blue()) blue_he_twin = blue_he->twin(); @@ -922,8 +896,7 @@ _map_halfedge_and_twin(Halfedge_handle he, // template void Arr_overlay_ss_visitor:: -_map_boundary_vertices(Event* event, Vertex_handle v, std::bool_constant) -{ +_map_boundary_vertices(Event* event, Vertex_handle v, std::bool_constant) { // Update the red and blue object if the last event on sc is on the boundary. if ((event->parameter_space_in_x() != ARR_INTERIOR) || (event->parameter_space_in_y() != ARR_INTERIOR)) @@ -938,8 +911,7 @@ _map_boundary_vertices(Event* event, Vertex_handle v, std::bool_constant) if (red_handle_p) info.first = *red_handle_p; if (!std::get_if(&(info.first)) && - !std::get_if(&(info.second))) - { + !std::get_if(&(info.second))) { // If both, the red and blue, variants do not represent face handles, // they must represt either vertex or edge handles. In this case it is // safe to apply the call to the overlay traits and erase the record, @@ -974,8 +946,7 @@ void Arr_overlay_ss_visitor:: _create_vertex(Event* event, Vertex_handle new_v, Subcurve* sc, - std::bool_constant) -{ + std::bool_constant) { const Point_2& pt = event->point(); const Cell_handle_red* red_handle = pt.red_cell_handle(); const Cell_handle_blue* blue_handle = pt.blue_cell_handle(); @@ -983,8 +954,7 @@ _create_vertex(Event* event, // If the vertex is on the boundary, postpone the notification, but // update the red and objects in case they are empty. if ((event->parameter_space_in_x() != ARR_INTERIOR) || - (event->parameter_space_in_y() != ARR_INTERIOR)) - { + (event->parameter_space_in_y() != ARR_INTERIOR)) { if (!red_handle) { CGAL_assertion(blue_handle != nullptr); // Obtain the red face by looking for a subcurve above. @@ -1020,8 +990,7 @@ void Arr_overlay_ss_visitor:: _create_vertex(Event* event, Vertex_handle new_v, Subcurve* sc, - std::bool_constant) -{ + std::bool_constant) { const Point_2& pt = event->point(); const Cell_handle_red* red_handle = pt.red_cell_handle(); const Cell_handle_blue* blue_handle = pt.blue_cell_handle(); @@ -1063,8 +1032,7 @@ _create_vertex(Event* event, template void Arr_overlay_ss_visitor:: _create_edge(Subcurve* sc, - Halfedge_handle new_he) -{ + Halfedge_handle new_he) { // Note that the "red" and "blue" halfedges are always directed from right // to left, so we make sure the overlaid halfedge is also directed from // right to left. diff --git a/Boolean_set_operations_2/doc/Boolean_set_operations_2/Boolean_set_operations_2.txt b/Boolean_set_operations_2/doc/Boolean_set_operations_2/Boolean_set_operations_2.txt index 2a3b938bf2f..d1560584843 100644 --- a/Boolean_set_operations_2/doc/Boolean_set_operations_2/Boolean_set_operations_2.txt +++ b/Boolean_set_operations_2/doc/Boolean_set_operations_2/Boolean_set_operations_2.txt @@ -700,15 +700,29 @@ swap its source and target points). The traits classes `Arr_segment_traits_2`, `Arr_non_caching_segment_traits_2`, `Arr_circle_segment_traits_2`, `Arr_conic_traits_2` and `Arr_rational_function_traits_2`, which are -bundled in the `Arrangement_2` package and distributed with \cgal, -are all models of the refined concept -`AosDirectionalXMonotoneTraits_2`.\cgalFootnote{The \cgalFootnoteCode{Arr_polyline_traits_2} class is not a model of the, \cgalFootnoteCode{AosDirectionalXMonotoneTraits_2} concept, as the \f$ x\f$-monotone curve it defines is always directed from left to right. Thus, an opposite curve cannot be constructed. However, it is not very useful to construct a polygon whose edges are polylines, as an ordinary polygon with linear edges can represent the same entity.} +bundled in the `Arrangement_2` package and distributed with \cgal, are +all models of the refined concept +`AosDirectionalXMonotoneTraits_2`.\cgalFootnote{The +\cgalFootnoteCode{Arr_polyline_traits_2} class is not a model +of the, \cgalFootnoteCode{AosDirectionalXMonotoneTraits_2} concept, as +the \f$ x\f$-monotone curve it defines is always directed from left to +right. Thus, an opposite curve cannot be constructed. However, it is +not very useful to construct a polygon whose edges are polylines, as +an ordinary polygon with linear edges can represent the same entity.} -Just as with the case of computations using models of the -`AosXMonotoneTraits_2` concept, operations are robust only -when exact arithmetic is used. When inexact arithmetic is used, -(nearly) degenerate configurations may result in abnormal termination -of the program or even incorrect results. +Operations on polygons (or general polygons) are guaranteed to be +robust only if the operations of the geometry traits used to carry out +the high-level operations are robust. Most operations on polygons use +geometry traits constructors, as they generate new polygons; such +constructors are guaranteed to be robust only if the kernel in use +supports exact constructions, such as the EPEC (Exact Predicate Exact +Construction) kernel. The `do_intersect()` overloaded predicates that +operate on (linear) polygons are exceptions, as they only use geometry +traits predicates; such predicates are guaranteed to be robust only if +the kernel in use supports exact predicates, such as the EPIC (Exact +Predicate Inexact Construction) kernel. When inexact arithmetic is +used, (nearly) degenerate configurations may result in abnormal +termination of the program or even incorrect results. \subsection bso_sseccirc_seg Operating on Polygons with Circular Arcs diff --git a/Boolean_set_operations_2/doc/Boolean_set_operations_2/CGAL/Boolean_set_operations_2.h b/Boolean_set_operations_2/doc/Boolean_set_operations_2/CGAL/Boolean_set_operations_2.h index 4fd5c2c9e38..e4079111c1b 100644 --- a/Boolean_set_operations_2/doc/Boolean_set_operations_2/CGAL/Boolean_set_operations_2.h +++ b/Boolean_set_operations_2/doc/Boolean_set_operations_2/CGAL/Boolean_set_operations_2.h @@ -19,6 +19,10 @@ namespace CGAL { * 2.`void complement(const Type1& pgn, Type2& res, const GpsTraits& traits);` * * + * \tparam Kernel a model of the concept `PolygonTraits_2`. + * \tparam Container a model of the concept `Container`; defaults to `std::vector. + * \tparam ArrTraits a model of the concept `AosDirectionalXMonotoneTraits_2`. + * \tparam GpsTraits a model of the concept `GeneralPolygonSetTraits_2`, which must be convertible to `ArrTraits`. * \tparam UsePolylines determines whether the boundary of the input polygon is * treated as a cyclic sequence of single (\f$x\f$-monotone) segments or as a * cyclic sequence of (\f$x\f$-monotone) polylines. If substituted with @@ -28,7 +32,7 @@ namespace CGAL { * to a standard polygon. If substituted with `CGAL::Tag_false`, the input * polygon is used as is. Refer to \ref bso_ssectraits_sel for more information. * - * - The types `Type` and `Type2` of the parameters must be convertible to the + * - The types `Type1` and `Type2` of the parameters must be convertible to the * types specified in a row in the table below, respectively. * - The types that apply to signature (1.1.) above are restricted to those * listed in rows 1 and 2 in the table below. @@ -54,6 +58,8 @@ namespace CGAL { * \sa \link boolean_join `CGAL::join()` \endlink * \sa \link boolean_difference `CGAL::difference()` \endlink * \sa \link boolean_symmetric_difference `CGAL::symmetric_difference()` \endlink + * \sa Polygon_2 + * \sa Polygon_with_holes_2 */ /// @{ @@ -224,6 +230,10 @@ namespace CGAL { * 2.`OutputIterator difference(const Type1& pgn1, const Type2& pgn2, OutputIterator oi, const GpsTraits& traits);` * * + * \tparam Kernel a model of the concept `PolygonTraits_2` + * \tparam Container a model of the concept `Container`; defaults to `std::vector. + * \tparam ArrTraits a model of the concept `AosDirectionalXMonotoneTraits_2` + * \tparam GpsTraits a model of the concept `GeneralPolygonSetTraits_2`, which must be convertible to `ArrTraits`. * \tparam UsePolylines determines whether the boundaries of the input polygons * are treated as cyclic sequences of single (\f$x\f$-monotone) segments or as * cyclic sequences of (\f$x\f$-monotone) polylines. If substituted with @@ -264,6 +274,8 @@ namespace CGAL { * \sa \link boolean_intersection `CGAL::intersection()` \endlink * \sa \link boolean_join `CGAL::join()` \endlink * \sa \link boolean_symmetric_difference `CGAL::symmetric_difference()` \endlink + * \sa Polygon_2 + * \sa Polygon_with_holes_2 */ /// @{ @@ -660,48 +672,22 @@ namespace CGAL { * A function template in this group that accepts two input polygons has one of * the following signatures: * - * - * - * + * + * *
1.1.`bool do_intersect(const Type1& pgn1, const Type2& pgn2, UsePolylines = Tag_true());`
1.2.`bool do_intersect(const Type1& pgn1, const Type2& pgn2);`
2.`bool do_intersect(const Type1& pgn1, const Type2& pgn2, const GpsTraits& traits);`
1.`bool do_intersect(const Type1& pgn1, const Type2& pgn2);`
2.`bool do_intersect(const Type1& pgn1, const Type2& pgn2, const GpsTraits& traits);`
* * There are also function templates that accept one or two ranges of input polygons: * - * - * - * - * - * - * + * + * + * + * *
3.1.`bool do_intersect(InputIterator begin, InputIterator end, UsePolylines = Tag_true());`
3.2.`bool do_intersect(InputIterator begin, InputIterator end);`
4.`bool do_intersect(InputIterator begin, InputIterator end, const GpsTraits& traits);`
5.1.`bool do_intersect(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, InputIterator2 end2, UsePolylines = Tag_true());`
5.2.`bool do_intersect(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, InputIterator2 end2);`
6.`bool do_intersect(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, InputIterator2 end2, const GpsTraits& traits);`
3.`bool do_intersect(InputIterator begin, InputIterator end);`
4.`bool do_intersect(InputIterator begin, InputIterator end, const GpsTraits& traits);`
5.`bool do_intersect(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, InputIterator2 end2);`
6.`bool do_intersect(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, InputIterator2 end2, const GpsTraits& traits);`
* - * \tparam UsePolylines determines whether the boundary of the input polygons - * are treated as a cyclic sequence of single (\f$x\f$-monotone) segments or as - * a cyclic sequence of (\f$x\f$-monotone) polylines. If substituted with - * `CGAL::Tag_true`, which is the default, the input polygons are converted to - * general polygons bounded by polylines before the operation is actually - * performed. If substituted with `CGAL::Tag_false`, the input polygons are used - * as is. Refer to \ref bso_ssectraits_sel for more information. - * - * - The types `Type1` and `Type2` of the parameters of - * `InputIterator1::value_type` and `InputIterator2::value_type` must be - * convertible to the types specified in a row in the table below, - * respectively. - * - * - The types that apply to signatures (1.1.) and (5.1.) above - * are restricted to those listed in rows 1–4 in the table - * below. - * - * - The types that apply to signatures (1.2.) and (5.2.) above - * are restricted to those listed in rows 5–8 in the table - * below. - * - * - The type of `InputIterator::value_type` in (3.1.) above - * must be convertible to either `Polygon_2` or `Polygon_with_holes_2`. - * - * - The type of `InputIterator::value_type` in (3.2.) above must be - * convertible to either `General_polygon_2` or - * `General_polygon_with_holes_2`. + * \tparam Kernel a model of the concept `PolygonTraits_2`. + * \tparam Container a model of the concept `Container`; defaults to `std::vector. + * \tparam ArrTraits a model of the concept `AosDirectionalXMonotoneTraits_2`. + * \tparam GpsTraits a model of the concept `GeneralPolygonSetTraits_2`, which must be convertible to `ArrTraits`. * *
* @@ -728,6 +714,8 @@ namespace CGAL { * \sa \link boolean_join `CGAL::join()` \endlink * \sa \link boolean_difference `CGAL::difference()` \endlink * \sa \link boolean_symmetric_difference `CGAL::symmetric_difference()` \endlink + * \sa Polygon_2 + * \sa Polygon_with_holes_2 */ /// @{ @@ -735,6 +723,11 @@ namespace CGAL { //////// Traits-less /*! determines whether two polygons intersect in their interior. + * + * The kernel used to instantiate the type of the input polygons must support + * exact predicates to guarantee correct results; however, inexact constructions + * are tolerated. + * * \param pgn1 the 1st input polygon. * \param pgn2 the 2nd input polygon. * \return `true` if `pgn1` and `pgn2` intersect in their interior and `false` @@ -745,25 +738,11 @@ bool do_intersect(const Polygon_2& pgn1, const Polygon_2& pgn2); /*! determines whether two polygons intersect in their interior. - * \tparam UsePolylines determines whether the boundaries of `pgn1` and `pgn2` - * are treated as cyclic sequences of single (\f$x\f$-monotone) segments - * or as a cyclic sequences of (\f$x\f$-monotone) polylines. If - * substituted with `CGAL::Tag_true`, which is the default, `pgn1` and - * `pgn2` are converted to general polygons, bounded by polylines - * before the operation is actually performed. If substituted with - * `CGAL::Tag_false`, `pgn1` and `pgn2` are used as is. Refer to \ref - * bso_ssectraits_sel for more information. - * \param pgn1 the 1st input polygon. - * \param pgn2 the 2nd input polygon. - * \return `true` if `pgn1` and `pgn2` intersect in their interior and `false` - * otherwise. - */ -template -bool do_intersect(const Polygon_2& pgn1, - const Polygon_2& pgn2, - UsePolylines = Tag_true()); - -/*! determines whether two polygons intersect in their interior. + * + * The kernel used to instantiate the type of the input polygons must support + * exact predicates to guarantee correct results; however, inexact constructions + * are tolerated. + * * \param pgn1 the 1st input polygon. * \param pgn2 the 2nd input polygon. * \return `true` if `pgn1` and `pgn2` intersect in their interior and `false` @@ -774,26 +753,11 @@ bool do_intersect(const Polygon_2& pgn1, const Polygon_with_holes_2& pgn2); /*! determines whether two polygons intersect in their interior. - * \tparam UsePolylines determines whether the boundaries of `pgn1` and `pgn2` - * are treated as cyclic sequences of single (\f$x\f$-monotone) segments - * or as a cyclic sequences of (\f$x\f$-monotone) polylines. If - * substituted with `CGAL::Tag_true`, which is the default, `pgn1` and - * `pgn2` are converted to a general polygon and a general polygon - * with holes, respectively, bounded by polylines before the operation - * is actually performed. If substituted with `CGAL::Tag_false`, `pgn1` - * and `pgn2` are used as is. Refer to \ref bso_ssectraits_sel for more - * information. - * \param pgn1 the 1st input polygon. - * \param pgn2 the 2nd input polygon. - * \return `true` if `pgn1` and `pgn2` intersect in their interior and `false` - * otherwise. - */ -template -bool do_intersect(const Polygon_2& pgn1, - const Polygon_with_holes_2& pgn2, - UsePolylines = Tag_true()); - -/*! determines whether two polygons intersect in their interior. + * + * The kernel used to instantiate the type of the input polygons must support + * exact predicates to guarantee correct results; however, inexact constructions + * are tolerated. + * * \param pgn1 the 1st input polygon. * \param pgn2 the 2nd input polygon. * \return `true` if `pgn1` and `pgn2` intersect in their interior and `false` @@ -803,27 +767,12 @@ template bool do_intersect(const Polygon_with_holes_2& pgn1, const Polygon_2& pgn2); -/*! determines whether two polygons intersect in their interior. - * \tparam UsePolylines determines whether the boundaries of `pgn1` and `pgn2` - * are treated as cyclic sequences of single (\f$x\f$-monotone) segments - * or as a cyclic sequences of (\f$x\f$-monotone) polylines. If - * substituted with `CGAL::Tag_true`, which is the default, `pgn1` and - * `pgn2` are converted to a general polygon with holes and a general - * polygon, respectively, bounded by polylines before the operation - * is actually performed. If substituted with `CGAL::Tag_false`, `pgn1` - * and `pgn2` are used as is. Refer to \ref bso_ssectraits_sel for more - * information. - * \param pgn1 the 1st input polygon. - * \param pgn2 the 2nd input polygon. - * \return `true` if `pgn1` and `pgn2` intersect in their interior and `false` - * otherwise. - */ -template -bool do_intersect(const Polygon_with_holes_2& pgn1, - const Polygon_2& pgn2, - UsePolylines = Tag_true()); - /*! determines whether two polygons with holes intersect in their interior. + * + * The kernel used to instantiate the type of the input polygons must support + * exact predicates to guarantee correct results; however, inexact constructions + * are tolerated. + * * \param pgn1 the 1st input polygon. * \param pgn2 the 2nd input polygon. * \return `true` if `pgn1` and `pgn2` intersect in their interior and `false` @@ -833,25 +782,6 @@ template bool do_intersect(const Polygon_with_holes_2& pgn1, const Polygon_with_holes_2& pgn2); -/*! determines whether two polygons with holes intersect in their interior. - * \tparam UsePolylines determines whether the boundaries of `pgn1` and `pgn2` - * are treated as cyclic sequences of single (\f$x\f$-monotone) segments - * or as a cyclic sequences of (\f$x\f$-monotone) polylines. If - * substituted with `CGAL::Tag_true`, which is the default, `pgn1` and - * `pgn2` are converted to general polygon with holes , bounded by - * polylines before the operation is actually performed. If substituted - * with `CGAL::Tag_false`, `pgn1` and `pgn2` are used as is. Refer to - * \ref bso_ssectraits_sel for more information. - * \param pgn1 the 1st input polygon. - * \param pgn2 the 2nd input polygon. - * \return `true` if `pgn1` and `pgn2` intersect in their interior and `false` - * otherwise. - */ -template -bool do_intersect(const Polygon_with_holes_2& pgn1, - const Polygon_with_holes_2& pgn2, - UsePolylines = Tag_true()); - /*! determines whether two general polygons intersect in their interior. * \param pgn1 the 1st input polygon. * \param pgn2 the 2nd input polygon. @@ -904,6 +834,13 @@ bool do_intersect(const General_polygon_with_holes_2& pgn1, * of general polygons or a range of general polygons with holes) determines * whether the open polygons (respectively general polygons) in the range have a common * point. + * + * When the operation is applied to linear polygons (that is, the value type of + * the input iterator is either `Polygon_2` or `Polygon_with_holes_2`), the + * kernel used to instantiate the type of the input polygons must support exact + * predicates to guarantee correct results; however, inexact constructions are + * tolerated. + * * \param begin the first iterator of the input range. Its value type is * either `Polygon_2` (respectively `General_polygon_2`) or * `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`). @@ -917,36 +854,16 @@ bool do_intersect(const General_polygon_with_holes_2& pgn1, template bool do_intersect(InputIterator begin, InputIterator end); -/*! Given a range of polygons or a range of polygons with holes (respectively a range - * of general polygons or a range of general polygons with holes) determines - * whether the open polygons (respectively general polygons) in the range have a common - * point. - * \tparam UsePolylines determines whether the boundaries of the polygons in the - * input range are treated as cyclic sequences of single - * (\f$x\f$-monotone) segments or as a cyclic sequences of - * (\f$x\f$-monotone) polylines. If substituted with `CGAL::Tag_true`, - * which is the default, the input polygons are converted to general - * polygon with holes , bounded by polylines before the operation is - * actually performed. If substituted with `CGAL::Tag_false`, `pgn1` and - * `pgn2` are used as is. Refer to \ref bso_ssectraits_sel for more - * information. - * \param begin the first iterator of the input range. Its value type is - * either `Polygon_2` (respectively `General_polygon_2`) or - * `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`). - * \param end the past-the-end iterator of the input range. Its value type is - * either `Polygon_2` (respectively `General_polygon_2`) or - * `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`). - * \return `true` if the pairwise intersections of all open polygons or polygons - * with holes (respectively general polygons or general polygons with holes) in - * the range [*begin,*end) overlap, and `false` otherwise. - */ -template -bool do_intersect(InputIterator begin, InputIterator end, - UsePolylines = Tag_true()); - /*! Given a range of polygons (respectively general polygons) and a range of polygons * with holes (respectively general polygons with holes) determines whether the open * polygons (respectively general polygons) in the two ranges have a common point. + * + * When the operation is applied to linear polygons (that is, the value type of + * any input iterator is either `Polygon_2` or `Polygon_with_holes_2`), the + * kernel used to instantiate the type of the input polygons must support exact + * predicates to guarantee correct results; however, inexact constructions are + * tolerated. + * * \param begin1 the first iterator of the 1st input range. Its value type is * `Polygon_2` (respectively `General_polygon_2`). * \param end1 the past-the-end iterator of the 1st input range. Its value @@ -964,40 +881,14 @@ template bool do_intersect(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, InputIterator2 end2); -/*! Given a range of polygons (respectively general polygons) and a range of polygons - * with holes (respectively general polygons with holes) determines whether the open - * polygons (respectively general polygons) in the two ranges have a common point. - * \tparam UsePolylines determines whether the boundaries of the polygons in the - * input ranges are treated as cyclic sequences of single - * (\f$x\f$-monotone) segments or as a cyclic sequences of - * (\f$x\f$-monotone) polylines. If substituted with `CGAL::Tag_true`, - * which is the default, the input polygons are converted to general - * polygon with holes , bounded by polylines before the operation is - * actually performed. If substituted with `CGAL::Tag_false`, `pgn1` and - * `pgn2` are used as is. Refer to \ref bso_ssectraits_sel for more - * information. - * \param begin1 the first iterator of the 1st input range. Its value type is - * `Polygon_2` (respectively `General_polygon_2`). - * \param end1 the past-the-end iterator of the 1st input range. Its value - * type is `Polygon_2` (respectively `General_polygon_2`). - * \param begin2 the first iterator of the 2nd input range. Its value type - * is `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`). - * \param end2 the past-the-end iterator of the 2nd input range. Its value - * type is `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`). - * \return `true` if the pairwise intersections of all open polygons (respectively - * general polygons) and polygons with holes (respectively general polygons with - * holes) in the ranges [*begin1,*end1) and [*begin2,*end2), - * respectively, overlap, and `false` otherwise. - */ -template -bool do_intersect(InputIterator1 begin1, InputIterator1 end1, - InputIterator2 begin2, InputIterator2 end2, - UsePolylines = Tag_true()); - //////// With Traits /*! determines whether two polygons intersect in their interior. + * + * The kernel used to instantiate the type of the input polygons must support + * exact predicates to guarantee correct results; however, inexact constructions + * are tolerated. + * * \param pgn1 the 1st input polygon. * \param pgn2 the 2nd input polygon. * \param traits a traits object. @@ -1011,6 +902,11 @@ bool do_intersect(const Polygon_2& pgn1, const GpsTraits& traits); /*! determines whether two polygons intersect in their interior. + * + * The kernel used to instantiate the type of the input polygons must support + * exact predicates to guarantee correct results; however, inexact constructions + * are tolerated. + * * \param pgn1 the 1st input polygon. * \param pgn2 the 2nd input polygon. * \param traits a traits object. @@ -1021,10 +917,14 @@ bool do_intersect(const Polygon_2& pgn1, template bool do_intersect(const Polygon_2& pgn1, const Polygon_with_holes_2& pgn2, - const GpsTraits& traits, const GpsTraits& traits); /*! determines whether two polygons intersect in their interior. + * + * The kernel used to instantiate the type of the input polygons must support + * exact predicates to guarantee correct results; however, inexact constructions + * are tolerated. + * * \param pgn1 the 1st input polygon. * \param pgn2 the 2nd input polygon. * \param traits a traits object. @@ -1038,6 +938,11 @@ bool do_intersect(const Polygon_with_holes_2& pgn1, const GpsTraits& traits); /*! determines whether two polygons with holes intersect in their interior. + * + * The kernel used to instantiate the type of the input polygons must support + * exact predicates to guarantee correct results; however, inexact constructions + * are tolerated. + * * \param pgn1 the 1st input polygon. * \param pgn2 the 2nd input polygon. * \param traits a traits object. @@ -1116,6 +1021,12 @@ bool do_intersect(const General_polygon_with_holes_2& pgn1, * of general polygons or a range of general polygons with holes) determines * whether the open polygons (respectively general polygons) in the range have a common * point. + * + * When the operation is applied to linear polygons (that is, the value type of + * the input iterator is either `Polygon_2` or `Polygon_with_holes_2`), the + * traits parameter `GpsTraits` must support exact predicates to guarantee + * correct results; however, inexact constructions are tolerated. + * * \param begin the first iterator of the input range. Its value type is * either `Polygon_2` (respectively `General_polygon_2`) or * `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`). @@ -1135,6 +1046,12 @@ bool do_intersect(InputIterator begin, InputIterator end, /*! Given a range of polygons (respectively general polygons) and a range of polygons * with holes (respectively general polygons with holes) determines whether the open * polygons (respectively general polygons) in the two ranges have a common point. + * + * When the operation is applied to linear polygons (that is, the value type of + * any input iterator is either `Polygon_2` or `Polygon_with_holes_2`), the + * traits parameter `GpsTraits` must support exact predicates to guarantee + * correct results; however, inexact constructions are tolerated. + * * \param begin1 the first iterator of the 1st input range. Its value type is * `Polygon_2` (respectively `General_polygon_2`). * \param end1 the past-the-end iterator of the 1st input range. Its value @@ -1186,6 +1103,10 @@ namespace CGAL { * *
6.`OutputIterator intersection(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, InputIterator2 end2, OutputIterator oi, const GpsTraits& traits);`
* + * \tparam Kernel a model of the concept `PolygonTraits_2`. + * \tparam Container a model of the concept `Container`; defaults to `std::vector. + * \tparam ArrTraits a model of the concept `AosDirectionalXMonotoneTraits_2`. + * \tparam GpsTraits a model of the concept `GeneralPolygonSetTraits_2`, which must be convertible to `ArrTraits`. * \tparam UsePolylines determines whether the boundaries of the input polygons * are treated as cyclic sequences of single (\f$x\f$-monotone) segments or as * cyclic sequences of (\f$x\f$-monotone) polylines. If substituted with @@ -1244,6 +1165,8 @@ namespace CGAL { * \sa \link boolean_join `CGAL::join()` \endlink * \sa \link boolean_difference `CGAL::difference()` \endlink * \sa \link boolean_symmetric_difference `CGAL::symmetric_difference()` \endlink + * \sa Polygon_2 + * \sa Polygon_with_holes_2 */ /// @{ @@ -1825,6 +1748,10 @@ namespace CGAL { * 6.`OutputIterator join(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, InputIterator2 end2, OutputIterator oi, const GpsTraits& traits);` * * + * \tparam Kernel a model of the concept `PolygonTraits_2`. + * \tparam Container a model of the concept `Container`; defaults to `std::vector. + * \tparam ArrTraits a model of the concept `AosDirectionalXMonotoneTraits_2`. + * \tparam GpsTraits a model of the concept `GeneralPolygonSetTraits_2`, which must be convertible to `ArrTraits`. * \tparam UsePolylines determines whether the boundaries of the input polygons * are treated as cyclic sequences of single (\f$x\f$-monotone) segments or as * cyclic sequences of (\f$x\f$-monotone) polylines. If substituted with @@ -1882,6 +1809,8 @@ namespace CGAL { * \sa \link boolean_intersection `CGAL::intersection()` \endlink * \sa \link boolean_difference `CGAL::difference()` \endlink * \sa \link boolean_symmetric_difference `CGAL::symmetric_difference()` \endlink + * \sa Polygon_2 + * \sa Polygon_with_holes_2 */ /// @{ @@ -2407,6 +2336,10 @@ namespace CGAL { * 4.`Oriented_side oriented_side(const Point_2& p, const Type& pgn, const GpsTraits& traits);` * * + * \tparam Kernel a model of the concept `PolygonTraits_2`. + * \tparam Container a model of the concept `Container`; defaults to `std::vector. + * \tparam ArrTraits a model of the concept `AosDirectionalXMonotoneTraits_2`. + * \tparam GpsTraits a model of the concept `GeneralPolygonSetTraits_2`, which must be convertible to `ArrTraits`. * \tparam UsePolylines determines whether the boundaries of the input polygons * are treated as cyclic sequences of single (\f$x\f$-monotone) segments or as * cyclic sequences of (\f$x\f$-monotone) polylines. If substituted with @@ -2446,6 +2379,8 @@ namespace CGAL { * \param traits an optional traits object. * * \sa \link boolean_do_intersect `CGAL::do_intersect()` \endlink + * \sa Polygon_2 + * \sa Polygon_with_holes_2 */ /// @{ @@ -2823,6 +2758,10 @@ namespace CGAL { * 6.`OutputIterator symmetric_difference(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, InputIterator2 end2, OutputIterator oi, const GpsTraits& traits);` * * + * \tparam Kernel a model of the concept `PolygonTraits_2`. + * \tparam Container a model of the concept `Container`; defaults to `std::vector. + * \tparam ArrTraits a model of the concept `AosDirectionalXMonotoneTraits_2`. + * \tparam GpsTraits a model of the concept `GeneralPolygonSetTraits_2`, which must be convertible to `ArrTraits`. * \tparam UsePolylines determines whether the boundaries of the input polygons * are treated as cyclic sequences of single (\f$x\f$-monotone) segments or as * cyclic sequences of (\f$x\f$-monotone) polylines. If substituted with @@ -2879,6 +2818,8 @@ namespace CGAL { * \sa \link boolean_intersection `CGAL::intersection()` \endlink * \sa \link boolean_join `CGAL::join()` \endlink * \sa \link boolean_difference `CGAL::difference()` \endlink + * \sa Polygon_2 + * \sa Polygon_with_holes_2 */ /// @{ diff --git a/Boolean_set_operations_2/examples/Boolean_set_operations_2/do_intersect.cpp b/Boolean_set_operations_2/examples/Boolean_set_operations_2/do_intersect.cpp index f242cf9c89c..cd2661e152f 100644 --- a/Boolean_set_operations_2/examples/Boolean_set_operations_2/do_intersect.cpp +++ b/Boolean_set_operations_2/examples/Boolean_set_operations_2/do_intersect.cpp @@ -5,27 +5,26 @@ #include #include -typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel; -typedef Kernel::Point_2 Point_2; -typedef CGAL::Polygon_2 Polygon_2; +using Kernel = CGAL::Exact_predicates_exact_constructions_kernel; +using Point_2 = Kernel::Point_2; +using Polygon_2 = CGAL::Polygon_2; #include "print_utils.h" -int main () -{ +int main() { Polygon_2 P; - P.push_back (Point_2 (-1,1)); - P.push_back (Point_2 (0,-1)); - P.push_back (Point_2 (1,1)); - std::cout << "P = "; print_polygon (P); + P.push_back(Point_2(-1, 1)); + P.push_back(Point_2(0, -1)); + P.push_back(Point_2(1, 1)); + std::cout << "P = "; print_polygon(P); Polygon_2 Q; - Q.push_back(Point_2 (-1,-1)); - Q.push_back(Point_2 (1,-1)); - Q.push_back(Point_2 (0,1)); - std::cout << "Q = "; print_polygon (Q); + Q.push_back(Point_2(-1, -1)); + Q.push_back(Point_2(1, -1)); + Q.push_back(Point_2(0, 1)); + std::cout << "Q = "; print_polygon(Q); - if ((CGAL::do_intersect (P, Q))) + if ((CGAL::do_intersect(P, Q))) std::cout << "The two polygons intersect in their interior." << std::endl; else std::cout << "The two polygons do not intersect." << std::endl; diff --git a/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Bso_internal_functions.h b/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Bso_internal_functions.h index d463c2dbbf0..875995c4f8e 100644 --- a/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Bso_internal_functions.h +++ b/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Bso_internal_functions.h @@ -8,10 +8,10 @@ // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // // -// Author(s): Baruch Zukerman -// Ron Wein -// Efi Fogel -// Simon Giraudot +// Author(s) : Baruch Zukerman +// Ron Wein +// Efi Fogel +// Simon Giraudot #ifndef CGAL_BSO_INTERNAL_FUNCTIONS_H #define CGAL_BSO_INTERNAL_FUNCTIONS_H @@ -33,7 +33,7 @@ namespace CGAL { // Single // With Traits -template +template inline bool s_do_intersect(const Pgn1& pgn1, const Pgn2& pgn2, Traits& traits) { General_polygon_set_2 gps(pgn1, traits); return gps.do_intersect(pgn2); @@ -52,7 +52,7 @@ inline bool s_do_intersect(const Pgn1& pgn1, const Pgn2& pgn2) { // With Traits template inline bool r_do_intersect(InputIterator begin, InputIterator end, - Traits& traits, unsigned int k=5) { + Traits& traits, std::size_t k = 5) { if (begin == end) return false; General_polygon_set_2 gps(*begin, traits); return gps.do_intersect(std::next(begin), end, k); @@ -61,8 +61,8 @@ inline bool r_do_intersect(InputIterator begin, InputIterator end, // Without Traits template inline bool r_do_intersect(InputIterator begin, InputIterator end, - unsigned int k=5) { - typedef typename std::iterator_traits::value_type Pgn; + std::size_t k = 5) { + using Pgn = typename std::iterator_traits::value_type; typename Gps_polyline_traits::Traits traits; const typename Gps_polyline_traits::Polyline_traits& ptraits(traits); return r_do_intersect(convert_polygon_iterator(begin, ptraits), @@ -74,7 +74,7 @@ inline bool r_do_intersect(InputIterator begin, InputIterator end, template inline bool r_do_intersect(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, InputIterator2 end2, - Traits& traits, unsigned int k=5) { + Traits& traits, std::size_t k = 5) { if (begin1 == end1) return do_intersect(begin2, end2, traits, k); General_polygon_set_2 gps(*begin1, traits); return gps.do_intersect(std::next(begin1), end1, begin2, end2, k); @@ -84,8 +84,8 @@ inline bool r_do_intersect(InputIterator1 begin1, InputIterator1 end1, template inline bool r_do_intersect (InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, InputIterator2 end2, - unsigned int k=5) { - typedef typename std::iterator_traits::value_type Pgn; + std::size_t k = 5) { + using Pgn = typename std::iterator_traits::value_type; typename Gps_polyline_traits::Traits traits; const typename Gps_polyline_traits::Polyline_traits& ptraits(traits); return r_do_intersect(convert_polygon_iterator(begin1, ptraits), @@ -119,8 +119,7 @@ inline Oriented_side _oriented_side(const Point_2& point, // Without Traits (polygon, polygon) template -inline Oriented_side _oriented_side(const Pgn1& pgn1, const Pgn2& pgn2) -{ +inline Oriented_side _oriented_side(const Pgn1& pgn1, const Pgn2& pgn2) { // Use the first polygon to determine the (default) traits typename Gps_polyline_traits::Traits traits; const typename Gps_polyline_traits::Polyline_traits& ptraits(traits); @@ -149,7 +148,7 @@ template ::Polyline_traits Polyline_traits; + using Polyline_traits = typename Gps_polyline_traits::Polyline_traits; typename Gps_polyline_traits::Traits traits; const Polyline_traits& ptraits(traits); @@ -163,7 +162,7 @@ inline OutputIterator s_intersection(const Pgn1& pgn1, const Pgn2& pgn2, template inline OutputIterator r_intersection(InputIterator begin, InputIterator end, OutputIterator oi, Traits& traits, - unsigned int k=5) { + std::size_t k = 5) { if (begin == end) return (oi); General_polygon_set_2 gps(*begin, traits); gps.intersection(std::next(begin), end, k); @@ -173,8 +172,8 @@ inline OutputIterator r_intersection(InputIterator begin, InputIterator end, // Without Traits template inline OutputIterator r_intersection(InputIterator begin, InputIterator end, - OutputIterator oi, unsigned int k=5) { - typedef typename std::iterator_traits::value_type Pgn; + OutputIterator oi, std::size_t k = 5) { + using Pgn = typename std::iterator_traits::value_type; typename Gps_polyline_traits::Traits traits; const typename Gps_polyline_traits::Polyline_traits& ptraits(traits); if (begin == end) return (oi); @@ -190,7 +189,7 @@ template gps(*begin1, traits); gps.intersection(std::next(begin1), end1, begin2, end2, k); @@ -203,8 +202,8 @@ template ::value_type Pgn; + OutputIterator oi, std::size_t k = 5) { + using Pgn = typename std::iterator_traits::value_type; typename Gps_polyline_traits::Traits traits; const typename Gps_polyline_traits::Polyline_traits& ptraits(traits); if (begin1 == end1) { @@ -228,7 +227,7 @@ r_intersection(InputIterator1 begin1, InputIterator1 end1, // Polygon_2 template inline bool _is_empty(const typename Traits::Polygon_2& pgn, Traits& traits) { - typedef typename Traits::Curve_const_iterator Curve_const_iterator; + using Curve_const_iterator = typename Traits::Curve_const_iterator; const std::pair& itr_pair = traits.construct_curves_2_object()(pgn); return (itr_pair.first == itr_pair.second); @@ -268,9 +267,9 @@ template inline bool s_join(const Pgn1& pgn1, const Pgn2& pgn2, Pwh& pwh) { // Use the first polygon to determine the (default) traits - typedef typename Gps_polyline_traits::Polyline_traits Polyline_traits; - typedef General_polygon_2 General_pgn; - typedef General_polygon_with_holes_2 General_pwh; + using Polyline_traits = typename Gps_polyline_traits::Polyline_traits; + using General_pgn = General_polygon_2; + using General_pwh = General_polygon_with_holes_2; General_pwh general_pwh; typename Gps_polyline_traits::Traits traits; @@ -287,7 +286,7 @@ inline bool s_join(const Pgn1& pgn1, const Pgn2& pgn2, Pwh& pwh) { template inline OutputIterator r_join(InputIterator begin, InputIterator end, OutputIterator oi, Traits& traits, - unsigned int k=5) { + std::size_t k = 5) { if (begin == end) return oi; General_polygon_set_2 gps(*begin, traits); gps.join(std::next(begin), end, k); @@ -297,8 +296,8 @@ inline OutputIterator r_join(InputIterator begin, InputIterator end, // Without traits template inline OutputIterator r_join(InputIterator begin, InputIterator end, - OutputIterator oi, unsigned int k=5) { - typedef typename std::iterator_traits::value_type Pgn; + OutputIterator oi, std::size_t k = 5) { + using Pgn = typename std::iterator_traits::value_type; typename Gps_polyline_traits::Traits traits; const typename Gps_polyline_traits::Polyline_traits& ptraits(traits); @@ -316,7 +315,7 @@ template gps(*begin1, traits); gps.join(std::next(begin1), end1, begin2, end2, k); @@ -328,8 +327,8 @@ template inline OutputIterator r_join(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, InputIterator2 end2, - OutputIterator oi, unsigned int k=5) { - typedef typename std::iterator_traits::value_type Pgn; + OutputIterator oi, std::size_t k = 5) { + using Pgn = typename std::iterator_traits::value_type; typename Gps_polyline_traits::Traits traits; const typename Gps_polyline_traits::Polyline_traits& ptraits(traits); if (begin1 == end1) { @@ -361,10 +360,9 @@ inline OutputIterator _difference(const Pgn1& pgn1, const Pgn2& pgn2, template inline OutputIterator _difference(const Pgn1& pgn1, const Pgn2& pgn2, - OutputIterator oi) -{ + OutputIterator oi) { // Use the first polygon to determine the (default) traits - typedef typename Gps_polyline_traits::Polyline_traits Polyline_traits; + using Polyline_traits = typename Gps_polyline_traits::Polyline_traits; typename Gps_polyline_traits::Traits traits; const Polyline_traits& ptraits(traits); @@ -394,7 +392,7 @@ template ::Polyline_traits Polyline_traits; + using Polyline_traits = typename Gps_polyline_traits::Polyline_traits; typename Gps_polyline_traits::Traits traits; const Polyline_traits& ptraits(traits); s_symmetric_difference(convert_polygon(pgn1, ptraits), @@ -409,7 +407,7 @@ template inline OutputIterator r_symmetric_difference(InputIterator begin, InputIterator end, OutputIterator oi, Traits& traits, - unsigned int k=5) { + std::size_t k = 5) { if (begin == end) return (oi); General_polygon_set_2 gps(*begin, traits); gps.symmetric_difference(std::next(begin), end, k); @@ -421,9 +419,8 @@ template inline OutputIterator r_symmetric_difference(InputIterator begin, InputIterator end, OutputIterator oi, - unsigned int k=5) -{ - typedef typename std::iterator_traits::value_type Pgn; + std::size_t k = 5) { + using Pgn = typename std::iterator_traits::value_type; typename Gps_polyline_traits::Traits traits; const typename Gps_polyline_traits::Polyline_traits& ptraits(traits); if (begin == end) return (oi); @@ -441,8 +438,7 @@ inline OutputIterator r_symmetric_difference(InputIterator1 begin1, InputIterator2 begin2, InputIterator2 end2, OutputIterator oi, Traits& traits, - unsigned int k=5) -{ + std::size_t k = 5) { if (begin1 == end1) return r_symmetric_difference(begin2, end2, oi, traits, k); General_polygon_set_2 gps(*begin1, traits); gps.symmetric_difference(std::next(begin1), end1, begin2, end2, k); @@ -457,8 +453,8 @@ inline OutputIterator r_symmetric_difference(InputIterator1 begin1, InputIterator2 begin2, InputIterator2 end2, OutputIterator oi, - unsigned int k=5) { - typedef typename std::iterator_traits::value_type Pgn; + std::size_t k = 5) { + using Pgn = typename std::iterator_traits::value_type; typename Gps_polyline_traits::Traits traits; const typename Gps_polyline_traits::Polyline_traits& ptraits(traits); if (begin1 == end1){ @@ -522,10 +518,10 @@ OutputIterator _complement(const General_polygon_with_holes_2& pgn, template void _complement(const Polygon_2& pgn, Pwh& pwh) { // Use the polygon to determine the (default) traits - typedef Polygon_2 Pgn; - typedef typename Gps_polyline_traits::Polyline_traits Polyline_traits; - typedef General_polygon_2 General_pgn; - typedef General_polygon_with_holes_2 General_pwh; + using Pgn = Polygon_2; + using Polyline_traits = typename Gps_polyline_traits::Polyline_traits; + using General_pgn = General_polygon_2; + using General_pwh = General_polygon_with_holes_2; General_pwh general_pwh; typename Gps_polyline_traits::Traits traits; @@ -539,8 +535,8 @@ template OutputIterator _complement(const Polygon_with_holes_2& pgn, OutputIterator oi) { // Use the polygon with holes to determine the (default) traits - typedef Polygon_with_holes_2 Pgn; - typedef typename Gps_polyline_traits::Polyline_traits Polyline_traits; + using Pgn = Polygon_with_holes_2; + using Polyline_traits = typename Gps_polyline_traits::Polyline_traits; typename Gps_polyline_traits::Traits traits; const Polyline_traits& ptraits(traits); diff --git a/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_agg_meta_traits.h b/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_agg_meta_traits.h index e4d6936e78f..54e19d69c21 100644 --- a/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_agg_meta_traits.h +++ b/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_agg_meta_traits.h @@ -7,12 +7,11 @@ // $Id$ // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // -// -// Author(s): Baruch Zukerman -// Efi Fogel +// Author(s) : Baruch Zukerman +// Efi Fogel -#ifndef CGAL_BSO_2_GPS_AGG_META_TRAITS_H -#define CGAL_BSO_2_GPS_AGG_META_TRAITS_H +#ifndef CGAL_GPS_AGG_META_TRAITS_H +#define CGAL_GPS_AGG_META_TRAITS_H #include @@ -24,18 +23,17 @@ namespace CGAL { template -class Gps_agg_curve_data : public Curve_with_halfedge -{ +class Gps_agg_curve_data : public Curve_with_halfedge { protected: - typedef Arrangement_ Arrangement; - typedef typename Arrangement::Halfedge_handle Halfedge_handle; - typedef Curve_with_halfedge Base; + using Arrangement = Arrangement_; + using Halfedge_handle = typename Arrangement::Halfedge_handle; + using Base = Curve_with_halfedge; const Arrangement* m_arr; // pointer to the arrangement containing the edge. - unsigned int m_bc; // the boundary counter of the halfedge with the same + std::size_t m_bc; // the boundary counter of the halfedge with the same // direction as the curve - unsigned int m_twin_bc; // the boundary counter of the halfedge with the same + std::size_t m_twin_bc; // the boundary counter of the halfedge with the same // direction as the curve public: @@ -47,24 +45,24 @@ public: {} Gps_agg_curve_data(const Arrangement* arr, Halfedge_handle he, - unsigned int bc, unsigned int twin_bc) : + std::size_t bc, std::size_t twin_bc) : Base(he), m_arr(arr), m_bc(bc), m_twin_bc(twin_bc) {} - unsigned int bc() const { return m_bc; } + std::size_t bc() const { return m_bc; } - unsigned int twin_bc() const { return m_twin_bc; } + std::size_t twin_bc() const { return m_twin_bc; } - unsigned int& bc() { return m_bc; } + std::size_t& bc() { return m_bc; } - unsigned int& twin_bc() { return m_twin_bc; } + std::size_t& twin_bc() { return m_twin_bc; } - void set_bc(unsigned int bc) { m_bc = bc; } + void set_bc(std::size_t bc) { m_bc = bc; } - void set_twin_bc(unsigned int twin_bc) { m_twin_bc = twin_bc; } + void set_twin_bc(std::size_t twin_bc) { m_twin_bc = twin_bc; } const Arrangement* arr() const { return m_arr; } }; @@ -73,54 +71,50 @@ template class Gps_agg_meta_traits : public Gps_traits_decorator, - Point_with_vertex > -{ - typedef Arrangement_ Arrangement; - typedef Arrangement Arr; + Point_with_vertex> { + using Arrangement = Arrangement_; + using Arr = Arrangement; - typedef typename Arr::Traits_adaptor_2 Traits; - typedef Traits Gt2; + using Traits = typename Arr::Traits_adaptor_2; + using Gt2 = Traits; - typedef typename Gt2::X_monotone_curve_2 Base_x_monotone_curve_2; - typedef typename Gt2::Point_2 Base_point_2; - typedef typename Gt2::Construct_min_vertex_2 Base_Construct_min_vertex_2; - typedef typename Gt2::Construct_max_vertex_2 Base_Construct_max_vertex_2; - typedef typename Gt2::Compare_endpoints_xy_2 Base_Compare_endpoints_xy_2; - typedef typename Gt2::Compare_xy_2 Base_Compare_xy_2; - typedef typename Gt2::Compare_y_at_x_right_2 Base_Compare_y_at_x_right_2; - typedef typename Gt2::Compare_y_at_x_2 Base_Compare_y_at_x_2; - typedef typename Gt2::Intersect_2 Base_Intersect_2; - typedef typename Gt2::Split_2 Base_Split_2; + using Base_x_monotone_curve_2 = typename Gt2::X_monotone_curve_2; + using Base_point_2 = typename Gt2::Point_2; + using Base_Construct_min_vertex_2 = typename Gt2::Construct_min_vertex_2; + using Base_Construct_max_vertex_2 = typename Gt2::Construct_max_vertex_2; + using Base_Compare_endpoints_xy_2 = typename Gt2::Compare_endpoints_xy_2; + using Base_Compare_xy_2 = typename Gt2::Compare_xy_2; + using Base_Compare_y_at_x_right_2 = typename Gt2::Compare_y_at_x_right_2; + using Base_Compare_y_at_x_2 = typename Gt2::Compare_y_at_x_2; + using Base_Intersect_2 = typename Gt2::Intersect_2; + using Base_Split_2 = typename Gt2::Split_2; - typedef typename Gt2::Parameter_space_in_x_2 Base_Parameter_space_in_x_2; - typedef typename Gt2::Compare_y_near_boundary_2 - Base_Compare_y_near_boundary_2; + using Base_Parameter_space_in_x_2 = typename Gt2::Parameter_space_in_x_2; + using Base_Compare_y_near_boundary_2 = typename Gt2::Compare_y_near_boundary_2; - typedef typename Gt2::Parameter_space_in_y_2 Base_Parameter_space_in_y_2; - typedef typename Gt2::Compare_x_near_boundary_2 - Base_Compare_x_near_boundary_2; + using Base_Parameter_space_in_y_2 = typename Gt2::Parameter_space_in_y_2; + using Base_Compare_x_near_boundary_2 = typename Gt2::Compare_x_near_boundary_2; public: - typedef typename Gt2::Multiplicity Multiplicity; - typedef Gps_agg_curve_data Curve_data; - typedef Point_with_vertex Point_data; + using Multiplicity = typename Gt2::Multiplicity; + using Curve_data = Gps_agg_curve_data; + using Point_data = Point_with_vertex; private: - typedef Gps_agg_meta_traits Self; - typedef Gps_traits_decorator Base; + using Self = Gps_agg_meta_traits; + using Base = Gps_traits_decorator; public: - typedef typename Base::X_monotone_curve_2 X_monotone_curve_2; - typedef typename Base::Point_2 Point_2; - typedef typename Gt2::Has_left_category Has_left_category; - typedef typename Gt2::Has_merge_category Has_merge_category; - typedef typename Gt2::Has_do_intersect_category - Has_do_intersect_category; + using X_monotone_curve_2 = typename Base::X_monotone_curve_2; + using Point_2 = typename Base::Point_2; + using Has_left_category = typename Gt2::Has_left_category; + using Has_merge_category = typename Gt2::Has_merge_category; + using Has_do_intersect_category = typename Gt2::Has_do_intersect_category; - typedef typename Arr::Left_side_category Left_side_category; - typedef typename Arr::Bottom_side_category Bottom_side_category; - typedef typename Arr::Top_side_category Top_side_category; - typedef typename Arr::Right_side_category Right_side_category; + using Left_side_category = typename Arr::Left_side_category; + using Bottom_side_category = typename Arr::Bottom_side_category; + using Top_side_category = typename Arr::Top_side_category; + using Right_side_category = typename Arr::Right_side_category; // a side is either oblivious or open (unbounded) static_assert(std::is_same::value || @@ -132,8 +126,8 @@ public: static_assert(std::is_same::value || std::is_same::value); - typedef typename Arr::Halfedge_handle Halfedge_handle; - typedef typename Arr::Vertex_handle Vertex_handle; + using Halfedge_handle = typename Arr::Halfedge_handle; + using Vertex_handle = typename Arr::Vertex_handle; Gps_agg_meta_traits() {} @@ -152,16 +146,13 @@ public: template OutputIterator operator()(const X_monotone_curve_2& cv1, const X_monotone_curve_2& cv2, - OutputIterator oi) const - { + OutputIterator oi) const { // Check whether the curves are already in the same arrangement, and thus // must be interior-disjoint if (cv1.data().arr() == cv2.data().arr()) return oi; - typedef const std::pair - Intersection_base_point; - typedef std::variant - Intersection_base_result; + using Intersection_base_point = const std::pair; + using Intersection_base_result = std::variant; const auto* base_traits = m_traits.m_base_traits; auto base_cmp_xy = base_traits->compare_xy_2_object(); @@ -191,8 +182,8 @@ public: const Base_x_monotone_curve_2* overlap_cv = std::get_if(&xection); CGAL_assertion(overlap_cv != nullptr); - unsigned int ov_bc; - unsigned int ov_twin_bc; + std::size_t ov_bc; + std::size_t ov_twin_bc; if (base_cmp_endpoints(cv1) == base_cmp_endpoints(cv2)) { // cv1 and cv2 have the same directions ov_bc = cv1.data().bc() + cv2.data().bc(); @@ -230,8 +221,7 @@ public: Split_2(const Base_Split_2& base) : m_base_split(base) {} void operator()(const X_monotone_curve_2& cv, const Point_2 & p, - X_monotone_curve_2& c1, X_monotone_curve_2& c2) const - { + X_monotone_curve_2& c1, X_monotone_curve_2& c2) const { m_base_split(cv.base(), p.base(), c1.base(), c2.base()); const Curve_data& cv_data = cv.data(); c1.set_data(Curve_data(cv_data.arr(), Halfedge_handle(), cv_data.bc(), @@ -259,8 +249,7 @@ public: * \param cv The curve. * \return The left endpoint. */ - Point_2 operator()(const X_monotone_curve_2 & cv) const - { + Point_2 operator()(const X_monotone_curve_2 & cv) const { if (cv.data().halfedge() == Halfedge_handle()) return (Point_2(m_base(cv.base()))); @@ -272,8 +261,7 @@ public: }; /*! Get a Construct_min_vertex_2 functor object. */ - Construct_min_vertex_2 construct_min_vertex_2_object() const - { + Construct_min_vertex_2 construct_min_vertex_2_object() const { return Construct_min_vertex_2(this->m_base_traits-> construct_min_vertex_2_object()); } @@ -285,15 +273,14 @@ public: public: Construct_max_vertex_2(const Base_Construct_max_vertex_2& base) : - m_base(base) + m_base(base) {} /*! Obtain the right endpoint of the x-monotone curve (segment). * \param cv The curve. * \return The right endpoint. */ - Point_2 operator()(const X_monotone_curve_2& cv) const - { + Point_2 operator()(const X_monotone_curve_2& cv) const { if (cv.data().halfedge() == Halfedge_handle()) return (Point_2(m_base(cv.base()))); @@ -304,8 +291,7 @@ public: }; /*! Get a Construct_min_vertex_2 functor object. */ - Construct_max_vertex_2 construct_max_vertex_2_object() const - { + Construct_max_vertex_2 construct_max_vertex_2_object() const { return Construct_max_vertex_2(this->m_base_traits-> construct_max_vertex_2_object()); } @@ -321,8 +307,7 @@ public: * \param cv The curve. * \return The left endpoint. */ - Comparison_result operator()(const Point_2& p1, const Point_2& p2) const - { + Comparison_result operator()(const Point_2& p1, const Point_2& p2) const { const Point_data& inf1 = p1.data(); const Point_data& inf2 = p2.data(); @@ -390,8 +375,7 @@ public: }; /*! Obtain a Construct_min_vertex_2 functor object. */ - Compare_y_near_boundary_2 compare_y_near_boundary_2_object() const - { + Compare_y_near_boundary_2 compare_y_near_boundary_2_object() const { return Compare_y_near_boundary_2(this->m_base_traits-> compare_y_near_boundary_2_object() ); @@ -429,8 +413,7 @@ public: }; /*! Obtain a Construct_min_vertex_2 functor object. */ - Parameter_space_in_y_2 parameter_space_in_y_2_object() const - { + Parameter_space_in_y_2 parameter_space_in_y_2_object() const { return Parameter_space_in_y_2(this->m_base_traits-> parameter_space_in_y_2_object()); } @@ -462,8 +445,7 @@ public: }; /*! Obtain a Construct_min_vertex_2 functor object. */ - Compare_x_near_boundary_2 compare_x_near_boundary_2_object() const - { + Compare_x_near_boundary_2 compare_x_near_boundary_2_object() const { return Compare_x_near_boundary_2(this->m_base_traits-> compare_x_near_boundary_2_object()); } diff --git a/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_agg_op.h b/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_agg_op.h index e047d78f884..a68818d8a53 100644 --- a/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_agg_op.h +++ b/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_agg_op.h @@ -7,11 +7,12 @@ // $Id$ // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // -// Author(s) : Baruch Zukerman -// Ophir Setter +// Author(s) : Baruch Zukerman +// Ophir Setter +// Efi Fogel -#ifndef CGAL_BSO_2_GPS_AGG_OP_H -#define CGAL_BSO_2_GPS_AGG_OP_H +#ifndef CGAL_GPS_AGG_OP_H +#define CGAL_GPS_AGG_OP_H #include @@ -19,8 +20,8 @@ * * The class Gps_agg_op is responsible for aggregated Boolean set operations * depending on a visitor template parameter. It uses the surface-sweep - * algorithm from the arrangement packages to overlay all the polygon sets, and - * then it uses a BFS that determines which of the faces is contained in the + * algorithm from the surface-sweep package to overlay all the polygon sets, and + * then it uses a BFS that determines which of the faces are contained in the * result using the visitor. */ @@ -37,31 +38,31 @@ namespace CGAL { -template +template class SweepVisitor> class Gps_agg_op { - typedef Arrangement_ Arrangement_2; - typedef BfsVisitor Bfs_visitor; + using Arrangement_2 = Arrangement_; + using Bfs_visitor = BfsVisitor; - typedef typename Arrangement_2::Traits_adaptor_2 Geometry_traits_2; - typedef typename Arrangement_2::Topology_traits Topology_traits; + using Geometry_traits_2 = typename Arrangement_2::Traits_adaptor_2; + using Topology_traits = typename Arrangement_2::Topology_traits; - typedef Arrangement_2 Arr; - typedef Geometry_traits_2 Gt2; - typedef Topology_traits Tt; + using Arr = Arrangement_2; + using Gt2 = Geometry_traits_2; + using Tt = Topology_traits; - typedef typename Gt2::Curve_const_iterator Curve_const_iterator; - typedef Gps_agg_meta_traits Mgt2; - typedef typename Mgt2::Curve_data Curve_data; - typedef typename Mgt2::X_monotone_curve_2 Meta_X_monotone_curve_2; + using Curve_const_iterator = typename Gt2::Curve_const_iterator; + using Mgt2 = Gps_agg_meta_traits; + using Curve_data = typename Mgt2::Curve_data; + using Meta_X_monotone_curve_2 = typename Mgt2::X_monotone_curve_2; - typedef typename Arr::Halfedge_handle Halfedge_handle; - typedef typename Arr::Halfedge_iterator Halfedge_iterator; - typedef typename Arr::Face_handle Face_handle; - typedef typename Arr::Edge_iterator Edge_iterator; - typedef typename Arr::Vertex_handle Vertex_handle; - typedef typename Arr::Allocator Allocator; + using Halfedge_handle = typename Arr::Halfedge_handle; + using Halfedge_iterator = typename Arr::Halfedge_iterator; + using Face_handle = typename Arr::Face_handle; + using Edge_iterator = typename Arr::Edge_iterator; + using Vertex_handle = typename Arr::Vertex_handle; + using Allocator = typename Arr::Allocator; - typedef std::pair *> Arr_entry; + using Arr_entry = std::pair *>; // We obtain a proper helper type from the topology traits of the arrangement. // However, the arrangement is parametrized with the Gt2 geometry traits, @@ -70,21 +71,16 @@ class Gps_agg_op { // We cannot parameterized the arrangement with the Mgt2 geometry // traits to start with, because it extends the curve type with arrangement // dependent types. (It is parameterized with the arrangement type.) - typedef Indexed_event Event; - typedef Arr_construction_subcurve - Subcurve; - typedef typename Tt::template Construction_helper - Helper_tmp; - typedef typename Helper_tmp::template rebind::other - Helper; - typedef Gps_agg_op_visitor Visitor; - typedef Gps_agg_op_surface_sweep_2 Surface_sweep_2; + using Event = Indexed_event; + using Subcurve = Arr_construction_subcurve; + using Helper_tmp = typename Tt::template Construction_helper; + using Helper = typename Helper_tmp::template rebind::other; + using Visitor = SweepVisitor; + using Surface_sweep_2 = Gps_agg_op_surface_sweep_2; - typedef Unique_hash_map - Edges_hash; - - typedef Unique_hash_map Faces_hash; - typedef Gps_bfs_scanner Bfs_scanner; + using Edges_hash = Unique_hash_map; + using Faces_hash = Unique_hash_map; + using Bfs_scanner = Gps_bfs_scanner; protected: Arr* m_arr; @@ -95,7 +91,7 @@ protected: Faces_hash m_faces_hash; // maps face to its IC (inside count) public: - /*! Constructor. */ + /*! constructs. */ Gps_agg_op(Arr& arr, std::vector& vert_vec, const Gt2& tr) : m_arr(&arr), m_traits(new Mgt2(tr)), @@ -103,40 +99,40 @@ public: m_surface_sweep(m_traits, &m_visitor) {} - void sweep_arrangements(unsigned int lower, unsigned int upper, - unsigned int jump, std::vector& arr_vec) - { - std::list curves_list; - - unsigned int n_inf_pgn = 0; // number of infinite polygons (arrangement + std::pair + prepare(std::size_t lower, std::size_t upper, std::size_t jump, + std::vector& arr_vec, std::list& curves_list) { + std::size_t n_inf_pgn = 0; // number of infinite polygons (arrangement // with a contained unbounded face - unsigned int n_pgn = 0; // number of polygons (arrangements) - unsigned int i; - - for (i = lower; i <= upper; i += jump, ++n_pgn) { + std::size_t n_pgn = 0; // number of polygons (arrangements) + for (auto i = lower; i <= upper; i += jump, ++n_pgn) { // The BFS scan (after the loop) starts in the reference face, // so we count the number of polygons that contain the reference face. Arr* arr = (arr_vec[i]).first; if (arr->reference_face()->contained()) ++n_inf_pgn; - Edge_iterator itr = arr->edges_begin(); - for(; itr != arr->edges_end(); ++itr) { + for (auto itr = arr->edges_begin(); itr != arr->edges_end(); ++itr) { // take only relevant edges (which separate between contained and // non-contained faces. - Halfedge_iterator he = itr; - if(he->face()->contained() == he->twin()->face()->contained()) - continue; - if ((Arr_halfedge_direction)he->direction() == ARR_RIGHT_TO_LEFT) - he = he->twin(); + Halfedge_handle he = itr; + if (he->face()->contained() == he->twin()->face()->contained()) continue; + if ((Arr_halfedge_direction)he->direction() == ARR_RIGHT_TO_LEFT) he = he->twin(); Curve_data cv_data(arr, he, 1, 0); curves_list.push_back(Meta_X_monotone_curve_2(he->curve(), cv_data)); } } + return std::make_pair(n_inf_pgn, n_pgn); + } - m_surface_sweep.sweep(curves_list.begin(), curves_list.end(), - lower, upper, jump, arr_vec); - + /*! sweeps the plane without interceptions. + */ + void sweep_arrangements(std::size_t lower, std::size_t upper, std::size_t jump, + std::vector& arr_vec) { + std::size_t n_inf_pgn, n_pgn; + std::list curves_list; + std::tie(n_inf_pgn, n_pgn) = prepare(lower, upper, jump, arr_vec, curves_list); + m_surface_sweep.sweep(curves_list.begin(), curves_list.end(), lower, upper, jump, arr_vec); m_faces_hash[m_arr->reference_face()] = n_inf_pgn; Bfs_visitor visitor(&m_edges_hash, &m_faces_hash, n_pgn); visitor.visit_ubf(m_arr->faces_begin(), n_inf_pgn); @@ -145,7 +141,69 @@ public: visitor.after_scan(*m_arr); } - /*! Destruct. + /*! sweeps the plane without interceptions, but stop when an intersection occurs. + */ + bool sweep_intercept_arrangements(std::size_t lower, std::size_t upper, std::size_t jump, + std::vector& arr_vec) { + std::size_t n_inf_pgn, n_pgn; + std::list curves_list; + std::tie(n_inf_pgn, n_pgn) = prepare(lower, upper, jump, arr_vec, curves_list); + auto res = m_surface_sweep.sweep_intercept(curves_list.begin(), curves_list.end(), lower, upper, jump, arr_vec); + if (res) return true; + + m_faces_hash[m_arr->reference_face()] = n_inf_pgn; + Bfs_visitor visitor(&m_edges_hash, &m_faces_hash, n_pgn); + visitor.visit_ubf(m_arr->faces_begin(), n_inf_pgn); + Bfs_scanner scanner(visitor); + scanner.scan(*m_arr); + visitor.after_scan(*m_arr); + return false; + } + + template + std::size_t prepare2(InputIterator begin, InputIterator end, std::list& curves_list) { + std::size_t n_inf_pgn = 0; // number of infinite polygons (arrangement + // with a contained unbounded face + for (auto it = begin; it != end; ++it) { + // The BFS scan (after the loop) starts in the reference face, + // so we count the number of polygons that contain the reference face. + Arr* arr = it->first; + if (arr->reference_face()->contained()) ++n_inf_pgn; + + for (auto ite = arr->edges_begin(); ite != arr->edges_end(); ++ite) { + // take only relevant edges (which separate between contained and + // non-contained faces. + Halfedge_handle he = ite; + if (he->face()->contained() == he->twin()->face()->contained()) continue; + if ((Arr_halfedge_direction)he->direction() == ARR_RIGHT_TO_LEFT) he = he->twin(); + + Curve_data cv_data(arr, he, 1, 0); + curves_list.push_back(Meta_X_monotone_curve_2(he->curve(), cv_data)); + } + } + return n_inf_pgn; + } + + /*! sweeps the plane without interceptions, but stop when an intersection occurs. + */ + template + bool sweep_intercept_arrangements2(InputIterator begin, InputIterator end) { + std::list curves_list; + auto n_inf_pgn = prepare2(begin, end, curves_list); + auto res = m_surface_sweep.sweep_intercept2(curves_list.begin(), curves_list.end(), begin, end); + if (res) return true; + + m_faces_hash[m_arr->reference_face()] = n_inf_pgn; + std::size_t n_pgn = std::distance(begin, end); // number of polygons (arrangements) + Bfs_visitor visitor(&m_edges_hash, &m_faces_hash, n_pgn); + visitor.visit_ubf(m_arr->faces_begin(), n_inf_pgn); + Bfs_scanner scanner(visitor); + scanner.scan(*m_arr); + visitor.after_scan(*m_arr); + return false; + } + + /*! destructs. */ ~Gps_agg_op() { delete m_traits; } }; diff --git a/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_agg_op_surface_sweep_2.h b/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_agg_op_surface_sweep_2.h index 2a76a46c271..842df631b95 100644 --- a/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_agg_op_surface_sweep_2.h +++ b/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_agg_op_surface_sweep_2.h @@ -7,11 +7,12 @@ // $Id$ // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // -// Author(s) : Baruch Zukerman -// Ron Wein +// Author(s) : Baruch Zukerman +// Ron Wein +// Efi Fogel -#ifndef CGAL_BSO_2_GSP_AGG_OP_SURFACE_SWEEP_2_H -#define CGAL_BSO_2_GSP_AGG_OP_SURFACE_SWEEP_2_H +#ifndef CGAL_GSP_AGG_OP_SURFACE_SWEEP_2_H +#define CGAL_GSP_AGG_OP_SURFACE_SWEEP_2_H #include @@ -27,34 +28,34 @@ namespace Ss2 = Surface_sweep_2; template class Gps_agg_op_surface_sweep_2 : public Ss2::Surface_sweep_2 { public: - typedef Arrangement_ Arrangement_2; - typedef Visitor_ Visitor; + using Arrangement_2 = Arrangement_; + using Visitor = Visitor_; - typedef typename Visitor::Geometry_traits_2 Geometry_traits_2; + using Geometry_traits_2 = typename Visitor::Geometry_traits_2; - typedef Arrangement_2 Arr; - typedef Geometry_traits_2 Gt2; + using Arr = Arrangement_2; + using Gt2 = Geometry_traits_2; - typedef typename Gt2::Point_2 Point_2; - typedef typename Gt2::X_monotone_curve_2 X_monotone_curve_2; + using Point_2 = typename Gt2::Point_2; + using X_monotone_curve_2 = typename Gt2::X_monotone_curve_2; - typedef typename Arr::Vertex_handle Vertex_handle; - typedef typename Arr::Halfedge_handle Halfedge_handle; + using Vertex_handle = typename Arr::Vertex_handle; + using Halfedge_handle = typename Arr::Halfedge_handle; - typedef std::pair *> Arr_entry; + using Arr_entry = std::pair *>; - typedef Ss2::Surface_sweep_2 Base; + using Base = Ss2::Surface_sweep_2; - typedef typename Visitor::Event Event; - typedef typename Visitor::Subcurve Subcurve; + using Event = typename Visitor::Event; + using Subcurve = typename Visitor::Subcurve; - typedef typename Base::Event_queue_iterator EventQueueIter; - typedef typename Event::Subcurve_iterator EventCurveIter; + using EventQueueIter = typename Base::Event_queue_iterator; + using EventCurveIter = typename Event::Subcurve_iterator; - typedef typename Event::Attribute Attribute; + using Attribute = typename Event::Attribute; - typedef std::list SubCurveList; - typedef typename SubCurveList::iterator SubCurveListIter; + using SubCurveList = std::list; + using SubCurveListIter = typename SubCurveList::iterator; public: /*! Constructor. @@ -70,21 +71,17 @@ public: Base(traits, visitor) {} - /*! Perform the sweep. */ - template - void sweep(CurveInputIterator curves_begin, CurveInputIterator curves_end, - unsigned int lower, unsigned int upper, unsigned int jump, - std::vector& arr_vec) - { + template + void pre_process(CurveInputIterator curves_begin, CurveInputIterator curves_end, + std::size_t lower, std::size_t upper, std::size_t jump, + std::vector& arr_vec) { CGAL_assertion(this->m_queue->empty() && this->m_statusLine.size() == 0); - typedef Unique_hash_map Vertices_map; - typedef typename Gt2::Compare_xy_2 Compare_xy_2; + using Vertices_map = Unique_hash_map; + using Compare_xy_2 = typename Gt2::Compare_xy_2; - this->m_visitor->before_sweep(); // Allocate all of the Subcurve objects as one block. - this->m_num_of_subCurves = - static_cast(std::distance(curves_begin, curves_end)); + this->m_num_of_subCurves = static_cast(std::distance(curves_begin, curves_end)); if (this->m_num_of_subCurves > 0) this->m_subCurves = this->m_subCurveAlloc.allocate(this->m_num_of_subCurves); @@ -95,9 +92,9 @@ public: Vertices_map vert_map; Vertex_handle vh; Vertex_handle invalid_v; - unsigned int i = lower; - unsigned int n = static_cast((arr_vec[i].second)->size()); - unsigned int j; + std::size_t i = lower; + auto n = (arr_vec[i].second)->size(); + std::size_t j; EventQueueIter q_iter; bool first = true; Attribute event_type; @@ -135,7 +132,7 @@ public: for (i += jump; i <= upper; i += jump) { // Merge the vertices of the other vectors into the existing queue. q_iter = this->m_queue->begin(); - n = static_cast((arr_vec[i].second)->size()); + n = (arr_vec[i].second)->size(); for (j = 0; j < n && (vh = (*(arr_vec[i].second))[j]) != invalid_v; j++) { event_type = _type_of_vertex(vh); @@ -170,7 +167,7 @@ public: // Go over all curves (which are associated with halfedges) and associate // them with the events we have just created. - unsigned int index = 0; + std::size_t index = 0; CurveInputIterator iter; Halfedge_handle he; Event* e_left; @@ -194,9 +191,10 @@ public: } // Create the subcurve object. - typedef decltype(this->m_subCurveAlloc) Subcurve_alloc; - std::allocator_traits::construct(this->m_subCurveAlloc, this->m_subCurves + index, - this->m_masterSubcurve); + using Subcurve_alloc = decltype(this->m_subCurveAlloc); + std::allocator_traits::construct(this->m_subCurveAlloc, + this->m_subCurves + index, + this->m_masterSubcurve); (this->m_subCurves + index)->init(*iter); (this->m_subCurves + index)->set_left_event(e_left); (this->m_subCurves + index)->set_right_event(e_right); @@ -204,13 +202,174 @@ public: e_right->add_curve_to_left(this->m_subCurves + index); this->_add_curve_to_right(e_left, this->m_subCurves + index); } + } - // Perform the sweep: + template + void pre_process2(CurveInputIterator curves_begin, CurveInputIterator curves_end, + InputIterator begin, InputIterator end) { + CGAL_assertion(this->m_queue->empty() && this->m_statusLine.size() == 0); + + using Vertices_map = Unique_hash_map; + using Compare_xy_2 = typename Gt2::Compare_xy_2; + + // Allocate all of the Subcurve objects as one block. + this->m_num_of_subCurves = std::distance(curves_begin, curves_end); + if (this->m_num_of_subCurves > 0) + this->m_subCurves = + this->m_subCurveAlloc.allocate(this->m_num_of_subCurves); + + + // Initialize the event queue using the vertices vectors. Note that these + // vertices are already sorted, we simply have to merge them + Vertices_map vert_map; + Vertex_handle vh; + Vertex_handle invalid_v; + // std::size_t i = lower; + auto it = begin; + auto n = it->second->size(); + std::size_t j; + EventQueueIter q_iter; + bool first = true; + Attribute event_type; + Event* event; + + for (j = 0; j < n && (vh = (*(it->second))[j]) != invalid_v; j++) { + // Insert the vertices of the first vector one after the other. + event_type = _type_of_vertex(vh); + if (event_type == Event::DEFAULT) continue; + + event = this->_allocate_event(vh->point(), event_type, + ARR_INTERIOR, ARR_INTERIOR); + // \todo When the boolean set operations are extended to support + // unbounded curves, we will need here a special treatment. + + #ifndef CGAL_ARRANGEMENT_ON_SURFACE_2_H + event->set_finite(); + #endif + + if (! first) { + q_iter = this->m_queue->insert_after(q_iter, event); + } + else { + q_iter = this->m_queue->insert(event); + first = false; + } + + vert_map[vh] = event; + } + + Comparison_result res = LARGER; + Compare_xy_2 comp_xy = this->m_traits->compare_xy_2_object(); + EventQueueIter q_end = this->m_queue->end(); + + for (++it; it != end; ++it) { + // Merge the vertices of the other vectors into the existing queue. + q_iter = this->m_queue->begin(); + n = it->second->size(); + + for (j = 0; j < n && (vh = (*(it->second))[j]) != invalid_v; j++) { + event_type = _type_of_vertex(vh); + if (event_type == Event::DEFAULT) continue; + + while ((q_iter != q_end) && + (res = comp_xy(vh->point(), (*q_iter)->point())) == LARGER) + { + ++q_iter; + } + + if (res == SMALLER || q_iter == q_end) { + event = this->_allocate_event(vh->point(), event_type, + ARR_INTERIOR, ARR_INTERIOR); + // \todo When the boolean set operations are extended to support + // unbounded curves, we will need here a special treatment. + +#ifndef CGAL_ARRANGEMENT_ON_SURFACE_2_H + event->set_finite(); +#endif + + this->m_queue->insert_before(q_iter, event); + vert_map[vh] = event; + } + else if (res == EQUAL) { + // In this case q_iter points to an event already associated with + // the vertex, so we just update the map: + vert_map[vh] = *q_iter; + } + } + } + + // Go over all curves (which are associated with halfedges) and associate + // them with the events we have just created. + std::size_t index = 0; + CurveInputIterator iter; + Halfedge_handle he; + Event* e_left; + Event* e_right; + + for (iter = curves_begin; iter != curves_end; ++iter, index++) { + // Get the events associated with the end-vertices of the current + // halfedge. + he = iter->data().halfedge(); + + CGAL_assertion(vert_map.is_defined(he->source())); + CGAL_assertion(vert_map.is_defined(he->target())); + + if ((Arr_halfedge_direction)he->direction() == ARR_LEFT_TO_RIGHT) { + e_left = vert_map[he->source()]; + e_right = vert_map[he->target()]; + } + else { + e_left = vert_map[he->target()]; + e_right = vert_map[he->source()]; + } + + // Create the subcurve object. + using Subcurve_alloc = decltype(this->m_subCurveAlloc); + std::allocator_traits::construct(this->m_subCurveAlloc, + this->m_subCurves + index, + this->m_masterSubcurve); + (this->m_subCurves + index)->init(*iter); + (this->m_subCurves + index)->set_left_event(e_left); + (this->m_subCurves + index)->set_right_event(e_right); + + e_right->add_curve_to_left(this->m_subCurves + index); + this->_add_curve_to_right(e_left, this->m_subCurves + index); + } + } + + /*! Perform the sweep. */ + template + void sweep(CurveInputIterator curves_begin, CurveInputIterator curves_end, + std::size_t lower, std::size_t upper, std::size_t jump, std::vector& arr_vec) { + this->m_visitor->before_sweep(); + pre_process(curves_begin, curves_end,lower, upper, jump, arr_vec); this->_sweep(); this->_complete_sweep(); this->m_visitor->after_sweep(); + } - return; + /*! Perform the sweep. */ + template + bool sweep_intercept(CurveInputIterator curves_begin, CurveInputIterator curves_end, + std::size_t lower, std::size_t upper, std::size_t jump, std::vector& arr_vec) { + this->m_visitor->before_sweep(); + pre_process(curves_begin, curves_end,lower, upper, jump, arr_vec); + this->_sweep(); + this->_complete_sweep(); + this->m_visitor->after_sweep(); + return this->m_visitor->found_intersection(); + } + + /*! Perform the sweep. */ + template + bool sweep_intercept2(CurveInputIterator curves_begin, CurveInputIterator curves_end, + InputIterator begin, InputIterator end) { + this->m_visitor->before_sweep(); + pre_process2(curves_begin, curves_end, begin, end); + this->_sweep(); + this->_complete_sweep(); + this->m_visitor->after_sweep(); + return this->m_visitor->found_intersection(); } private: @@ -218,8 +377,7 @@ private: * Check if the given vertex is an endpoint of an edge we are going * to use in the sweep. */ - Attribute _type_of_vertex(Vertex_handle v) - { + Attribute _type_of_vertex(Vertex_handle v) { typename Arr::Halfedge_around_vertex_circulator first, circ; circ = first = v->incident_halfedges(); @@ -232,7 +390,6 @@ private: else return (Event::LEFT_END); } ++circ; - } while (circ != first); // If we reached here, we should not keep this vertex. diff --git a/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_agg_op_visitor.h b/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_agg_op_visitor.h index 3e88b1ecef5..71ab8e64521 100644 --- a/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_agg_op_visitor.h +++ b/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_agg_op_visitor.h @@ -7,12 +7,12 @@ // $Id$ // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // -// -// Author(s) : Baruch Zukerman -// Ron Wein +// Author(s) : Baruch Zukerman +// Ron Wein +// Efi Fogel -#ifndef CGAL_BSO_2_GSP_AGG_OP_VISITOR_H -#define CGAL_BSO_2_GSP_AGG_OP_VISITOR_H +#ifndef CGAL_GSP_AGG_OP_VISITOR_H +#define CGAL_GSP_AGG_OP_VISITOR_H #include @@ -31,33 +31,29 @@ class Gps_agg_op_base_visitor : Helper_, typename Default::Get >::type> -{ + Visitor_>>::type> { public: - typedef Helper_ Helper; - typedef Arrangement_ Arrangement_2; + using Helper = Helper_; + using Arrangement_2 = Arrangement_; - typedef typename Helper::Geometry_traits_2 Geometry_traits_2; - typedef typename Helper::Event Event; - typedef typename Helper::Subcurve Subcurve; + using Geometry_traits_2 = typename Helper::Geometry_traits_2; + using Event = typename Helper::Event; + using Subcurve = typename Helper::Subcurve; private: - typedef Geometry_traits_2 Gt2; - typedef Arrangement_2 Arr; - - typedef Gps_agg_op_base_visitor - Self; - typedef typename Default::Get::type Visitor; - typedef Arr_construction_ss_visitor Base; + using Gt2 = Geometry_traits_2; + using Arr = Arrangement_2; + using Self = Gps_agg_op_base_visitor; + using Visitor = typename Default::Get::type; + using Base = Arr_construction_ss_visitor; public: - typedef typename Arr::Halfedge_handle Halfedge_handle; - typedef typename Arr::Vertex_handle Vertex_handle; - typedef typename Gt2::X_monotone_curve_2 X_monotone_curve_2; - typedef typename Gt2::Point_2 Point_2; + using Halfedge_handle = typename Arr::Halfedge_handle; + using Vertex_handle = typename Arr::Vertex_handle; + using X_monotone_curve_2 = typename Gt2::X_monotone_curve_2; + using Point_2 = typename Gt2::Point_2; - typedef Unique_hash_map - Edges_hash; + using Edges_hash = Unique_hash_map; protected: Edges_hash* m_edges_hash; // maps halfedges to their BC (coundary counter) @@ -72,8 +68,7 @@ public: // TODO add mpl-warning virtual Halfedge_handle insert_in_face_interior(const X_monotone_curve_2& cv, - Subcurve* sc) - { + Subcurve* sc) { Halfedge_handle he = Base::insert_in_face_interior(cv, sc); insert_edge_to_hash(he, cv); return he; @@ -83,8 +78,7 @@ public: Halfedge_handle hhandle, Halfedge_handle prev, Subcurve* sc, - bool& new_face_created) - { + bool& new_face_created) { Halfedge_handle res_he = Base::insert_at_vertices(cv, hhandle, prev, sc, new_face_created); insert_edge_to_hash(res_he, cv); @@ -93,8 +87,7 @@ public: virtual Halfedge_handle insert_from_right_vertex(const X_monotone_curve_2& cv, Halfedge_handle he, - Subcurve* sc) - { + Subcurve* sc) { Halfedge_handle res_he = Base::insert_from_right_vertex(cv, he, sc); insert_edge_to_hash(res_he, cv); return res_he; @@ -102,16 +95,14 @@ public: virtual Halfedge_handle insert_from_left_vertex(const X_monotone_curve_2& cv, Halfedge_handle he, - Subcurve* sc) - { + Subcurve* sc) { Halfedge_handle res_he = Base::insert_from_left_vertex(cv, he, sc); insert_edge_to_hash(res_he, cv); return res_he; } private: - void insert_edge_to_hash(Halfedge_handle he, const X_monotone_curve_2& cv) - { + void insert_edge_to_hash(Halfedge_handle he, const X_monotone_curve_2& cv) { const Comparison_result he_dir = ((Arr_halfedge_direction)he->direction() == ARR_LEFT_TO_RIGHT) ? SMALLER : LARGER; @@ -133,54 +124,53 @@ private: template class Gps_agg_op_visitor : - public Gps_agg_op_base_visitor > -{ + public Gps_agg_op_base_visitor< + Helper_, Arrangement_, + typename Default::Get>::type> { public: - typedef Helper_ Helper; - typedef Arrangement_ Arrangement_2; + using Helper = Helper_; + using Arrangement_2 = Arrangement_; - typedef typename Helper::Geometry_traits_2 Geometry_traits_2; - typedef typename Helper::Event Event; - typedef typename Helper::Subcurve Subcurve; + using Geometry_traits_2 = typename Helper::Geometry_traits_2; + using Event = typename Helper::Event; + using Subcurve = typename Helper::Subcurve; private: - typedef Geometry_traits_2 Gt2; - typedef Arrangement_2 Arr; + using Gt2 = Geometry_traits_2; + using Arr = Arrangement_2; - typedef Gps_agg_op_visitor Self; - typedef typename Default::Get::type Visitor; - typedef Gps_agg_op_base_visitor Base; + using Self = Gps_agg_op_visitor; + using Visitor = typename Default::Get::type; + using Base = Gps_agg_op_base_visitor; public: - typedef typename Base::Halfedge_handle Halfedge_handle; - typedef typename Base::Vertex_handle Vertex_handle; - typedef typename Gt2::X_monotone_curve_2 X_monotone_curve_2; - typedef typename Gt2::Point_2 Point_2; + using Edges_hash = typename Base::Edges_hash; + using Halfedge_handle = typename Base::Halfedge_handle; + using Vertex_handle = typename Base::Vertex_handle; + using X_monotone_curve_2 = typename Gt2::X_monotone_curve_2; + using Point_2 = typename Gt2::Point_2; protected: - unsigned int m_event_count; // The number of events so far. + std::size_t m_event_count; // The number of events so far. std::vector* m_vertices_vec; // The vertices, sorted in // ascending order. public: - Gps_agg_op_visitor(Arr* arr, typename Base::Edges_hash* hash, + Gps_agg_op_visitor(Arr* arr, Edges_hash* hash, std::vector* vertices_vec) : Base(arr, hash), m_event_count(0), m_vertices_vec(vertices_vec) {} - void before_handle_event(Event* event) - { + void before_handle_event(Event* event) { event->set_index(m_event_count); m_event_count++; } virtual Halfedge_handle - insert_in_face_interior(const X_monotone_curve_2& cv, Subcurve* sc) - { + insert_in_face_interior(const X_monotone_curve_2& cv, Subcurve* sc) { Halfedge_handle res_he = Base::insert_in_face_interior(cv, sc); // We now have a halfedge whose source vertex is associated with the @@ -198,8 +188,7 @@ public: virtual Halfedge_handle insert_from_right_vertex(const X_monotone_curve_2& cv, Halfedge_handle he, - Subcurve* sc) - { + Subcurve* sc) { Halfedge_handle res_he = Base::insert_from_right_vertex(cv, he, sc); // We now have a halfedge whose target vertex is associated with the @@ -213,9 +202,8 @@ public: virtual Halfedge_handle insert_from_left_vertex(const X_monotone_curve_2& cv, Halfedge_handle he, - Subcurve* sc) - { - Halfedge_handle res_he = Base::insert_from_left_vertex(cv, he, sc); + Subcurve* sc) { + Halfedge_handle res_he = Base::insert_from_left_vertex(cv, he, sc); // We now have a halfedge whose target vertex is associated with the // current event(we have already dealt with its source vertex). @@ -223,18 +211,16 @@ public: CGAL_assertion((Arr_halfedge_direction)res_he->direction() == ARR_LEFT_TO_RIGHT); - _insert_vertex (curr_event, res_he->target()); + _insert_vertex(curr_event, res_he->target()); return res_he; } private: - void _insert_vertex(const Event* event, Vertex_handle v) - { - const unsigned int index = event->index(); + void _insert_vertex(const Event* event, Vertex_handle v) { + const auto index = event->index(); if (index >= m_vertices_vec->size()) m_vertices_vec->resize(2 * (index + 1)); (*m_vertices_vec)[index] = v; } - }; } // namespace CGAL diff --git a/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_bfs_base_visitor.h b/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_bfs_base_visitor.h index 0312f6781c3..b269c73623b 100644 --- a/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_bfs_base_visitor.h +++ b/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_bfs_base_visitor.h @@ -8,90 +8,83 @@ // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // // -// Author(s) : Baruch Zukerman -// Ophir Setter +// Author(s) : Baruch Zukerman +// Ophir Setter #ifndef CGAL_GPS_BPS_BASE_VISITOR_H #define CGAL_GPS_BPS_BASE_VISITOR_H #include - #include namespace CGAL { //! Gps_bfs_base_visitor /*! This is a base class for all visitors that are responsible for merging - polygon sets. - We use DerivedVisitor for static polymorphism for using contained_criteria - which determines if we should mark the face as contained given the inside - count of the face. -*/ -template -class Gps_bfs_base_visitor -{ - typedef Arrangement_ Arrangement; - typedef typename Arrangement::Face_iterator Face_iterator; - typedef typename Arrangement::Halfedge_iterator Halfedge_iterator; + * polygon sets. + * We use DerivedVisitor for static polymorphism for using contained_criteria + * which determines if we should mark the face as contained given the inside + * count of the face. + */ +template +class Gps_bfs_base_visitor { + using Arrangement = Arrangement_; + using Face_iterator = typename Arrangement::Face_iterator; + using Halfedge_iterator = typename Arrangement::Halfedge_iterator; + public: - typedef Unique_hash_map Edges_hash; - typedef Unique_hash_map Faces_hash; + using Edges_hash = Unique_hash_map; + using Faces_hash = Unique_hash_map; protected: - Edges_hash* m_edges_hash; - Faces_hash* m_faces_hash; - unsigned int m_num_of_polygons; // number of polygons + Edges_hash* m_edges_hash; + Faces_hash* m_faces_hash; + std::size_t m_num_of_polygons; // number of polygons public: - Gps_bfs_base_visitor(Edges_hash* edges_hash, Faces_hash* faces_hash, - unsigned int n_pgn): + std::size_t n_pgn): m_edges_hash(edges_hash), m_faces_hash(faces_hash), m_num_of_polygons(n_pgn) {} - - //! discovered_face -/*! discovered_face is called by Gps_bfs_scanner when it reveals a new face - during a BFS scan. In the BFS traversal we are going from old_face to - new_face through the half-edge he. - \param old_face The face that was already revealed - \param new_face The face that we have just now revealed - \param he The half-edge that is used to traverse between them. -*/ + //! discovered_face + /*! discovered_face is called by Gps_bfs_scanner when it reveals a new face + * during a BFS scan. In the BFS traversal we are going from old_face to + * new_face through the half-edge he. + * \param old_face The face that was already revealed + * \param new_face The face that we have just now revealed + * \param he The half-edge that is used to traverse between them. + */ void discovered_face(Face_iterator old_face, Face_iterator new_face, - Halfedge_iterator he) - { - unsigned int ic = compute_ic(old_face, new_face, he); + Halfedge_iterator he) { + std::size_t ic = compute_ic(old_face, new_face, he); if (static_cast(this)->contained_criteria(ic)) new_face->set_contained(true); } // mark the unbounded_face (true iff contained) - void visit_ubf(Face_iterator ubf, unsigned int ubf_ic) - { + void visit_ubf(Face_iterator ubf, std::size_t ubf_ic) { CGAL_assertion(ubf->is_unbounded()); - if(static_cast(this)->contained_criteria(ubf_ic)) + if (static_cast(this)->contained_criteria(ubf_ic)) ubf->set_contained(true); } protected: - // compute the inside count of a face - unsigned int compute_ic(Face_iterator f1, - Face_iterator f2, - Halfedge_iterator he) - { + std::size_t compute_ic(Face_iterator f1, + Face_iterator f2, + Halfedge_iterator he) { CGAL_assertion(m_edges_hash->is_defined(he) && m_edges_hash->is_defined(he->twin()) && m_faces_hash->is_defined(f1) && - !m_faces_hash->is_defined(f2)); - unsigned int ic_f2 = + ! m_faces_hash->is_defined(f2)); + std::size_t ic_f2 = (*m_faces_hash)[f1] - (*m_edges_hash)[he] + (*m_edges_hash)[he->twin()]; (*m_faces_hash)[f2] = ic_f2; diff --git a/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_bfs_intersection_visitor.h b/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_bfs_intersection_visitor.h index cb624debf2c..d3b4ec19be4 100644 --- a/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_bfs_intersection_visitor.h +++ b/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_bfs_intersection_visitor.h @@ -7,59 +7,50 @@ // $Id$ // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // -// - -// Author(s) : Baruch Zukerman -// Ophir Setter - +// Author(s) : Baruch Zukerman +// Ophir Setter +// Efi Fogel #ifndef CGAL_GPS_BFS_INTERSECTION_VISITOR_H #define CGAL_GPS_BFS_INTERSECTION_VISITOR_H #include - #include namespace CGAL { -template +template class Gps_bfs_intersection_visitor : -public Gps_bfs_base_visitor > -{ - typedef Arrangement_ Arrangement; - typedef typename Arrangement::Face_iterator Face_iterator; - typedef typename Arrangement::Halfedge_iterator Halfedge_iterator; - typedef Gps_bfs_intersection_visitor Self; - typedef Gps_bfs_base_visitor Base; - typedef typename Base::Edges_hash Edges_hash; - typedef typename Base::Faces_hash Faces_hash; - + public Gps_bfs_base_visitor> { + using Arrangement = Arrangement_; + using Face_iterator = typename Arrangement::Face_iterator; + using Halfedge_iterator = typename Arrangement::Halfedge_iterator; + using Self = Gps_bfs_intersection_visitor; + using Base = Gps_bfs_base_visitor; + using Edges_hash = typename Base::Edges_hash; + using Faces_hash = typename Base::Faces_hash; public: - Gps_bfs_intersection_visitor(Edges_hash* edges_hash, Faces_hash* faces_hash, - unsigned int n_polygons): + std::size_t n_polygons): Base(edges_hash, faces_hash, n_polygons) {} - - //! contained_criteria -/*! contained_criteria is used to the determine if the face which has - inside count should be marked as contained. - \param ic the inner count of the talked-about face. - \return true if the face of ic, otherwise false. -*/ - bool contained_criteria(unsigned int ic) - { + //! contained_criteria + /*! contained_criteria is used to the determine if the face which has + * inside count should be marked as contained. + * \param ic the inner count of the talked-about face. + * \return true if the face of ic, otherwise false. + */ + bool contained_criteria(std::size_t ic) { // intersection means that all polygons contain the face. CGAL_assertion(ic <= this->m_num_of_polygons); return (ic == this->m_num_of_polygons); } - void after_scan(Arrangement&) - {} + void after_scan(Arrangement&) {} }; } //namespace CGAL diff --git a/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_bfs_join_visitor.h b/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_bfs_join_visitor.h index 3d81533d19f..702d3c22ed0 100644 --- a/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_bfs_join_visitor.h +++ b/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_bfs_join_visitor.h @@ -8,52 +8,46 @@ // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // // -// Author(s) : Baruch Zukerman -// Ophir Setter +// Author(s) : Baruch Zukerman +// Ophir Setter #ifndef CGAL_GPS_BFS_JOIN_VISITOR_H #define CGAL_GPS_BFS_JOIN_VISITOR_H #include - #include namespace CGAL { -template +template class Gps_bfs_join_visitor : -public Gps_bfs_base_visitor > -{ - typedef Arrangement_ Arrangement; - typedef typename Arrangement::Face_iterator Face_iterator; - typedef typename Arrangement::Halfedge_iterator Halfedge_iterator; - typedef Gps_bfs_join_visitor Self; - typedef Gps_bfs_base_visitor Base; - typedef typename Base::Edges_hash Edges_hash; - typedef typename Base::Faces_hash Faces_hash; +public Gps_bfs_base_visitor> { + using Arrangement = Arrangement_; + using Face_iterator = typename Arrangement::Face_iterator; + using Halfedge_iterator = typename Arrangement::Halfedge_iterator; + using Self = Gps_bfs_join_visitor; + using Base = Gps_bfs_base_visitor; + using Edges_hash = typename Base::Edges_hash; + using Faces_hash = typename Base::Faces_hash; public: - - Gps_bfs_join_visitor(Edges_hash* edges_hash, Faces_hash* faces_hash, unsigned int n_pgn): + Gps_bfs_join_visitor(Edges_hash* edges_hash, Faces_hash* faces_hash, std::size_t n_pgn): Base(edges_hash, faces_hash, n_pgn) {} - //! contained_criteria -/*! contained_criteria is used to the determine if the face which has - inside count should be marked as contained. - \param ic the inner count of the talked-about face. - \return true if the face of ic, otherwise false. -*/ - bool contained_criteria(unsigned int ic) - { + //! contained_criteria + /*! contained_criteria is used to the determine if the face which has + * inside count should be marked as contained. + * \param ic the inner count of the talked-about face. + * \return true if the face of ic, otherwise false. + */ + bool contained_criteria(std::size_t ic) { // at least one polygon contains the face. return (ic > 0); } - void after_scan(Arrangement&) - {} - + void after_scan(Arrangement&) {} }; } //namespace CGAL diff --git a/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_bfs_xor_visitor.h b/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_bfs_xor_visitor.h index 591113740d9..0ac795c7d32 100644 --- a/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_bfs_xor_visitor.h +++ b/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_bfs_xor_visitor.h @@ -8,8 +8,8 @@ // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // // -// Author(s) : Baruch Zukerman -// Ophir Setter +// Author(s) : Baruch Zukerman +// Ophir Setter #ifndef CGAL_GPS_BFS_XOR_VISITOR_H #define CGAL_GPS_BFS_XOR_VISITOR_H @@ -21,73 +21,61 @@ namespace CGAL { -template +template class Gps_bfs_xor_visitor : -public Gps_bfs_base_visitor > -{ - typedef Arrangement_ Arrangement; - typedef typename Arrangement::Face_iterator Face_iterator; - typedef typename Arrangement::Halfedge_iterator Halfedge_iterator; - typedef Gps_bfs_xor_visitor Self; - typedef Gps_bfs_base_visitor Base; - typedef typename Base::Edges_hash Edges_hash; - typedef typename Base::Faces_hash Faces_hash; + public Gps_bfs_base_visitor> { + using Arrangement = Arrangement_; + using Face_iterator = typename Arrangement::Face_iterator; + using Halfedge_iterator = typename Arrangement::Halfedge_iterator; + using Self = Gps_bfs_xor_visitor; + using Base = Gps_bfs_base_visitor; + using Edges_hash = typename Base::Edges_hash; + using Faces_hash = typename Base::Faces_hash; public: - Gps_bfs_xor_visitor(Edges_hash* edges_hash, Faces_hash* faces_hash, - unsigned int n_pgn) : + std::size_t n_pgn) : Base(edges_hash, faces_hash, n_pgn) {} - //! contained_criteria + //! contained_criteria /*! contained_criteria is used to the determine if the face which has inside count should be marked as contained. \param ic the inner count of the talked-about face. \return true if the face of ic, otherwise false. */ - bool contained_criteria(unsigned int ic) - { + bool contained_criteria(std::size_t ic) { // xor means odd number of polygons. return (ic % 2) == 1; } //! after_scan postprocessing after bfs scan. -/*! The function fixes some of the curves, to be in the same direction as the - half-edges. - - \param arr The given arrangement. -*/ - void after_scan(Arrangement& arr) - { - typedef typename Arrangement::Geometry_traits_2 Traits; - typedef typename Traits::Compare_endpoints_xy_2 Compare_endpoints_xy_2; - typedef typename Traits::Construct_opposite_2 Construct_opposite_2; - typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2; - typedef typename Arrangement::Edge_iterator Edge_iterator; + /*! The function fixes some of the curves, to be in the same direction as the + * half-edges. + * + * \param arr The given arrangement. + */ + void after_scan(Arrangement& arr) { + using Traits = typename Arrangement::Geometry_traits_2; + using X_monotone_curve_2 = typename Traits::X_monotone_curve_2; Traits tr; - Compare_endpoints_xy_2 cmp_endpoints = - tr.compare_endpoints_xy_2_object(); - Construct_opposite_2 ctr_opp = tr.construct_opposite_2_object(); + auto cmp_endpoints = tr.compare_endpoints_xy_2_object(); + auto ctr_opp = tr.construct_opposite_2_object(); - for(Edge_iterator eit = arr.edges_begin(); - eit != arr.edges_end(); - ++eit) - { - Halfedge_iterator he = eit; + for (auto eit = arr.edges_begin(); eit != arr.edges_end(); ++eit) { + Halfedge_iterator he = eit; const X_monotone_curve_2& cv = he->curve(); - const bool is_cont = he->face()->contained(); - const Comparison_result he_res = + const bool is_cont = he->face()->contained(); + const Comparison_result he_res = ((Arr_halfedge_direction)he->direction() == ARR_LEFT_TO_RIGHT) ? - SMALLER : LARGER; + SMALLER : LARGER; const bool has_same_dir = (cmp_endpoints(cv) == he_res); if ((is_cont && !has_same_dir) || (!is_cont && has_same_dir)) arr.modify_edge(he, ctr_opp(cv)); } } - }; } //namespace CGAL diff --git a/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_do_intersect_agg_op_visitor.h b/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_do_intersect_agg_op_visitor.h new file mode 100644 index 00000000000..b81334bf978 --- /dev/null +++ b/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_do_intersect_agg_op_visitor.h @@ -0,0 +1,93 @@ +// Copyright (c) 2005 Tel-Aviv University (Israel). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial +// +// Author(s) : Efi Fogel + +#ifndef CGAL_GSP_DO_INTERSECT_AGG_OP_VISITOR_H +#define CGAL_GSP_DO_INTERSECT_AGG_OP_VISITOR_H + +#include + +#include +#include +#include + +namespace CGAL { + +template +class Gps_do_intersect_agg_op_visitor : + public Gps_agg_op_visitor< + Helper_, Arrangement_, + typename Default::Get>::type> { +public: + using Helper = Helper_; + using Arrangement_2 = Arrangement_; + using Geometry_traits_2 = typename Helper::Geometry_traits_2; + using Event = typename Helper::Event; + using Subcurve = typename Helper::Subcurve; + +private: + using Gt2 = Geometry_traits_2; + using Arr = Arrangement_2; + using Self = Gps_do_intersect_agg_op_visitor; + using Visitor = typename Default::Get::type; + using Base = Gps_agg_op_visitor; + +protected: + bool m_found_x; + +public: + using Edges_hash = typename Base::Edges_hash; + using Vertex_handle = typename Base::Vertex_handle; + using Status_line_iterator = typename Base::Status_line_iterator; + using X_monotone_curve_2 = typename Base::X_monotone_curve_2; + using Point_2 = typename Base::Point_2; + using Multiplicity = typename Base::Multiplicity; + + Gps_do_intersect_agg_op_visitor(Arr* arr, Edges_hash* hash, + std::vector* vertices_vec) : + Base(arr, hash, vertices_vec), + m_found_x(false) + {} + + /*! Update an event that corresponds to a curve endpoint. */ + void update_event(Event* e, const Point_2& end_point, const X_monotone_curve_2& cv, Arr_curve_end cv_end, bool is_new) + { Base::update_event(e, end_point, cv, cv_end, is_new); } + + /*! Update an event that corresponds to a curve endpoint */ + void update_event(Event* e, const X_monotone_curve_2& cv, Arr_curve_end cv_end, bool is_new ) + { Base::update_event(e, cv, cv_end, is_new); } + + /*! Update an event that corresponds to a curve endpoint */ + void update_event(Event* e, const Point_2& p, bool is_new) + { Base::update_event(e, p, is_new); } + + /*! Update an event that corresponds to an intersection */ + void update_event(Event* e, Subcurve* sc) { Base::update_event(e, sc); } + + /*! Update an event that corresponds to an intersection between curves */ + void update_event(Event* e, Subcurve* sc1, Subcurve* sc2, bool is_new, Multiplicity multiplicity) { + if ((multiplicity % 2) == 1) m_found_x = true; + Base::update_event(e, sc1, sc2, is_new, multiplicity); + } + + //! + bool after_handle_event(Event* e, Status_line_iterator iter, bool flag) { + auto res = Base::after_handle_event(e, iter, flag); + if (m_found_x) this->surface_sweep()->stop_sweep(); + return res; + } + + /*! Getter */ + bool found_intersection() { return m_found_x; } +}; + +} // namespace CGAL + +#endif diff --git a/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_do_intersect_functor.h b/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_do_intersect_functor.h index d110a8e30f4..11101d6c021 100644 --- a/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_do_intersect_functor.h +++ b/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_do_intersect_functor.h @@ -15,112 +15,61 @@ #include - namespace CGAL { -template -class Gps_do_intersect_functor -{ +template +class Gps_do_intersect_functor { public: + using Arrangement_2 = Arrangement_; - typedef Arrangement_ Arrangement_2; + using Face_const_handle = typename Arrangement_2::Face_const_handle; + using Vertex_const_handle = typename Arrangement_2::Vertex_const_handle; + using Halfedge_const_handle = typename Arrangement_2::Halfedge_const_handle; - typedef typename Arrangement_2::Face_const_handle Face_const_handle; - typedef typename Arrangement_2::Vertex_const_handle Vertex_const_handle; - typedef typename Arrangement_2::Halfedge_const_handle Halfedge_const_handle; - - typedef typename Arrangement_2::Face_handle Face_handle; - typedef typename Arrangement_2::Halfedge_handle Halfedge_handle; - typedef typename Arrangement_2::Vertex_handle Vertex_handle; + using Face_handle = typename Arrangement_2::Face_handle; + using Halfedge_handle = typename Arrangement_2::Halfedge_handle; + using Vertex_handle = typename Arrangement_2::Vertex_handle; // default constructor - Gps_do_intersect_functor() : m_found_reg_intersection(false), - m_found_boudary_intersection(false) - + Gps_do_intersect_functor() : + m_found_reg_intersection(false), + m_found_boudary_intersection(false) {} - void create_face (Face_const_handle f1, - Face_const_handle f2, - Face_handle ) - { - if(f1->contained() && f2->contained()) - // found intersection - m_found_reg_intersection = true; - } + void create_face(Face_const_handle f1, Face_const_handle f2, Face_handle) + { if (f1->contained() && f2->contained()) m_found_reg_intersection = true; } + void create_vertex(Vertex_const_handle, Vertex_const_handle, Vertex_handle) + { m_found_boudary_intersection = true; } - void create_vertex(Vertex_const_handle , - Vertex_const_handle , - Vertex_handle ) - { - m_found_boudary_intersection = true; - } + void create_vertex(Vertex_const_handle, Halfedge_const_handle, Vertex_handle) + { m_found_boudary_intersection = true; } - void create_vertex(Vertex_const_handle , - Halfedge_const_handle , - Vertex_handle ) - { - m_found_boudary_intersection = true; - } + void create_vertex(Halfedge_const_handle, Vertex_const_handle, Vertex_handle) + { m_found_boudary_intersection = true; } - void create_vertex(Halfedge_const_handle , - Vertex_const_handle , - Vertex_handle ) - { - m_found_boudary_intersection = true; - } + void create_vertex(Halfedge_const_handle, Halfedge_const_handle, Vertex_handle) {} - void create_vertex(Halfedge_const_handle , - Halfedge_const_handle , - Vertex_handle ) - {} + void create_vertex(Face_const_handle, Vertex_const_handle, Vertex_handle) {} + void create_vertex(Vertex_const_handle, Face_const_handle, Vertex_handle) {} - void create_vertex(Face_const_handle , - Vertex_const_handle , - Vertex_handle ) - {} + void create_edge(Halfedge_const_handle, Halfedge_const_handle, Halfedge_handle) + { m_found_boudary_intersection = true; } - void create_vertex(Vertex_const_handle , - Face_const_handle , - Vertex_handle ) - {} + void create_edge(Halfedge_const_handle, Face_const_handle, Halfedge_handle) {} - void create_edge(Halfedge_const_handle , - Halfedge_const_handle , - Halfedge_handle ) - { - m_found_boudary_intersection = true; - } + void create_edge(Face_const_handle, Halfedge_const_handle, Halfedge_handle) {} - void create_edge(Halfedge_const_handle , - Face_const_handle , - Halfedge_handle ) - {} + bool found_reg_intersection() const { return m_found_reg_intersection; } - void create_edge(Face_const_handle , - Halfedge_const_handle , - Halfedge_handle ) - {} + bool found_boundary_intersection() const { return m_found_boudary_intersection; } - - bool found_reg_intersection() const - { - return m_found_reg_intersection; - } - - bool found_boundary_intersection() const - { - return m_found_boudary_intersection; - } - - protected: - - bool m_found_reg_intersection; - bool m_found_boudary_intersection; +protected: + bool m_found_reg_intersection; + bool m_found_boudary_intersection; }; - } //namespace CGAL #endif diff --git a/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_merge.h b/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_merge.h index 95a4d282ab7..cf5801a57a2 100644 --- a/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_merge.h +++ b/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_merge.h @@ -7,15 +7,17 @@ // $Id$ // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // -// Author(s) : Baruch Zukerman +// Author(s) : Baruch Zukerman +// Efi Fogel #ifndef CGAL_GPS_MERGE_H #define CGAL_GPS_MERGE_H #include - #include +#include +#include #include #include #include @@ -23,50 +25,40 @@ namespace CGAL { -/*! - \file Gps_merge.h - \brief This file contains classes that are responsible for merging - two sets of polygons in the divide-and-conquer algorithm. - The file contains 3 mergers: Join_merge, Intersection_merge and - Xor_merge. Join_merge is used when we want to merge the two sets, - Intersection_merge is used for intersection, and Xor_merge is used - for symmetric difference. -*/ - -//! Base_merge -/*! Base_merge is the base class for all merger classes. - All merges used BFS algorithm with a different visitor when discovering - a new face. +/*! \file Gps_merge.h + * + * This file contains classes that are responsible for merging two sets of + * polygons in the divide-and-conquer algorithm. The file contains 3 mergers: + * Join_merge, Intersection_merge and Xor_merge. Join_merge is used when we want + * to merge the two sets, Intersection_merge is used for intersection, and + * Xor_merge is used for symmetric difference. */ -template -class Base_merge -{ - typedef Arrangement_ Arrangement_2; - typedef Visitor_ Visitor; - typedef typename Arrangement_2::Vertex_handle Vertex_handle; - typedef std::pair *> Arr_entry; + +/*! Base_merge + * Base_merge is the base class for all merger classes. + * All merges used BFS algorithm with a different visitor when discovering + * a new face. + */ +template +class Base_merge { + using Arrangement_2 = Arrangement_; + using Visitor = Visitor_; + using Vertex_handle = typename Arrangement_2::Vertex_handle; + using Arr_entry = std::pair*>; public: - void operator()(unsigned int i, - unsigned int j, - unsigned int jump, - std::vector& arr_vec) - { - if(i==j) - return; + void operator()(std::size_t i, std::size_t j, std::size_t jump, std::vector& arr_vec) { + if (i == j) return; - const typename Arrangement_2::Geometry_traits_2 * tr = - arr_vec[i].first->geometry_traits(); - Arrangement_2 *res = new Arrangement_2(tr); - std::vector *verts = new std::vector; + const auto* tr = arr_vec[i].first->geometry_traits(); + Arrangement_2* res = new Arrangement_2(tr); + std::vector* verts = new std::vector; - Gps_agg_op - agg_op(*res, *verts, *(res->traits_adaptor())); + using Agg_op = Gps_agg_op; + Agg_op agg_op(*res, *verts, *(res->traits_adaptor())); agg_op.sweep_arrangements(i, j, jump, arr_vec); - for(unsigned int count=i; count<=j; count+=jump) - { + for (std::size_t count = i; count <= j; count += jump) { delete (arr_vec[count].first); delete (arr_vec[count].second); } @@ -74,38 +66,92 @@ public: arr_vec[i].first = res; arr_vec[i].second = verts; } - }; -//! Join_merge -/*! Join_merge is used to join two sets of polygons together in the D&C - algorithm. It is a base merge with a visitor that joins faces. +/*! Base_intercepted_merge + * Base_intercepted_merge is the base class for all merger classes that can be + * interceted (e.g., when an intersection is detected). All merges used BFS + * algorithm with a different visitor when discovering a new face. */ -template -class Join_merge : public Base_merge > -{}; +template +class Base_intercepted_merge { + using Arrangement_2 = Arrangement_; + using Visitor = Visitor_; + using Vertex_handle = typename Arrangement_2::Vertex_handle; + using Arr_entry = std::pair*>; +public: + template + bool operator()(InputIterator begin, InputIterator end) { + CGAL_assertion(begin != end); -//! Intersection_merge -/*! Intersection_merge is used to merge two sets of polygons creating their - intersection. - */ -template -class Intersection_merge : public Base_merge > -{}; + const auto* tr = begin->first->geometry_traits(); + Arrangement_2* arr = new Arrangement_2(tr); + std::vector* verts = new std::vector; -//! Xor_merge -/*! Xor_merge is used to merge two sets of polygons creating their - symmetric difference. - */ -template -class Xor_merge : public Base_merge > -{ + using Agg_op = Gps_agg_op; + Agg_op agg_op(*arr, *verts, *(arr->traits_adaptor())); + auto res = agg_op.sweep_intercept_arrangements2(begin, end); + + begin->first = arr; + begin->second = verts; + + return res; + } + + bool operator()(std::size_t i, std::size_t j, std::size_t jump, std::vector& arr_vec) { + if (i == j) return false; + + const auto* tr = arr_vec[i].first->geometry_traits(); + Arrangement_2* arr = new Arrangement_2(tr); + std::vector* verts = new std::vector; + + using Agg_op = Gps_agg_op; + Agg_op agg_op(*arr, *verts, *(arr->traits_adaptor())); + auto res = agg_op.sweep_intercept_arrangements(i, j, jump, arr_vec); + + for (auto count = i; count <= j; count += jump) { + delete (arr_vec[count].first); + arr_vec[count].first = nullptr; + delete (arr_vec[count].second); + arr_vec[count].second = nullptr; + } + + arr_vec[i].first = arr; + arr_vec[i].second = verts; + return res; + } }; +/*! Join_merge + * Join_merge is used to join two sets of polygons together in the D&C + * algorithm. It is a base merge with a visitor that joins faces. + */ +template +class Join_merge : public Base_merge>{}; + +/*! Intersection_merge + * Intersection_merge is used to merge two sets of polygons creating their + * intersection. + */ +template +class Intersection_merge : public Base_merge>{}; + +/*! Do_intersect_merge + * Do_intersect_merge is used to merge two sets of polygons creating their + * intersection. When an intersection in the interior of the boundary curves + * is detected, the sweep is intercepted. + */ +template +class Do_intersect_merge : public Base_intercepted_merge>{}; + +/*! Xor_merge + * Xor_merge is used to merge two sets of polygons creating their + * symmetric difference. + */ +template +class Xor_merge : public Base_merge>{}; + } //namespace CGAL #endif diff --git a/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_on_surface_base_2.h b/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_on_surface_base_2.h index a5a5b834a01..9dfe75151bf 100644 --- a/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_on_surface_base_2.h +++ b/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_on_surface_base_2.h @@ -7,14 +7,16 @@ // $Id$ // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // -// Author(s) : Baruch Zukerman -// Ophir Setter -// Guy Zucker - +// Author(s) : Baruch Zukerman +// Ophir Setter +// Guy Zucker +// Efi Fogel #ifndef CGAL_GPS_ON_SURFACE_BASE_2_H #define CGAL_GPS_ON_SURFACE_BASE_2_H +#include + #include #include @@ -27,6 +29,7 @@ #include #include +#include #include #include #include @@ -37,131 +40,118 @@ #include #include - -/*! - \file Gps_on_surface_base_2.h - \brief A class that allows Boolean set operations. - This class is the base class for General_polygon_set_on_surface_2 and - receives extra template parameter which allows different validation - policies. If you do not want validation then use the default validation - policy. A different validation policy example can be found in - General_polygon_set_on_surface_2. -*/ - +/*! \file Gps_on_surface_base_2.h + * \brief A class that allows Boolean set operations. + * This class is the base class for General_polygon_set_on_surface_2 and + * receives extra template parameter which allows different validation + * policies. If you do not want validation then use the default validation + * policy. A different validation policy example can be found in + * General_polygon_set_on_surface_2. + */ namespace CGAL { -namespace Boolean_set_operation_2_internal -{ - struct NoValidationPolicy - { - /*! is_valid - Checks if a Traits::Polygon_2 OR - * Traits::Polygon_with_holes_2 are valid. - * In this validation policy we do NOT do anything. - */ - template - inline static void is_valid(const Polygon&, const Traits&) {} - }; +namespace Boolean_set_operation_2_internal { + +struct NoValidationPolicy { + /*! is_valid - Checks if a Traits::Polygon_2 OR + * Traits::Polygon_with_holes_2 are valid. + * In this validation policy we do NOT do anything. + */ + template + inline static void is_valid(const Polygon&, const Traits&) {} +}; + } -//! General_polygon_set_on_surface_2 -/*! This class is the base class for General_polygon_set_on_surface_2 and - receives extra template parameter which allows different validation - policies. If you do not want validation then use the default validation - policy. A different validation policy example can be found in - General_polygon_set_on_surface_2. +/*! `General_polygon_set_on_surface_2` class is the base class for + * `General_polygon_set_on_surface_2` and receives extra template parameter + * which allows different validation policies. If you do not want validation + * then use the default validation policy. A different validation policy example + * can be found in General_polygon_set_on_surface_2. */ -template -class Gps_on_surface_base_2 -{ +template +class Gps_on_surface_base_2 { public: - typedef Traits_ Traits_2; - typedef TopTraits_ Topology_traits; - typedef typename Traits_2::Polygon_2 Polygon_2; - typedef typename Traits_2::Polygon_with_holes_2 Polygon_with_holes_2; - typedef CGAL::Arrangement_on_surface_2 - Arrangement_on_surface_2; - typedef typename Arrangement_on_surface_2::Size Size; + using Traits_2 = Traits_; + using Topology_traits = TopTraits_; + using Polygon_2 = typename Traits_2::Polygon_2; + using Polygon_with_holes_2 = typename Traits_2::Polygon_with_holes_2; + using Arrangement_on_surface_2 = CGAL::Arrangement_on_surface_2; + using Size = typename Arrangement_on_surface_2::Size; private: - typedef Arrangement_on_surface_2 Aos_2; + using Aos_2 = Arrangement_on_surface_2; - typedef Gps_on_surface_base_2 < - Traits_2, Topology_traits, ValidationPolicy> Self; - typedef typename Traits_2::Point_2 Point_2; - typedef typename Traits_2::X_monotone_curve_2 X_monotone_curve_2; + using Self = Gps_on_surface_base_2< Traits_2, Topology_traits, ValidationPolicy>; + using Point_2 = typename Traits_2::Point_2; + using X_monotone_curve_2 = typename Traits_2::X_monotone_curve_2; - typedef typename Polygon_with_holes_2::Hole_const_iterator - GP_Holes_const_iterator; - typedef typename Traits_2::Curve_const_iterator Curve_const_iterator; - typedef typename Traits_2::Compare_endpoints_xy_2 - Compare_endpoints_xy_2; - typedef typename Traits_2::Construct_opposite_2 Construct_opposite_2; + using GP_Holes_const_iterator = typename Polygon_with_holes_2::Hole_const_iterator; + using Curve_const_iterator = typename Traits_2::Curve_const_iterator; + using Compare_endpoints_xy_2 = typename Traits_2::Compare_endpoints_xy_2; + using Construct_opposite_2 = typename Traits_2::Construct_opposite_2; - typedef typename Aos_2::Face_const_iterator Face_const_iterator; - typedef typename Aos_2::Halfedge_const_iterator Halfedge_const_iterator; - typedef typename Aos_2::Vertex_const_iterator Vertex_const_iterator; - typedef typename Aos_2::Edge_const_iterator Edge_const_iterator; - typedef typename Aos_2::Outer_ccb_const_iterator Outer_ccb_const_iterator; - typedef typename Aos_2::Inner_ccb_const_iterator Inner_ccb_const_iterator; - typedef typename Aos_2::Ccb_halfedge_const_circulator - Ccb_halfedge_const_circulator; - typedef typename Aos_2::Face_iterator Face_iterator; - typedef typename Aos_2::Halfedge_iterator Halfedge_iterator; - typedef typename Aos_2::Vertex_iterator Vertex_iterator; - typedef typename Aos_2::Edge_iterator Edge_iterator; - typedef typename Aos_2::Outer_ccb_iterator Outer_ccb_iterator; - typedef typename Aos_2::Inner_ccb_iterator Inner_ccb_iterator; - typedef typename Aos_2::Ccb_halfedge_circulator Ccb_halfedge_circulator; - typedef typename Aos_2::Face_handle Face_handle; - typedef typename Aos_2::Halfedge_handle Halfedge_handle; - typedef typename Aos_2::Vertex_handle Vertex_handle; + using Face_const_iterator = typename Aos_2::Face_const_iterator; + using Halfedge_const_iterator = typename Aos_2::Halfedge_const_iterator; + using Vertex_const_iterator = typename Aos_2::Vertex_const_iterator; + using Edge_const_iterator = typename Aos_2::Edge_const_iterator; + using Outer_ccb_const_iterator = typename Aos_2::Outer_ccb_const_iterator; + using Inner_ccb_const_iterator = typename Aos_2::Inner_ccb_const_iterator; + using Ccb_halfedge_const_circulator = typename Aos_2::Ccb_halfedge_const_circulator; + using Face_iterator = typename Aos_2::Face_iterator; + using Halfedge_iterator = typename Aos_2::Halfedge_iterator; + using Vertex_iterator = typename Aos_2::Vertex_iterator; + using Edge_iterator = typename Aos_2::Edge_iterator; + using Outer_ccb_iterator = typename Aos_2::Outer_ccb_iterator; + using Inner_ccb_iterator = typename Aos_2::Inner_ccb_iterator; + using Ccb_halfedge_circulator = typename Aos_2::Ccb_halfedge_circulator; + using Face_handle = typename Aos_2::Face_handle; + using Halfedge_handle = typename Aos_2::Halfedge_handle; + using Vertex_handle = typename Aos_2::Vertex_handle; - typedef typename Aos_2::Face_const_handle Face_const_handle; - typedef typename Aos_2::Halfedge_const_handle Halfedge_const_handle; - typedef typename Aos_2::Vertex_const_handle Vertex_const_handle; + using Face_const_handle = typename Aos_2::Face_const_handle; + using Halfedge_const_handle = typename Aos_2::Halfedge_const_handle; + using Vertex_const_handle = typename Aos_2::Vertex_const_handle; - typedef typename Aos_2::Halfedge_around_vertex_const_circulator - Halfedge_around_vertex_const_circulator; + using Halfedge_around_vertex_const_circulator = typename Aos_2::Halfedge_around_vertex_const_circulator; + using Vertices = std::vector; + using Arr_entry = std::pair; - typedef std::pair *> Arr_entry; - - typedef typename Arrangement_on_surface_2:: - Topology_traits::Default_point_location_strategy Point_location; + using Point_location = typename Arrangement_on_surface_2::Topology_traits::Default_point_location_strategy; protected: - // Traits* should be removed and only m_traits should be used. // If you, who reads this text, have time, replace m_traits // with m_traits_adaptor and try to do something about m_traits_owner. const Traits_2* m_traits; - CGAL::Arr_traits_adaptor_2 m_traits_adaptor; - bool m_traits_owner; + CGAL::Arr_traits_adaptor_2 m_traits_adaptor; + bool m_traits_owner; - // the underlying arrangement - Aos_2* m_arr; + + Aos_2* m_arr; // the underlying arrangement + Vertices* m_vertices; // sorted vertices public: - - // default constructor - Gps_on_surface_base_2() : m_traits(new Traits_2()), - m_traits_adaptor(*m_traits), - m_traits_owner(true), - m_arr(new Aos_2(m_traits)) + // constructs default + Gps_on_surface_base_2() : + m_traits(new Traits_2()), + m_traits_adaptor(*m_traits), + m_traits_owner(true), + m_arr(new Aos_2(m_traits)) {} - // constructor with traits object - Gps_on_surface_base_2(const Traits_2& tr) : m_traits(&tr), - m_traits_adaptor(*m_traits), - m_traits_owner(false), - m_arr(new Aos_2(m_traits)) + // constructs with traits object + Gps_on_surface_base_2(const Traits_2& tr) : + m_traits(&tr), + m_traits_adaptor(*m_traits), + m_traits_owner(false), + m_arr(new Aos_2(m_traits)) {} - // Copy constructor + // copy constructs Gps_on_surface_base_2(const Self& ps) : m_traits(new Traits_2(*(ps.m_traits))), m_traits_adaptor(*m_traits), @@ -169,14 +159,11 @@ public: m_arr(new Aos_2(*(ps.m_arr))) {} - // Assignment operator - Gps_on_surface_base_2& operator=(const Self& ps) - { - if (this == &ps) - return (*this); + // assigns + Gps_on_surface_base_2& operator=(const Self& ps) { + if (this == &ps) return (*this); - if (m_traits_owner) - delete m_traits; + if (m_traits_owner) delete m_traits; delete m_arr; m_traits = new Traits_2(*(ps.m_traits)); m_traits_adaptor = CGAL::Arr_traits_adaptor_2(*m_traits); @@ -185,73 +172,67 @@ public: return (*this); } - // Constructor + // constructs explicit Gps_on_surface_base_2(const Polygon_2& pgn) : m_traits(new Traits_2()), m_traits_adaptor(*m_traits), m_traits_owner(true), - m_arr(new Aos_2(m_traits)) - { + m_arr(new Aos_2(m_traits)) { ValidationPolicy::is_valid(pgn, *m_traits); _insert(pgn, *m_arr); } - // Constructor + // constructs explicit Gps_on_surface_base_2(const Polygon_2& pgn, const Traits_2& tr) : m_traits(&tr), m_traits_adaptor(*m_traits), m_traits_owner(false), - m_arr(new Aos_2(m_traits)) - { + m_arr(new Aos_2(m_traits)) { ValidationPolicy::is_valid(pgn, *m_traits); _insert(pgn, *m_arr); } - // Constructor + // constructs explicit Gps_on_surface_base_2(const Polygon_with_holes_2& pgn_with_holes) : m_traits(new Traits_2()), m_traits_adaptor(*m_traits), m_traits_owner(true), - m_arr(new Aos_2(m_traits)) - { + m_arr(new Aos_2(m_traits)) { ValidationPolicy::is_valid(pgn_with_holes,*m_traits); _insert(pgn_with_holes, *m_arr); } - // Constructor + // constructs explicit Gps_on_surface_base_2(const Polygon_with_holes_2& pgn_with_holes, const Traits_2& tr) : m_traits(&tr), m_traits_adaptor(*m_traits), m_traits_owner(false), - m_arr(new Aos_2(m_traits)) - { + m_arr(new Aos_2(m_traits)) { ValidationPolicy::is_valid(pgn_with_holes,*m_traits); _insert(pgn_with_holes, *m_arr); } protected: - Gps_on_surface_base_2(Aos_2* arr) : m_traits(new Traits_2()), - m_traits_adaptor(*m_traits), - m_traits_owner(true), - m_arr(arr) + Gps_on_surface_base_2(Aos_2* arr) : + m_traits(new Traits_2()), + m_traits_adaptor(*m_traits), + m_traits_owner(true), + m_arr(arr) {} public: - //destructor - virtual ~Gps_on_surface_base_2() - { + // destructs + virtual ~Gps_on_surface_base_2() { delete m_arr; - if (m_traits_owner) - delete m_traits; + if (m_traits_owner) delete m_traits; } - void simplify(const Polygon_2& pgn, Polygon_with_holes_2& res) - { - typedef Gps_polygon_simplifier Simplifier; + void simplify(const Polygon_2& pgn, Polygon_with_holes_2& res) { + using Simplifier = Gps_polygon_simplifier; - Aos_2* arr = new Aos_2(); + Aos_2* arr = new Aos_2(); Simplifier simp(*arr, *m_traits); simp.simplify(pgn); @@ -259,33 +240,30 @@ public: Self gps(arr); gps._reset_faces(); - typedef Oneset_iterator OutputItr; + using OutputItr = Oneset_iterator; OutputItr oi (res); gps.polygons_with_holes(oi); } - // insert a simple polygon - void insert(const Polygon_2& pgn) - { + // inserts a simple polygon + void insert(const Polygon_2& pgn) { ValidationPolicy::is_valid(pgn, *m_traits); _insert(pgn, *m_arr); } - // insert a polygon with holes - void insert(const Polygon_with_holes_2& pgn_with_holes) - { + // inserts a polygon with holes + void insert(const Polygon_with_holes_2& pgn_with_holes) { ValidationPolicy::is_valid(pgn_with_holes, *m_traits); _insert(pgn_with_holes, *m_arr); } - // insert a range of polygons that can be either simple polygons + // inserts a range of polygons that can be either simple polygons // or polygons with holes // precondition: the polygons are disjoint and simple template void insert(PolygonIterator pgn_begin, PolygonIterator pgn_end); - - // insert two ranges of : the first one for simple polygons, + // inserts two ranges of : the first one for simple polygons, // the second one for polygons with holes // precondition: the first range is disjoint simple polygons // the second range is disjoint polygons with holes @@ -294,389 +272,377 @@ public: PolygonWithHolesIterator pgn_with_holes_begin, PolygonWithHolesIterator pgn_with_holes_end); - // test for intersection with a simple polygon - bool do_intersect(const Polygon_2& pgn) const - { + // tests for intersection with a simple polygon + bool do_intersect(const Polygon_2& pgn) const { ValidationPolicy::is_valid(pgn, *m_traits); Self other(pgn, *m_traits); - return (do_intersect(other)); + return do_intersect(other); } - // test for intersection with a polygon with holes - bool do_intersect(const Polygon_with_holes_2& pgn_with_holes) const - { + // tests for intersection with a polygon with holes + bool do_intersect(const Polygon_with_holes_2& pgn_with_holes) const { ValidationPolicy::is_valid(pgn_with_holes, *m_traits); Self other(pgn_with_holes, *m_traits); - return (do_intersect(other)); + return do_intersect(other); } - //test for intersection with another Gps_on_surface_base_2 object - bool do_intersect(const Self& other) const - { + // tests for intersection with another Gps_on_surface_base_2 object + bool do_intersect(const Self& other) const { if (this->is_empty() || other.is_empty()) return false; if (this->is_plane() || other.is_plane()) return true; Aos_2 res_arr; - Gps_do_intersect_functor func; - overlay(*m_arr, *(other.m_arr), res_arr, func); + Gps_do_intersect_functor func; + if (do_intersect_overlay(*m_arr, *(other.m_arr), res_arr, func)) return true; return func.found_reg_intersection(); } - // intersection with a simple polygon - void intersection(const Polygon_2& pgn) - { + // intersects with a simple polygon + void intersection(const Polygon_2& pgn) { ValidationPolicy::is_valid(pgn, *m_traits); _intersection(pgn); } - // intersection with a polygon with holes - void intersection(const Polygon_with_holes_2& pgn) - { + // intersects with a polygon with holes + void intersection(const Polygon_with_holes_2& pgn) { ValidationPolicy::is_valid(pgn, *m_traits); _intersection(pgn); } - //intersection with another Gps_on_surface_base_2 object - void intersection(const Self& other) - { - _intersection(other); - } + // intersects with another Gps_on_surface_base_2 object + void intersection(const Self& other) { _intersection(other); } - void intersection(const Self& gps1, const Self& gps2) - { + void intersection(const Self& gps1, const Self& gps2) { this->clear(); _intersection(*(gps1.m_arr), *(gps2.m_arr), *(this->m_arr)); } - - // join with a simple polygon - void join(const Polygon_2& pgn) - { + // joins with a simple polygon + void join(const Polygon_2& pgn) { ValidationPolicy::is_valid(pgn, *m_traits); _join(pgn); } - // join with a polygon with holes - void join(const Polygon_with_holes_2& pgn) - { + // joins with a polygon with holes + void join(const Polygon_with_holes_2& pgn) { ValidationPolicy::is_valid(pgn, *m_traits); _join(pgn); } - //join with another Gps_on_surface_base_2 object - void join(const Self& other) - { - _join(other); - } + // joins with another Gps_on_surface_base_2 object + void join(const Self& other) { _join(other); } - void join(const Self& gps1, const Self& gps2) - { + void join(const Self& gps1, const Self& gps2) { this->clear(); _join(*(gps1.m_arr), *(gps2.m_arr), *(this->m_arr)); } - // difference with a simple polygon - void difference (const Polygon_2& pgn) - { + // computes the difference with a simple polygon + void difference(const Polygon_2& pgn) { ValidationPolicy::is_valid(pgn, *m_traits); _difference(pgn); } - // difference with a polygon with holes - void difference (const Polygon_with_holes_2& pgn) - { + // computes the difference with a polygon with holes + void difference(const Polygon_with_holes_2& pgn) { ValidationPolicy::is_valid(pgn, *m_traits); _difference(pgn); } - //difference with another Gps_on_surface_base_2 object - void difference (const Self& other) - { - _difference(other); - } + // computes the difference with another Gps_on_surface_base_2 object + void difference(const Self& other) { _difference(other); } - void difference(const Self& gps1, const Self& gps2) - { + void difference(const Self& gps1, const Self& gps2) { this->clear(); _difference(*(gps1.m_arr), *(gps2.m_arr), *(this->m_arr)); } - - // symmetric_difference with a simple polygon - void symmetric_difference(const Polygon_2& pgn) - { + // computes the symmetric_difference with a simple polygon + void symmetric_difference(const Polygon_2& pgn) { ValidationPolicy::is_valid(pgn, *m_traits); _symmetric_difference(pgn); } - // symmetric_difference with a polygon with holes - void symmetric_difference(const Polygon_with_holes_2& pgn) - { + // computes the symmetric_difference with a polygon with holes + void symmetric_difference(const Polygon_with_holes_2& pgn) { ValidationPolicy::is_valid(pgn, *m_traits); _symmetric_difference(pgn); } - //symmetric_difference with another Gps_on_surface_base_2 object - void symmetric_difference(const Self& other) - { - _symmetric_difference(other); - } + // computes the symmetric_difference with another Gps_on_surface_base_2 object + void symmetric_difference(const Self& other) { _symmetric_difference(other); } - void symmetric_difference(const Self& gps1, const Self& gps2) - { + void symmetric_difference(const Self& gps1, const Self& gps2) { this->clear(); _symmetric_difference(*(gps1.m_arr), *(gps2.m_arr), *(this->m_arr)); } + void complement() { this->_complement(m_arr); } - void complement() - { - this->_complement(m_arr); - } - - void complement(const Self& other) - { + void complement(const Self& other) { *(this->m_arr) = *(other.m_arr); this->complement(); } - void fix_curves_direction() - { - _fix_curves_direction(*m_arr); - } + void fix_curves_direction() { _fix_curves_direction(*m_arr); } Size number_of_polygons_with_holes() const; - // Traits_2& traits() - // { - // return *m_traits; - // } + // Traits_2& traits() { return *m_traits; } const Traits_2& traits() const { return *m_traits; } - bool is_empty() const - { - // We have to check that all the faces of an empty arrangement are not - // contained in the polygon set (there can be several faces in an empty - // arrangement, dependent on the topology traits. - // The point is that if the arrangement is "empty" (meaning that no curve - // or point were inserted and that it is in its original state) then - // all the faces (created by the topology traits) should have the same - // result for contained() --- from Boolean operations point of view there - // can not be an empty arrangement which has several faces with different - // attributes. - return (m_arr->is_empty() && !m_arr->faces_begin()->contained()); - } + // We have to check that all the faces of an empty arrangement are not + // contained in the polygon set (there can be several faces in an empty + // arrangement, dependent on the topology traits. + // The point is that if the arrangement is "empty" (meaning that no curve + // or point were inserted and that it is in its original state) then + // all the faces (created by the topology traits) should have the same + // result for contained() --- from Boolean operations point of view there + // can not be an empty arrangement which has several faces with different + // attributes. + bool is_empty() const { return this->_is_empty(m_arr); } - bool is_plane() const - { + bool _is_empty(Aos_2* arr) const + { return (arr->is_empty() && ! arr->faces_begin()->contained()); } + + bool is_plane() const { // Same comment as in "is_empty" above, just with adjustments. return (m_arr->is_empty() && m_arr->faces_begin()->contained()); } - void clear() - { - m_arr->clear(); - } + void clear() { m_arr->clear(); } - - Oriented_side oriented_side(const Point_2& q) const - { + Oriented_side oriented_side(const Point_2& q) const { Point_location pl(*m_arr); Object obj = pl.locate(q); Face_const_iterator f; - if (CGAL::assign(f, obj)) - { - if (f->contained()) - return ON_POSITIVE_SIDE; - + if (CGAL::assign(f, obj)) { + if (f->contained()) return ON_POSITIVE_SIDE; return ON_NEGATIVE_SIDE ; } return ON_ORIENTED_BOUNDARY ; } - Oriented_side oriented_side(const Polygon_2& pgn) const - { + Oriented_side oriented_side(const Polygon_2& pgn) const { ValidationPolicy::is_valid(pgn, *m_traits); Self other(pgn); return (oriented_side(other)); } - Oriented_side oriented_side(const Polygon_with_holes_2& pgn) const - { + Oriented_side oriented_side(const Polygon_with_holes_2& pgn) const { ValidationPolicy::is_valid(pgn, *m_traits); Self other(pgn); return (oriented_side(other)); } - Oriented_side oriented_side(const Self& other) const - { - if (this->is_empty() || other.is_empty()) - return ON_NEGATIVE_SIDE; - - if (this->is_plane() || other.is_plane()) - return ON_POSITIVE_SIDE; + Oriented_side oriented_side(const Self& other) const { + if (this->is_empty() || other.is_empty()) return ON_NEGATIVE_SIDE; + if (this->is_plane() || other.is_plane()) return ON_POSITIVE_SIDE; Aos_2 res_arr; - - Gps_do_intersect_functor func; + Gps_do_intersect_functor func; overlay(*m_arr, *(other.m_arr), res_arr, func); - if (func.found_reg_intersection()) - return ON_POSITIVE_SIDE; - - if (func.found_boundary_intersection()) - return ON_ORIENTED_BOUNDARY; - + if (func.found_reg_intersection()) return ON_POSITIVE_SIDE; + if (func.found_boundary_intersection()) return ON_ORIENTED_BOUNDARY; return ON_NEGATIVE_SIDE; } - - // returns the location of the query point + // obtains the location of the query point bool locate(const Point_2& q, Polygon_with_holes_2& pgn) const; - /*! Obtain a const reference to the underlying arrangement + /*! obtains a const reference to the underlying arrangement * \return the underlying arrangement. */ - const Aos_2& arrangement() const - { - return *m_arr; - } + const Aos_2& arrangement() const { return *m_arr; } - /*! Obtain a reference to the underlying arrangement + /*! obtains a reference to the underlying arrangement * \return the underlying arrangement. */ - Aos_2& arrangement() - { - return *m_arr; - } + Aos_2& arrangement() { return *m_arr; } protected: - bool _is_valid(Aos_2& arr) { - if (!CGAL::is_valid(arr)) - return false; + if (! CGAL::is_valid(arr)) return false; Compare_endpoints_xy_2 cmp_endpoints = m_traits->compare_endpoints_xy_2_object(); - for (Edge_const_iterator eci = arr.edges_begin(); - eci != arr.edges_end(); - ++eci) - { + for (auto eci = arr.edges_begin(); eci != arr.edges_end(); ++eci) { Halfedge_const_handle he = eci; - if (he->face() == he->twin()->face()) - { - return false; - } - if (he->face()->contained() == he->twin()->face()->contained()) - { - return false; - } + if (he->face() == he->twin()->face()) return false; + if (he->face()->contained() == he->twin()->face()->contained()) return false; - const X_monotone_curve_2& cv = he->curve(); - const bool is_cont = he->face()->contained(); - const Comparison_result he_res = + const X_monotone_curve_2& cv = he->curve(); + const bool is_cont = he->face()->contained(); + const Comparison_result he_res = ((Arr_halfedge_direction)he->direction() == ARR_LEFT_TO_RIGHT) ? SMALLER : LARGER; - const bool has_same_dir = (cmp_endpoints(cv) == he_res); + const bool has_same_dir = (cmp_endpoints(cv) == he_res); - if ((is_cont && !has_same_dir) || (!is_cont && has_same_dir)) { - return false; - } + if ((is_cont && !has_same_dir) || (!is_cont && has_same_dir)) return false; } return true; } public: + // + bool is_valid() { return _is_valid(*this->m_arr); } - /*! */ - bool is_valid() - { - return _is_valid(*this->m_arr); - } - - // get the simple polygons, takes O(n) + // obtains the simple polygons, takes O(n) template OutputIterator polygons_with_holes(OutputIterator out) const; - // test for intersection of a range of polygons + // tests for intersection of a range of polygons template - bool do_intersect(InputIterator begin, InputIterator end, unsigned int k = 5) - { + bool do_intersect(InputIterator begin, InputIterator end, std::size_t k = 5) { Self other(*this); - other.intersection(begin, end, k); - return (other.is_empty()); + return other._do_intersect(begin, end, k); } + // intersects a range of polygons + template + inline bool _do_intersect(InputIterator begin, InputIterator end, std::size_t k) { + // m_vertices = new Vertices; + // sort_vertices(*m_arr, *m_vertices); + // Do_intersect_merge do_intersect_merge; + // auto res = do_intersect_divide_and_conquer2(begin, end, k, do_intersect_merge); + // delete m_vertices; + // if (res) return res; + // remove_redundant_edges(); + // _reset_faces(); + // return is_empty(); + + std::vector arr_vec(std::distance(begin, end) + 1); + arr_vec[0].first = this->m_arr; + std::size_t i = 1; + + for (auto it = begin; it != end; ++it, ++i) { + ValidationPolicy::is_valid((*it), *m_traits); + arr_vec[i].first = new Aos_2(m_traits); + _insert(*it, *(arr_vec[i].first)); + } + + Do_intersect_merge do_intersect_merge; + auto res = do_intersect_divide_and_conquer(0, arr_vec.size() - 1, arr_vec, k, do_intersect_merge); + + // The resulting arrangement is at index 0 + this->m_arr = arr_vec[0].first; + delete arr_vec[0].second; + if (res) { + for (std::size_t i = 1; i < arr_vec.size(); ++i) { + if (arr_vec[i].first) delete arr_vec[i].first; + if (arr_vec[i].second) delete arr_vec[i].second; + } + return res; + } + + _remove_redundant_edges(arr_vec[0].first); + _reset_faces(arr_vec[0].first); + return ! _is_empty(arr_vec[0].first); + } + + //! template bool do_intersect(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, InputIterator2 end2, - unsigned int k = 5) - { + std::size_t k = 5) { Self other(*this); - other.intersection(begin1, end1, begin2, end2, k); - return (other.is_empty()); + return other._do_intersect(begin1, end1, begin2, end2, k); } - // join a range of polygons + //! + template + bool _do_intersect(InputIterator1 begin1, InputIterator1 end1, + InputIterator2 begin2, InputIterator2 end2, + std::size_t k = 5) { + std::vector arr_vec(std::distance(begin1, end1) + std::distance(begin2, end2) + 1); + arr_vec[0].first = this->m_arr; + std::size_t i = 1; + + for (auto itr1 = begin1; itr1 != end1; ++itr1, ++i) { + ValidationPolicy::is_valid(*itr1, *m_traits); + arr_vec[i].first = new Aos_2(m_traits); + _insert(*itr1, *(arr_vec[i].first)); + } + + for (auto itr2 = begin2; itr2 != end2; ++itr2, ++i) { + ValidationPolicy::is_valid(*itr2,*m_traits); + arr_vec[i].first = new Aos_2(m_traits); + _insert(*itr2, *(arr_vec[i].first)); + } + + Do_intersect_merge do_intersect_merge; + auto res = do_intersect_divide_and_conquer(0, arr_vec.size() - 1, arr_vec, k, do_intersect_merge); + + // The resulting arrangement is at index 0 + this->m_arr = arr_vec[0].first; + delete arr_vec[0].second; + if (res) { + for (std::size_t i = 1; i < arr_vec.size(); ++i) { + if (arr_vec[i].first) delete arr_vec[i].first; + if (arr_vec[i].second) delete arr_vec[i].second; + } + return res; + } + + _remove_redundant_edges(arr_vec[0].first); + _reset_faces(arr_vec[0].first); + return ! _is_empty(arr_vec[0].first); + } + + // joins a range of polygons template - void join(InputIterator begin, InputIterator end, unsigned int k = 5) - { + void join(InputIterator begin, InputIterator end, std::size_t k = 5) { typename std::iterator_traits::value_type pgn; this->join(begin, end, pgn, k); this->remove_redundant_edges(); this->_reset_faces(); } - // join range of simple polygons + // joins a range of simple polygons // 5 is the magic number in which we switch to a sweep-based algorithm // instead of a D&C algorithm. This point should be further studies, as // it is hard to believe that this is the best value for all applications. template inline void join(InputIterator begin, InputIterator end, Polygon_2&, - unsigned int k = 5) - { - std::vector arr_vec (std::distance(begin, end) + 1); + std::size_t k = 5) { + std::vector arr_vec(std::distance(begin, end) + 1); arr_vec[0].first = this->m_arr; - unsigned int i = 1; - for (InputIterator itr = begin; itr != end; ++itr, ++i) - { + std::size_t i = 1; + for (InputIterator itr = begin; itr != end; ++itr, ++i) { ValidationPolicy::is_valid((*itr), *m_traits); arr_vec[i].first = new Aos_2(m_traits); _insert(*itr, *(arr_vec[i].first)); } Join_merge join_merge; - _build_sorted_vertices_vectors (arr_vec); - _divide_and_conquer(0, static_cast(arr_vec.size()-1), arr_vec, k, join_merge); + _divide_and_conquer(0, arr_vec.size() - 1, arr_vec, k, join_merge); //the result arrangement is at index 0 this->m_arr = arr_vec[0].first; delete arr_vec[0].second; } - //join range of polygons with holes (see previous comment about k=5). + // joins a range of polygons with holes (see previous comment about k=5). template inline void join(InputIterator begin, InputIterator end, - Polygon_with_holes_2&, unsigned int k = 5) - { - std::vector arr_vec (std::distance(begin, end) + 1); + Polygon_with_holes_2&, std::size_t k = 5) { + std::vector arr_vec(std::distance(begin, end) + 1); arr_vec[0].first = this->m_arr; - unsigned int i = 1; - for (InputIterator itr = begin; itr!=end; ++itr, ++i) - { + std::size_t i = 1; + for (InputIterator itr = begin; itr!=end; ++itr, ++i) { ValidationPolicy::is_valid((*itr), *m_traits); arr_vec[i].first = new Aos_2(m_traits); _insert(*itr, *(arr_vec[i].first)); } Join_merge join_merge; - _build_sorted_vertices_vectors (arr_vec); - _divide_and_conquer(0, static_cast(arr_vec.size()-1), arr_vec, k, join_merge); + _divide_and_conquer(0, arr_vec.size() - 1, arr_vec, k, join_merge); - //the result arrangement is at index 0 + // the result arrangement is at index 0 this->m_arr = arr_vec[0].first; delete arr_vec[0].second; } @@ -685,197 +651,167 @@ public: template inline void join(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, InputIterator2 end2, - unsigned int k = 5) - { - std::vector arr_vec (std::distance(begin1, end1)+ - std::distance(begin2, end2)+1); + std::size_t k = 5) { + std::vector arr_vec(std::distance(begin1, end1) + std::distance(begin2, end2) + 1); arr_vec[0].first = this->m_arr; - unsigned int i = 1; + std::size_t i = 1; - for (InputIterator1 itr1 = begin1; itr1!=end1; ++itr1, ++i) - { + for (InputIterator1 itr1 = begin1; itr1 != end1; ++itr1, ++i) { arr_vec[i].first = new Aos_2(m_traits); _insert(*itr1, *(arr_vec[i].first)); } - for (InputIterator2 itr2 = begin2; itr2!=end2; ++itr2, ++i) - { + for (InputIterator2 itr2 = begin2; itr2 != end2; ++itr2, ++i) { arr_vec[i].first = new Aos_2(m_traits); _insert(*itr2, *(arr_vec[i].first)); } Join_merge join_merge; - _build_sorted_vertices_vectors (arr_vec); - _divide_and_conquer(0, static_cast(arr_vec.size()-1), arr_vec, k, join_merge); + _divide_and_conquer(0, arr_vec.size() - 1, arr_vec, k, join_merge); - //the result arrangement is at index 0 + // the result arrangement is at index 0 this->m_arr = arr_vec[0].first; delete arr_vec[0].second; this->remove_redundant_edges(); this->_reset_faces(); } - - // intersect range of polygins (see previous comment about k=5). + // intersects a range of polygins (see previous comment about k=5). template inline void intersection(InputIterator begin, InputIterator end, - unsigned int k = 5) - { + std::size_t k = 5) { typename std::iterator_traits::value_type pgn; this->intersection(begin, end, pgn, k); this->remove_redundant_edges(); this->_reset_faces(); } - - // intersect range of simple polygons + // intersects a range of simple polygons template inline void intersection(InputIterator begin, InputIterator end, - Polygon_2&, unsigned int k) - { - std::vector arr_vec (std::distance(begin, end) + 1); + Polygon_2&, std::size_t k) { + std::vector arr_vec(std::distance(begin, end) + 1); arr_vec[0].first = this->m_arr; - unsigned int i = 1; + std::size_t i = 1; - for (InputIterator itr = begin; itr!=end; ++itr, ++i) - { + for (InputIterator itr = begin; itr != end; ++itr, ++i) { ValidationPolicy::is_valid((*itr), *m_traits); arr_vec[i].first = new Aos_2(m_traits); _insert(*itr, *(arr_vec[i].first)); } Intersection_merge intersection_merge; - _build_sorted_vertices_vectors (arr_vec); - _divide_and_conquer(0, static_cast(arr_vec.size()-1), arr_vec, k, intersection_merge); + _divide_and_conquer(0, arr_vec.size() - 1, arr_vec, k, intersection_merge); - //the result arrangement is at index 0 + // the result arrangement is at index 0 this->m_arr = arr_vec[0].first; delete arr_vec[0].second; } - //intersect range of polygons with holes + // intersects a range of polygons with holes template inline void intersection(InputIterator begin, InputIterator end, - Polygon_with_holes_2&, unsigned int k) - { - std::vector arr_vec (std::distance(begin, end) + 1); + Polygon_with_holes_2&, std::size_t k) { + std::vector arr_vec(std::distance(begin, end) + 1); arr_vec[0].first = this->m_arr; - unsigned int i = 1; + std::size_t i = 1; - for (InputIterator itr = begin; itr!=end; ++itr, ++i) - { + for (InputIterator itr = begin; itr != end; ++itr, ++i) { ValidationPolicy::is_valid((*itr), *m_traits); arr_vec[i].first = new Aos_2(m_traits); _insert(*itr, *(arr_vec[i].first)); } Intersection_merge intersection_merge; - _build_sorted_vertices_vectors (arr_vec); - _divide_and_conquer(0, static_cast(arr_vec.size()-1), arr_vec, k, intersection_merge); + _divide_and_conquer(0, arr_vec.size() - 1, arr_vec, k, intersection_merge); - //the result arrangement is at index 0 + // the result arrangement is at index 0 this->m_arr = arr_vec[0].first; delete arr_vec[0].second; } - template inline void intersection(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, InputIterator2 end2, - unsigned int k = 5) - { - std::vector arr_vec (std::distance(begin1, end1)+ - std::distance(begin2, end2)+1); + std::size_t k = 5) { + std::vector arr_vec(std::distance(begin1, end1) + std::distance(begin2, end2) + 1); arr_vec[0].first = this->m_arr; - unsigned int i = 1; + std::size_t i = 1; - for (InputIterator1 itr1 = begin1; itr1!=end1; ++itr1, ++i) - { + for (InputIterator1 itr1 = begin1; itr1 != end1; ++itr1, ++i) { ValidationPolicy::is_valid(*itr1, *m_traits); arr_vec[i].first = new Aos_2(m_traits); _insert(*itr1, *(arr_vec[i].first)); } - for (InputIterator2 itr2 = begin2; itr2!=end2; ++itr2, ++i) - { + for (InputIterator2 itr2 = begin2; itr2 != end2; ++itr2, ++i) { ValidationPolicy::is_valid(*itr2,*m_traits); arr_vec[i].first = new Aos_2(m_traits); _insert(*itr2, *(arr_vec[i].first)); } Intersection_merge intersection_merge; - _build_sorted_vertices_vectors (arr_vec); - _divide_and_conquer(0, static_cast(arr_vec.size()-1), arr_vec, k, intersection_merge); + _divide_and_conquer(0, arr_vec.size() - 1, arr_vec, k, intersection_merge); - //the result arrangement is at index 0 + // the result arrangement is at index 0 this->m_arr = arr_vec[0].first; delete arr_vec[0].second; this->remove_redundant_edges(); this->_reset_faces(); } - - - // symmetric_difference of a range of polygons (similar to xor) + // computes the symmetric_difference of a range of polygons (similar to xor) // (see previous comment about k=5). template inline void symmetric_difference(InputIterator begin, InputIterator end, - unsigned int k = 5) - { + std::size_t k = 5) { typename std::iterator_traits::value_type pgn; this->symmetric_difference(begin, end, pgn, k); this->remove_redundant_edges(); this->_reset_faces(); } - - // intersect range of simple polygons (see previous comment about k=5). + // intersect a range of simple polygons (see previous comment about k=5). template inline void symmetric_difference(InputIterator begin, InputIterator end, - Polygon_2&, unsigned int k = 5) - { - std::vector arr_vec (std::distance(begin, end) + 1); + Polygon_2&, std::size_t k = 5) { + std::vector arr_vec(std::distance(begin, end) + 1); arr_vec[0].first = this->m_arr; - unsigned int i = 1; + std::size_t i = 1; - for (InputIterator itr = begin; itr!=end; ++itr, ++i) - { + for (InputIterator itr = begin; itr!=end; ++itr, ++i) { ValidationPolicy::is_valid(*itr,*m_traits); arr_vec[i].first = new Aos_2(m_traits); _insert(*itr, *(arr_vec[i].first)); } Xor_merge xor_merge; - _build_sorted_vertices_vectors (arr_vec); - _divide_and_conquer(0, static_cast(arr_vec.size()-1), arr_vec, k, xor_merge); + _divide_and_conquer(0, arr_vec.size() - 1, arr_vec, k, xor_merge); - //the result arrangement is at index 0 + // the result arrangement is at index 0 this->m_arr = arr_vec[0].first; delete arr_vec[0].second; } - //intersect range of polygons with holes (see previous comment about k=5). + // intersects a range of polygons with holes (see previous comment about k=5). template - inline void symmetric_difference(InputIterator begin, InputIterator end, - Polygon_with_holes_2&, unsigned int k = 5) - { - std::vector arr_vec (std::distance(begin, end) + 1); + inline void symmetric_difference(InputIterator begin, InputIterator end, + Polygon_with_holes_2&, std::size_t k = 5) { + std::vector arr_vec(std::distance(begin, end) + 1); arr_vec[0].first = this->m_arr; - unsigned int i = 1; + std::size_t i = 1; - for (InputIterator itr = begin; itr!=end; ++itr, ++i) - { + for (InputIterator itr = begin; itr != end; ++itr, ++i) { ValidationPolicy::is_valid(*itr,*m_traits); arr_vec[i].first = new Aos_2(m_traits); _insert(*itr, *(arr_vec[i].first)); } Xor_merge xor_merge; - _build_sorted_vertices_vectors (arr_vec); - _divide_and_conquer(0, static_cast(arr_vec.size()-1), arr_vec, k, xor_merge); + _divide_and_conquer(0, arr_vec.size() - 1, arr_vec, k, xor_merge); - //the result arrangement is at index 0 + // the result arrangement is at index 0 this->m_arr = arr_vec[0].first; delete arr_vec[0].second; } @@ -884,32 +820,27 @@ public: template inline void symmetric_difference(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, InputIterator2 end2, - unsigned int k = 5) - { - std::vector arr_vec (std::distance(begin1, end1)+ - std::distance(begin2, end2)+1); + std::size_t k = 5) { + std::vector arr_vec(std::distance(begin1, end1) + std::distance(begin2, end2) + 1); arr_vec[0].first = this->m_arr; - unsigned int i = 1; + std::size_t i = 1; - for (InputIterator1 itr1 = begin1; itr1!=end1; ++itr1, ++i) - { + for (InputIterator1 itr1 = begin1; itr1 != end1; ++itr1, ++i) { ValidationPolicy::is_valid(*itr1, *m_traits); arr_vec[i].first = new Aos_2(m_traits); _insert(*itr1, *(arr_vec[i].first)); } - for (InputIterator2 itr2 = begin2; itr2!=end2; ++itr2, ++i) - { + for (InputIterator2 itr2 = begin2; itr2 != end2; ++itr2, ++i) { ValidationPolicy::is_valid(*itr2, *m_traits); arr_vec[i].first = new Aos_2(m_traits); _insert(*itr2, *(arr_vec[i].first)); } Xor_merge xor_merge; - _build_sorted_vertices_vectors (arr_vec); - _divide_and_conquer(0, static_cast(arr_vec.size()-1), arr_vec, k, xor_merge); + _divide_and_conquer(0, arr_vec.size() - 1, arr_vec, k, xor_merge); - //the result arrangement is at index 0 + // the result arrangement is at index 0 this->m_arr = arr_vec[0].first; delete arr_vec[0].second; this->remove_redundant_edges(); @@ -917,96 +848,85 @@ public: } static void construct_polygon(Ccb_halfedge_const_circulator ccb, - Polygon_2 & pgn, const Traits_2* tr); + Polygon_2& pgn, const Traits_2* tr); bool is_hole_of_face(Face_const_handle f, Halfedge_const_handle he) const; Ccb_halfedge_const_circulator get_boundary_of_polygon(Face_const_iterator f) const; - void remove_redundant_edges() - { - this->_remove_redundant_edges(m_arr); - } + void remove_redundant_edges() { this->_remove_redundant_edges(m_arr); } protected: - bool is_redundant(Halfedge_handle he) - { - return he->face()->contained() == he->twin()->face()->contained(); - } + { return he->face()->contained() == he->twin()->face()->contained(); } typename Aos_2::Dcel::Halfedge* - _halfedge(Halfedge_handle h) - { - return &(*h); - } + _halfedge(Halfedge_handle h) { return &(*h); } - void set_flag_of_halfedges_of_final_argt(Halfedge_handle h, int flag) - { - Halfedge_handle start=h; - do{ + void set_flag_of_halfedges_of_final_argt(Halfedge_handle h, int flag) { + Halfedge_handle start = h; + do { h->set_flag(flag); - h=h->next(); - while (is_redundant(h)) - h=h->twin()->next(); - } while(start!=h); + h = h->next(); + while (is_redundant(h)) h = h->twin()->next(); + } while (start != h); } - void _remove_redundant_edges(Aos_2* arr) - { + void _remove_redundant_edges(Aos_2* arr) { + using Dcel = typename Aos_2::Dcel; + using Vertex = typename Dcel::Vertex; + using Halfedge = typename Dcel::Halfedge; + using Face = typename Dcel::Face; + // const integer for handling the status of halfedges // during the flooding algorithm to tag halfedges as // on an inner or outer ccb in the final arrangement - static const int ON_INNER_CCB=0; - static const int ON_OUTER_CCB=1; - static const int NOT_VISITED=-1; - static const int NEW_CCB_ASSIGNED=2; + static const int ON_INNER_CCB = 0; + static const int ON_OUTER_CCB = 1; + static const int NOT_VISITED = -1; + static const int NEW_CCB_ASSIGNED = 2; // Consider the faces incident to a redundant edge and use a union-find // algorithm to group faces in set that will be merged by the removal // of redundant edges. Then only the master of the set will be kept. // Here we also collect edges that needs to be removed. - typedef Union_find UF_faces; + using UF_faces = Union_find; std::vector face_handles; UF_faces uf_faces; - std::vector< typename Aos_2::Dcel::Halfedge* > edges_to_remove; - bool all_edges_are_redundant=true; + std::vector edges_to_remove; + bool all_edges_are_redundant = true; - for (Edge_iterator itr = arr->edges_begin(); itr != arr->edges_end(); ++itr) - { + for (auto itr = arr->edges_begin(); itr != arr->edges_end(); ++itr) { Halfedge_handle he = itr; he->set_flag(NOT_VISITED); he->twin()->set_flag(NOT_VISITED); // put in the same set faces that will be merged when removing redundant edges - if ( is_redundant(he) ) - { - typename Aos_2::Dcel::Face* f1=&(*he->face()), - * f2=&(*he->twin()->face()); + if (is_redundant(he)) { + Face* f1 = &(*he->face()); + Face* f2 = &(*he->twin()->face()); if (f1->id_not_set()){ f1->set_id(face_handles.size()); - face_handles.push_back( uf_faces.make_set( f1 ) ); + face_handles.push_back(uf_faces.make_set(f1)); } if (f2->id_not_set()){ f2->set_id(face_handles.size()); - face_handles.push_back( uf_faces.make_set( f2 ) ); + face_handles.push_back(uf_faces.make_set(f2)); } uf_faces.unify_sets(face_handles[f1->id()], face_handles[f2->id()]); - edges_to_remove.push_back( _halfedge(he) ); + edges_to_remove.push_back(_halfedge(he)); } else - all_edges_are_redundant=false; + all_edges_are_redundant = false; } // the code in this function assumes there is only one unbounded face // (in the if below and in the part to keep the unbounded face even if // not the master of its set) - CGAL_assertion(std::distance(arr->unbounded_faces_begin(), - arr->unbounded_faces_end()) == 1); - - if (all_edges_are_redundant){ - bool is_contained=arr->unbounded_faces_begin()->contained(); + CGAL_assertion(std::distance(arr->unbounded_faces_begin(), arr->unbounded_faces_end()) == 1); + if (all_edges_are_redundant) { + bool is_contained = arr->unbounded_faces_begin()->contained(); arr->clear(); arr->unbounded_faces_begin()->set_contained(is_contained); return; @@ -1015,7 +935,7 @@ protected: // nothing needs to be done if (edges_to_remove.empty() ) return; - // Start tagging ccbs + // Start tagging ccbs // For all halfedge that is part of a face that will be subject to a merge // due to the removal of redundant edges, we now flag whether the halfedge // will be part of an outer ccb or an inner ccb in the final arrangement @@ -1028,38 +948,34 @@ protected: // first collect all non-redundant halfedges std::vector halfedges_that_was_on_an_outer_ccb; + // bitset indicating if the outer_ccb of a face was already set - std::vector face_outer_ccb_set(face_handles.size(),false); - for (Halfedge_iterator itr = arr->halfedges_begin(); itr != arr->halfedges_end(); ++itr) - { + std::vector face_outer_ccb_set(face_handles.size(), false); + for (auto itr = arr->halfedges_begin(); itr != arr->halfedges_end(); ++itr) { Halfedge_handle h = itr; - if (is_redundant(h)) - { + if (is_redundant(h)) { // mark redundant edges as we will reuse ccb, thus breaking the function is_redundant() // needed for "update halfedge ccb pointers" h->set_flag(NEW_CCB_ASSIGNED); h->twin()->set_flag(NEW_CCB_ASSIGNED); } - else{ + else { // tag halfedges of modified faces that are on an inner ccb // or twin of a halfedge on an inner ccb. - if (h->flag()!=NOT_VISITED) continue; - if(h->is_on_inner_ccb()) - { + if (h->flag() != NOT_VISITED) continue; + if(h->is_on_inner_ccb()) { //visit inner ccb of h in the final arrangement - if (!h->face()->id_not_set()) + if (! h->face()->id_not_set()) set_flag_of_halfedges_of_final_argt(h,ON_INNER_CCB); CGAL_assertion(h->twin()->is_on_outer_ccb()); - if ( h->twin()->flag()!=NOT_VISITED || - h->twin()->face()->id_not_set()) continue; + if (h->twin()->flag() != NOT_VISITED || h->twin()->face()->id_not_set()) continue; //visit outer ccb of h in the final arrangement - set_flag_of_halfedges_of_final_argt(h->twin(),ON_OUTER_CCB); - std::size_t master_id= - (*uf_faces.find(face_handles[h->twin()->face()->id()]))->id(); - face_outer_ccb_set[master_id]=true; + set_flag_of_halfedges_of_final_argt(h->twin(), ON_OUTER_CCB); + std::size_t master_id = (*uf_faces.find(face_handles[h->twin()->face()->id()]))->id(); + face_outer_ccb_set[master_id] = true; } - else{ - if (!h->face()->id_not_set()) + else { + if (! h->face()->id_not_set()) halfedges_that_was_on_an_outer_ccb.push_back(h); } } @@ -1067,79 +983,71 @@ protected: bool something_was_updated; // iterative step to propagate changes layer by layer - do{ - something_was_updated=false; + do { + something_was_updated = false; // update the bitset using the bit value of the master set // and also set the bit of the unbounded cc to 1 (as it has no unbounded ccb) - for(typename UF_faces::iterator it=uf_faces.begin(), - it_end=uf_faces.end(); it!=it_end; ++it) - { + for (auto it = uf_faces.begin(), it_end = uf_faces.end(); it != it_end; ++it) { if (face_outer_ccb_set[(*it)->id()]) continue; - typename UF_faces::handle master=uf_faces.find(it); + typename UF_faces::handle master = uf_faces.find(it); //remove faces that are not the master of their set (but the unbounded face) if ((*it)->is_unbounded()) - face_outer_ccb_set[(*master)->id()]=true; - if ( master!=it) - face_outer_ccb_set[(*it)->id()]=face_outer_ccb_set[(*master)->id()]; + face_outer_ccb_set[(*master)->id()] = true; + if (master != it) + face_outer_ccb_set[(*it)->id()] = face_outer_ccb_set[(*master)->id()]; } // update halfedge flag according to the flag of the twin halfedge // or if the outer ccb of the cc was set - for(Halfedge_handle h : halfedges_that_was_on_an_outer_ccb) - { - if (h->flag()!=NOT_VISITED) continue; - std::size_t face_master_id=(*uf_faces.find(face_handles[h->face()->id()]))->id(); - if (h->twin()->flag()==ON_INNER_CCB){ - set_flag_of_halfedges_of_final_argt(h,ON_OUTER_CCB); - face_outer_ccb_set[face_master_id]=true; - something_was_updated=true; + for (Halfedge_handle h : halfedges_that_was_on_an_outer_ccb) { + if (h->flag() != NOT_VISITED) continue; + std::size_t face_master_id = (*uf_faces.find(face_handles[h->face()->id()]))->id(); + if (h->twin()->flag() == ON_INNER_CCB){ + set_flag_of_halfedges_of_final_argt(h, ON_OUTER_CCB); + face_outer_ccb_set[face_master_id] = true; + something_was_updated = true; } - else - { - if (face_outer_ccb_set[face_master_id]){ - set_flag_of_halfedges_of_final_argt(h,ON_INNER_CCB); - something_was_updated=true; + else { + if (face_outer_ccb_set[face_master_id]) { + set_flag_of_halfedges_of_final_argt(h, ON_INNER_CCB); + something_was_updated = true; } } } } - while(something_was_updated); + while (something_was_updated); // last loop, if some tags are not set it means that they are the only ccb // of the face and that they have to be the outer ccb - for(Halfedge_handle h : halfedges_that_was_on_an_outer_ccb) - { - if (h->flag()!=NOT_VISITED) continue; - std::size_t face_master_id=(*uf_faces.find(face_handles[h->face()->id()]))->id(); - set_flag_of_halfedges_of_final_argt(h,ON_OUTER_CCB); - face_outer_ccb_set[face_master_id]=true; + for (Halfedge_handle h : halfedges_that_was_on_an_outer_ccb) { + if (h->flag() != NOT_VISITED) continue; + std::size_t face_master_id = (*uf_faces.find(face_handles[h->face()->id()]))->id(); + set_flag_of_halfedges_of_final_argt(h, ON_OUTER_CCB); + face_outer_ccb_set[face_master_id] = true; } // at this position there might be some bits in face_outer_ccb_set not set // but they are corresponding to the unbounded face - // End tagging ccbs + // End tagging ccbs // update the next/prev relationship around vertices kept incident // to at least one edge to remove. We link non redundant halfedges together. //We also collect vertices to remove at the same time. - std::vector< typename Aos_2::Dcel::Vertex* > vertices_to_remove; - for(Vertex_iterator vi=arr->vertices_begin(), vi_end=arr->vertices_end(); vi!=vi_end; ++vi) - { - typename Aos_2::Dcel::Vertex* v_ptr=&(*vi); - Halfedge_handle h_start=vi->incident_halfedges(), h=h_start; + std::vector vertices_to_remove; + for (auto vi = arr->vertices_begin(), vi_end = arr->vertices_end(); vi != vi_end; ++vi) { + Vertex* v_ptr = &(*vi); + Halfedge_handle h_start = vi->incident_halfedges(); + Halfedge_handle h = h_start; std::vector non_redundant_edges; - bool found_no_redundant=true; - do{ - if( !is_redundant(h) ) - non_redundant_edges.push_back(h); - else{ - found_no_redundant=false; - } - h=h->next()->twin(); - }while(h!=h_start); + bool found_no_redundant = true; + do { + if (! is_redundant(h)) non_redundant_edges.push_back(h); + else found_no_redundant = false; + h = h->next()->twin(); + } while (h != h_start); // if only redundant edges are incident to the vertex, then the // vertex will be removed and nothing needs to be done. - if (non_redundant_edges.empty()){ + if (non_redundant_edges.empty()) { vertices_to_remove.push_back(v_ptr); continue; } @@ -1147,35 +1055,31 @@ protected: if (found_no_redundant) continue; std::size_t nb_edges=non_redundant_edges.size(); - CGAL_assertion( nb_edges >= 2); + CGAL_assertion(nb_edges >= 2); non_redundant_edges.push_back(non_redundant_edges.front()); //update vertex halfedge v_ptr->set_halfedge(_halfedge(non_redundant_edges.back())); - for (std::size_t i=0; inext()->twin()!=h2) + for (std::size_t i = 0; i < nb_edges; ++i) { + Halfedge_handle h1 = non_redundant_edges[i]; + Halfedge_handle h2 = non_redundant_edges[i+1]; + if ( h1->next()->twin() != h2) _halfedge(h1)->set_next(_halfedge(h2->twin())); } } //collect faces to remove and update unbounded face flag - std::vector< typename Aos_2::Dcel::Face*> faces_to_remove; - std::vector< typename Aos_2::Dcel::Outer_ccb* > outer_ccbs_to_remove; - std::vector< typename Aos_2::Dcel::Inner_ccb* > inner_ccbs_to_remove; - for(typename UF_faces::iterator it=uf_faces.begin(), - it_end=uf_faces.end(); it!=it_end; ++it) - { - typename UF_faces::handle master=uf_faces.find(it); + std::vector faces_to_remove; + std::vector outer_ccbs_to_remove; + std::vector inner_ccbs_to_remove; + for (typename UF_faces::iterator it = uf_faces.begin(), it_end = uf_faces.end(); it != it_end; ++it) { + typename UF_faces::handle master = uf_faces.find(it); //remove faces that are not the master of their set (but the unbounded face) - if ( master!=it) - { + if (master != it) { // force to keep the unbounded face - if ((*it)->is_unbounded()) - { - face_handles[(*master)->id()]=it; + if ((*it)->is_unbounded()) { + face_handles[(*master)->id()] = it; faces_to_remove.push_back(*master); } else @@ -1183,10 +1087,10 @@ protected: } //collect for reuse/removal all inner and outer ccbs - for(void* ptr : (*it)->_outer_ccbs()) - outer_ccbs_to_remove.push_back( static_cast(ptr)->outer_ccb() ); - for(void* ptr : (*it)->_inner_ccbs()) - inner_ccbs_to_remove.push_back( static_cast(ptr)->inner_ccb() ); + for (void* ptr : (*it)->_outer_ccbs()) + outer_ccbs_to_remove.push_back(static_cast(ptr)->outer_ccb()); + for (void* ptr : (*it)->_inner_ccbs()) + inner_ccbs_to_remove.push_back(static_cast(ptr)->inner_ccb()); (*it)->_outer_ccbs().clear(); (*it)->_inner_ccbs().clear(); } @@ -1196,70 +1100,63 @@ protected: // the face field of outer and inner ccb are used in the loop to access the old face a halfedge // used to contribute to. These two vectors are used to delay the association to the new face to // avoid overwriting a field that is still needed - typedef std::pair Outer_ccb_and_face; - typedef std::pair Inner_ccb_and_face; + using Outer_ccb_and_face = std::pair; + using Inner_ccb_and_face = std::pair; std::vector outer_ccb_and_new_face_pairs; std::vector inner_ccb_and_new_face_pairs; // update halfedge ccb pointers - for (Halfedge_iterator itr = arr->halfedges_begin(); itr != arr->halfedges_end(); ++itr) - { + for (auto itr = arr->halfedges_begin(); itr != arr->halfedges_end(); ++itr) { Halfedge_handle h = itr; CGAL_assertion(h->face() != Face_handle()); if (h->face()->id_not_set()) continue; - CGAL_assertion(h->flag()!=NOT_VISITED); + CGAL_assertion(h->flag() != NOT_VISITED); // either a redundant edge or an edge of an already handled ccb - if ( h->flag()==NEW_CCB_ASSIGNED ) continue; + if (h->flag() == NEW_CCB_ASSIGNED) continue; - CGAL_assertion( h->flag()==ON_INNER_CCB || h->flag()==ON_OUTER_CCB ); + CGAL_assertion(h->flag() == ON_INNER_CCB || h->flag() == ON_OUTER_CCB); - typename Aos_2::Dcel::Face* f=&(*h->face()); + Face* f = &(*h->face()); - if (!f->id_not_set()) - { + if (! f->id_not_set()) { // we use the master of the set as face, but we force to keep the unbounded face, // thus this hack - f = *(face_handles[ - (*uf_faces.find(face_handles[f->id()]))->id() - ]); - if (h->flag()==ON_INNER_CCB) - { - bool reuse_inner_ccb = !inner_ccbs_to_remove.empty(); - typename Aos_2::Dcel::Inner_ccb* inner_ccb = !reuse_inner_ccb? - accessor.new_inner_ccb():inner_ccbs_to_remove.back(); + f = *(face_handles[(*uf_faces.find(face_handles[f->id()]))->id()]); + if (h->flag() == ON_INNER_CCB) { + bool reuse_inner_ccb = ! inner_ccbs_to_remove.empty(); + typename Dcel::Inner_ccb* inner_ccb = ! reuse_inner_ccb ? + accessor.new_inner_ccb() : inner_ccbs_to_remove.back(); if ( reuse_inner_ccb ) inner_ccbs_to_remove.pop_back(); - Halfedge_handle hstart=h; - do{ + Halfedge_handle hstart = h; + do { _halfedge(h)->set_inner_ccb(inner_ccb); h->set_flag(NEW_CCB_ASSIGNED); - h=h->next(); - }while(hstart!=h); + h = h->next(); + } while (hstart != h); f->add_inner_ccb(inner_ccb,_halfedge(h)); inner_ccb->set_halfedge(_halfedge(h)); - if (!reuse_inner_ccb) - inner_ccb->set_face(f); + if (! reuse_inner_ccb) inner_ccb->set_face(f); else - inner_ccb_and_new_face_pairs.push_back( std::make_pair(inner_ccb, f) ); + inner_ccb_and_new_face_pairs.push_back( std::make_pair(inner_ccb, f)); } - else{ + else { // create a new outer ccb if none is available - typename Aos_2::Dcel::Outer_ccb* outer_ccb; - if (!outer_ccbs_to_remove.empty()) - { + typename Dcel::Outer_ccb* outer_ccb; + if (!outer_ccbs_to_remove.empty()) { outer_ccb = outer_ccbs_to_remove.back(); outer_ccbs_to_remove.pop_back(); } - else{ + else { outer_ccb = accessor.new_outer_ccb(); outer_ccb->set_face(f); } - Halfedge_handle hstart=h; - do{ + Halfedge_handle hstart = h; + do { _halfedge(h)->set_outer_ccb(outer_ccb); h->set_flag(NEW_CCB_ASSIGNED); - h=h->next(); - }while(hstart!=h); + h = h->next(); + } while (hstart != h); f->add_outer_ccb(outer_ccb,_halfedge(h)); outer_ccb->set_halfedge(_halfedge(h)); outer_ccb_and_new_face_pairs.push_back( std::make_pair(outer_ccb, f) ); @@ -1268,84 +1165,65 @@ protected: } // now set the new face for all ccbs - for(Outer_ccb_and_face& ccb_and_face : outer_ccb_and_new_face_pairs) + for (Outer_ccb_and_face& ccb_and_face : outer_ccb_and_new_face_pairs) ccb_and_face.first->set_face(ccb_and_face.second); - for(Inner_ccb_and_face& ccb_and_face : inner_ccb_and_new_face_pairs) + for (Inner_ccb_and_face& ccb_and_face : inner_ccb_and_new_face_pairs) ccb_and_face.first->set_face(ccb_and_face.second); //remove no longer used edges, vertices and faces - accessor.delete_vertices( vertices_to_remove ); - accessor.delete_edges( edges_to_remove ); - accessor.delete_faces( faces_to_remove ); - accessor.delete_outer_ccbs( outer_ccbs_to_remove ); - accessor.delete_inner_ccbs( inner_ccbs_to_remove ); + accessor.delete_vertices(vertices_to_remove); + accessor.delete_edges(edges_to_remove); + accessor.delete_faces(faces_to_remove); + accessor.delete_outer_ccbs(outer_ccbs_to_remove); + accessor.delete_inner_ccbs(inner_ccbs_to_remove); - for (typename Aos_2::Face_iterator fit=arr->faces_begin(), - end=arr->faces_end(); - fit!=end; ++fit) - { - fit->reset_id(); // reset the id that will be no longer used for this face + for (auto fit = arr->faces_begin(), end = arr->faces_end(); fit != end; ++fit) { + fit->reset_id(); // reset the id that will no longer be used for this face } } - - class Less_vertex_handle - { - typename Traits_2::Compare_xy_2 comp_xy; + //! + class Less_vertex_handle { + typename Traits_2::Compare_xy_2 comp_xy; public: - - Less_vertex_handle (const typename Traits_2::Compare_xy_2& cmp) : - comp_xy (cmp) + Less_vertex_handle(const typename Traits_2::Compare_xy_2& cmp) : + comp_xy(cmp) {} - bool operator() (Vertex_handle v1, Vertex_handle v2) const - { - return (comp_xy (v1->point(), v2->point()) == SMALLER); - } + bool operator()(Vertex_handle v1, Vertex_handle v2) const + { return (comp_xy (v1->point(), v2->point()) == SMALLER); } }; - void _complement(Aos_2* arr) - { - for (Face_iterator fit = arr->faces_begin(); - fit != arr->faces_end(); - ++fit) - { + void _complement(Aos_2* arr) { + for (Face_iterator fit = arr->faces_begin(); fit != arr->faces_end(); ++fit) fit->set_contained(!fit->contained()); - } Construct_opposite_2 ctr_opp = m_traits->construct_opposite_2_object(); - for (Edge_iterator eit = arr->edges_begin(); - eit != arr->edges_end(); - ++eit) - { + for (Edge_iterator eit = arr->edges_begin(); eit != arr->edges_end(); ++eit) { Halfedge_handle he = eit; const X_monotone_curve_2& cv = he->curve(); arr->modify_edge(he, ctr_opp(cv)); } } - //fix the directions of the curves (given correct marked face) + // fixes the directions of the curves (given correct marked face) // it should be called mostly after symmetric_difference. - void _fix_curves_direction(Aos_2& arr) - { + void _fix_curves_direction(Aos_2& arr) { Compare_endpoints_xy_2 cmp_endpoints = arr.geometry_traits()->compare_endpoints_xy_2_object(); Construct_opposite_2 ctr_opp = arr.geometry_traits()->construct_opposite_2_object(); - for (Edge_iterator eit = arr.edges_begin(); - eit != arr.edges_end(); - ++eit) - { - Halfedge_handle he = eit; - const X_monotone_curve_2& cv = he->curve(); - const bool is_cont = he->face()->contained(); - const Comparison_result he_res = + for (Edge_iterator eit = arr.edges_begin(); eit != arr.edges_end(); ++eit) { + Halfedge_handle he = eit; + const X_monotone_curve_2& cv = he->curve(); + const bool is_cont = he->face()->contained(); + const Comparison_result he_res = ((Arr_halfedge_direction)he->direction() == ARR_LEFT_TO_RIGHT) ? SMALLER : LARGER; - const bool has_same_dir = (cmp_endpoints(cv) == he_res); + const bool has_same_dir = (cmp_endpoints(cv) == he_res); if ((is_cont && !has_same_dir) || (!is_cont && has_same_dir)) { arr.modify_edge(he, ctr_opp(cv)); @@ -1353,76 +1231,149 @@ protected: } } - void _build_sorted_vertices_vectors (std::vector& arr_vec) - { - Less_vertex_handle comp (m_traits->compare_xy_2_object()); - Aos_2 *p_arr; - Vertex_iterator vit; - const std::size_t n = arr_vec.size(); - std::size_t i, j; - - for (i = 0; i < n; i++) - { - // Allocate a vector of handles to all vertices in the current - // arrangement. - p_arr = arr_vec[i].first; + //! Allocate, collect , and sort the vertex handles of the arrangements in the given interval + void _build_sorted_vertices_vectors(std::size_t lower, std::size_t upper, std::vector& arr_vec) { + Less_vertex_handle comp(m_traits->compare_xy_2_object()); + for (std::size_t i = lower; i < upper + 1; i++) { + // Allocate a vector of handles to all vertices in the current arrangement. + Aos_2* p_arr = arr_vec[i].first; arr_vec[i].second = new std::vector; - arr_vec[i].second->resize (p_arr->number_of_vertices()); + arr_vec[i].second->resize(p_arr->number_of_vertices()); - for (j = 0, vit = p_arr->vertices_begin(); - vit != p_arr->vertices_end(); - j++, ++vit) - { - (*(arr_vec[i].second))[j] = vit; + std::size_t j = 0; + for (auto vit = p_arr->vertices_begin(); vit != p_arr->vertices_end(); ++vit) { + (*(arr_vec[i].second))[j++] = vit; } // Sort the vector. - std::sort (arr_vec[i].second->begin(), arr_vec[i].second->end(), comp); + std::sort(arr_vec[i].second->begin(), arr_vec[i].second->end(), comp); } } - template - void _divide_and_conquer (unsigned int lower, unsigned int upper, - std::vector& arr_vec, - unsigned int k, Merge merge_func) - { - if ((upper - lower) < k) - { + //! extracts and sorts the vertices + void sort_vertices(Aos_2& arr, Vertices& vertices) { + std::size_t j = 0; + vertices.resize(arr.number_of_vertices()); + for (auto vit = arr.vertices_begin(); vit != arr.vertices_end(); ++vit) vertices[j++] = vit; + + // Sort the vector. + Less_vertex_handle comp(m_traits->compare_xy_2_object()); + std::sort(vertices.begin(), vertices.end(), comp); + } + + //! Divide & conquer + template + void _divide_and_conquer(std::size_t lower, std::size_t upper, + std::vector& arr_vec, + std::size_t k, Merge merge_func) { + // static int indent = 0; + // std::cout << std::setw(indent) << "" << "D&C [" << lower << "," << upper << "," << k << "]\n"; + if ((upper - lower) < k) { + // std::cout << std::setw(indent) << "" << "Merging [" << lower << "," << upper << "," << 1 << "]\n"; + _build_sorted_vertices_vectors(lower, upper, arr_vec); merge_func(lower, upper, 1, arr_vec); return; } - unsigned int sub_size = ((upper - lower + 1) / k); - unsigned int i = 0; - unsigned int curr_lower = lower; + auto sub_size = ((upper - lower + 1) / k); + auto curr_lower = lower; - for (; i + bool do_intersect_divide_and_conquer(std::size_t lower, std::size_t upper, + std::vector& arr_vec, + std::size_t k, Merge merge_func) { + // static int indent = 0; + // std::cout << std::setw(indent) << "" << "D&C [" << lower << "," << upper << "," << k << "]\n"; + if ((upper - lower) < k) { + // std::cout << std::setw(indent) << "" << "Merging [" << lower << "," << upper << "," << 1 << "]\n"; + _build_sorted_vertices_vectors(lower, upper, arr_vec); + return merge_func(lower, upper, 1, arr_vec); + } + + auto sub_size = ((upper - lower + 1) / k); + auto curr_lower = lower; + + for (std::size_t i = 0; i < k - 1; ++i, curr_lower += sub_size) { + // indent += 2; + auto res = do_intersect_divide_and_conquer(curr_lower, curr_lower + sub_size-1, arr_vec, k, merge_func); + // indent -= 2; + if (res) return res; + } + + // indent += 2; + auto res = do_intersect_divide_and_conquer(curr_lower, upper, arr_vec, k, merge_func); + // indent -= 2; + if (res) return res; + + // std::cout << std::setw(indent) << "" << "Merging [" << lower << "," << curr_lower << "," << sub_size << "]\n"; + return merge_func(lower, curr_lower, sub_size, arr_vec); } - void _reset_faces(Aos_2* arr) const - { - Face_const_iterator fit = arr->faces_begin(); - for ( ; fit != arr->faces_end(); ++fit) - { + template + bool do_intersect_divide_and_conquer2(InputIterator begin, InputIterator end, std::size_t k, Merge merge) { + std::vector arr_entries; + arr_entries.reserve(k); + arr_entries.resize(1); + arr_entries[0].first = m_arr; + arr_entries[0].second = m_vertices; + std::size_t size = std::distance(begin, end); + auto it = begin; + while (it != end) { + std::size_t num = (std::min)(size+1, k); + arr_entries.resize(num); + for (std::size_t i = 1; i < num; ++i) { + // process pgn + auto* p_arr = new Aos_2(m_traits); + auto* p_vertices = new Vertices; + ValidationPolicy::is_valid(*it, *m_traits); + arr_entries[i].first = p_arr; + arr_entries[i].second = p_vertices; + _insert(*it++, *p_arr); + sort_vertices(*p_arr, *p_vertices); + } + auto res = merge(arr_entries.begin(), arr_entries.end()); + for (std::size_t i = 1; i < num; ++i) { + delete arr_entries[i].first; + delete arr_entries[i].second; + } + if (res) { + arr_entries.clear(); + return res; + } + arr_entries.resize(1); + size -= (num-1); + } + m_arr = arr_entries[0].first; + m_vertices = arr_entries[0].second; + arr_entries.clear(); + return false; + } + + // marks all faces as non-visited + void _reset_faces() const { _reset_faces(m_arr); } + + void _reset_faces(Aos_2* arr) const { + for (auto fit = arr->faces_begin(); fit != arr->faces_end(); ++fit) fit->set_visited(false); - } } - void _insert(const Polygon_2& pgn, Aos_2& arr); // The function below is public because @@ -1439,8 +1390,7 @@ protected: void _insert(PolygonIter p_begin, PolygonIter p_end, Polygon_2& pgn); template - void _insert(PolygonIter p_begin, PolygonIter p_end, - Polygon_with_holes_2& pgn); + void _insert(PolygonIter p_begin, PolygonIter p_end, Polygon_with_holes_2& pgn); template void _construct_curves(const Polygon_2& pgn, OutputIterator oi); @@ -1448,38 +1398,28 @@ protected: template void _construct_curves(const Polygon_with_holes_2& pgn, OutputIterator oi); - - bool _is_empty(const Polygon_2& pgn) const - { + bool _is_empty(const Polygon_2& pgn) const { const std::pair& itr_pair = m_traits->construct_curves_2_object()(pgn); return (itr_pair.first == itr_pair.second); } - bool _is_empty(const Polygon_with_holes_2& ) const - { - return (false); - } + bool _is_empty(const Polygon_with_holes_2& ) const { return (false); } - bool _is_plane(const Polygon_2& ) const - { - return (false); - } + bool _is_plane(const Polygon_2& ) const { return (false); } - bool _is_plane(const Polygon_with_holes_2& pgn) const - { - //typedef typename Traits_2::Is_unbounded Is_unbounded; + bool _is_plane(const Polygon_with_holes_2& pgn) const { + // using Is_unbounded = typename Traits_2::Is_unbounded; bool unbounded = m_traits->is_unbounded_object()(pgn); std::pair pair = m_traits->construct_holes_object()(pgn); return (unbounded && (pair.first == pair.second)); - //used to return + // used to return // (pgn.is_unbounded() && (pgn.holes_begin() == pgn.holes_end())) } - void _intersection(const Aos_2& arr) - { + void _intersection(const Aos_2& arr) { Aos_2* res_arr = new Aos_2(m_traits); Gps_intersection_functor func; overlay(*m_arr, arr, *res_arr, func); @@ -1487,12 +1427,11 @@ protected: m_arr = res_arr; remove_redundant_edges(); - //fix_curves_direction(); // not needed for intersection + // fix_curves_direction(); // not needed for intersection CGAL_assertion(is_valid()); } - void _intersection(const Aos_2& arr1, const Aos_2& arr2, Aos_2& res) - { + void _intersection(const Aos_2& arr1, const Aos_2& arr2, Aos_2& res) { Gps_intersection_functor func; overlay(arr1, arr2, res, func); _remove_redundant_edges(&res); @@ -1500,15 +1439,12 @@ protected: CGAL_assertion(_is_valid(res)); } - template - void _intersection(const Polygon_& pgn) - { - if (_is_empty(pgn)) - this->clear(); + template + void _intersection(const Polygon_& pgn) { + if (_is_empty(pgn)) this->clear(); if (_is_plane(pgn)) return; if (this->is_empty()) return; - if (this->is_plane()) - { + if (this->is_plane()) { Aos_2* arr = new Aos_2(m_traits); _insert(pgn, *arr); delete (this->m_arr); @@ -1521,17 +1457,14 @@ protected: _intersection(second_arr); } - void _intersection(const Self& other) - { - if (other.is_empty()) - { + void _intersection(const Self& other) { + if (other.is_empty()) { m_arr->clear(); return; } if (other.is_plane()) return; if (this->is_empty()) return; - if (this->is_plane()) - { + if (this->is_plane()) { *(this->m_arr) = *(other.m_arr); return; } @@ -1539,8 +1472,7 @@ protected: _intersection(*(other.m_arr)); } - void _join(const Aos_2& arr) - { + void _join(const Aos_2& arr) { Aos_2* res_arr = new Aos_2(m_traits); Gps_join_functor func; overlay(*m_arr, arr, *res_arr, func); @@ -1548,36 +1480,31 @@ protected: m_arr = res_arr; remove_redundant_edges(); - //fix_curves_direction(); // not needed for join + // fix_curves_direction(); // not needed for join CGAL_assertion(is_valid()); } - void _join(const Aos_2& arr1, const Aos_2& arr2, Aos_2& res) - { + void _join(const Aos_2& arr1, const Aos_2& arr2, Aos_2& res) { Gps_join_functor func; overlay(arr1, arr2, res, func); _remove_redundant_edges(&res); - //_fix_curves_direction(res); // not needed for join + // _fix_curves_direction(res); // not needed for join CGAL_assertion(_is_valid(res)); } - template - void _join(const Polygon_& pgn) - { + template + void _join(const Polygon_& pgn) { if (_is_empty(pgn)) return; - if (_is_plane(pgn)) - { + if (_is_plane(pgn)) { this->clear(); // Even in an empty arrangement there can be several faces // (because of the topology traits). - for (Face_iterator fit = this->m_arr->faces_begin(); - fit != this->m_arr->faces_end(); ++fit) + for (auto fit = this->m_arr->faces_begin(); fit != this->m_arr->faces_end(); ++fit) fit->set_contained(true); return; } - if (this->is_empty()) - { + if (this->is_empty()) { Aos_2* arr = new Aos_2(m_traits); _insert(pgn, *arr); delete (this->m_arr); @@ -1591,23 +1518,18 @@ protected: _join(second_arr); } - - void _join(const Self& other) - { + void _join(const Self& other) { if (other.is_empty()) return; - if (other.is_plane()) - { + if (other.is_plane()) { this->clear(); // Even in an empty arrangement there can be several faces // (because of the topology traits). - for (Face_iterator fit = this->m_arr->faces_begin(); - fit != this->m_arr->faces_end(); ++fit) + for (Face_iterator fit = this->m_arr->faces_begin(); fit != this->m_arr->faces_end(); ++fit) fit->set_contained(true); return; } - if (this->is_empty()) - { + if (this->is_empty()) { *(this->m_arr) = *(other.m_arr); return; } @@ -1615,8 +1537,7 @@ protected: _join(*(other.m_arr)); } - void _difference(const Aos_2& arr) - { + void _difference(const Aos_2& arr) { Aos_2* res_arr = new Aos_2(m_traits); Gps_difference_functor func; overlay(*m_arr, arr, *res_arr, func); @@ -1628,8 +1549,7 @@ protected: CGAL_assertion(is_valid()); } - void _difference(const Aos_2& arr1, const Aos_2& arr2, Aos_2& res) - { + void _difference(const Aos_2& arr1, const Aos_2& arr2, Aos_2& res) { Gps_difference_functor func; overlay(arr1, arr2, res, func); _remove_redundant_edges(&res); @@ -1637,18 +1557,15 @@ protected: CGAL_assertion(_is_valid(res)); } - template - void _difference(const Polygon_& pgn) - { + template + void _difference(const Polygon_& pgn) { if (_is_empty(pgn)) return; - if (_is_plane(pgn)) - { + if (_is_plane(pgn)) { this->clear(); return; } if (this->is_empty()) return; - if (this->is_plane()) - { + if (this->is_plane()) { Aos_2* arr = new Aos_2(m_traits); _insert(pgn, *arr); delete (this->m_arr); @@ -1662,18 +1579,14 @@ protected: _difference(second_arr); } - - void _difference(const Self& other) - { + void _difference(const Self& other) { if (other.is_empty()) return; - if (other.is_plane()) - { + if (other.is_plane()) { this->clear(); return; } if (this->is_empty()) return; - if (this->is_plane()) - { + if (this->is_plane()) { *(this->m_arr) = *(other.m_arr); this->complement(); return; @@ -1682,8 +1595,7 @@ protected: _difference(*(other.m_arr)); } - void _symmetric_difference(const Aos_2& arr) - { + void _symmetric_difference(const Aos_2& arr) { Aos_2* res_arr = new Aos_2(m_traits); Gps_sym_diff_functor func; overlay(*m_arr, arr, *res_arr, func); @@ -1695,8 +1607,7 @@ protected: CGAL_assertion(is_valid()); } - void _symmetric_difference(const Aos_2& arr1, const Aos_2& arr2, Aos_2& res) - { + void _symmetric_difference(const Aos_2& arr1, const Aos_2& arr2, Aos_2& res) { Gps_sym_diff_functor func; overlay(arr1, arr2, res, func); _remove_redundant_edges(&res); @@ -1704,18 +1615,14 @@ protected: CGAL_assertion(_is_valid(res)); } - template - void _symmetric_difference(const Polygon_& pgn) - { + template + void _symmetric_difference(const Polygon_& pgn) { if (_is_empty(pgn)) return; - - if (_is_plane(pgn)) - { + if (_is_plane(pgn)) { this->complement(); return; } - if (this->is_empty()) - { + if (this->is_empty()) { Aos_2* arr = new Aos_2(m_traits); _insert(pgn, *arr); delete (this->m_arr); @@ -1723,8 +1630,7 @@ protected: return; } - if (this->is_plane()) - { + if (this->is_plane()) { Aos_2* arr = new Aos_2(m_traits); _insert(pgn, *arr); delete (this->m_arr); @@ -1739,23 +1645,19 @@ protected: } - void _symmetric_difference(const Self& other) - { + void _symmetric_difference(const Self& other) { if (other.is_empty()) return; - if (other.is_plane()) - { + if (other.is_plane()) { this->complement(); return; } - if (this->is_empty()) - { + if (this->is_empty()) { *(this->m_arr) = *(other.m_arr); return; } - if (this->is_plane()) - { + if (this->is_plane()) { *(this->m_arr) = *(other.m_arr); this->complement(); return; @@ -1771,4 +1673,4 @@ protected: #include -#endif // CGAL_GPS_ON_SURFACE_BASE_2_H +#endif diff --git a/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_polygon_simplifier.h b/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_polygon_simplifier.h index 224a3b9570c..547ece6db74 100644 --- a/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_polygon_simplifier.h +++ b/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_polygon_simplifier.h @@ -7,11 +7,10 @@ // $Id$ // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // -// -// Author(s) : Baruch Zukerman +// Author(s) : Baruch Zukerman -#ifndef CGAL_BSO_2_GPS_POLYGON_SIMPILFIER_H -#define CGAL_BSO_2_GPS_POLYGON_SIMPILFIER_H +#ifndef CGAL_GPS_POLYGON_SIMPILFIER_H +#define CGAL_GPS_POLYGON_SIMPILFIER_H #include @@ -31,34 +30,33 @@ namespace Ss2 = Surface_sweep_2; template class Gps_polygon_simplifier { - typedef Arrangement_ Arrangement_2; + using Arrangement_2 = Arrangement_; - typedef typename Arrangement_2::Geometry_traits_2 Geometry_traits_2; - typedef typename Arrangement_2::Topology_traits Topology_traits; + using Geometry_traits_2 = typename Arrangement_2::Geometry_traits_2; + using Topology_traits = typename Arrangement_2::Topology_traits; - typedef Arrangement_2 Arr; - typedef Geometry_traits_2 Gt2; - typedef Topology_traits Tt; + using Arr = Arrangement_2; + using Gt2 = Geometry_traits_2; + using Tt = Topology_traits; - typedef typename Gt2::Curve_const_iterator Curve_const_iterator; - typedef typename Gt2::Polygon_2 Polygon_2; - typedef typename Gt2::Polygon_with_holes_2 Polygon_with_holes_2; - typedef typename Gt2::Construct_curves_2 Construct_curves_2; + using Curve_const_iterator = typename Gt2::Curve_const_iterator; + using Polygon_2 = typename Gt2::Polygon_2; + using Polygon_with_holes_2 = typename Gt2::Polygon_with_holes_2; + using Construct_curves_2 = typename Gt2::Construct_curves_2; - typedef Gps_simplifier_traits Mgt2; - typedef typename Mgt2::Curve_data Curve_data; - typedef typename Mgt2::X_monotone_curve_2 Meta_X_monotone_curve_2; + using Mgt2 = Gps_simplifier_traits; + using Curve_data = typename Mgt2::Curve_data; + using Meta_X_monotone_curve_2 = typename Mgt2::X_monotone_curve_2; - typedef typename Arr::Halfedge_handle Halfedge_handle; - typedef typename Arr::Halfedge_iterator Halfedge_iterator; - typedef typename Arr::Face_handle Face_handle; - typedef typename Arr::Face_iterator Face_iterator; - typedef typename Arr::Edge_iterator Edge_iterator; - typedef typename Arr::Vertex_handle Vertex_handle; - typedef typename Arr::Ccb_halfedge_const_circulator - Ccb_halfedge_const_circulator; - typedef typename Arr::Ccb_halfedge_circulator Ccb_halfedge_circulator; - typedef typename Arr::Allocator Allocator; + using Halfedge_handle = typename Arr::Halfedge_handle; + using Halfedge_iterator = typename Arr::Halfedge_iterator; + using Face_handle = typename Arr::Face_handle; + using Face_iterator = typename Arr::Face_iterator; + using Edge_iterator = typename Arr::Edge_iterator; + using Vertex_handle = typename Arr::Vertex_handle; + using Ccb_halfedge_const_circulator = typename Arr::Ccb_halfedge_const_circulator; + using Ccb_halfedge_circulator = typename Arr::Ccb_halfedge_circulator; + using Allocator = typename Arr::Allocator; // We obtain a proper helper type from the topology traits of the arrangement. // However, the arrangement is parametrized with the Gt2 geometry traits, @@ -67,22 +65,18 @@ class Gps_polygon_simplifier { // We cannot parameterized the arrangement with the Mgt2 geometry // traits to start with, because it extends the curve type with arrangement // dependent types. (It is parameterized with the arrangement type.) - typedef Indexed_event Event; - typedef Arr_construction_subcurve - Subcurve; - typedef typename Tt::template Construction_helper - Helper_tmp; - typedef typename Helper_tmp::template rebind::other - Helper; - typedef Gps_agg_op_base_visitor Visitor; - typedef Ss2::Surface_sweep_2 Surface_sweep_2; + using Event = Indexed_event; + using Subcurve = Arr_construction_subcurve; + using Helper_tmp = typename Tt::template Construction_helper; + using Helper = typename Helper_tmp::template rebind::other; + using Visitor = Gps_agg_op_base_visitor; + using Surface_sweep_2 = Ss2::Surface_sweep_2; - typedef Unique_hash_map - Edges_hash; + using Edges_hash = Unique_hash_map; - typedef Unique_hash_map Faces_hash; - typedef Gps_bfs_join_visitor Bfs_visitor; - typedef Gps_bfs_scanner Bfs_scanner; + using Faces_hash = Unique_hash_map; + using Bfs_visitor = Gps_bfs_join_visitor; + using Bfs_scanner = Gps_bfs_scanner; protected: Arr* m_arr; @@ -104,16 +98,14 @@ public: {} /*! Destructor. */ - ~Gps_polygon_simplifier() - { + ~Gps_polygon_simplifier() { if (m_own_traits && (m_traits != nullptr)) { delete m_traits; m_traits = nullptr; } } - void simplify(const Polygon_2& pgn) - { + void simplify(const Polygon_2& pgn) { Construct_curves_2 ctr_curves = reinterpret_cast(m_traits)->construct_curves_2_object(); @@ -122,14 +114,13 @@ public: std::pair itr_pair = ctr_curves(pgn); - unsigned int index = 0; + std::size_t index = 0; for (Curve_const_iterator itr = itr_pair.first; itr != itr_pair.second; - ++itr, ++index) - { + ++itr, ++index) { Curve_data cv_data(1, 0, index); curves_list.push_back(Meta_X_monotone_curve_2(*itr, cv_data)); } - m_traits->set_polygon_size(static_cast(curves_list.size())); + m_traits->set_polygon_size(curves_list.size()); m_surface_sweep.sweep(curves_list.begin(), curves_list.end()); diff --git a/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_polygon_validation.h b/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_polygon_validation.h index baf8908269c..f92c68c4860 100644 --- a/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_polygon_validation.h +++ b/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_polygon_validation.h @@ -7,14 +7,13 @@ // $Id$ // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // -// -// Author(s): Baruch Zukerman -// Ron Wein -// Boris Kozorovitzky -// Guy Zucker +// Author(s) : Baruch Zukerman +// Ron Wein +// Boris Kozorovitzky +// Guy Zucker -#ifndef CGAL_BSO_2_GPS_POLYGON_VALIDATION_2_H -#define CGAL_BSO_2_GPS_POLYGON_VALIDATION_2_H +#ifndef CGAL_GPS_POLYGON_VALIDATION_2_H +#define CGAL_GPS_POLYGON_VALIDATION_2_H #include diff --git a/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_simplifier_traits.h b/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_simplifier_traits.h index 24b69369a43..058b9c7df9b 100644 --- a/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_simplifier_traits.h +++ b/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_simplifier_traits.h @@ -7,9 +7,8 @@ // $Id$ // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // -// -// Author(s): Baruch Zukerman -// Efi Fogel +// Author(s) : Baruch Zukerman +// Efi Fogel #ifndef CGAL_GPS_SIMPLIFIER_TRAITS_H #define CGAL_GPS_SIMPLIFIER_TRAITS_H @@ -23,97 +22,94 @@ namespace CGAL { class Gps_simplifier_curve_data { protected: - unsigned int m_bc; - unsigned int m_twin_bc; - unsigned int m_index; + std::size_t m_bc; + std::size_t m_twin_bc; + std::size_t m_index; public: Gps_simplifier_curve_data() {} - Gps_simplifier_curve_data(unsigned int bc, unsigned int twin_bc, - unsigned int index): + Gps_simplifier_curve_data(std::size_t bc, std::size_t twin_bc, + std::size_t index): m_bc(bc), m_twin_bc(twin_bc), m_index(index) {} - unsigned int bc() const { return m_bc; } + std::size_t bc() const { return m_bc; } - unsigned int twin_bc() const { return m_twin_bc; } + std::size_t twin_bc() const { return m_twin_bc; } - unsigned int index() const { return m_index; } + std::size_t index() const { return m_index; } - unsigned int& index() { return m_index; } + std::size_t& index() { return m_index; } - unsigned int& twin_bc() { return m_twin_bc; } + std::size_t& twin_bc() { return m_twin_bc; } - void set_bc(unsigned int bc) { m_bc = bc; } + void set_bc(std::size_t bc) { m_bc = bc; } - void set_twin_bc(unsigned int twin_bc) { m_twin_bc = twin_bc; } + void set_twin_bc(std::size_t twin_bc) { m_twin_bc = twin_bc; } - void set_index(unsigned int index) { m_index = index; } + void set_index(std::size_t index) { m_index = index; } }; struct Gps_simplifier_point_data { protected: - unsigned int m_index; + std::size_t m_index; public: Gps_simplifier_point_data() {} - Gps_simplifier_point_data(unsigned int index) : m_index(index) {} + Gps_simplifier_point_data(std::size_t index) : m_index(index) {} - unsigned int index() const { return m_index; } + std::size_t index() const { return m_index; } - void set_index(unsigned int index) { m_index = index; } + void set_index(std::size_t index) { m_index = index; } }; template class Gps_simplifier_traits : public Gps_traits_decorator -{ + Gps_simplifier_point_data> { public: - typedef Traits_ Traits; - typedef Gps_traits_decorator Base; - typedef Gps_simplifier_traits Self; - typedef typename Traits::X_monotone_curve_2 Base_x_monotone_curve_2; - typedef typename Traits::Point_2 Base_point_2; - typedef typename Traits::Construct_min_vertex_2 Base_Construct_min_vertex_2; - typedef typename Traits::Construct_max_vertex_2 Base_Construct_max_vertex_2; - typedef typename Traits::Compare_endpoints_xy_2 Base_Compare_endpoints_xy_2; - typedef typename Traits::Compare_xy_2 Base_Compare_xy_2; - typedef typename Traits::Compare_y_at_x_right_2 Base_Compare_y_at_x_right_2; - typedef typename Traits::Compare_y_at_x_2 Base_Compare_y_at_x_2; - typedef typename Traits::Intersect_2 Base_Intersect_2; - typedef typename Traits::Split_2 Base_Split_2; + using Traits = Traits_; + using Base = Gps_traits_decorator; + using Self = Gps_simplifier_traits; + using Base_x_monotone_curve_2 = typename Traits::X_monotone_curve_2; + using Base_point_2 = typename Traits::Point_2; + using Base_Construct_min_vertex_2 = typename Traits::Construct_min_vertex_2; + using Base_Construct_max_vertex_2 = typename Traits::Construct_max_vertex_2; + using Base_Compare_endpoints_xy_2 = typename Traits::Compare_endpoints_xy_2; + using Base_Compare_xy_2 = typename Traits::Compare_xy_2; + using Base_Compare_y_at_x_right_2 = typename Traits::Compare_y_at_x_right_2; + using Base_Compare_y_at_x_2 = typename Traits::Compare_y_at_x_2; + using Base_Intersect_2 = typename Traits::Intersect_2; + using Base_Split_2 = typename Traits::Split_2; protected: - mutable unsigned int m_pgn_size; + mutable std::size_t m_pgn_size; public: - typedef typename Base::X_monotone_curve_2 X_monotone_curve_2; - typedef typename Base::Point_2 Point_2; - typedef typename Base::Multiplicity Multiplicity; + using X_monotone_curve_2 = typename Base::X_monotone_curve_2; + using Point_2 = typename Base::Point_2; + using Multiplicity = typename Base::Multiplicity; - typedef typename Base::Curve_data Curve_data; - typedef typename Base::Point_data Point_data; + using Curve_data = typename Base::Curve_data; + using Point_data = typename Base::Point_data; Gps_simplifier_traits() {} Gps_simplifier_traits(const Traits& tr) : Base(tr) {} - unsigned int polygon_size() const { return m_pgn_size; } + std::size_t polygon_size() const { return m_pgn_size; } - void set_polygon_size(unsigned int pgn_size) const { m_pgn_size = pgn_size; } + void set_polygon_size(std::size_t pgn_size) const { m_pgn_size = pgn_size; } - bool is_valid_index(unsigned int index) const + bool is_valid_index(std::size_t index) const { return (index < m_pgn_size); } - unsigned int invalid_index() const { return (m_pgn_size); } + std::size_t invalid_index() const { return (m_pgn_size); } class Intersect_2 { private: @@ -129,12 +125,9 @@ public: template OutputIterator operator()(const X_monotone_curve_2& cv1, const X_monotone_curve_2& cv2, - OutputIterator oi) const - { - typedef const std::pair - Intersection_base_point; - typedef std::variant - Intersection_base_result; + OutputIterator oi) const { + using Intersection_base_point = const std::pair; + using Intersection_base_result = std::variant; const auto* base_traits = m_traits.m_base_traits; auto base_cmp_xy = base_traits->compare_xy_2_object(); @@ -146,7 +139,7 @@ public: //if (m_traits.is_valid_index(cv1.data().index()) && // m_traits.is_valid_index(cv2.data().index())) //{ - // unsigned int index_diff = + // std::size_t index_diff = // (cv1.data().index() > cv2.data().index()) ? // (cv1.data().index() - cv2.data().index()): // (cv2.data().index() - cv1.data().index()); @@ -180,8 +173,8 @@ public: std::get_if(&xection); CGAL_assertion(overlap_cv != nullptr); - unsigned int ov_bc; - unsigned int ov_twin_bc; + std::size_t ov_bc; + std::size_t ov_twin_bc; if (base_cmp_endpoints(cv1) == base_cmp_endpoints(cv2)) { // cv1 and cv2 have the same directions ov_bc = cv1.data().bc() + cv2.data().bc(); @@ -207,7 +200,7 @@ public: }; /*! Obtain an Intersect_2 functor object. */ - Intersect_2 intersect_2_object () const { return Intersect_2(*this); } + Intersect_2 intersect_2_object() const { return Intersect_2(*this); } class Split_2 { private: @@ -220,8 +213,7 @@ public: public: void operator()(const X_monotone_curve_2& cv, const Point_2 & p, - X_monotone_curve_2& c1, X_monotone_curve_2& c2) const - { + X_monotone_curve_2& c1, X_monotone_curve_2& c2) const { const auto* base_traits = m_traits.m_base_traits; auto base_split = base_traits->split_2_object(); base_split(cv.base(), p.base(), c1.base(), c2.base()); @@ -250,8 +242,7 @@ public: * \param cv The curve. * \return The left endpoint. */ - Point_2 operator()(const X_monotone_curve_2 & cv) const - { + Point_2 operator()(const X_monotone_curve_2 & cv) const { const auto* base_traits = m_traits.m_base_traits; auto base_ctr_min_vertex = base_traits->construct_min_vertex_2_object(); @@ -290,8 +281,7 @@ public: * \param cv The curve. * \return The left endpoint. */ - Point_2 operator() (const X_monotone_curve_2 & cv) const - { + Point_2 operator() (const X_monotone_curve_2 & cv) const { const auto* base_traits = m_traits.m_base_traits; auto base_ctr_max_vertex = base_traits->construct_max_vertex_2_object(); if (! m_traits.is_valid_index(cv.data().index())) @@ -329,8 +319,7 @@ public: * \param cv The curve. * \return The left endpoint. */ - Comparison_result operator()(const Point_2& p1, const Point_2& p2) const - { + Comparison_result operator()(const Point_2& p1, const Point_2& p2) const { const auto* base_traits = m_traits.m_base_traits; auto base_cmp_xy = base_traits->compare_xy_2_object(); diff --git a/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Indexed_event.h b/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Indexed_event.h index 3203bbbd7bb..2eb04e51830 100644 --- a/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Indexed_event.h +++ b/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Indexed_event.h @@ -11,8 +11,8 @@ // Ron Wein // Efi Fogel -#ifndef CGAL_BSO_2_INDEXED_VISITOR_H -#define CGAL_BSO_2_INDEXED_VISITOR_H +#ifndef CGAL_INDEXED_VISITOR_H +#define CGAL_INDEXED_VISITOR_H #include @@ -32,17 +32,16 @@ class Indexed_event : Arrangement_, Allocator_>, Allocator_>, - Arrangement_> -{ + Arrangement_> { private: - unsigned int m_index; + std::size_t m_index; public: Indexed_event() : m_index (0) {} - unsigned int index() const { return (m_index); } + std::size_t index() const { return (m_index); } - void set_index(unsigned int index) { m_index = index; } + void set_index(std::size_t index) { m_index = index; } }; } // namespace CGAL diff --git a/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Polygon_conversions.h b/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Polygon_conversions.h index 0f880d66ad2..00670b6ba88 100644 --- a/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Polygon_conversions.h +++ b/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Polygon_conversions.h @@ -31,9 +31,9 @@ namespace CGAL { // Utility struct template struct Gps_polyline_traits { - typedef typename Gps_default_traits::Arr_traits Segment_traits; - typedef Arr_polyline_traits_2 Polyline_traits; - typedef Gps_traits_2 Traits; + using Segment_traits = typename Gps_default_traits::Arr_traits; + using Polyline_traits = Arr_polyline_traits_2; + using Traits = Gps_traits_2; }; // Helper to map Polygon_2 -> General_polygon_2 / PWH_2 -> General_PWH_2 @@ -85,9 +85,7 @@ using Disable_if_Polygon_2_iterator = // Convert Polygon_2 to General_polygon_2 template General_polygon_2 -convert_polygon(const Polygon_2& polygon, - const ArrTraits& traits) -{ +convert_polygon(const Polygon_2& polygon, const ArrTraits& traits) { auto ctr = traits.construct_curve_2_object(); if (polygon.is_empty()) return General_polygon_2(); using Point = typename ArrTraits::Point_2; @@ -99,22 +97,20 @@ convert_polygon(const Polygon_2& polygon, General_polygon_2 gpgn; auto make_x_mtn = traits.make_x_monotone_2_object(); make_x_mtn(cv, - boost::make_function_output_iterator - ([&](const Make_x_monotone_result& obj) - { gpgn.push_back(*(std::get_if(&obj))); })); + boost::make_function_output_iterator([&](const Make_x_monotone_result& obj) + { gpgn.push_back(*(std::get_if(&obj))); })); return gpgn; } // Convert Polygon_with_holes_2 to General_polygon_with_holes_2 template -General_polygon_with_holes_2 > +General_polygon_with_holes_2> convert_polygon(const Polygon_with_holes_2& pwh, const ArrTraits& traits) { - typedef General_polygon_2 General_pgn; - typedef Polygon_2 Pgn; - auto converter = [&](const Pgn& pgn)->General_pgn { - return convert_polygon(pgn, traits); - }; + using General_pgn = General_polygon_2; + using Pgn = Polygon_2; + auto converter = [&](const Pgn& pgn)->General_pgn + { return convert_polygon(pgn, traits); }; return General_polygon_with_holes_2> (convert_polygon(pwh.outer_boundary(), traits), boost::make_transform_iterator(pwh.holes().begin(), converter), @@ -137,14 +133,11 @@ convert_polygon_back(const General_polygon_2& gpgn) { // Convert General_polygon_with_holes_2 to Polygon_with_holes_2 template Polygon_with_holes_2 -convert_polygon_back(const General_polygon_with_holes_2 - >& gpwh) -{ +convert_polygon_back(const General_polygon_with_holes_2>& gpwh) { using Pgn = Polygon_2; using General_pgn = General_polygon_2; - auto converter = [](const General_pgn& gpgn)->Pgn { - return convert_polygon_back(gpgn); - }; + auto converter = [](const General_pgn& gpgn)->Pgn + { return convert_polygon_back(gpgn); }; return Polygon_with_holes_2 (convert_polygon_back(gpwh.outer_boundary()), boost::make_transform_iterator(gpwh.holes().begin(), converter), @@ -155,21 +148,17 @@ convert_polygon_back(const General_polygon_with_holes_2 // Polygon_2 to General_polygon_2, or // Polygon_with_holes_2 to General_polygon_with_holes_2 template -boost::transform_iterator -::value_type>::type - (typename std::iterator_traits::reference)>, - InputIterator> -convert_polygon_iterator(InputIterator it, const Traits& traits) -{ +boost::transform_iterator::value_type>::type + (typename std::iterator_traits::reference)>, InputIterator> +convert_polygon_iterator(InputIterator it, const Traits& traits) { using Input_type = typename std::iterator_traits::value_type; using Return_type = typename General_polygon_of_polygon::type; using Function_type = std::function; - Function_type func = - [&traits](const Input_type& p)->Return_type - { return convert_polygon(p, traits); }; + Function_type func = [&traits](const Input_type& p)->Return_type + { return convert_polygon(p, traits); }; return boost::transform_iterator(it, func); } @@ -186,8 +175,7 @@ struct Polygon_converter { // Convert and export to output iterator. template - void operator()(const General_polygon_with_holes_2 - >& gpwh) const + void operator()(const General_polygon_with_holes_2>& gpwh) const { *m_output++ = convert_polygon_back(gpwh); } }; @@ -195,9 +183,7 @@ struct Polygon_converter { // OutputIterator template struct Polygon_converter_output_iterator : - boost::function_output_iterator > -{ + boost::function_output_iterator> { using Converter = Polygon_converter; using Base = boost::function_output_iterator; @@ -214,11 +200,8 @@ struct Polygon_converter_output_iterator : // (indirection with Polygon_2) template Polygon_converter_output_iterator -convert_polygon_back(OutputIterator& output, - const Polygon_2&) -{ - return Polygon_converter_output_iterator - (output); +convert_polygon_back(OutputIterator& output, const Polygon_2&) { + return Polygon_converter_output_iterator(output); } // Converts General_polygon_with_holes_2 to Polygon_with_holes_2 @@ -226,10 +209,8 @@ convert_polygon_back(OutputIterator& output, template Polygon_converter_output_iterator convert_polygon_back(OutputIterator& output, - const Polygon_with_holes_2&) -{ - return Polygon_converter_output_iterator - (output); + const Polygon_with_holes_2&) { + return Polygon_converter_output_iterator(output); } template @@ -238,7 +219,6 @@ struct Iterator_to_gps_traits { typedef typename Gps_default_traits::Traits Traits; }; - } -#endif // CGAL_BSO_POLYGON_CONVERSIONS_H +#endif diff --git a/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/do_intersect.h b/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/do_intersect.h index c81f2397ba4..5b7b7f7b655 100644 --- a/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/do_intersect.h +++ b/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/do_intersect.h @@ -8,10 +8,10 @@ // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // // -// Author(s): Baruch Zukerman -// Ron Wein -// Efi Fogel -// Simon Giraudot +// Author(s) : Baruch Zukerman +// Ron Wein +// Efi Fogel +// Simon Giraudot #ifndef CGAL_BOOLEAN_SET_OPERATIONS_2_DO_INTERSECT_H #define CGAL_BOOLEAN_SET_OPERATIONS_2_DO_INTERSECT_H @@ -33,12 +33,18 @@ #include #include -namespace CGAL -{ +namespace CGAL { /// \name do_intersect() functions. //@{ +/*! We do not use polyline for do_intersect), as we relly on the overlay traits + * to only intercept intersections between the interiors of segments that + * comprise the boundary of polygons. Observe that The intersections between the + * interiors of polylines that comprise the boundary of polygons may include an + * endpoint of a segment, and we do not want that. + */ + // Polygon_2, Polygon_2 ======================================================== // With Traits template @@ -47,24 +53,24 @@ inline bool do_intersect(const Polygon_2& pgn1, Traits& traits) { return s_do_intersect(pgn1, pgn2, traits); } -// With Tag_true +// without traits template inline bool do_intersect(const Polygon_2& pgn1, - const Polygon_2& pgn2, - Tag_true = Tag_true()) -{ return s_do_intersect(pgn1, pgn2); } - -// With Tag_false -template -inline bool do_intersect(const Polygon_2& pgn1, - const Polygon_2& pgn2, - Tag_false) -{ - typedef Polygon_2 Polygon; + const Polygon_2& pgn2) { + using Polygon = Polygon_2; typename Gps_default_traits::Traits traits; return s_do_intersect(pgn1, pgn2, traits); } +#ifndef CGAL_NO_DEPRECATED_CODE +template +inline bool do_intersect(const Polygon_2& pgn1, + const Polygon_2& pgn2, + std::bool_constant) { + return do_intersect(pgn1, pgn2); +} +#endif + // Polygon_2, Polygon_with_hole_2 ============================================== // With Traits template @@ -73,25 +79,25 @@ inline bool do_intersect(const Polygon_2& pgn1, Traits& traits) { return s_do_intersect(pgn1, pgn2, traits); } -// With Tag_true +// Without traits template inline bool do_intersect(const Polygon_2& pgn1, - const Polygon_with_holes_2& pgn2, - Tag_true = Tag_true()) -{ return s_do_intersect(pgn1, pgn2); } - -// With Tag_false -template -inline bool do_intersect(const Polygon_2& pgn1, - const Polygon_with_holes_2& pgn2, - Tag_false) -{ + const Polygon_with_holes_2& pgn2) { // Use the first polygon to determine the (default) traits - typedef Polygon_2 Polygon; + using Polygon = Polygon_2; typename Gps_default_traits::Traits traits; return s_do_intersect(pgn1, pgn2, traits); } +#ifndef CGAL_NO_DEPRECATED_CODE +template +inline bool do_intersect(const Polygon_2& pgn1, + const Polygon_with_holes_2& pgn2, + std::bool_constant) { + return do_intersect(pgn1, pgn2); +} +#endif + // Polygon_with_hole_2, Polygon_2 ============================================== // With Traits template @@ -100,25 +106,25 @@ inline bool do_intersect(const Polygon_with_holes_2& pgn1, Traits& traits) { return s_do_intersect(pgn1, pgn2, traits); } -// With Tag_true +// Without traits template inline bool do_intersect(const Polygon_with_holes_2& pgn1, - const Polygon_2& pgn2, - Tag_true = Tag_true()) -{ return s_do_intersect(pgn1, pgn2); } - -// With Tag_false -template -inline bool do_intersect(const Polygon_with_holes_2& pgn1, - const Polygon_2& pgn2, - Tag_false) -{ + const Polygon_2& pgn2) { // Use the first polygon to determine the (default) traits - typedef Polygon_with_holes_2 Polygon_with_holes; + using Polygon_with_holes = Polygon_with_holes_2; typename Gps_default_traits::Traits traits; return s_do_intersect(pgn1, pgn2, traits); } +#ifndef CGAL_NO_DEPRECATED_CODE +template +inline bool do_intersect(const Polygon_with_holes_2& pgn1, + const Polygon_2& pgn2, + std::bool_constant) { + return do_intersect(pgn1, pgn2); +} +#endif + // Polygon_with_hole_2, Polygon_with_hole_2 ==================================== // With Traits template @@ -127,25 +133,25 @@ inline bool do_intersect(const Polygon_with_holes_2& pgn1, Traits& traits) { return s_do_intersect(pgn1, pgn2, traits); } -// With Tag_true +// Without traits template inline bool do_intersect(const Polygon_with_holes_2& pgn1, - const Polygon_with_holes_2& pgn2, - Tag_true = Tag_true()) -{ return s_do_intersect(pgn1, pgn2); } - -// With Tag_false -template -inline bool do_intersect(const Polygon_with_holes_2& pgn1, - const Polygon_with_holes_2& pgn2, - Tag_false) -{ + const Polygon_with_holes_2& pgn2) { // Use the first polygon to determine the (default) traits - typedef Polygon_with_holes_2 Polygon_with_holes; + using Polygon_with_holes = Polygon_with_holes_2; typename Gps_default_traits::Traits traits; return s_do_intersect(pgn1, pgn2, traits); } +#ifndef CGAL_NO_DEPRECATED_CODE +template +inline bool do_intersect(const Polygon_with_holes_2& pgn1, + const Polygon_with_holes_2& pgn2, + std::bool_constant) { + return do_intersect(pgn1, pgn2); +} +#endif + // General_polygon_2, General_polygon_2 ======================================== // With Traits template @@ -157,14 +163,22 @@ inline bool do_intersect(const General_polygon_2& pgn1, // Without Traits template inline bool do_intersect(const General_polygon_2& pgn1, - const General_polygon_2& pgn2) -{ + const General_polygon_2& pgn2) { // Use the first polygon to determine the (default) traits - typedef General_polygon_2 Polygon; + using Polygon = General_polygon_2; typename Gps_default_traits::Traits traits; return s_do_intersect(pgn1, pgn2, traits); } +#ifndef CGAL_NO_DEPRECATED_CODE +template +inline bool do_intersect(const General_polygon_2& pgn1, + const General_polygon_2& pgn2, + std::bool_constant) { + return do_intersect(pgn1, pgn2); +} +#endif + // General_polygon_2, General_polygon_with_holes_2 ============================= // With Traits template @@ -178,14 +192,23 @@ inline bool do_intersect(const General_polygon_2& pgn1, template inline bool do_intersect(const General_polygon_2& pgn1, const General_polygon_with_holes_2 - >& pgn2) -{ + >& pgn2) { // Use the first polygon to determine the (default) traits - typedef General_polygon_2 Polygon; + using Polygon = General_polygon_2; typename Gps_default_traits::Traits traits; return s_do_intersect(pgn1, pgn2, traits); } +#ifndef CGAL_NO_DEPRECATED_CODE +template +inline bool do_intersect(const General_polygon_2& pgn1, + const General_polygon_with_holes_2 + >& pgn2, + std::bool_constant) { + return do_intersect(pgn1, pgn2); +} +#endif + // General_polygon_with_holes_2, General_polygon_2 ============================= // With Traits template @@ -199,15 +222,25 @@ inline bool do_intersect(const General_polygon_with_holes_2 template inline bool do_intersect(const General_polygon_with_holes_2 >& pgn1, - const General_polygon_2& pgn2) -{ + const General_polygon_2& pgn2) { // Use the first polygon to determine the (default) traits - typedef General_polygon_2 Polygon; - typedef General_polygon_with_holes_2 Polygon_with_holes; + using Polygon = General_polygon_2; + using Polygon_with_holes = General_polygon_with_holes_2; typename Gps_default_traits::Traits traits; return s_do_intersect(pgn1, pgn2, traits); } +#ifndef CGAL_NO_DEPRECATED_CODE +template +inline bool do_intersect(const General_polygon_with_holes_2 + >& pgn1, + const General_polygon_2& pgn2, + std::bool_constant) { + return do_intersect(pgn1, pgn2); +} +#endif + + // General_polygon_with_holes_2, General_polygon_with_holes_2 ================== // With Traits template @@ -219,14 +252,22 @@ inline bool do_intersect(const General_polygon_with_holes_2& pgn1, // Without Traits template inline bool do_intersect(const General_polygon_with_holes_2& pgn1, - const General_polygon_with_holes_2& pgn2) -{ + const General_polygon_with_holes_2& pgn2) { // Use the first polygon to determine the (default) traits - typedef General_polygon_with_holes_2 Polygon_with_holes; + using Polygon_with_holes = General_polygon_with_holes_2; typename Gps_default_traits::Traits traits; return s_do_intersect(pgn1, pgn2, traits); } +#ifndef CGAL_NO_DEPRECATED_CODE +template +inline bool do_intersect(const General_polygon_with_holes_2& pgn1, + const General_polygon_with_holes_2& pgn2, + std::bool_constant) { + return do_intersect(pgn1, pgn2); +} +#endif + //@} /// \name Aggregated do_intersect() functions. @@ -235,26 +276,15 @@ inline bool do_intersect(const General_polygon_with_holes_2& pgn1, // With Traits template inline bool do_intersect(InputIterator begin, InputIterator end, Traits& traits, - unsigned int k=5, + std::size_t k = 5, std::enable_if_t::value>* = 0) { return r_do_intersect(begin, end, traits, k); } // Without Traits -// Tag_true => convert to polylines template -inline bool do_intersect(InputIterator begin, InputIterator end, - Tag_true = Tag_true(), unsigned int k=5, +inline bool do_intersect(InputIterator begin, InputIterator end, std::size_t k = 5, std::enable_if_t::value>* = 0, - Enable_if_Polygon_2_iterator* = 0) -{ return r_do_intersect(begin, end, k); } - -// Tag_false => do not convert to polylines -template -inline bool do_intersect(InputIterator begin, InputIterator end, - Tag_false, unsigned int k=5, - std::enable_if_t::value>* = 0, - Enable_if_Polygon_2_iterator* = 0) -{ + Enable_if_Polygon_2_iterator* = 0) { typename Iterator_to_gps_traits::Traits traits; return r_do_intersect(begin, end, traits, k); } @@ -262,49 +292,57 @@ inline bool do_intersect(InputIterator begin, InputIterator end, // General polygons or polygons with holes template inline bool do_intersect(InputIterator begin, InputIterator end, - unsigned int k=5, + std::size_t k = 5, std::enable_if_t::value>* = 0, - Disable_if_Polygon_2_iterator* = 0) -{ + Disable_if_Polygon_2_iterator* = 0) { typename Iterator_to_gps_traits::Traits traits; return do_intersect(begin, end, traits, k); } +#ifndef CGAL_NO_DEPRECATED_CODE +template +inline bool do_intersect(InputIterator begin, InputIterator end, std::bool_constant, + std::enable_if_t::value>* = 0) { + return do_intersect(begin, end); +} +#endif + // With Traits template inline bool do_intersect(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, InputIterator2 end2, - Traits& traits, unsigned int k=5) + Traits& traits, std::size_t k = 5) { return r_do_intersect(begin1, end1, begin2, end2, traits, k); } // Without Traits -// Tag_true => convert to polylines template -inline bool do_intersect (InputIterator1 begin1, InputIterator1 end1, - InputIterator2 begin2, InputIterator2 end2, - Tag_true = Tag_true(), unsigned int k=5, - Enable_if_Polygon_2_iterator* = 0) -{ return r_do_intersect(begin1, end1, begin2, end2, k); } - -// Tag_false => do not convert to polylines -template -inline bool do_intersect (InputIterator1 begin1, InputIterator1 end1, - InputIterator2 begin2, InputIterator2 end2, - Tag_false, unsigned int k=5, - Enable_if_Polygon_2_iterator* = 0) +inline bool do_intersect(InputIterator1 begin1, InputIterator1 end1, + InputIterator2 begin2, InputIterator2 end2, + std::size_t k = 5, + Enable_if_Polygon_2_iterator* = 0) { return r_do_intersect(begin1, end1, begin2, end2, k); } // General polygons or polygons with holes template -inline bool do_intersect (InputIterator1 begin1, InputIterator1 end1, - InputIterator2 begin2, InputIterator2 end2, - unsigned int k=5, - Disable_if_Polygon_2_iterator* = 0) -{ +inline bool do_intersect(InputIterator1 begin1, InputIterator1 end1, + InputIterator2 begin2, InputIterator2 end2, + std::size_t k = 5, + Disable_if_Polygon_2_iterator* = 0) { typename Iterator_to_gps_traits::Traits traits; return r_do_intersect(begin1, end1, begin2, end2, traits, k); } +#ifndef CGAL_NO_DEPRECATED_CODE +template +inline bool do_intersect(InputIterator1 begin1, InputIterator1 end1, + InputIterator2 begin2, InputIterator2 end2, + std::bool_constant, + std::enable_if_t::value && + CGAL::is_iterator::value >* = 0) { + return do_intersect(begin1, end1, begin2, end2); +} +#endif + //@} } //namespace CGAL diff --git a/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/intersection.h b/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/intersection.h index 180fe406107..f38054d63c4 100644 --- a/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/intersection.h +++ b/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/intersection.h @@ -7,11 +7,10 @@ // $Id$ // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // -// -// Author(s): Baruch Zukerman -// Ron Wein -// Efi Fogel -// Simon Giraudot +// Author(s) : Baruch Zukerman +// Ron Wein +// Efi Fogel +// Simon Giraudot #ifndef CGAL_BOOLEAN_SET_OPERATIONS_2_INTERSECTION_H #define CGAL_BOOLEAN_SET_OPERATIONS_2_INTERSECTION_H @@ -33,8 +32,7 @@ #include #include -namespace CGAL -{ +namespace CGAL { /// \name intersection() functions. //@{ @@ -59,10 +57,9 @@ inline OutputIterator intersection(const Polygon_2& pgn1, template inline OutputIterator intersection(const Polygon_2& pgn1, const Polygon_2& pgn2, - OutputIterator out, Tag_false) -{ + OutputIterator out, Tag_false) { // Use the first polygon to determine the (default) traits - typedef Polygon_2 Polygon; + using Polygon = Polygon_2; typename Gps_default_traits::Traits traits; return s_intersection(pgn1, pgn2, out, traits); } @@ -90,10 +87,9 @@ template inline OutputIterator intersection(const Polygon_2& pgn1, const Polygon_with_holes_2& pgn2, - OutputIterator out, Tag_false) -{ + OutputIterator out, Tag_false) { // Use the first polygon to determine the (default) traits - typedef Polygon_2 Polygon; + using Polygon = Polygon_2; typename Gps_default_traits::Traits traits; return s_intersection(pgn1, pgn2, out, traits); } @@ -121,10 +117,9 @@ template inline OutputIterator intersection(const Polygon_with_holes_2& pgn1, const Polygon_2& pgn2, - OutputIterator out, Tag_false) -{ + OutputIterator out, Tag_false) { // Use the first polygon to determine the (default) traits - typedef Polygon_with_holes_2 Polygon_with_holes; + using Polygon_with_holes = Polygon_with_holes_2; typename Gps_default_traits::Traits traits; return s_intersection(pgn1, pgn2, out, traits); } @@ -152,10 +147,9 @@ template inline OutputIterator intersection(const Polygon_with_holes_2& pgn1, const Polygon_with_holes_2& pgn2, - OutputIterator out, Tag_false) -{ + OutputIterator out, Tag_false) { // Use the first polygon to determine the (default) traits - typedef Polygon_with_holes_2 Polygon_with_holes; + using Polygon_with_holes = Polygon_with_holes_2; typename Gps_default_traits::Traits traits; return s_intersection(pgn1, pgn2, out, traits); } @@ -172,10 +166,9 @@ inline OutputIterator intersection(const General_polygon_2& pgn1, template inline OutputIterator intersection(const General_polygon_2& pgn1, const General_polygon_2& pgn2, - OutputIterator out) -{ + OutputIterator out) { // Use the first polygon to determine the (default) traits - typedef General_polygon_2 Polygon; + using Polygon = General_polygon_2; typename Gps_default_traits::Traits traits; return s_intersection(pgn1, pgn2, out, traits); } @@ -194,10 +187,9 @@ template inline OutputIterator intersection(const General_polygon_2& pgn1, const General_polygon_with_holes_2 >& pgn2, - OutputIterator out) -{ + OutputIterator out) { // Use the first polygon to determine the (default) traits - typedef General_polygon_2 Polygon; + using Polygon = General_polygon_2; typename Gps_default_traits::Traits traits; return s_intersection(pgn1, pgn2, out, traits); } @@ -216,11 +208,10 @@ template inline OutputIterator intersection(const General_polygon_with_holes_2 >& pgn1, const General_polygon_2& pgn2, - OutputIterator out) -{ + OutputIterator out) { // Use the first polygon to determine the (default) traits - typedef General_polygon_2 Polygon; - typedef General_polygon_with_holes_2 Polygon_with_holes; + using Polygon = General_polygon_2; + using Polygon_with_holes = General_polygon_with_holes_2; typename Gps_default_traits::Traits traits; return s_intersection(pgn1, pgn2, out, traits); } @@ -239,10 +230,9 @@ template inline OutputIterator intersection(const General_polygon_with_holes_2& pgn1, const General_polygon_with_holes_2& pgn2, - OutputIterator out) -{ + OutputIterator out) { // Use the first polygon to determine the (default) traits - typedef General_polygon_with_holes_2 Polygon_with_holes; + using Polygon_with_holes = General_polygon_with_holes_2; typename Gps_default_traits::Traits traits; return s_intersection(pgn1, pgn2, out, traits); } @@ -256,7 +246,7 @@ intersection(const General_polygon_with_holes_2& pgn1, template inline OutputIterator intersection(InputIterator begin, InputIterator end, OutputIterator oi, Traits& traits, - unsigned int k=5) + std::size_t k = 5) { return r_intersection(begin, end, oi, traits, k); } // Without Traits @@ -265,7 +255,7 @@ template inline OutputIterator intersection(InputIterator begin, InputIterator end, OutputIterator oi, Tag_true = Tag_true(), - unsigned int k=5, + std::size_t k = 5, Enable_if_Polygon_2_iterator* = 0) { return r_intersection(begin, end, oi, k); } @@ -273,9 +263,8 @@ intersection(InputIterator begin, InputIterator end, template inline OutputIterator intersection(InputIterator begin, InputIterator end, - OutputIterator oi, Tag_false, unsigned int k=5, - Enable_if_Polygon_2_iterator* = 0) -{ + OutputIterator oi, Tag_false, std::size_t k = 5, + Enable_if_Polygon_2_iterator* = 0) { typename Iterator_to_gps_traits::Traits traits; return r_intersection(begin, end, oi, traits, k); } @@ -284,11 +273,10 @@ intersection(InputIterator begin, InputIterator end, template inline OutputIterator intersection(InputIterator begin, InputIterator end, - OutputIterator oi, unsigned int k=5, + OutputIterator oi, std::size_t k = 5, // workaround to avoid ambiguous calls with kernel functions std::enable_if_t::value>* = 0, - Disable_if_Polygon_2_iterator* = 0) -{ + Disable_if_Polygon_2_iterator* = 0) { typename Iterator_to_gps_traits::Traits traits; return r_intersection(begin, end, oi, traits, k); } @@ -300,7 +288,7 @@ template * = 0) { return r_intersection(begin1, end1, begin2, end2, oi, k); } @@ -320,9 +308,8 @@ template * = 0) -{ + OutputIterator oi, Tag_false, std::size_t k = 5, + Enable_if_Polygon_2_iterator* = 0) { typename Iterator_to_gps_traits::Traits traits; return r_intersection(begin1, end1, begin2, end2, oi, traits, k); } @@ -333,9 +320,8 @@ template * = 0) -{ + OutputIterator oi, std::size_t k = 5, + Disable_if_Polygon_2_iterator* = 0) { typename Iterator_to_gps_traits::Traits traits; return r_intersection(begin1, end1, begin2, end2, oi, traits, k); } diff --git a/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/join.h b/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/join.h index 9ec9ea2527d..88c0d338b0e 100644 --- a/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/join.h +++ b/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/join.h @@ -7,11 +7,10 @@ // $Id$ // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // -// -// Author(s): Baruch Zukerman -// Ron Wein -// Efi Fogel -// Simon Giraudot +// Author(s) : Baruch Zukerman +// Ron Wein +// Efi Fogel +// Simon Giraudot #ifndef CGAL_BOOLEAN_SET_OPERATIONS_2_JOIN_H #define CGAL_BOOLEAN_SET_OPERATIONS_2_JOIN_H @@ -33,8 +32,7 @@ #include #include -namespace CGAL -{ +namespace CGAL { /// \name join() functions. //@{ @@ -60,10 +58,9 @@ template inline bool join(const Polygon_2& pgn1, const Polygon_2& pgn2, Polygon_with_holes_2& res, - Tag_false) -{ + Tag_false) { // Use the first polygon to determine the (default) traits - typedef Polygon_2 Polygon; + using Polygon = Polygon_2; typename Gps_default_traits::Traits traits; return s_join(pgn1, pgn2, res, traits); } @@ -89,10 +86,9 @@ template inline bool join(const Polygon_2& pgn1, const Polygon_with_holes_2& pgn2, Polygon_with_holes_2& res, - Tag_false) -{ + Tag_false) { // Use the first polygon to determine the (default) traits - typedef Polygon_2 Polygon; + using Polygon = Polygon_2; typename Gps_default_traits::Traits traits; return s_join(pgn1, pgn2, res, traits); } @@ -118,10 +114,9 @@ template inline bool join(const Polygon_with_holes_2& pgn1, const Polygon_2& pgn2, Polygon_with_holes_2& res, - Tag_false) -{ + Tag_false) { // Use the first polygon to determine the (default) traits - typedef Polygon_with_holes_2 Polygon_with_holes; + using Polygon_with_holes = Polygon_with_holes_2; typename Gps_default_traits::Traits traits; return s_join(pgn1, pgn2, res, traits); } @@ -147,10 +142,9 @@ template inline bool join(const Polygon_with_holes_2& pgn1, const Polygon_with_holes_2& pgn2, Polygon_with_holes_2& res, - Tag_false) -{ + Tag_false) { // Use the first polygon to determine the (default) traits - typedef Polygon_with_holes_2 Polygon_with_holes; + using Polygon_with_holes = Polygon_with_holes_2; typename Gps_default_traits::Traits traits; return s_join(pgn1, pgn2, res, traits); } @@ -170,10 +164,9 @@ template inline bool join(const General_polygon_2& pgn1, const General_polygon_2& pgn2, - General_polygon_with_holes_2 >& res) -{ + General_polygon_with_holes_2 >& res) { // Use the first polygon to determine the (default) traits - typedef General_polygon_2 Polygon; + using Polygon = General_polygon_2; typename Gps_default_traits::Traits traits; return s_join(pgn1, pgn2, res, traits); } @@ -193,10 +186,9 @@ template inline bool join(const General_polygon_2& pgn1, const General_polygon_with_holes_2 >& pgn2, - General_polygon_with_holes_2 >& res) -{ + General_polygon_with_holes_2 >& res) { // Use the first polygon to determine the (default) traits - typedef General_polygon_2 Polygon; + using Polygon = General_polygon_2; typename Gps_default_traits::Traits traits; return s_join(pgn1, pgn2, res, traits); } @@ -216,11 +208,10 @@ template inline bool join(const General_polygon_with_holes_2 >& pgn1, const General_polygon_2& pgn2, - General_polygon_with_holes_2 >& res) -{ + General_polygon_with_holes_2 >& res) { // Use the first polygon to determine the (default) traits - typedef General_polygon_2 Polygon; - typedef General_polygon_with_holes_2 Polygon_with_holes; + using Polygon = General_polygon_2; + using Polygon_with_holes = General_polygon_with_holes_2; typename Gps_default_traits::Traits traits; return s_join(pgn1, pgn2, res, traits); } @@ -237,10 +228,9 @@ inline bool join(const General_polygon_with_holes_2& pgn1, template inline bool join(const General_polygon_with_holes_2& pgn1, const General_polygon_with_holes_2& pgn2, - General_polygon_with_holes_2& res) -{ + General_polygon_with_holes_2& res) { // Use the first polygon to determine the (default) traits - typedef General_polygon_with_holes_2 Polygon_with_holes; + using Polygon_with_holes = General_polygon_with_holes_2; typename Gps_default_traits::Traits traits; return s_join(pgn1, pgn2, res, traits); } @@ -253,7 +243,7 @@ inline bool join(const General_polygon_with_holes_2& pgn1, // With Traits template inline OutputIterator join(InputIterator begin, InputIterator end, - OutputIterator oi, Traits& traits, unsigned int k=5) + OutputIterator oi, Traits& traits, std::size_t k = 5) { return r_join(begin, end, oi, traits, k); } // Without Traits @@ -261,16 +251,15 @@ inline OutputIterator join(InputIterator begin, InputIterator end, template inline OutputIterator join(InputIterator begin, InputIterator end, OutputIterator oi, Tag_true = Tag_true(), - unsigned int k=5, + std::size_t k = 5, Enable_if_Polygon_2_iterator* = 0) { return r_join(begin, end, oi, k); } // Tag_false => do not convert to polylines template inline OutputIterator join(InputIterator begin, InputIterator end, - OutputIterator oi, Tag_false, unsigned int k=5, - Enable_if_Polygon_2_iterator* = 0) -{ + OutputIterator oi, Tag_false, std::size_t k = 5, + Enable_if_Polygon_2_iterator* = 0) { typename Iterator_to_gps_traits::Traits traits; return r_join(begin, end, oi, traits, k); } @@ -278,9 +267,8 @@ inline OutputIterator join(InputIterator begin, InputIterator end, // General polygons or polygons with holes template inline OutputIterator join(InputIterator begin, InputIterator end, - OutputIterator oi, unsigned int k=5, - Disable_if_Polygon_2_iterator* = 0) -{ + OutputIterator oi, std::size_t k = 5, + Disable_if_Polygon_2_iterator* = 0) { typename Iterator_to_gps_traits::Traits traits; return r_join(begin, end, oi, traits, k); } @@ -291,7 +279,7 @@ template inline OutputIterator join(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, InputIterator2 end2, - OutputIterator oi, Traits& traits, unsigned int k=5) + OutputIterator oi, Traits& traits, std::size_t k = 5) { return r_join(begin1, end1, begin2, end2, oi, traits, k); } // Without Traits @@ -301,7 +289,7 @@ template * = 0) { return r_join(begin1, end1, begin2, end2, oi, k); } @@ -310,9 +298,8 @@ template inline OutputIterator join(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, InputIterator2 end2, - OutputIterator oi, Tag_false, unsigned int k=5, - Enable_if_Polygon_2_iterator* = 0) -{ + OutputIterator oi, Tag_false, std::size_t k = 5, + Enable_if_Polygon_2_iterator* = 0) { typename Iterator_to_gps_traits::Traits traits; return r_join(begin1, end1, begin2, end2, oi, traits, k); } @@ -322,9 +309,8 @@ template inline OutputIterator join(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, InputIterator2 end2, - OutputIterator oi, unsigned int k=5, - Disable_if_Polygon_2_iterator* = 0) -{ + OutputIterator oi, std::size_t k = 5, + Disable_if_Polygon_2_iterator* = 0) { typename Iterator_to_gps_traits::Traits traits; return r_join(begin1, end1, begin2, end2, oi, traits, k); } diff --git a/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/symmetric_difference.h b/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/symmetric_difference.h index dfe0297dcde..544bf4d0dc3 100644 --- a/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/symmetric_difference.h +++ b/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/symmetric_difference.h @@ -7,11 +7,10 @@ // $Id$ // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // -// -// Author(s): Baruch Zukerman -// Ron Wein -// Efi Fogel -// Simon Giraudot +// Author(s) : Baruch Zukerman +// Ron Wein +// Efi Fogel +// Simon Giraudot #ifndef CGAL_BOOLEAN_SET_OPERATIONS_SYMMETRIC_DIFFERENCE_H #define CGAL_BOOLEAN_SET_OPERATIONS_SYMMETRIC_DIFFERENCE_H @@ -33,8 +32,7 @@ #include #include -namespace CGAL -{ +namespace CGAL { /// \name symmetric_difference() functions. //@{ @@ -62,10 +60,9 @@ template inline OutputIterator symmetric_difference(const Polygon_2& pgn1, const Polygon_2& pgn2, - OutputIterator oi, Tag_false) -{ + OutputIterator oi, Tag_false) { // Use the first polygon to determine the (default) traits - typedef Polygon_2 Polygon; + using Polygon = Polygon_2; typename Gps_default_traits::Traits traits; return s_symmetric_difference(pgn1, pgn2, oi, traits); } @@ -93,10 +90,9 @@ template inline OutputIterator symmetric_difference(const Polygon_2& pgn1, const Polygon_with_holes_2& pgn2, - OutputIterator oi, Tag_false) -{ + OutputIterator oi, Tag_false) { // Use the first polygon to determine the (default) traits - typedef Polygon_2 Polygon; + using Polygon = Polygon_2; typename Gps_default_traits::Traits traits; return s_symmetric_difference(pgn1, pgn2, oi, traits); } @@ -124,10 +120,9 @@ template inline OutputIterator symmetric_difference(const Polygon_with_holes_2& pgn1, const Polygon_2& pgn2, - OutputIterator oi, Tag_false) -{ + OutputIterator oi, Tag_false) { // Use the first polygon to determine the (default) traits - typedef Polygon_with_holes_2 Polygon_with_holes; + using Polygon_with_holes = Polygon_with_holes_2; typename Gps_default_traits::Traits traits; return s_symmetric_difference(pgn1, pgn2, oi, traits); } @@ -155,10 +150,9 @@ template inline OutputIterator symmetric_difference(const Polygon_with_holes_2& pgn1, const Polygon_with_holes_2& pgn2, - OutputIterator oi, Tag_false) -{ + OutputIterator oi, Tag_false) { // Use the first polygon to determine the (default) traits - typedef Polygon_with_holes_2 Polygon_with_holes; + using Polygon_with_holes = Polygon_with_holes_2; typename Gps_default_traits::Traits traits; return s_symmetric_difference(pgn1, pgn2, oi, traits); } @@ -176,10 +170,9 @@ template inline OutputIterator symmetric_difference(const General_polygon_2& pgn1, const General_polygon_2& pgn2, - OutputIterator oi) -{ + OutputIterator oi) { // Use the first polygon to determine the (default) traits - typedef General_polygon_2 Polygon; + using Polygon = General_polygon_2; typename Gps_default_traits::Traits traits; return s_symmetric_difference(pgn1, pgn2, oi, traits); } @@ -200,10 +193,9 @@ inline OutputIterator symmetric_difference(const General_polygon_2& pgn1, const General_polygon_with_holes_2 >& pgn2, - OutputIterator oi) -{ + OutputIterator oi) { // Use the first polygon to determine the (default) traits - typedef General_polygon_2 Polygon; + using Polygon = General_polygon_2; typename Gps_default_traits::Traits traits; return s_symmetric_difference(pgn1, pgn2, oi, traits); } @@ -224,11 +216,10 @@ inline OutputIterator symmetric_difference(const General_polygon_with_holes_2 >& pgn1, const General_polygon_2& pgn2, - OutputIterator oi) -{ + OutputIterator oi) { // Use the first polygon to determine the (default) traits - typedef General_polygon_2 Polygon; - typedef General_polygon_with_holes_2 Polygon_with_holes; + using Polygon = General_polygon_2; + using Polygon_with_holes = General_polygon_with_holes_2; typename Gps_default_traits::Traits traits; return s_symmetric_difference(pgn1, pgn2, oi, traits); } @@ -247,9 +238,8 @@ template inline OutputIterator symmetric_difference(const General_polygon_with_holes_2& pgn1, const General_polygon_with_holes_2& pgn2, - OutputIterator oi) -{ - typedef General_polygon_with_holes_2 Polygon_with_holes; + OutputIterator oi) { + using Polygon_with_holes = General_polygon_with_holes_2; typename Gps_default_traits::Traits traits; return s_symmetric_difference(pgn1, pgn2, oi, traits); } @@ -264,7 +254,7 @@ template inline OutputIterator symmetric_difference(InputIterator begin, InputIterator end, OutputIterator oi, Traits& traits, - unsigned int k=5) + std::size_t k = 5) { return r_symmetric_difference(begin, end, oi, traits, k); } // Without Traits @@ -272,7 +262,7 @@ OutputIterator symmetric_difference(InputIterator begin, InputIterator end, template inline OutputIterator symmetric_difference(InputIterator begin, InputIterator end, - OutputIterator oi, Tag_true = Tag_true(), unsigned int k=5, + OutputIterator oi, Tag_true = Tag_true(), std::size_t k = 5, Enable_if_Polygon_2_iterator* = 0) { return r_symmetric_difference(begin, end, oi, k); } @@ -280,9 +270,8 @@ symmetric_difference(InputIterator begin, InputIterator end, template inline OutputIterator symmetric_difference(InputIterator begin, InputIterator end, - OutputIterator oi, Tag_false, unsigned int k=5, - Enable_if_Polygon_2_iterator* = 0) -{ + OutputIterator oi, Tag_false, std::size_t k = 5, + Enable_if_Polygon_2_iterator* = 0) { typename Iterator_to_gps_traits::Traits traits; return r_symmetric_difference(begin, end, oi, traits, k); } @@ -291,9 +280,8 @@ symmetric_difference(InputIterator begin, InputIterator end, template inline OutputIterator symmetric_difference(InputIterator begin, InputIterator end, - OutputIterator oi, unsigned int k=5, - Disable_if_Polygon_2_iterator* = 0) -{ + OutputIterator oi, std::size_t k = 5, + Disable_if_Polygon_2_iterator* = 0) { typename Iterator_to_gps_traits::Traits traits; return r_symmetric_difference(begin, end, oi, traits, k); } @@ -306,7 +294,7 @@ inline OutputIterator symmetric_difference(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, InputIterator2 end2, OutputIterator oi, Traits& traits, - unsigned int k=5) + std::size_t k = 5) { return r_symmetric_difference(begin1, end1, begin2, end2, oi, traits, k); } // Without Traits @@ -316,7 +304,7 @@ template * = 0) { return r_symmetric_difference(begin1, end1, begin2, end2, oi, k); } @@ -326,9 +314,8 @@ template * = 0) -{ + OutputIterator oi, Tag_false, std::size_t k = 5, + Enable_if_Polygon_2_iterator* = 0) { typename Iterator_to_gps_traits::Traits traits; return r_symmetric_difference(begin1, end1, begin2, end2, oi, traits, k); } @@ -339,9 +326,8 @@ template * = 0) -{ + OutputIterator oi, std::size_t k = 5, + Disable_if_Polygon_2_iterator* = 0) { typename Iterator_to_gps_traits::Traits traits; return r_symmetric_difference(begin1, end1, begin2, end2, oi, traits, k); } diff --git a/Boolean_set_operations_2/include/CGAL/General_polygon_set_2.h b/Boolean_set_operations_2/include/CGAL/General_polygon_set_2.h index 9a378e8000e..88af2b5eae7 100644 --- a/Boolean_set_operations_2/include/CGAL/General_polygon_set_2.h +++ b/Boolean_set_operations_2/include/CGAL/General_polygon_set_2.h @@ -7,8 +7,8 @@ // $Id$ // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // -// Author(s) : Baruch Zukerman -// Efi Fogel +// Author(s) : Baruch Zukerman +// Efi Fogel #ifndef CGAL_GENERAL_POLYGON_SET_2_H #define CGAL_GENERAL_POLYGON_SET_2_H @@ -27,25 +27,20 @@ namespace CGAL { // General_polygon_set_2 -template > -class General_polygon_set_2 : public General_polygon_set_on_surface_2 - ::Traits> -{ -protected: - typedef General_polygon_set_2 Self; +template > +class General_polygon_set_2 : + public General_polygon_set_on_surface_2< + Traits_, typename Default_planar_topology::Traits> { public: - typedef Traits_ Traits_2; - typedef Dcel_ Dcel; - - typedef General_polygon_set_on_surface_2 ::Traits> - Base; - - typedef CGAL::Arrangement_2 Arrangement_2; - - typedef typename Base::Polygon_2 Polygon_2; - typedef typename Base::Polygon_with_holes_2 Polygon_with_holes_2; + using Traits_2 = Traits_; + using Dcel = Dcel_; + using Self = General_polygon_set_2; + using Topology_traits = typename Default_planar_topology::Traits; + using Base = General_polygon_set_on_surface_2; + using Arrangement_2 = CGAL::Arrangement_2; + using Polygon_2 = typename Base::Polygon_2; + using Polygon_with_holes_2 = typename Base::Polygon_with_holes_2; // default constructor General_polygon_set_2() : Base() {} @@ -80,19 +75,16 @@ public: using Base::join; using Base::symmetric_difference; - inline void intersection(const Self& ps1, const Self& ps2) - { + inline void intersection(const Self& ps1, const Self& ps2) { Base::intersection(static_cast(ps1), static_cast(ps2)); } - inline void join(const Self& ps1, const Self& ps2) - { + inline void join(const Self& ps1, const Self& ps2) { Base::join(static_cast(ps1), static_cast(ps2)); } - inline void symmetric_difference(const Self& ps1, const Self& ps2) - { + inline void symmetric_difference(const Self& ps1, const Self& ps2) { Base::symmetric_difference(static_cast(ps1), static_cast(ps2)); } diff --git a/Boolean_set_operations_2/include/CGAL/General_polygon_set_on_surface_2.h b/Boolean_set_operations_2/include/CGAL/General_polygon_set_on_surface_2.h index 8e05b354176..62c50f18536 100644 --- a/Boolean_set_operations_2/include/CGAL/General_polygon_set_on_surface_2.h +++ b/Boolean_set_operations_2/include/CGAL/General_polygon_set_on_surface_2.h @@ -7,8 +7,8 @@ // $Id$ // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // -// Author(s) : Baruch Zukerman -// Efi Fogel +// Author(s): Baruch Zukerman +// Efi Fogel // Ophir Setter #ifndef CGAL_GENERAL_POLYGON_SET_ON_SURFACE_2_H @@ -23,54 +23,48 @@ namespace CGAL { -namespace Boolean_set_operation_2_internal -{ - struct PreconditionValidationPolicy - { - /*! is_valid - Checks if a Traits::Polygon_2 OR - Traits::Polygon_with_holes_2 are valid. - This validation policy checks that polygons are valid in a - CGAL_precondition macro. We inherit from Gps_on_surface_base_2 - and use preconditions to validate the input polygons. +namespace Boolean_set_operation_2_internal { + +struct PreconditionValidationPolicy { + /*! Checks if a Traits::Polygon_2 or Traits::Polygon_with_holes_2 are valid. + * This validation policy checks that polygons are valid in a + * CGAL_precondition macro. We inherit from Gps_on_surface_base_2 and use + * preconditions to validate the input polygons. */ - template - inline static void is_valid(const Polygon& p, const Traits& t) - { - CGAL_precondition(is_valid_unknown_polygon(p, t)); - CGAL_USE(p); CGAL_USE(t); - } - }; + template + inline static void is_valid(const Polygon& p, const Traits& t) { + CGAL_precondition(is_valid_unknown_polygon(p, t)); + CGAL_USE(p); CGAL_USE(t); + } +}; + } -// General_polygon_set_on_surface_2 -/* - This class is derived from Gps_on_surface_base_2. - It enforces the validation conditions for general polygons, and is therefore - the basic implementation that should be used by the user -*/ -template - class General_polygon_set_on_surface_2 : - public Gps_on_surface_base_2 -{ +/* `General_polygon_set_on_surface_2` class is derived from + * `Gps_on_surface_base_2`. It enforces the validation conditions for general + * polygons, and is therefore the basic implementation that should be used by + * the user + */ +template +class General_polygon_set_on_surface_2 : + public Gps_on_surface_base_2< + Traits_, TopTraits_, + Boolean_set_operation_2_internal::PreconditionValidationPolicy> { + protected: - typedef Traits_ Traits_2; - typedef General_polygon_set_on_surface_2 Self; - typedef Gps_on_surface_base_2 Base; + using Traits_2 = Traits_; + using Self = General_polygon_set_on_surface_2; + using Base = Gps_on_surface_base_2; public: - typedef typename Base::Polygon_2 Polygon_2; - typedef typename Base::Polygon_with_holes_2 - Polygon_with_holes_2; - typedef typename Base::Arrangement_on_surface_2 - Arrangement_on_surface_2; + using Polygon_2 = typename Base::Polygon_2; + using Polygon_with_holes_2 = typename Base::Polygon_with_holes_2; + using Arrangement_on_surface_2 = typename Base::Arrangement_on_surface_2; public: - // default constructor - General_polygon_set_on_surface_2() : Base() - {} + General_polygon_set_on_surface_2() : Base() {} // constructor from a traits object General_polygon_set_on_surface_2(const Traits_2& traits) : Base(traits) {} @@ -79,8 +73,7 @@ public: General_polygon_set_on_surface_2(const Self& ps) : Base(ps) {} // assignment operator - General_polygon_set_on_surface_2& operator=(const Self& ps) - { + General_polygon_set_on_surface_2& operator=(const Self& ps) { Base::operator=(ps); return (*this); } @@ -90,19 +83,15 @@ public: // constructor from a polygon with holes explicit - General_polygon_set_on_surface_2(const Polygon_with_holes_2& pwh) : - Base(pwh) - {} + General_polygon_set_on_surface_2(const Polygon_with_holes_2& pwh) : Base(pwh) {} // constructor from a polygon and a traits object - explicit General_polygon_set_on_surface_2(const Polygon_2& pgn, - const Traits_2& traits) : + explicit General_polygon_set_on_surface_2(const Polygon_2& pgn, const Traits_2& traits) : Base(pgn, traits) {} // constructor from a polygon with holes and a traits object explicit - General_polygon_set_on_surface_2(const Polygon_with_holes_2& pwh, - const Traits_2& traits) : + General_polygon_set_on_surface_2(const Polygon_with_holes_2& pwh, const Traits_2& traits) : Base(pwh, traits) {} @@ -142,4 +131,4 @@ private: #include -#endif // CGAL_GENERAL_POLYGON_SET_ON_SURFACE_2_H +#endif diff --git a/Boolean_set_operations_2/test/Boolean_set_operations_2/bug_3989.cpp b/Boolean_set_operations_2/test/Boolean_set_operations_2/bug_3989.cpp deleted file mode 100644 index 36c1354c549..00000000000 --- a/Boolean_set_operations_2/test/Boolean_set_operations_2/bug_3989.cpp +++ /dev/null @@ -1,48 +0,0 @@ -#include -#include -#include -#include - -typedef CGAL::Exact_predicates_exact_constructions_kernel K; - - -int main() -{ - CGAL::Polygon_2 ob; - ob.push_back(CGAL::Point_2(1, 1)); - ob.push_back(CGAL::Point_2(1, 0)); - ob.push_back(CGAL::Point_2(6, 0)); - ob.push_back(CGAL::Point_2(6, 7)); - ob.push_back(CGAL::Point_2(0, 7)); - ob.push_back(CGAL::Point_2(0, 1)); - - CGAL::Polygon_2 h; - h.push_back(CGAL::Point_2(2, 1)); - h.push_back(CGAL::Point_2(2, 2)); - h.push_back(CGAL::Point_2(3, 2)); - h.push_back(CGAL::Point_2(3, 3)); - h.push_back(CGAL::Point_2(2, 3)); - h.push_back(CGAL::Point_2(2, 4)); - h.push_back(CGAL::Point_2(3, 4)); - h.push_back(CGAL::Point_2(3, 5)); - h.push_back(CGAL::Point_2(4, 5)); - h.push_back(CGAL::Point_2(4, 1)); - - CGAL::Polygon_with_holes_2 ob_with_holes(ob); - ob_with_holes.add_hole(h); - CGAL::Polygon_set_2 inter(ob_with_holes); - - CGAL::Polygon_2 new_poly; - new_poly.push_back(CGAL::Point_2(1, 1)); - new_poly.push_back(CGAL::Point_2(2, 1)); - new_poly.push_back(CGAL::Point_2(2, 2)); - new_poly.push_back(CGAL::Point_2(2, 3)); - new_poly.push_back(CGAL::Point_2(2, 4)); - new_poly.push_back(CGAL::Point_2(2, 5)); - new_poly.push_back(CGAL::Point_2(3, 5)); - new_poly.push_back(CGAL::Point_2(4, 5)); - new_poly.push_back(CGAL::Point_2(4, 6)); - new_poly.push_back(CGAL::Point_2(1, 6)); - - inter.difference(new_poly); -} \ No newline at end of file diff --git a/Boolean_set_operations_2/test/Boolean_set_operations_2/test_compilation.cpp b/Boolean_set_operations_2/test/Boolean_set_operations_2/test_compilation.cpp index 38b40217451..065a7d27bcf 100644 --- a/Boolean_set_operations_2/test/Boolean_set_operations_2/test_compilation.cpp +++ b/Boolean_set_operations_2/test/Boolean_set_operations_2/test_compilation.cpp @@ -1,4 +1,3 @@ - #include #include @@ -13,35 +12,32 @@ #include //typedef CGAL::Quotient Number_type; -typedef int Number_type; +using Number_type = int; -typedef CGAL::Simple_cartesian Kernel; +using Kernel = CGAL::Simple_cartesian; -typedef CGAL::Gps_segment_traits_2 Traits; -typedef CGAL::Polygon_set_2 Ps; +using Traits = CGAL::Gps_segment_traits_2; +using Ps = CGAL::Polygon_set_2; -typedef CGAL::Arr_segment_traits_2 Arr_traits; -typedef CGAL::Gps_traits_2 General_traits; -typedef CGAL::General_polygon_set_2 Gps; +using Arr_traits = CGAL::Arr_segment_traits_2; +using General_traits = CGAL::Gps_traits_2; +using Gps = CGAL::General_polygon_set_2; -typedef CGAL::Arr_non_caching_segment_traits_2 Nc_traits; -typedef CGAL::Gps_segment_traits_2, - Nc_traits> Traits_non_caching; -typedef CGAL::General_polygon_set_2 Gps_non_caching; +using Nc_traits = CGAL::Arr_non_caching_segment_traits_2; +using Traits_non_caching = CGAL::Gps_segment_traits_2, Nc_traits>; +using Gps_non_caching = CGAL::General_polygon_set_2; -template -void test() -{ - typedef typename GPS::Traits_2 Traits; - typedef typename Traits::Point_2 Point_2; - typedef typename Traits::Polygon_2 Polygon_2; - typedef typename Traits::Polygon_with_holes_2 Polygon_with_holes_2; +template +void test() { + using Traits = typename GPS::Traits_2; + using Point_2 = typename Traits::Point_2; + using Polygon_2 = typename Traits::Polygon_2; + using Polygon_with_holes_2 = typename Traits::Polygon_with_holes_2; Polygon_2 pgn1, pgn2; - Polygon_with_holes_2 pgn_with_holes1, pgn_with_holes2; - std::vector polygons; - std::vector polygons_with_holes; + Polygon_with_holes_2 pgn_with_holes1, pgn_with_holes2; + std::vector polygons; + std::vector polygons_with_holes; GPS gps; GPS other; @@ -242,8 +238,7 @@ void test() GPS new_gps2 = gps; } -void test_CGAL_Polygon_variants() -{ +void test_CGAL_Polygon_variants() { typedef CGAL::Polygon_2 Polygon_2; typedef CGAL::Polygon_with_holes_2 Polygon_with_holes_2; typedef CGAL::Gps_default_traits::Traits Traits; @@ -257,45 +252,25 @@ void test_CGAL_Polygon_variants() Traits tr; CGAL::do_intersect(pgn1, pgn2); - CGAL::do_intersect(pgn1, pgn2, CGAL::Tag_true()); - CGAL::do_intersect(pgn1, pgn2, CGAL::Tag_false()); CGAL::do_intersect(pgn1, pgn2, tr); CGAL::do_intersect(pgn1, pgn_with_holes2); - CGAL::do_intersect(pgn1, pgn_with_holes2, CGAL::Tag_true()); - CGAL::do_intersect(pgn1, pgn_with_holes2, CGAL::Tag_false()); CGAL::do_intersect(pgn1, pgn_with_holes2, tr); CGAL::do_intersect(pgn_with_holes1, pgn2); - CGAL::do_intersect(pgn_with_holes1, pgn2, CGAL::Tag_true()); - CGAL::do_intersect(pgn_with_holes1, pgn2, CGAL::Tag_false()); CGAL::do_intersect(pgn_with_holes1, pgn2, tr); CGAL::do_intersect(pgn_with_holes1, pgn_with_holes2); - CGAL::do_intersect(pgn_with_holes1, pgn_with_holes2, CGAL::Tag_true()); - CGAL::do_intersect(pgn_with_holes1, pgn_with_holes2, CGAL::Tag_false()); CGAL::do_intersect(pgn_with_holes1, pgn_with_holes2, tr); CGAL::do_intersect(polygons.begin(), polygons.end()); - CGAL::do_intersect(polygons.begin(), polygons.end(), CGAL::Tag_true()); - CGAL::do_intersect(polygons.begin(), polygons.end(), CGAL::Tag_false()); CGAL::do_intersect(polygons.begin(), polygons.end(), tr); CGAL::do_intersect(polygons_with_holes.begin(), polygons_with_holes.end()); - CGAL::do_intersect(polygons_with_holes.begin(), polygons_with_holes.end(), - CGAL::Tag_true()); - CGAL::do_intersect(polygons_with_holes.begin(), polygons_with_holes.end(), - CGAL::Tag_false()); CGAL::do_intersect(polygons_with_holes.begin(), polygons_with_holes.end(), tr); CGAL::do_intersect(polygons.begin(), polygons.end(), polygons_with_holes.begin(), polygons_with_holes.end()); - CGAL::do_intersect(polygons.begin(), polygons.end(), - polygons_with_holes.begin(), polygons_with_holes.end(), - CGAL::Tag_true()); - CGAL::do_intersect(polygons.begin(), polygons.end(), - polygons_with_holes.begin(), polygons_with_holes.end(), - CGAL::Tag_false()); CGAL::do_intersect(polygons.begin(), polygons.end(), polygons_with_holes.begin(), polygons_with_holes.end(), tr); @@ -519,8 +494,7 @@ void test_CGAL_Polygon_variants() CGAL::complement(pgn_with_holes1, std::back_inserter(result), tr); } -int main() -{ +int main() { test(); test(); test(); diff --git a/Boolean_set_operations_2/test/Boolean_set_operations_2/test_do_intersect_circles.cpp b/Boolean_set_operations_2/test/Boolean_set_operations_2/test_do_intersect_circles.cpp new file mode 100644 index 00000000000..0d97afc5b06 --- /dev/null +++ b/Boolean_set_operations_2/test/Boolean_set_operations_2/test_do_intersect_circles.cpp @@ -0,0 +1,94 @@ +#include + +#include +#include +#include +#include +#include +// #include + +using Kernel = CGAL::Exact_predicates_exact_constructions_kernel; +using Point_2 = Kernel::Point_2; +using Polygon_2 = CGAL::Polygon_2; +using Circle_2 = Kernel::Circle_2; + +int main() { + Kernel kernel; + auto ctr_circle = kernel.construct_circle_2_object(); + auto circle1 = ctr_circle(Point_2(0, 1), 1); + auto circle2 = ctr_circle(Point_2(0, -1), 1); + auto circle3 = ctr_circle(Point_2(0, 2), 4); + + // 1. Circular arcs and linear segments + using Circle_segment_arr_traits_2 = CGAL::Arr_circle_segment_traits_2; + using Circle_segment_xcv_2 = Circle_segment_arr_traits_2::X_monotone_curve_2; + using Circle_segment_pnt_2 = Circle_segment_arr_traits_2::Point_2; + using Circle_segment_gps_traits_2 = CGAL::Gps_traits_2; + using Circle_segment_polygon = Circle_segment_gps_traits_2::General_polygon_2; + + Circle_segment_arr_traits_2 circle_segment_traits; + + Circle_segment_pnt_2 cs_pnt11(1, 1); + Circle_segment_pnt_2 cs_pnt12(-1, 1); + Circle_segment_xcv_2 xcv11(circle1, cs_pnt11, cs_pnt12, CGAL::COUNTERCLOCKWISE); + Circle_segment_xcv_2 xcv12(circle1, cs_pnt12, cs_pnt11, CGAL::COUNTERCLOCKWISE); + Circle_segment_polygon pgn1; + pgn1.push_back(xcv11); + pgn1.push_back(xcv12); + + Circle_segment_pnt_2 cs_pnt21(1, -1); + Circle_segment_pnt_2 cs_pnt22(-1, -1); + Circle_segment_xcv_2 xcv21(circle2, cs_pnt21, cs_pnt22, CGAL::COUNTERCLOCKWISE); + Circle_segment_xcv_2 xcv22(circle2, cs_pnt22, cs_pnt21, CGAL::COUNTERCLOCKWISE); + Circle_segment_polygon pgn2; + pgn2.push_back(xcv21); + pgn2.push_back(xcv22); + + Circle_segment_pnt_2 cs_pnt31(2, 2); + Circle_segment_pnt_2 cs_pnt32(-2, 2); + Circle_segment_xcv_2 xcv31(circle3, cs_pnt31, cs_pnt32, CGAL::COUNTERCLOCKWISE); + Circle_segment_xcv_2 xcv32(circle3, cs_pnt32, cs_pnt31, CGAL::COUNTERCLOCKWISE); + Circle_segment_polygon pgn3; + pgn3.push_back(xcv31); + pgn3.push_back(xcv32); + + // 1.1. + auto do_intersect = CGAL::do_intersect(pgn1, pgn2); + if (do_intersect) { + std::cerr << "The circles intersect (case 1)\n" << std::endl; + return 1; + } + + // 1.2. + std::vector pgns1 = { pgn1, pgn2 }; + do_intersect = CGAL::do_intersect(pgns1.begin(), pgns1.end()); + if (do_intersect) { + std::cerr << "The circles intersect (case 2)\n" << std::endl; + return 1; + } + + // 2.1. + do_intersect = CGAL::do_intersect(pgn1, pgn3); + if (! do_intersect) { + std::cerr << "The circles do not intersect (case 1)\n" << std::endl; + return 1; + } + + // 2.2. + std::vector pgns2 = { pgn1, pgn3 }; + do_intersect = CGAL::do_intersect(pgns2.begin(), pgns2.end()); + if (! do_intersect) { + std::cerr << "The circles do not intersect (case 2)\n" << std::endl; + return 1; + } + + // using Circle_segment_arr = CGAL::Arrangement_2; + // Circle_segment_arr arr; + // CGAL::insert_non_intersecting_curve(arr, xcv11); + // CGAL::insert_non_intersecting_curve(arr, xcv12); + // CGAL::insert_non_intersecting_curve(arr, xcv21); + // CGAL::insert_non_intersecting_curve(arr, xcv22); + // CGAL::draw(arr); + + return 0; +} diff --git a/Installation/CHANGES.md b/Installation/CHANGES.md index a1caaaa7107..871b294b112 100644 --- a/Installation/CHANGES.md +++ b/Installation/CHANGES.md @@ -27,6 +27,16 @@ Release date: July 2026 Its constructor accepts a `Mesh` and optional named parameters to set the weight of the line policy relative to the plane policy, set the boundary cost multiplier or provide vertex normals. - **Breaking change**: `CGAL::Surface_mesh_simplification::GarlandHeckbert_policies.h` is now an alias of `CGAL::Surface_mesh_simplification::GarlandHeckbert_plane_and_line_policies.h` and is no longer deprecated. +### [2D Regularized Boolean Set-Operations](https://doc.cgal.org/6.1/Manual/packages.html#PkgBooleanSetOperations2) + +- Optimized `do_intersect()`: (i) made it robust even with an inexact-predicate kernel, and (ii) made it quit + once an intersection is detected. (In the past, the intersection was computed in one phase and examined in a + subsequent phase.) This optimization somehow breaks backward compatibility as follows. + The variants of the free function `do_intersect()` that accept a third optional parameter, namely UsePolylines, + which determines whether the boundaries of the input polygons are treated as cyclic sequences of + (`x`-monotone) segments or as a cyclic sequences of (`x`-monotone) polylines, do not accept this third + parameter any longer. (This third optional parameter was introduced a few years ago, and now abandoned only for + `do_intersect()`.) ## [Release 6.1](https://github.com/CGAL/cgal/releases/tag/v6.1) diff --git a/Surface_sweep_2/include/CGAL/Surface_sweep_2/Default_visitor_base.h b/Surface_sweep_2/include/CGAL/Surface_sweep_2/Default_visitor_base.h index 441e9682488..c3930e490a5 100644 --- a/Surface_sweep_2/include/CGAL/Surface_sweep_2/Default_visitor_base.h +++ b/Surface_sweep_2/include/CGAL/Surface_sweep_2/Default_visitor_base.h @@ -7,8 +7,8 @@ // $Id$ // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // -// Author(s) : Baruch Zukerman -// Efi Fogel +// Author(s) : Baruch Zukerman +// Efi Fogel #ifndef CGAL_SURFACE_SWEEP_2_DEFAULT_VISITOR_BASE_H #define CGAL_SURFACE_SWEEP_2_DEFAULT_VISITOR_BASE_H @@ -50,28 +50,27 @@ template class Default_visitor_base { public: - typedef GeometryTraits_2 Geometry_traits_2; - typedef Event_ Event; - typedef Subcurve_ Subcurve; - typedef Allocator_ Allocator; - typedef Visitor_ Visitor; + using Geometry_traits_2 = GeometryTraits_2; + using Event = Event_; + using Subcurve = Subcurve_; + using Allocator = Allocator_; + using Visitor = Visitor_; private: - typedef Geometry_traits_2 Gt2; - typedef Default_visitor_base - Self; + using Gt2 = Geometry_traits_2; + using Self = Default_visitor_base; public: - typedef typename Subcurve::Status_line_iterator Status_line_iterator; + using Status_line_iterator = typename Subcurve::Status_line_iterator; - typedef typename Gt2::X_monotone_curve_2 X_monotone_curve_2; - typedef typename Gt2::Point_2 Point_2; + using X_monotone_curve_2 = typename Gt2::X_monotone_curve_2; + using Point_2 = typename Gt2::Point_2; + using Multiplicity = typename Gt2::Multiplicity; - typedef typename Event::Subcurve_iterator Event_subcurve_iterator; - typedef typename Event::Subcurve_reverse_iterator - Event_subcurve_reverse_iterator; + using Event_subcurve_iterator = typename Event::Subcurve_iterator; + using Event_subcurve_reverse_iterator = typename Event::Subcurve_reverse_iterator; - typedef No_intersection_surface_sweep_2 Surface_sweep_2; + using Surface_sweep_2 = No_intersection_surface_sweep_2; protected: // Data members: @@ -134,7 +133,8 @@ public: void update_event(Event* /* e */, Subcurve* /* sc1 */, Subcurve* /* sc2 */, - bool /* is_new */) + bool /* is_new */, + Multiplicity /* multiplicity */) {} /*! Update the event. */ diff --git a/Surface_sweep_2/include/CGAL/Surface_sweep_2/Do_interior_intersect_visitor.h b/Surface_sweep_2/include/CGAL/Surface_sweep_2/Do_interior_intersect_visitor.h index ebdd0331c8e..0278f0464fa 100644 --- a/Surface_sweep_2/include/CGAL/Surface_sweep_2/Do_interior_intersect_visitor.h +++ b/Surface_sweep_2/include/CGAL/Surface_sweep_2/Do_interior_intersect_visitor.h @@ -7,9 +7,9 @@ // $Id$ // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // -// Author(s) : Baruch Zukerman -// Ron Wein -// Efi Fogel +// Author(s) : Baruch Zukerman +// Ron Wein +// Efi Fogel #ifndef CGAL_SURFACE_SWEEP_2_DO_INTERIOR_INTERSECT_VISITORS_H #define CGAL_SURFACE_SWEEP_2_DO_INTERIOR_INTERSECT_VISITORS_H @@ -39,27 +39,27 @@ template , - GeometryTraits_2, Allocator_> -{ + GeometryTraits_2, Allocator_> { public: - typedef GeometryTraits_2 Geometry_traits_2; - typedef Allocator_ Allocator; + using Geometry_traits_2 = GeometryTraits_2; + using Allocator = Allocator_; private: - typedef Geometry_traits_2 Gt2; - typedef Do_interior_intersect_visitor Self; - typedef Default_visitor Base; + using Gt2 = Geometry_traits_2; + using Self = Do_interior_intersect_visitor; + using Base = Default_visitor; public: - typedef typename Base::Event Event; - typedef typename Base::Subcurve Subcurve; + using Event = typename Base::Event; + using Subcurve = typename Base::Subcurve; - typedef typename Subcurve::Status_line_iterator Status_line_iterator; + using Status_line_iterator = typename Subcurve::Status_line_iterator; - typedef typename Gt2::X_monotone_curve_2 X_monotone_curve_2; - typedef typename Gt2::Point_2 Point_2; + using X_monotone_curve_2 = typename Gt2::X_monotone_curve_2; + using Point_2 = typename Gt2::Point_2; + using Multiplicity = typename Gt2::Multiplicity; - typedef typename Base::Surface_sweep_2 Surface_sweep_2; + using Surface_sweep_2 = typename Base::Surface_sweep_2; protected: // Data members: @@ -69,8 +69,7 @@ public: Do_interior_intersect_visitor() : m_found_x(false) {} template - void sweep(CurveIterator begin, CurveIterator end) - { + void sweep(CurveIterator begin, CurveIterator end) { std::vector curves_vec; std::vector points_vec; @@ -89,7 +88,8 @@ public: void update_event(Event* /* e */, Subcurve* /* sc1 */, Subcurve* /* sc2 */, - bool /* is_new */) + bool /* is_new */, + Multiplicity /* multiplicity */) { m_found_x = true; } void update_event(Event* /* e */, @@ -115,8 +115,7 @@ public: {} template - void sweep_xcurves(XCurveIterator begin, XCurveIterator end) - { + void sweep_xcurves(XCurveIterator begin, XCurveIterator end) { // Perform the sweep. Surface_sweep_2* sl = this->surface_sweep(); sl->sweep(begin, end); @@ -129,8 +128,7 @@ public: bool after_handle_event(Event* /* event */, Status_line_iterator /* iter */, - bool /* flag */) - { + bool /* flag */) { if (m_found_x) { Surface_sweep_2* sl = this->surface_sweep(); sl->stop_sweep(); diff --git a/Surface_sweep_2/include/CGAL/Surface_sweep_2/Surface_sweep_2_impl.h b/Surface_sweep_2/include/CGAL/Surface_sweep_2/Surface_sweep_2_impl.h index df7bd3a5510..3193f48e75b 100644 --- a/Surface_sweep_2/include/CGAL/Surface_sweep_2/Surface_sweep_2_impl.h +++ b/Surface_sweep_2/include/CGAL/Surface_sweep_2/Surface_sweep_2_impl.h @@ -7,9 +7,9 @@ // $Id$ // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // -// Author(s) : Baruch Zukerman -// Efi Fogel -// (based on old version by Tali Zvi) +// Author(s) : Baruch Zukerman +// Efi Fogel +// (based on a previous version developed by Tali Zvi) #ifndef CGAL_SURFACE_SWEEP_2_IMPL_H #define CGAL_SURFACE_SWEEP_2_IMPL_H @@ -33,8 +33,7 @@ namespace Surface_sweep_2 { // Initialize the data structures for the sweep-line algorithm. // template -void Surface_sweep_2::_init_structures() -{ +void Surface_sweep_2::_init_structures() { // Initialize the structures maintained by the base sweep-line class. Base::_init_structures(); } @@ -43,8 +42,7 @@ void Surface_sweep_2::_init_structures() // Complete the sweep (complete the data structures). // template -void Surface_sweep_2::_complete_sweep() -{ +void Surface_sweep_2::_complete_sweep() { CGAL_SS_PRINT_START_EOL("completing the sweep"); // Complete the sweep process using base sweep-line class. @@ -68,8 +66,7 @@ void Surface_sweep_2::_complete_sweep() // Handle the subcurves to the left of the current event point. // template -void Surface_sweep_2::_handle_left_curves() -{ +void Surface_sweep_2::_handle_left_curves() { CGAL_SS_PRINT_START("handling left curves at ("); CGAL_SS_DEBUG(this->PrintEvent(this->m_currentEvent)); CGAL_SS_PRINT_TEXT(")"); @@ -189,14 +186,12 @@ void Surface_sweep_2::_handle_left_curves() // and with a left end not being the current event // template -void Surface_sweep_2::_clip_non_active_curve_at_current_event(Subcurve* subcurve) -{ +void Surface_sweep_2::_clip_non_active_curve_at_current_event(Subcurve* subcurve) { // ignore active curve (will be split at intersection point) if (subcurve->hint() != this->m_statusLine.end() && subcurve->hint() != Status_line_iterator() ) return; - if (!subcurve->is_start_point(this->m_currentEvent)) - { + if (! subcurve->is_start_point(this->m_currentEvent)) { CGAL_SS_PRINT_TEXT("Splitting "); CGAL_SS_PRINT_CURVE(subcurve); CGAL_SS_PRINT_EOL(); @@ -215,13 +210,11 @@ void Surface_sweep_2::_clip_non_active_curve_at_current_event(Subcurve* sub // Handle the overlaps between subcurves to the right of the current event point. // template -void Surface_sweep_2::_handle_overlaps_in_right_curves() -{ - const std::vector< std::pair >& subcurve_pairs - = this->m_currentEvent->overlaps_on_right; +void Surface_sweep_2::_handle_overlaps_in_right_curves() { + const std::vector< std::pair >& subcurve_pairs = + this->m_currentEvent->overlaps_on_right; - if (!subcurve_pairs.empty()) - { + if (!subcurve_pairs.empty()) { // handling overlaps on the right of the current event. // Only one curve from the overlapping curve is currently // in the right curves of the event. Other curve overlapping @@ -240,11 +233,10 @@ void Surface_sweep_2::_handle_overlaps_in_right_curves() // in the following map having a curve on the right of the event // as key, we get all the curves that overlap with that curve // on the right of the event - typedef std::map > Subcurve_map; + typedef std::map> Subcurve_map; Subcurve_map tests_per_subcurve_on_right; - for (std::size_t i=0; i::_handle_overlaps_in_right_curves() tests_per_subcurve_on_right[subcurve_pairs[i].first].push_back(subcurve_pairs[i].second); } - for(typename Subcurve_map::iterator it = tests_per_subcurve_on_right.begin(), - end = tests_per_subcurve_on_right.end(); it!=end; ++it) - { + for (auto it = tests_per_subcurve_on_right.begin(), end = tests_per_subcurve_on_right.end(); it != end; ++it) { std::size_t nbc = it->second.size(); // remove possible duplicates - if (nbc>1) - { + if (nbc > 1) { std::sort(it->second.begin(), it->second.end()); typename std::vector::iterator last = std::unique(it->second.begin(), it->second.end()); @@ -277,8 +266,7 @@ void Surface_sweep_2::_handle_overlaps_in_right_curves() else{ // get the curve just after the key in the sorted set of curves on the right as it might be replaced Subcurve_iterator next_after = this->m_currentEvent->get_curve_after_on_right(it->first); - for (std::size_t i=0; isecond[i], *std::prev(next_after), this->m_currentEvent); CGAL_assertion(it->second.size()==nbc); // make sure the container was not updated } @@ -289,27 +277,19 @@ void Surface_sweep_2::_handle_overlaps_in_right_curves() } // split curves not already split. TODO: this should be done above? - for (Event_subcurve_iterator subcurve_it = this->m_currentEvent->right_curves_begin(); - subcurve_it != this->m_currentEvent->right_curves_end(); - ++subcurve_it) - { + for (auto subcurve_it = this->m_currentEvent->right_curves_begin(); + subcurve_it != this->m_currentEvent->right_curves_end(); ++subcurve_it) _clip_non_active_curve_at_current_event(*subcurve_it); - } } //----------------------------------------------------------------------------- // Handle the subcurves to the right of the current event point. // template -void Surface_sweep_2::_handle_right_curves() -{ - - for(Event_subcurve_iterator sc_it = this->m_currentEvent->right_curves_begin(), - sc_it_end = this->m_currentEvent->right_curves_end(); - sc_it!=sc_it_end; ++sc_it) - { +void Surface_sweep_2::_handle_right_curves() { + for (auto sc_it = this->m_currentEvent->right_curves_begin(), sc_it_end = this->m_currentEvent->right_curves_end(); + sc_it != sc_it_end; ++sc_it) (*sc_it)->reset_left_event(); - } CGAL_SS_PRINT_START("handling right curves at ("); CGAL_SS_DEBUG(this->PrintEvent(this->m_currentEvent)); @@ -329,15 +309,11 @@ void Surface_sweep_2::_handle_right_curves() // - We also check to see if the two intersect again to the right of the // point. - Event_subcurve_iterator currentOne = - this->m_currentEvent->right_curves_begin(); - Event_subcurve_iterator rightCurveEnd = - this->m_currentEvent->right_curves_end(); + Event_subcurve_iterator currentOne = this->m_currentEvent->right_curves_begin(); + Event_subcurve_iterator rightCurveEnd = this->m_currentEvent->right_curves_end(); CGAL_SS_PRINT_INSERT(*currentOne); - Status_line_iterator slIter = - this->m_statusLine.insert_before(this->m_status_line_insert_hint, - *currentOne); + Status_line_iterator slIter = this->m_statusLine.insert_before(this->m_status_line_insert_hint, *currentOne); Subcurve* sc = *currentOne; sc->set_hint(slIter); @@ -352,8 +328,7 @@ void Surface_sweep_2::_handle_right_curves() ++currentOne; while (currentOne != rightCurveEnd) { CGAL_SS_PRINT_INSERT(*currentOne); - slIter = this->m_statusLine.insert_before(this->m_status_line_insert_hint, - *currentOne); + slIter = this->m_statusLine.insert_before(this->m_status_line_insert_hint, *currentOne); Subcurve* sc = *currentOne; sc->set_hint(slIter); @@ -390,12 +365,8 @@ bool Surface_sweep_2::_add_curve_to_right(Event* event, Subcurve* curve) CGAL_SS_PRINT_CURVE(curve); CGAL_SS_PRINT_EOL(); - Event_subcurve_iterator iter; - for (iter = event->right_curves_begin(); iter != event->right_curves_end(); - ++iter) - { - if (*iter == curve) - { + for (auto iter = event->right_curves_begin(); iter != event->right_curves_end(); ++iter) { + if (*iter == curve) { CGAL_SS_PRINT_END_EOL("adding a Curve to the right (curve exists)"); return false; } @@ -405,8 +376,7 @@ bool Surface_sweep_2::_add_curve_to_right(Event* event, Subcurve* curve) if ((*iter)->are_all_leaves_contained(curve)) { CGAL_SS_PRINT_END_EOL("adding a Curve to the right (containing curve exists)"); - if ( (*iter)->right_event() != curve->right_event() ) - { + if ((*iter)->right_event() != curve->right_event()) { CGAL_assertion( this->m_queueEventLess((*iter)->right_event(), curve->right_event()) == SMALLER ); // subcurve has to end before _add_curve_to_right( (*iter)->right_event(), curve); // WARNING recursive } @@ -417,8 +387,7 @@ bool Surface_sweep_2::_add_curve_to_right(Event* event, Subcurve* curve) } if (curve->are_all_leaves_contained(*iter)) { - if ( (*iter)->right_event() != curve->right_event() ) - { + if ( (*iter)->right_event() != curve->right_event()) { CGAL_assertion(this->m_queueEventLess(curve->right_event(), (*iter)->right_event()) == SMALLER); // subcurve has to end before _add_curve_to_right( curve->right_event(), *iter); // WARNING recursive } @@ -426,8 +395,7 @@ bool Surface_sweep_2::_add_curve_to_right(Event* event, Subcurve* curve) (*iter)->right_event()->remove_curve_from_left(*iter); *iter = curve; // replace the current curve with the new one. - CGAL_SS_PRINT_END_EOL - ("replacing a Curve to the right (curve partially overlaps)"); + CGAL_SS_PRINT_END_EOL("replacing a Curve to the right (curve partially overlaps)"); return false; } @@ -443,11 +411,10 @@ bool Surface_sweep_2::_add_curve_to_right(Event* event, Subcurve* curve) } // a new overlap needs to be computed - if (event!=this->m_currentEvent) + if (event != this->m_currentEvent) event->overlaps_on_right.push_back( std::make_pair(static_cast(*(pair_res.second)), - static_cast(curve)) - ); + static_cast(curve))); else _intersect(static_cast(curve), static_cast(*(pair_res.second)), @@ -467,8 +434,7 @@ bool Surface_sweep_2::_add_curve_to_right(Event* event, Subcurve* curve) // template void Surface_sweep_2::_remove_curve_from_status_line(Subcurve* leftCurve, - bool remove_for_good) -{ + bool remove_for_good) { CGAL_SS_PRINT_START("removing a curve from the status line, "); CGAL_SS_PRINT_CURVE(leftCurve); CGAL_SS_PRINT_EOL(); @@ -513,8 +479,7 @@ void Surface_sweep_2::_remove_curve_from_status_line(Subcurve* leftCurve, // template void Surface_sweep_2::_intersect(Subcurve* c1, Subcurve* c2, - Event* event_for_overlap) -{ + Event* event_for_overlap) { CGAL_SS_PRINT_START("computing intersection of "); CGAL_SS_PRINT_CURVE(c1); CGAL_SS_PRINT_TEXT(" and "); @@ -538,8 +503,7 @@ void Surface_sweep_2::_intersect(Subcurve* c1, Subcurve* c2, Subcurve_vector all_leaves_diff; Subcurve* first_parent = nullptr; if ((c1->originating_subcurve1() != nullptr) || - (c2->originating_subcurve2() != nullptr)) - { + (c2->originating_subcurve2() != nullptr)) { // get the subcurve leaves of c1 and of c2. Then extract from the smallest // set the subcurves leaves that are not in the other one. If empty, it // means that a subcurves is completely contained in another one. @@ -628,9 +592,7 @@ void Surface_sweep_2::_intersect(Subcurve* c1, Subcurve* c2, CGAL_SS_PRINT_CURVE(first_parent); CGAL_SS_PRINT_EOL(); X_monotone_curve_2 xc = first_parent->last_curve(); - for (auto sc_it = all_leaves_diff.begin(); - sc_it != all_leaves_diff.end(); ++sc_it) - { + for (auto sc_it = all_leaves_diff.begin(); sc_it != all_leaves_diff.end(); ++sc_it) { CGAL_SS_PRINT_TEXT("Inter with curve: "); CGAL_SS_PRINT_CURVE((*sc_it)); CGAL_SS_PRINT_EOL(); @@ -681,12 +643,10 @@ void Surface_sweep_2::_intersect(Subcurve* c1, Subcurve* c2, if ((ps_x1 == ps_x2) && (ps_y1 == ps_y2) && ((ps_x1 != ARR_INTERIOR) || (ps_y1 != ARR_INTERIOR)) && this->m_traits->is_closed_2_object()(c1->last_curve(), ARR_MIN_END) && - this->m_traits->is_closed_2_object()(c2->last_curve(), ARR_MIN_END)) - { + this->m_traits->is_closed_2_object()(c2->last_curve(), ARR_MIN_END)) { if ((std::get_if(&(*vi)) != nullptr) && this->m_traits->equal_2_object()(ctr_min(c1->last_curve()), - ctr_min(c2->last_curve()))) - { + ctr_min(c2->last_curve()))) { CGAL_SS_PRINT_TEXT("Skipping common left endpoint on boundary ..."); CGAL_SS_PRINT_EOL(); ++vi; @@ -719,12 +679,10 @@ void Surface_sweep_2::_intersect(Subcurve* c1, Subcurve* c2, if ((ps_x1 == ps_x2) && (ps_y1 == ps_y2) && ((ps_x1 != ARR_INTERIOR) || (ps_y2 != ARR_INTERIOR)) && this->m_traits->is_closed_2_object()(c1->last_curve(), ARR_MAX_END) && - this->m_traits->is_closed_2_object()(c2->last_curve(), ARR_MAX_END)) - { + this->m_traits->is_closed_2_object()(c2->last_curve(), ARR_MAX_END)) { if (this->m_traits->equal_2_object() (this->m_traits->construct_max_vertex_2_object()(c1->last_curve()), - this->m_traits->construct_max_vertex_2_object()(c2->last_curve()))) - { + this->m_traits->construct_max_vertex_2_object()(c2->last_curve()))) { vector_inserter vi_last = vi_end; --vi_last; @@ -791,8 +749,7 @@ template void Surface_sweep_2::_create_intersection_point(const Point_2& xp, Multiplicity multiplicity, Subcurve*& c1, - Subcurve*& c2) -{ + Subcurve*& c2) { CGAL_SS_PRINT_START_EOL("creating an intersection point between"); CGAL_SS_PRINT_CURVE(c1); CGAL_SS_PRINT_EOL(); @@ -814,7 +771,7 @@ void Surface_sweep_2::_create_intersection_point(const Point_2& xp, e->set_intersection(); - this->m_visitor->update_event(e, c1, c2, true); + this->m_visitor->update_event(e, c1, c2, true, multiplicity); e->push_back_curve_to_left(c1); e->push_back_curve_to_left(c2); @@ -858,7 +815,7 @@ void Surface_sweep_2::_create_intersection_point(const Point_2& xp, _add_curve_to_right(e, c1); _add_curve_to_right(e, c2); e->set_intersection(); - this->m_visitor->update_event(e, c1, c2, false); + this->m_visitor->update_event(e, c1, c2, false, multiplicity); if (multiplicity == 0) { if (e->is_right_curve_bigger(c1, c2, this->m_traits)) std::swap(c1, c2); @@ -895,8 +852,7 @@ _create_overlapping_curve(const X_monotone_curve_2& overlap_cv, Subcurve*& c1 , Subcurve*& c2, const Subcurve_vector& all_leaves_diff, Subcurve* first_parent, - Event* event_on_overlap) -{ + Event* event_on_overlap) { // An overlap occurs: CGAL_SS_PRINT_START_EOL("creating an overlapping curve"); @@ -935,14 +891,12 @@ _create_overlapping_curve(const X_monotone_curve_2& overlap_cv, if ((ps_x_r != ARR_INTERIOR) || (ps_y_r != ARR_INTERIOR)) { // CGAL_assertion(c1->right_event() == c2->right_event()); // right_event = c1->right_event(); - right_event = this->_push_event(overlap_cv, ARR_MAX_END, Event::DEFAULT, - ps_x_r, ps_y_r).first; + right_event = this->_push_event(overlap_cv, ARR_MAX_END, Event::DEFAULT, ps_x_r, ps_y_r).first; } else { auto max_vertex = this->m_traits->construct_max_vertex_2_object(); auto right_end = max_vertex(overlap_cv); - right_event = this->_push_event(right_end, Event::DEFAULT, ARR_INTERIOR, - ARR_INTERIOR).first; + right_event = this->_push_event(right_end, Event::DEFAULT, ARR_INTERIOR, ARR_INTERIOR).first; } if (!c1->is_start_point(left_event)) { @@ -968,12 +922,9 @@ _create_overlapping_curve(const X_monotone_curve_2& overlap_cv, // Allocate the new Subcurve for the overlap Subcurve* overlap_sc=nullptr; - if (all_leaves_diff.empty()) - { + if (all_leaves_diff.empty()) { // first check that an equivalent curve is not already in left_event - for (Subcurve_iterator iter = left_event->right_curves_begin(); - iter != left_event->right_curves_end(); ++iter) - { + for (auto iter = left_event->right_curves_begin(); iter != left_event->right_curves_end(); ++iter) { if ((*iter)->has_same_leaves(c1, c2)) { CGAL_SS_PRINT_TEXT("Reuse overlapping curve "); CGAL_SS_PRINT_CURVE(*iter); @@ -983,8 +934,7 @@ _create_overlapping_curve(const X_monotone_curve_2& overlap_cv, } } - if (overlap_sc==nullptr) - { + if (overlap_sc == nullptr) { CGAL_SS_PRINT_TEXT("Allocate a new subcurve for the overlap (no common subcurves)"); CGAL_SS_PRINT_EOL(); // no duplicate only one curve is needed @@ -1005,10 +955,7 @@ _create_overlapping_curve(const X_monotone_curve_2& overlap_cv, CGAL_SS_PRINT_EOL(); // create an overlapping curve per subcurve in second_parent that is not in first_parent - for (typename std::vector::const_iterator sc_it = all_leaves_diff.begin(); - sc_it != all_leaves_diff.end(); - ++sc_it) - { + for (auto sc_it = all_leaves_diff.begin(); sc_it != all_leaves_diff.end(); ++sc_it) { overlap_sc = this->m_subCurveAlloc.allocate(1); std::allocator_traits::construct(this->m_subCurveAlloc,overlap_sc, this->m_masterSubcurve); overlap_sc->set_hint(this->m_statusLine.end()); @@ -1063,8 +1010,7 @@ _create_overlapping_curve(const X_monotone_curve_2& overlap_cv, // or updated. // template -void Surface_sweep_2::_add_curve(Event* e, Subcurve* sc, Attribute type) -{ +void Surface_sweep_2::_add_curve(Event* e, Subcurve* sc, Attribute type) { if (sc == nullptr) return; if (type == Event::LEFT_END) {