mirror of https://github.com/CGAL/cgal
Optimize the `do_intersect()` functions of the 2D Regularized Boolean Set Operation" package (made it tolerant to inexact kernels.) (#9050)
## Summary of Changes Optimized `do_intersect(polygon, polygon)`, `do_intersect(begin, end)`, and `do_intersect(begin1, end1, begin2, end2)`: (i) Terminated the execution once an intersection is detected. (In the past, the intersection was computed in one phase and examined in a subsequent phase.) (ii) Made the variants of the free functions `do_intersect()` that apply to linear polygons, robust even with an inexact-construction kernel. The variants that apply to generalized polygons endure inexact constructions much more than before; however, there are rare degenerate cases that are still require an exact construction kernel. In general, the changes described here do not affect the default interface, so a small feature is not required. However, it is a major impact, and it does affect the interface as described bellow, and even somehow break backward compatibility. Recently, the code of the package "2D Regularized Boolean Set Operations" was optimized. In particular, a 3rd optional parameter was introduced in the free functions. It determined whether the boundaries of the input polygons are treated as cyclic sequences of single (`x`-monotone) segments or as a cyclic sequences of (`x`-monotone) polylines. The change described here eliminates this 3rd parameter, and brings the interface of the `do_intersect() function back to the original design with two input polygons. ## Release Management * Affected package(s): Boolean_set_operations_2, Surface_sweep, Arrangement_on_surface_2 * Feature/Small Feature (if any): [here](https://cgalwiki.geometryfactory.com/CGAL/Members/wiki/Features/Small_Features/do_intersect_polygon_2_predicates_only) * Link to compiled documentation (obligatory for small feature) [*wrong link name to be changed*](httpssss://wrong_URL_to_be_changed/Manual/Pkg) * License and copyright ownership: TAU
This commit is contained in:
commit
1069678f36
|
|
@ -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 <efifogel@gmail.com>
|
||||||
|
|
||||||
|
#ifndef CGAL_ARR_DO_INTERSECT_OVERLAY_2_H
|
||||||
|
#define CGAL_ARR_DO_INTERSECT_OVERLAY_2_H
|
||||||
|
|
||||||
|
#include <CGAL/license/Arrangement_on_surface_2.h>
|
||||||
|
|
||||||
|
#include <CGAL/disable_warnings.h>
|
||||||
|
|
||||||
|
/*! \file
|
||||||
|
*
|
||||||
|
* Definition of the global do_intersect_overlay_2() function.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <CGAL/Arrangement_on_surface_2.h>
|
||||||
|
#include <CGAL/Surface_sweep_2.h>
|
||||||
|
#include <CGAL/Surface_sweep_2/Arr_default_overlay_traits_base.h>
|
||||||
|
#include <CGAL/Surface_sweep_2/Arr_overlay_traits_2.h>
|
||||||
|
#include <CGAL/Surface_sweep_2/Arr_do_intersect_overlay_ss_visitor.h>
|
||||||
|
#include <CGAL/Surface_sweep_2/Arr_overlay_event.h>
|
||||||
|
#include <CGAL/Surface_sweep_2/Arr_overlay_subcurve.h>
|
||||||
|
#include <CGAL/assertions.h>
|
||||||
|
|
||||||
|
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 <typename GeometryTraitsA_2,
|
||||||
|
typename GeometryTraitsB_2,
|
||||||
|
typename GeometryTraitsRes_2,
|
||||||
|
typename TopologyTraitsA,
|
||||||
|
typename TopologyTraitsB,
|
||||||
|
typename TopologyTraitsRes,
|
||||||
|
typename OverlayTraits>
|
||||||
|
bool do_intersect_overlay(const Arrangement_on_surface_2<GeometryTraitsA_2, TopologyTraitsA>& arr1,
|
||||||
|
const Arrangement_on_surface_2<GeometryTraitsB_2, TopologyTraitsB>& arr2,
|
||||||
|
Arrangement_on_surface_2<GeometryTraitsRes_2, TopologyTraitsRes>& 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<Agt2, Att>;
|
||||||
|
using Arr_b = Arrangement_on_surface_2<Bgt2, Btt>;
|
||||||
|
using Arr_res = Arrangement_on_surface_2<Rgt2, Rtt>;
|
||||||
|
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<A_point, Res_point>::value);
|
||||||
|
static_assert(std::is_convertible<B_point, Res_point>::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<A_xcv, Res_xcv>::value);
|
||||||
|
static_assert(std::is_convertible<B_xcv, Res_xcv>::value);
|
||||||
|
|
||||||
|
using Gt_adaptor_2 = Arr_traits_basic_adaptor_2<Rgt2>;
|
||||||
|
using Ovl_gt2 = Arr_overlay_traits_2<Gt_adaptor_2, Arr_a, Arr_b>;
|
||||||
|
using Ovl_event = Arr_overlay_event<Ovl_gt2, Arr_res, Allocator>;
|
||||||
|
using Ovl_curve = Arr_overlay_subcurve<Ovl_gt2, Ovl_event, Allocator>;
|
||||||
|
using Ovl_helper = typename TopologyTraitsRes::template Overlay_helper<Ovl_gt2, Ovl_event, Ovl_curve, Arr_a, Arr_b>;
|
||||||
|
using Diovl_visitor = Arr_do_intersect_overlay_ss_visitor<Ovl_helper, Overlay_traits>;
|
||||||
|
|
||||||
|
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<Ovl_x_monotone_curve_2> 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<std::is_same_v<Gt_adaptor_2, Ovl_gt2>, const Ovl_gt2&, Ovl_gt2> ex_traits(*traits_adaptor);
|
||||||
|
|
||||||
|
Diovl_visitor visitor(&arr1, &arr2, &arr, &ovl_tr);
|
||||||
|
Ss2::Surface_sweep_2<Diovl_visitor> 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<typename Agt2::Bottom_side_category, Arr_contracted_side_tag>::value) {
|
||||||
|
surface_sweep.sweep(xcvs.begin(), xcvs.end());
|
||||||
|
xcvs.clear();
|
||||||
|
return visitor.found_intersection();
|
||||||
|
}
|
||||||
|
surface_sweep.indexed_sweep(xcvs, Indexed_sweep_accessor<Arr_a, Arr_b, Ovl_x_monotone_curve_2>(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<Ovl_point_2> 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<Cell_handle_blue>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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<Cell_handle_red>(),
|
||||||
|
std::make_optional(Cell_handle_blue(v2)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear the result arrangement and perform the sweep to construct it.
|
||||||
|
arr.clear();
|
||||||
|
if (std::is_same<typename Agt2::Bottom_side_category, Arr_contracted_side_tag>::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<Arr_a, Arr_b, Ovl_x_monotone_curve_2>(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 <typename GeometryTraitsA_2,
|
||||||
|
typename GeometryTraitsB_2,
|
||||||
|
typename GeometryTraitsRes_2,
|
||||||
|
typename TopologyTraitsA,
|
||||||
|
typename TopologyTraitsB,
|
||||||
|
typename TopologyTraitsRes>
|
||||||
|
bool do_intersect_overlay(const Arrangement_on_surface_2<GeometryTraitsA_2, TopologyTraitsA>& arr1,
|
||||||
|
const Arrangement_on_surface_2<GeometryTraitsB_2, TopologyTraitsB>& arr2,
|
||||||
|
Arrangement_on_surface_2<GeometryTraitsRes_2, TopologyTraitsRes>& 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<Agt2, Att>;
|
||||||
|
using Arr_b = Arrangement_on_surface_2<Bgt2, Btt>;
|
||||||
|
using Arr_res = Arrangement_on_surface_2<Rgt2, Rtt>;
|
||||||
|
|
||||||
|
_Arr_default_overlay_traits_base<Arr_a, Arr_b, Arr_res> ovl_traits;
|
||||||
|
return do_intersect_overlay(arr1, arr2, arr, ovl_traits);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
#include <CGAL/enable_warnings.h>
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -40,24 +40,18 @@
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
|
|
||||||
template <typename Arr1, typename Arr2, typename Curve>
|
template <typename Arr1, typename Arr2, typename Curve>
|
||||||
class Indexed_sweep_accessor
|
class Indexed_sweep_accessor {
|
||||||
{
|
private:
|
||||||
const Arr1& arr1;
|
const Arr1& m_arr1;
|
||||||
const Arr2& arr2;
|
const Arr2& m_arr2;
|
||||||
mutable std::vector<void*> backup_inc;
|
mutable std::vector<void*> m_backup_inc;
|
||||||
|
|
||||||
public:
|
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)
|
std::size_t nb_vertices() const { return m_arr1.number_of_vertices() + m_arr2.number_of_vertices(); }
|
||||||
: arr1(arr1), arr2(arr2) { }
|
|
||||||
|
|
||||||
std::size_t nb_vertices() const
|
std::size_t min_end_index(const Curve& c) const {
|
||||||
{
|
|
||||||
return arr1.number_of_vertices() + arr2.number_of_vertices();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::size_t min_end_index (const Curve& c) const
|
|
||||||
{
|
|
||||||
if (c.red_halfedge_handle() != typename Curve::HH_red())
|
if (c.red_halfedge_handle() != typename Curve::HH_red())
|
||||||
return reinterpret_cast<std::size_t>(c.red_halfedge_handle()->target()->inc());
|
return reinterpret_cast<std::size_t>(c.red_halfedge_handle()->target()->inc());
|
||||||
// else
|
// else
|
||||||
|
|
@ -65,8 +59,7 @@ public:
|
||||||
return reinterpret_cast<std::size_t>(c.blue_halfedge_handle()->target()->inc());
|
return reinterpret_cast<std::size_t>(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())
|
if (c.red_halfedge_handle() != typename Curve::HH_red())
|
||||||
return reinterpret_cast<std::size_t>(c.red_halfedge_handle()->source()->inc());
|
return reinterpret_cast<std::size_t>(c.red_halfedge_handle()->source()->inc());
|
||||||
// else
|
// else
|
||||||
|
|
@ -74,52 +67,36 @@ public:
|
||||||
return reinterpret_cast<std::size_t>(c.blue_halfedge_handle()->source()->inc());
|
return reinterpret_cast<std::size_t>(c.blue_halfedge_handle()->source()->inc());
|
||||||
}
|
}
|
||||||
|
|
||||||
const Curve& curve (const Curve& c) const
|
const Curve& curve(const Curve& c) const { return c; }
|
||||||
{
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initializes indices by squatting Vertex::inc();
|
// Initializes indices by squatting Vertex::inc();
|
||||||
void before_init() const
|
void before_init() const {
|
||||||
{
|
|
||||||
std::size_t idx = 0;
|
std::size_t idx = 0;
|
||||||
backup_inc.resize (nb_vertices());
|
m_backup_inc.resize (nb_vertices());
|
||||||
for (typename Arr1::Vertex_const_iterator vit = arr1.vertices_begin();
|
for (auto vit = m_arr1.vertices_begin(); vit != m_arr1.vertices_end(); ++vit, ++idx) {
|
||||||
vit != arr1.vertices_end(); ++vit, ++idx)
|
CGAL_assertion(idx < m_backup_inc.size());
|
||||||
{
|
m_backup_inc[idx] = vit->inc();
|
||||||
CGAL_assertion (idx < backup_inc.size());
|
|
||||||
backup_inc[idx] = vit->inc();
|
|
||||||
vit->set_inc(reinterpret_cast<void*>(idx));
|
vit->set_inc(reinterpret_cast<void*>(idx));
|
||||||
}
|
}
|
||||||
for (typename Arr2::Vertex_const_iterator vit = arr2.vertices_begin();
|
for (auto vit = m_arr2.vertices_begin(); vit != m_arr2.vertices_end(); ++vit, ++idx) {
|
||||||
vit != arr2.vertices_end(); ++vit, ++idx)
|
CGAL_assertion(idx < m_backup_inc.size());
|
||||||
{
|
m_backup_inc[idx] = vit->inc();
|
||||||
CGAL_assertion (idx < backup_inc.size());
|
|
||||||
backup_inc[idx] = vit->inc();
|
|
||||||
vit->set_inc(reinterpret_cast<void*>(idx));
|
vit->set_inc(reinterpret_cast<void*>(idx));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restores state of arrangements before index squatting
|
// Restores state of arrangements before index squatting
|
||||||
void after_init() const
|
void after_init() const {
|
||||||
{
|
|
||||||
std::size_t idx = 0;
|
std::size_t idx = 0;
|
||||||
for (typename Arr1::Vertex_const_iterator vit = arr1.vertices_begin();
|
for (auto vit = m_arr1.vertices_begin(); vit != m_arr1.vertices_end(); ++vit, ++idx) {
|
||||||
vit != arr1.vertices_end(); ++vit, ++idx)
|
CGAL_assertion(idx < m_backup_inc.size());
|
||||||
{
|
vit->set_inc(m_backup_inc[idx]);
|
||||||
CGAL_assertion (idx < backup_inc.size());
|
|
||||||
vit->set_inc (backup_inc[idx]);
|
|
||||||
}
|
}
|
||||||
for (typename Arr2::Vertex_const_iterator vit = arr2.vertices_begin();
|
for (auto vit = m_arr2.vertices_begin(); vit != m_arr2.vertices_end(); ++vit, ++idx) {
|
||||||
vit != arr2.vertices_end(); ++vit, ++idx)
|
CGAL_assertion(idx < m_backup_inc.size());
|
||||||
{
|
vit->set_inc(m_backup_inc[idx]);
|
||||||
CGAL_assertion (idx < backup_inc.size());
|
|
||||||
vit->set_inc (backup_inc[idx]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*! Compute the overlay of two input arrangements.
|
/*! Compute the overlay of two input arrangements.
|
||||||
|
|
@ -148,64 +125,55 @@ template <typename GeometryTraitsA_2,
|
||||||
typename TopologyTraitsB,
|
typename TopologyTraitsB,
|
||||||
typename TopologyTraitsRes,
|
typename TopologyTraitsRes,
|
||||||
typename OverlayTraits>
|
typename OverlayTraits>
|
||||||
void
|
void overlay(const Arrangement_on_surface_2<GeometryTraitsA_2, TopologyTraitsA>& arr1,
|
||||||
overlay(const Arrangement_on_surface_2<GeometryTraitsA_2, TopologyTraitsA>& arr1,
|
|
||||||
const Arrangement_on_surface_2<GeometryTraitsB_2, TopologyTraitsB>& arr2,
|
const Arrangement_on_surface_2<GeometryTraitsB_2, TopologyTraitsB>& arr2,
|
||||||
Arrangement_on_surface_2<GeometryTraitsRes_2, TopologyTraitsRes>& arr,
|
Arrangement_on_surface_2<GeometryTraitsRes_2, TopologyTraitsRes>& arr,
|
||||||
OverlayTraits& ovl_tr)
|
OverlayTraits& ovl_tr) {
|
||||||
{
|
using Agt2 = GeometryTraitsA_2;
|
||||||
typedef GeometryTraitsA_2 Agt2;
|
using Bgt2 = GeometryTraitsB_2;
|
||||||
typedef GeometryTraitsB_2 Bgt2;
|
using Rgt2 = GeometryTraitsRes_2;
|
||||||
typedef GeometryTraitsRes_2 Rgt2;
|
using Att = TopologyTraitsA;
|
||||||
typedef TopologyTraitsA Att;
|
using Btt = TopologyTraitsB;
|
||||||
typedef TopologyTraitsB Btt;
|
using Rtt = TopologyTraitsRes;
|
||||||
typedef TopologyTraitsRes Rtt;
|
using Overlay_traits = OverlayTraits;
|
||||||
typedef OverlayTraits Overlay_traits;
|
|
||||||
|
|
||||||
typedef Arrangement_on_surface_2<Agt2, Att> Arr_a;
|
using Arr_a = Arrangement_on_surface_2<Agt2, Att>;
|
||||||
typedef Arrangement_on_surface_2<Bgt2, Btt> Arr_b;
|
using Arr_b = Arrangement_on_surface_2<Bgt2, Btt>;
|
||||||
typedef Arrangement_on_surface_2<Rgt2, Rtt> Arr_res;
|
using Arr_res = Arrangement_on_surface_2<Rgt2, Rtt>;
|
||||||
typedef typename Arr_res::Allocator Allocator;
|
using Allocator = typename Arr_res::Allocator;
|
||||||
|
|
||||||
// some type assertions (not all, but better than nothing).
|
// some type assertions (not all, but better than nothing).
|
||||||
typedef typename Agt2::Point_2 A_point;
|
using A_point = typename Agt2::Point_2;
|
||||||
typedef typename Bgt2::Point_2 B_point;
|
using B_point = typename Bgt2::Point_2;
|
||||||
typedef typename Rgt2::Point_2 Res_point;
|
using Res_point = typename Rgt2::Point_2;
|
||||||
static_assert(std::is_convertible<A_point, Res_point>::value);
|
static_assert(std::is_convertible<A_point, Res_point>::value);
|
||||||
static_assert(std::is_convertible<B_point, Res_point>::value);
|
static_assert(std::is_convertible<B_point, Res_point>::value);
|
||||||
|
|
||||||
typedef typename Agt2::X_monotone_curve_2 A_xcv;
|
using A_xcv = typename Agt2::X_monotone_curve_2;
|
||||||
typedef typename Bgt2::X_monotone_curve_2 B_xcv;
|
using B_xcv = typename Bgt2::X_monotone_curve_2;
|
||||||
typedef typename Rgt2::X_monotone_curve_2 Res_xcv;
|
using Res_xcv = typename Rgt2::X_monotone_curve_2;
|
||||||
static_assert(std::is_convertible<A_xcv, Res_xcv>::value);
|
static_assert(std::is_convertible<A_xcv, Res_xcv>::value);
|
||||||
static_assert(std::is_convertible<B_xcv, Res_xcv>::value);
|
static_assert(std::is_convertible<B_xcv, Res_xcv>::value);
|
||||||
|
|
||||||
typedef Arr_traits_basic_adaptor_2<Rgt2> Gt_adaptor_2;
|
using Gt_adaptor_2 = Arr_traits_basic_adaptor_2<Rgt2>;
|
||||||
typedef Arr_overlay_traits_2<Gt_adaptor_2, Arr_a, Arr_b>
|
using Ovl_gt2 = Arr_overlay_traits_2<Gt_adaptor_2, Arr_a, Arr_b>;
|
||||||
Ovl_gt2;
|
using Ovl_event = Arr_overlay_event<Ovl_gt2, Arr_res, Allocator>;
|
||||||
typedef Arr_overlay_event<Ovl_gt2, Arr_res, Allocator>
|
using Ovl_curve = Arr_overlay_subcurve<Ovl_gt2, Ovl_event, Allocator>;
|
||||||
Ovl_event;
|
using Ovl_helper = typename TopologyTraitsRes::template Overlay_helper<Ovl_gt2, Ovl_event, Ovl_curve, Arr_a, Arr_b>;
|
||||||
typedef Arr_overlay_subcurve<Ovl_gt2, Ovl_event, Allocator>
|
using Ovl_visitor = Arr_overlay_ss_visitor<Ovl_helper, Overlay_traits>;
|
||||||
Ovl_curve;
|
|
||||||
typedef typename TopologyTraitsRes::template
|
|
||||||
Overlay_helper<Ovl_gt2, Ovl_event, Ovl_curve, Arr_a, Arr_b>
|
|
||||||
Ovl_helper;
|
|
||||||
typedef Arr_overlay_ss_visitor<Ovl_helper, Overlay_traits>
|
|
||||||
Ovl_visitor;
|
|
||||||
|
|
||||||
typedef typename Ovl_gt2::X_monotone_curve_2 Ovl_x_monotone_curve_2;
|
using Ovl_x_monotone_curve_2 = typename Ovl_gt2::X_monotone_curve_2;
|
||||||
typedef typename Ovl_gt2::Point_2 Ovl_point_2;
|
using Ovl_point_2 = typename Ovl_gt2::Point_2;
|
||||||
typedef typename Ovl_gt2::Cell_handle_red Cell_handle_red;
|
using Cell_handle_red = typename Ovl_gt2::Cell_handle_red;
|
||||||
typedef typename Ovl_gt2::Optional_cell_red Optional_cell_red;
|
using Optional_cell_red = typename Ovl_gt2::Optional_cell_red;
|
||||||
typedef typename Ovl_gt2::Cell_handle_blue Cell_handle_blue;
|
using Cell_handle_blue = typename Ovl_gt2::Cell_handle_blue;
|
||||||
typedef typename Ovl_gt2::Optional_cell_blue Optional_cell_blue;
|
using Optional_cell_blue = typename Ovl_gt2::Optional_cell_blue;
|
||||||
|
|
||||||
CGAL_USE_TYPE(Optional_cell_red);
|
CGAL_USE_TYPE(Optional_cell_red);
|
||||||
CGAL_USE_TYPE(Optional_cell_blue);
|
CGAL_USE_TYPE(Optional_cell_blue);
|
||||||
|
|
||||||
// The result arrangement cannot be on of the input arrangements.
|
// The result arrangement cannot be on of the input arrangements.
|
||||||
CGAL_precondition(((void*)(&arr) != (void*)(&arr1)) &&
|
CGAL_precondition(((void*)(&arr) != (void*)(&arr1)) && ((void*)(&arr) != (void*)(&arr2)));
|
||||||
((void*)(&arr) != (void*)(&arr2)));
|
|
||||||
|
|
||||||
// Prepare a vector of extended x-monotone curves that represent all edges
|
// Prepare a vector of extended x-monotone curves that represent all edges
|
||||||
// in both input arrangements. Each curve is associated with a halfedge
|
// in both input arrangements. Each curve is associated with a halfedge
|
||||||
|
|
@ -216,23 +184,20 @@ overlay(const Arrangement_on_surface_2<GeometryTraitsA_2, TopologyTraitsA>& arr1
|
||||||
xcvs_vec(arr1.number_of_edges() + arr2.number_of_edges());
|
xcvs_vec(arr1.number_of_edges() + arr2.number_of_edges());
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
|
|
||||||
typename Arr_a::Edge_const_iterator eit1;
|
for (auto eit1 = arr1.edges_begin(); eit1 != arr1.edges_end(); ++eit1, ++i) {
|
||||||
for (eit1 = arr1.edges_begin(); eit1 != arr1.edges_end(); ++eit1, ++i) {
|
|
||||||
typename Arr_a::Halfedge_const_handle he1 = eit1;
|
typename Arr_a::Halfedge_const_handle he1 = eit1;
|
||||||
if (he1->direction() != ARR_RIGHT_TO_LEFT) he1 = he1->twin();
|
if (he1->direction() != ARR_RIGHT_TO_LEFT) he1 = he1->twin();
|
||||||
xcvs_vec[i] = Ovl_x_monotone_curve_2(eit1->curve(), he1, invalid_he2);
|
xcvs_vec[i] = Ovl_x_monotone_curve_2(eit1->curve(), he1, invalid_he2);
|
||||||
}
|
}
|
||||||
|
|
||||||
typename Arr_b::Edge_const_iterator eit2;
|
for (auto eit2 = arr2.edges_begin(); eit2 != arr2.edges_end(); ++eit2, ++i) {
|
||||||
for (eit2 = arr2.edges_begin(); eit2 != arr2.edges_end(); ++eit2, ++i) {
|
|
||||||
typename Arr_b::Halfedge_const_handle he2 = eit2;
|
typename Arr_b::Halfedge_const_handle he2 = eit2;
|
||||||
if (he2->direction() != ARR_RIGHT_TO_LEFT) he2 = he2->twin();
|
if (he2->direction() != ARR_RIGHT_TO_LEFT) he2 = he2->twin();
|
||||||
xcvs_vec[i] = Ovl_x_monotone_curve_2(eit2->curve(), invalid_he1, he2);
|
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.
|
// Obtain an extended traits-class object and define the sweep-line visitor.
|
||||||
const typename Arr_res::Traits_adaptor_2* traits_adaptor =
|
const typename Arr_res::Traits_adaptor_2* traits_adaptor = arr.traits_adaptor();
|
||||||
arr.traits_adaptor();
|
|
||||||
|
|
||||||
/* We would like to avoid copy construction of the geometry traits class.
|
/* We would like to avoid copy construction of the geometry traits class.
|
||||||
* Copy construction is undesired, because it may results with data
|
* Copy construction is undesired, because it may results with data
|
||||||
|
|
@ -246,29 +211,22 @@ overlay(const Arrangement_on_surface_2<GeometryTraitsA_2, TopologyTraitsA>& arr1
|
||||||
* Use the form 'A a(*b);' and not ''A a = b;' to handle the case where A has
|
* 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).
|
* only an implicit constructor, (which takes *b as a parameter).
|
||||||
*/
|
*/
|
||||||
std::conditional_t<std::is_same_v<Gt_adaptor_2, Ovl_gt2>,
|
std::conditional_t<std::is_same_v<Gt_adaptor_2, Ovl_gt2>, const Ovl_gt2&, Ovl_gt2> ex_traits(*traits_adaptor);
|
||||||
const Ovl_gt2&, Ovl_gt2>
|
|
||||||
ex_traits(*traits_adaptor);
|
|
||||||
|
|
||||||
Ovl_visitor visitor(&arr1, &arr2, &arr, &ovl_tr);
|
Ovl_visitor visitor(&arr1, &arr2, &arr, &ovl_tr);
|
||||||
Ss2::Surface_sweep_2<Ovl_visitor> surface_sweep(&ex_traits, &visitor);
|
Ss2::Surface_sweep_2<Ovl_visitor> surface_sweep(&ex_traits, &visitor);
|
||||||
|
|
||||||
// In case both arrangement do not contain isolated vertices, go on and
|
// In case both arrangement do not contain isolated vertices, go on and
|
||||||
// overlay them.
|
// overlay them.
|
||||||
const std::size_t total_iso_verts =
|
const std::size_t total_iso_verts = arr1.number_of_isolated_vertices() + arr2.number_of_isolated_vertices();
|
||||||
arr1.number_of_isolated_vertices() + arr2.number_of_isolated_vertices();
|
|
||||||
|
|
||||||
if (total_iso_verts == 0) {
|
if (total_iso_verts == 0) {
|
||||||
// Clear the result arrangement and perform the sweep to construct it.
|
// Clear the result arrangement and perform the sweep to construct it.
|
||||||
arr.clear();
|
arr.clear();
|
||||||
if (std::is_same<typename Agt2::Bottom_side_category,
|
if (std::is_same<typename Agt2::Bottom_side_category, Arr_contracted_side_tag>::value)
|
||||||
Arr_contracted_side_tag>::value)
|
|
||||||
surface_sweep.sweep(xcvs_vec.begin(), xcvs_vec.end());
|
surface_sweep.sweep(xcvs_vec.begin(), xcvs_vec.end());
|
||||||
else
|
else
|
||||||
surface_sweep.indexed_sweep (xcvs_vec,
|
surface_sweep.indexed_sweep(xcvs_vec, Indexed_sweep_accessor<Arr_a, Arr_b, Ovl_x_monotone_curve_2>(arr1, arr2));
|
||||||
Indexed_sweep_accessor
|
|
||||||
<Arr_a, Arr_b, Ovl_x_monotone_curve_2>
|
|
||||||
(arr1, arr2));
|
|
||||||
xcvs_vec.clear();
|
xcvs_vec.clear();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -278,37 +236,28 @@ overlay(const Arrangement_on_surface_2<GeometryTraitsA_2, TopologyTraitsA>& arr1
|
||||||
std::vector<Ovl_point_2> pts_vec(total_iso_verts);
|
std::vector<Ovl_point_2> pts_vec(total_iso_verts);
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
typename Arr_a::Vertex_const_iterator vit1;
|
for (auto vit1 = arr1.vertices_begin(); vit1 != arr1.vertices_end(); ++vit1) {
|
||||||
for (vit1 = arr1.vertices_begin(); vit1 != arr1.vertices_end(); ++vit1) {
|
|
||||||
if (vit1->is_isolated()) {
|
if (vit1->is_isolated()) {
|
||||||
typename Arr_a::Vertex_const_handle v1 = vit1;
|
typename Arr_a::Vertex_const_handle v1 = vit1;
|
||||||
pts_vec[i++] =
|
pts_vec[i++] = Ovl_point_2(vit1->point(), std::make_optional(Cell_handle_red(v1)),
|
||||||
Ovl_point_2(vit1->point(), std::make_optional(Cell_handle_red(v1)),
|
|
||||||
std::optional<Cell_handle_blue>());
|
std::optional<Cell_handle_blue>());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
typename Arr_b::Vertex_const_iterator vit2;
|
for (auto vit2 = arr2.vertices_begin(); vit2 != arr2.vertices_end(); ++vit2) {
|
||||||
for (vit2 = arr2.vertices_begin(); vit2 != arr2.vertices_end(); ++vit2) {
|
|
||||||
if (vit2->is_isolated()) {
|
if (vit2->is_isolated()) {
|
||||||
typename Arr_b::Vertex_const_handle v2 = vit2;
|
typename Arr_b::Vertex_const_handle v2 = vit2;
|
||||||
pts_vec[i++] =
|
pts_vec[i++] = Ovl_point_2(vit2->point(), std::optional<Cell_handle_red>(),
|
||||||
Ovl_point_2(vit2->point(), std::optional<Cell_handle_red>(),
|
|
||||||
std::make_optional(Cell_handle_blue(v2)));
|
std::make_optional(Cell_handle_blue(v2)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear the result arrangement and perform the sweep to construct it.
|
// Clear the result arrangement and perform the sweep to construct it.
|
||||||
arr.clear();
|
arr.clear();
|
||||||
if (std::is_same<typename Agt2::Bottom_side_category,
|
if (std::is_same<typename Agt2::Bottom_side_category, Arr_contracted_side_tag>::value)
|
||||||
Arr_contracted_side_tag>::value)
|
surface_sweep.sweep(xcvs_vec.begin(), xcvs_vec.end(), pts_vec.begin(), pts_vec.end());
|
||||||
surface_sweep.sweep(xcvs_vec.begin(), xcvs_vec.end(),
|
|
||||||
pts_vec.begin(), pts_vec.end());
|
|
||||||
else
|
else
|
||||||
surface_sweep.indexed_sweep (xcvs_vec,
|
surface_sweep.indexed_sweep(xcvs_vec, Indexed_sweep_accessor<Arr_a, Arr_b, Ovl_x_monotone_curve_2>(arr1, arr2),
|
||||||
Indexed_sweep_accessor
|
|
||||||
<Arr_a, Arr_b, Ovl_x_monotone_curve_2>
|
|
||||||
(arr1, arr2),
|
|
||||||
pts_vec.begin(), pts_vec.end());
|
pts_vec.begin(), pts_vec.end());
|
||||||
xcvs_vec.clear();
|
xcvs_vec.clear();
|
||||||
pts_vec.clear();
|
pts_vec.clear();
|
||||||
|
|
@ -325,20 +274,18 @@ template <typename GeometryTraitsA_2,
|
||||||
typename TopologyTraitsA,
|
typename TopologyTraitsA,
|
||||||
typename TopologyTraitsB,
|
typename TopologyTraitsB,
|
||||||
typename TopologyTraitsRes>
|
typename TopologyTraitsRes>
|
||||||
void
|
void overlay(const Arrangement_on_surface_2<GeometryTraitsA_2, TopologyTraitsA>& arr1,
|
||||||
overlay(const Arrangement_on_surface_2<GeometryTraitsA_2, TopologyTraitsA>& arr1,
|
|
||||||
const Arrangement_on_surface_2<GeometryTraitsB_2, TopologyTraitsB>& arr2,
|
const Arrangement_on_surface_2<GeometryTraitsB_2, TopologyTraitsB>& arr2,
|
||||||
Arrangement_on_surface_2<GeometryTraitsRes_2, TopologyTraitsRes>& arr)
|
Arrangement_on_surface_2<GeometryTraitsRes_2, TopologyTraitsRes>& arr) {
|
||||||
{
|
using Agt2 = GeometryTraitsA_2;
|
||||||
typedef GeometryTraitsA_2 Agt2;
|
using Bgt2 = GeometryTraitsB_2;
|
||||||
typedef GeometryTraitsB_2 Bgt2;
|
using Rgt2 = GeometryTraitsRes_2;
|
||||||
typedef GeometryTraitsRes_2 Rgt2;
|
using Att = TopologyTraitsA;
|
||||||
typedef TopologyTraitsA Att;
|
using Btt = TopologyTraitsB;
|
||||||
typedef TopologyTraitsB Btt;
|
using Rtt = TopologyTraitsRes;
|
||||||
typedef TopologyTraitsRes Rtt;
|
using Arr_a = Arrangement_on_surface_2<Agt2, Att>;
|
||||||
typedef Arrangement_on_surface_2<Agt2, Att> Arr_a;
|
using Arr_b = Arrangement_on_surface_2<Bgt2, Btt>;
|
||||||
typedef Arrangement_on_surface_2<Bgt2, Btt> Arr_b;
|
using Arr_res = Arrangement_on_surface_2<Rgt2, Rtt>;
|
||||||
typedef Arrangement_on_surface_2<Rgt2, Rtt> Arr_res;
|
|
||||||
|
|
||||||
_Arr_default_overlay_traits_base<Arr_a, Arr_b, Arr_res> ovl_traits;
|
_Arr_default_overlay_traits_base<Arr_a, Arr_b, Arr_res> ovl_traits;
|
||||||
overlay(arr1, arr2, arr, ovl_traits);
|
overlay(arr1, arr2, arr, ovl_traits);
|
||||||
|
|
|
||||||
|
|
@ -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 <efif@post.tau.ac.il>
|
||||||
|
|
||||||
|
#ifndef CGAL_DO_INTERSECT_ARR_OVERLAY_SS_VISITOR_H
|
||||||
|
#define CGAL_DO_INTERSECT_ARR_OVERLAY_SS_VISITOR_H
|
||||||
|
|
||||||
|
#include <CGAL/license/Arrangement_on_surface_2.h>
|
||||||
|
|
||||||
|
/*! \file
|
||||||
|
*
|
||||||
|
* Definition of the Arr_do_intersect_overlay_ss_visitor class-template.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <CGAL/Default.h>
|
||||||
|
#include <CGAL/Surface_sweep_2/Arr_overlay_ss_visitor.h>
|
||||||
|
|
||||||
|
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 <typename OverlayHelper, typename OverlayTraits, typename Visitor_ = Default>
|
||||||
|
class Arr_do_intersect_overlay_ss_visitor :
|
||||||
|
public Arr_overlay_ss_visitor<
|
||||||
|
OverlayHelper, OverlayTraits,
|
||||||
|
typename Default::Get<Visitor_,
|
||||||
|
Arr_do_intersect_overlay_ss_visitor<OverlayHelper, OverlayTraits, Visitor_> >::type> {
|
||||||
|
private:
|
||||||
|
using Overlay_helper = OverlayHelper;
|
||||||
|
using Overlay_traits = OverlayTraits;
|
||||||
|
|
||||||
|
using Self = Arr_do_intersect_overlay_ss_visitor<Overlay_helper, Overlay_traits, Visitor_>;
|
||||||
|
using Visitor = typename Default::Get<Visitor_, Self>::type;
|
||||||
|
using Base = Arr_overlay_ss_visitor<Overlay_helper, Overlay_traits, 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
|
||||||
|
|
@ -42,35 +42,33 @@ class Arr_no_intersection_insertion_ss_visitor :
|
||||||
public Arr_construction_ss_visitor<
|
public Arr_construction_ss_visitor<
|
||||||
Helper_,
|
Helper_,
|
||||||
typename Default::Get<Visitor_, Arr_no_intersection_insertion_ss_visitor<
|
typename Default::Get<Visitor_, Arr_no_intersection_insertion_ss_visitor<
|
||||||
Helper_, Visitor_> >::type>
|
Helper_, Visitor_> >::type> {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
typedef Helper_ Helper;
|
using Helper = Helper_;
|
||||||
|
|
||||||
typedef typename Helper::Geometry_traits_2 Geometry_traits_2;
|
using Geometry_traits_2 = typename Helper::Geometry_traits_2;
|
||||||
typedef typename Helper::Event Event;
|
using Event = typename Helper::Event;
|
||||||
typedef typename Helper::Subcurve Subcurve;
|
using Subcurve = typename Helper::Subcurve;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef Geometry_traits_2 Gt2;
|
using Gt2 = Geometry_traits_2;
|
||||||
typedef Arr_no_intersection_insertion_ss_visitor<Helper, Visitor_>
|
using Self = Arr_no_intersection_insertion_ss_visitor<Helper, Visitor_>;
|
||||||
Self;
|
using Visitor = typename Default::Get<Visitor_, Self>::type;
|
||||||
typedef typename Default::Get<Visitor_, Self>::type Visitor;
|
using Base = Arr_construction_ss_visitor<Helper, Visitor>;
|
||||||
typedef Arr_construction_ss_visitor<Helper, Visitor> Base;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef typename Gt2::X_monotone_curve_2 X_monotone_curve_2;
|
using X_monotone_curve_2 = typename Gt2::X_monotone_curve_2;
|
||||||
typedef typename Gt2::Point_2 Point_2;
|
using Point_2 = typename Gt2::Point_2;
|
||||||
|
using Multiplicity = typename Gt2::Multiplicity;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
typedef typename Subcurve::Status_line_iterator Status_line_iterator;
|
using Status_line_iterator = typename Subcurve::Status_line_iterator;
|
||||||
typedef typename Base::Event_subcurve_reverse_iterator
|
using Event_subcurve_reverse_iterator = typename Base::Event_subcurve_reverse_iterator;
|
||||||
Event_subcurve_reverse_iterator;
|
|
||||||
|
|
||||||
typedef typename Helper::Arrangement_2 Arrangement_2;
|
using Arrangement_2 = typename Helper::Arrangement_2;
|
||||||
typedef typename Arrangement_2::Vertex_handle Vertex_handle;
|
using Vertex_handle = typename Arrangement_2::Vertex_handle;
|
||||||
typedef typename Arrangement_2::Halfedge_handle Halfedge_handle;
|
using Halfedge_handle = typename Arrangement_2::Halfedge_handle;
|
||||||
typedef typename Arrangement_2::Face_handle Face_handle;
|
using Face_handle = typename Arrangement_2::Face_handle;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*! Constructor. */
|
/*! Constructor. */
|
||||||
|
|
@ -103,13 +101,12 @@ public:
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void update_event(Event* /* e */, Subcurve* /* sc1 */, Subcurve* /* sc2 */,
|
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 */, 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;
|
Vertex_handle invalid_v;
|
||||||
if (e->point().vertex_handle() == invalid_v)
|
if (e->point().vertex_handle() == invalid_v)
|
||||||
e->point().set_vertex_handle(pt.vertex_handle());
|
e->point().set_vertex_handle(pt.vertex_handle());
|
||||||
|
|
@ -241,8 +238,7 @@ void Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::before_sweep()
|
||||||
//
|
//
|
||||||
template <typename Hlpr, typename Vis>
|
template <typename Hlpr, typename Vis>
|
||||||
void Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::
|
void Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::
|
||||||
before_handle_event(Event* event)
|
before_handle_event(Event* event) {
|
||||||
{
|
|
||||||
// First we notify the helper class on the event.
|
// First we notify the helper class on the event.
|
||||||
this->m_helper.before_handle_event(event);
|
this->m_helper.before_handle_event(event);
|
||||||
|
|
||||||
|
|
@ -330,8 +326,7 @@ before_handle_event(Event* event)
|
||||||
//
|
//
|
||||||
template <typename Hlpr, typename Vis>
|
template <typename Hlpr, typename Vis>
|
||||||
bool Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::
|
bool Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::
|
||||||
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;
|
const Halfedge_handle invalid_he;
|
||||||
if (cv.halfedge_handle() != invalid_he) return false;
|
if (cv.halfedge_handle() != invalid_he) return false;
|
||||||
// Insert the curve into the arrangement
|
// Insert the curve into the arrangement
|
||||||
|
|
@ -344,8 +339,7 @@ add_subcurve_(const X_monotone_curve_2& cv, Subcurve* sc)
|
||||||
//
|
//
|
||||||
template <typename Hlpr, typename Vis>
|
template <typename Hlpr, typename Vis>
|
||||||
void Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::
|
void Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::
|
||||||
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;
|
if (add_subcurve_(cv, sc)) return;
|
||||||
|
|
||||||
Halfedge_handle next_ccw_he =
|
Halfedge_handle next_ccw_he =
|
||||||
|
|
@ -359,8 +353,7 @@ add_subcurve(const X_monotone_curve_2& cv, Subcurve* sc)
|
||||||
template <typename Hlpr, typename Vis>
|
template <typename Hlpr, typename Vis>
|
||||||
typename Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::Halfedge_handle
|
typename Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::Halfedge_handle
|
||||||
Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::
|
Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::
|
||||||
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);
|
Event* last_event = this->last_event_on_subcurve(sc);
|
||||||
Vertex_handle last_v = last_event->point().vertex_handle();
|
Vertex_handle last_v = last_event->point().vertex_handle();
|
||||||
Vertex_handle curr_v = this->current_event()->point().vertex_handle();
|
Vertex_handle curr_v = this->current_event()->point().vertex_handle();
|
||||||
|
|
@ -385,8 +378,7 @@ template <typename Hlpr, typename Vis>
|
||||||
typename Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::Halfedge_handle
|
typename Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::Halfedge_handle
|
||||||
Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::
|
Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::
|
||||||
insert_from_left_vertex(const X_monotone_curve_2& cv, Halfedge_handle he,
|
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();
|
Vertex_handle curr_v = this->current_event()->point().vertex_handle();
|
||||||
if (curr_v != Vertex_handle())
|
if (curr_v != Vertex_handle())
|
||||||
return (this->m_arr->insert_at_vertices(cv.base(), he, curr_v));
|
return (this->m_arr->insert_at_vertices(cv.base(), he, curr_v));
|
||||||
|
|
@ -400,8 +392,7 @@ template <typename Hlpr, typename Vis>
|
||||||
typename Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::Halfedge_handle
|
typename Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::Halfedge_handle
|
||||||
Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::
|
Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::
|
||||||
insert_from_right_vertex(const X_monotone_curve_2& cv, Halfedge_handle he,
|
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);
|
Event* last_event = this->last_event_on_subcurve(sc);
|
||||||
Vertex_handle last_v = last_event->point().vertex_handle();
|
Vertex_handle last_v = last_event->point().vertex_handle();
|
||||||
if (last_v != Vertex_handle())
|
if (last_v != Vertex_handle())
|
||||||
|
|
@ -426,8 +417,7 @@ insert_at_vertices(const X_monotone_curve_2& cv,
|
||||||
template <typename Hlpr, typename Vis>
|
template <typename Hlpr, typename Vis>
|
||||||
typename Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::Vertex_handle
|
typename Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::Vertex_handle
|
||||||
Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::
|
Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::
|
||||||
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 the isolated vertex is already at the arrangement, return:
|
||||||
if (pt.vertex_handle() != Vertex_handle()) return Vertex_handle();
|
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 Hlpr, typename Vis>
|
template <typename Hlpr, typename Vis>
|
||||||
typename Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::Halfedge_handle
|
typename Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::Halfedge_handle
|
||||||
Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::
|
Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::
|
||||||
_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
|
// Check if the vertex to be associated with the left end of the curve has
|
||||||
// already been created.
|
// already been created.
|
||||||
Event* last_event = this->last_event_on_subcurve(sc);
|
Event* last_event = this->last_event_on_subcurve(sc);
|
||||||
|
|
@ -514,8 +503,7 @@ template <typename Hlpr, typename Vis>
|
||||||
typename Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::Halfedge_handle
|
typename Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::Halfedge_handle
|
||||||
Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::
|
Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::
|
||||||
_insert_from_left_vertex(const X_monotone_curve_2& cv,
|
_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
|
// Check if the vertex to be associated with the right end of the curve has
|
||||||
// already been created.
|
// already been created.
|
||||||
Event* curr_event = this->current_event();
|
Event* curr_event = this->current_event();
|
||||||
|
|
@ -551,8 +539,7 @@ template <typename Hlpr, typename Vis>
|
||||||
typename Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::Halfedge_handle
|
typename Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::Halfedge_handle
|
||||||
Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::
|
Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::
|
||||||
_insert_from_right_vertex(const X_monotone_curve_2& cv, Halfedge_handle prev,
|
_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
|
// Check if the vertex to be associated with the left end of the curve has
|
||||||
// already been created.
|
// already been created.
|
||||||
Event* last_event = this->last_event_on_subcurve(sc);
|
Event* last_event = this->last_event_on_subcurve(sc);
|
||||||
|
|
@ -589,8 +576,7 @@ typename Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::Halfedge_handle
|
||||||
Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::
|
Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::
|
||||||
_insert_at_vertices(const X_monotone_curve_2& cv,
|
_insert_at_vertices(const X_monotone_curve_2& cv,
|
||||||
Halfedge_handle prev1, Halfedge_handle prev2,
|
Halfedge_handle prev1, Halfedge_handle prev2,
|
||||||
Subcurve* sc, bool& new_face_created)
|
Subcurve* sc, bool& new_face_created) {
|
||||||
{
|
|
||||||
// Perform the insertion.
|
// Perform the insertion.
|
||||||
new_face_created = false;
|
new_face_created = false;
|
||||||
bool swapped_predecessors = false;
|
bool swapped_predecessors = false;
|
||||||
|
|
@ -632,8 +618,7 @@ _insert_at_vertices(const X_monotone_curve_2& cv,
|
||||||
template <typename Hlpr, typename Vis>
|
template <typename Hlpr, typename Vis>
|
||||||
typename Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::Face_handle
|
typename Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::Face_handle
|
||||||
Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::
|
Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::
|
||||||
_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
|
// Go up the status line and try to locate a curve which is associated
|
||||||
// with a valid arrangement halfedge.
|
// with a valid arrangement halfedge.
|
||||||
const Halfedge_handle invalid_he;
|
const Halfedge_handle invalid_he;
|
||||||
|
|
|
||||||
|
|
@ -40,92 +40,80 @@ namespace CGAL {
|
||||||
* arrangement, creating a result arrangement. All three arrangements are
|
* arrangement, creating a result arrangement. All three arrangements are
|
||||||
* embedded on the same type of surface and use the same geometry traits.
|
* embedded on the same type of surface and use the same geometry traits.
|
||||||
*/
|
*/
|
||||||
template <typename OverlayHelper, typename OverlayTraits,
|
template <typename OverlayHelper, typename OverlayTraits, typename Visitor_ = Default>
|
||||||
typename Visitor_ = Default>
|
|
||||||
class Arr_overlay_ss_visitor :
|
class Arr_overlay_ss_visitor :
|
||||||
public Arr_construction_ss_visitor<
|
public Arr_construction_ss_visitor<
|
||||||
typename OverlayHelper::Construction_helper,
|
typename OverlayHelper::Construction_helper,
|
||||||
typename Default::Get<Visitor_,
|
typename Default::Get<Visitor_,
|
||||||
Arr_overlay_ss_visitor<OverlayHelper, OverlayTraits,
|
Arr_overlay_ss_visitor<OverlayHelper, OverlayTraits, Visitor_> >::type> {
|
||||||
Visitor_> >::type>
|
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
typedef OverlayHelper Overlay_helper;
|
using Overlay_helper = OverlayHelper;
|
||||||
typedef OverlayTraits Overlay_traits;
|
using Overlay_traits = OverlayTraits;
|
||||||
|
|
||||||
typedef typename Overlay_helper::Geometry_traits_2 Geometry_traits_2;
|
using Geometry_traits_2 = typename Overlay_helper::Geometry_traits_2;
|
||||||
typedef typename Overlay_helper::Event Event;
|
using Event = typename Overlay_helper::Event;
|
||||||
typedef typename Overlay_helper::Subcurve Subcurve;
|
using Subcurve = typename Overlay_helper::Subcurve;
|
||||||
|
|
||||||
typedef typename Overlay_helper::Arrangement_red_2 Arrangement_red_2;
|
using Arrangement_red_2 = typename Overlay_helper::Arrangement_red_2;
|
||||||
typedef typename Overlay_helper::Arrangement_blue_2 Arrangement_blue_2;
|
using Arrangement_blue_2 = typename Overlay_helper::Arrangement_blue_2;
|
||||||
|
|
||||||
typedef typename Overlay_helper::Construction_helper Construction_helper;
|
|
||||||
|
|
||||||
|
using Construction_helper = typename Overlay_helper::Construction_helper;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef Geometry_traits_2 Gt2;
|
using Gt2 = Geometry_traits_2;
|
||||||
typedef Arrangement_red_2 Ar2;
|
using Ar2 = Arrangement_red_2;
|
||||||
typedef Arrangement_blue_2 Ab2;
|
using Ab2 = Arrangement_blue_2;
|
||||||
|
|
||||||
typedef Arr_overlay_ss_visitor<Overlay_helper, Overlay_traits, Visitor_>
|
using Self = Arr_overlay_ss_visitor<Overlay_helper, Overlay_traits, Visitor_>;
|
||||||
Self;
|
using Visitor = typename Default::Get<Visitor_, Self>::type;
|
||||||
typedef typename Default::Get<Visitor_, Self>::type Visitor;
|
using Base = Arr_construction_ss_visitor<Construction_helper, Visitor>;
|
||||||
typedef Arr_construction_ss_visitor<Construction_helper, Visitor>
|
|
||||||
Base;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef typename Gt2::X_monotone_curve_2 X_monotone_curve_2;
|
using X_monotone_curve_2 = typename Gt2::X_monotone_curve_2;
|
||||||
typedef typename Gt2::Point_2 Point_2;
|
using Point_2 = typename Gt2::Point_2;
|
||||||
|
using Multiplicity = typename Gt2::Multiplicity;
|
||||||
|
|
||||||
// The input arrangements (the "red" and the "blue" one):
|
// The input arrangements (the "red" and the "blue" one):
|
||||||
typedef typename Ar2::Halfedge_const_handle Halfedge_handle_red;
|
using Halfedge_handle_red = typename Ar2::Halfedge_const_handle;
|
||||||
typedef typename Ar2::Face_const_handle Face_handle_red;
|
using Face_handle_red = typename Ar2::Face_const_handle;
|
||||||
typedef typename Ar2::Vertex_const_handle Vertex_handle_red;
|
using Vertex_handle_red = typename Ar2::Vertex_const_handle;
|
||||||
|
|
||||||
typedef typename Ab2::Halfedge_const_handle Halfedge_handle_blue;
|
using Halfedge_handle_blue = typename Ab2::Halfedge_const_handle;
|
||||||
typedef typename Ab2::Face_const_handle Face_handle_blue;
|
using Face_handle_blue = typename Ab2::Face_const_handle;
|
||||||
typedef typename Ab2::Vertex_const_handle Vertex_handle_blue;
|
using Vertex_handle_blue = typename Ab2::Vertex_const_handle;
|
||||||
|
|
||||||
// The resulting arrangement:
|
// The resulting arrangement:
|
||||||
typedef typename Overlay_helper::Arrangement_2 Arrangement_2;
|
using Arrangement_2 = typename Overlay_helper::Arrangement_2;
|
||||||
typedef typename Arrangement_2::Halfedge_handle Halfedge_handle;
|
using Halfedge_handle = typename Arrangement_2::Halfedge_handle;
|
||||||
typedef typename Arrangement_2::Face_handle Face_handle;
|
using Face_handle = typename Arrangement_2::Face_handle;
|
||||||
typedef typename Arrangement_2::Vertex_handle Vertex_handle;
|
using Vertex_handle = typename Arrangement_2::Vertex_handle;
|
||||||
typedef typename Arrangement_2::Ccb_halfedge_circulator
|
using Ccb_halfedge_circulator = typename Arrangement_2::Ccb_halfedge_circulator;
|
||||||
Ccb_halfedge_circulator;
|
using Outer_ccb_iterator = typename Arrangement_2::Outer_ccb_iterator;
|
||||||
typedef typename Arrangement_2::Outer_ccb_iterator Outer_ccb_iterator;
|
|
||||||
|
|
||||||
typedef typename Base::Event_subcurve_iterator
|
using Event_subcurve_iterator = typename Base::Event_subcurve_iterator;
|
||||||
Event_subcurve_iterator;
|
using Event_subcurve_reverse_iterator = typename Base::Event_subcurve_reverse_iterator;
|
||||||
typedef typename Base::Event_subcurve_reverse_iterator
|
using Status_line_iterator = typename Base::Status_line_iterator;
|
||||||
Event_subcurve_reverse_iterator;
|
|
||||||
typedef typename Base::Status_line_iterator Status_line_iterator;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
typedef typename Gt2::Cell_handle_red Cell_handle_red;
|
using Cell_handle_red = typename Gt2::Cell_handle_red;
|
||||||
typedef typename Gt2::Optional_cell_red Optional_cell_red;
|
using Optional_cell_red = typename Gt2::Optional_cell_red;
|
||||||
typedef typename Gt2::Cell_handle_blue Cell_handle_blue;
|
using Cell_handle_blue = typename Gt2::Cell_handle_blue;
|
||||||
typedef typename Gt2::Optional_cell_blue Optional_cell_blue;
|
using Optional_cell_blue = typename Gt2::Optional_cell_blue;
|
||||||
|
|
||||||
typedef std::pair<Halfedge_handle_red, Halfedge_handle_blue>
|
using Halfedge_info = std::pair<Halfedge_handle_red, Halfedge_handle_blue>;
|
||||||
Halfedge_info;
|
using Halfedge_map = Unique_hash_map<Halfedge_handle, Halfedge_info>;
|
||||||
typedef Unique_hash_map<Halfedge_handle, Halfedge_info>
|
|
||||||
Halfedge_map;
|
|
||||||
|
|
||||||
typedef std::pair<Cell_handle_red, Cell_handle_blue> Handle_info;
|
using Handle_info = std::pair<Cell_handle_red, Cell_handle_blue>;
|
||||||
typedef std::unordered_map<Vertex_handle, Handle_info, Handle_hash_function>
|
using Vertex_map = std::unordered_map<Vertex_handle, Handle_info, Handle_hash_function>;
|
||||||
Vertex_map;
|
|
||||||
|
|
||||||
// Side categoties:
|
// Side categoties:
|
||||||
typedef typename Gt2::Left_side_category Left_side_category;
|
using Left_side_category = typename Gt2::Left_side_category;
|
||||||
typedef typename Gt2::Bottom_side_category Bottom_side_category;
|
using Bottom_side_category = typename Gt2::Bottom_side_category;
|
||||||
typedef typename Gt2::Top_side_category Top_side_category;
|
using Top_side_category = typename Gt2::Top_side_category;
|
||||||
typedef typename Gt2::Right_side_category Right_side_category;
|
using Right_side_category = typename Gt2::Right_side_category;
|
||||||
|
|
||||||
typedef typename Arr_has_identified_sides<Left_side_category,
|
using Has_identified_sides_category =
|
||||||
Bottom_side_category>::result
|
typename Arr_has_identified_sides<Left_side_category, Bottom_side_category>::result;
|
||||||
Has_identified_sides_category;
|
|
||||||
|
|
||||||
// Data members:
|
// Data members:
|
||||||
Overlay_traits* m_overlay_traits; // The overlay traits object.
|
Overlay_traits* m_overlay_traits; // The overlay traits object.
|
||||||
|
|
@ -195,10 +183,9 @@ public:
|
||||||
void update_event(Event* /* e */,
|
void update_event(Event* /* e */,
|
||||||
Subcurve* /* c1 */,
|
Subcurve* /* c1 */,
|
||||||
Subcurve* /* c2 */,
|
Subcurve* /* c2 */,
|
||||||
bool CGAL_assertion_code(is_new))
|
bool CGAL_assertion_code(is_new),
|
||||||
{
|
Multiplicity /* multiplicity */)
|
||||||
CGAL_assertion(is_new == true);
|
{ CGAL_assertion(is_new == true); }
|
||||||
}
|
|
||||||
|
|
||||||
/*! Update an event. */
|
/*! Update an event. */
|
||||||
void update_event(Event* e, Subcurve* sc);
|
void update_event(Event* e, Subcurve* sc);
|
||||||
|
|
@ -408,8 +395,7 @@ protected:
|
||||||
// A notification issued before the sweep process starts.
|
// A notification issued before the sweep process starts.
|
||||||
//
|
//
|
||||||
template <typename OvlHlpr, typename OvlTr, typename Vis>
|
template <typename OvlHlpr, typename OvlTr, typename Vis>
|
||||||
void Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::before_sweep()
|
void Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::before_sweep() {
|
||||||
{
|
|
||||||
// Initialize the necessary fields in the base construction visitor.
|
// Initialize the necessary fields in the base construction visitor.
|
||||||
// Note that the construction visitor also informs its helper class that
|
// Note that the construction visitor also informs its helper class that
|
||||||
// the sweep process is about to start.
|
// the sweep process is about to start.
|
||||||
|
|
@ -425,8 +411,7 @@ protected:
|
||||||
//
|
//
|
||||||
template <typename OvlHlpr, typename OvlTr, typename Vis>
|
template <typename OvlHlpr, typename OvlTr, typename Vis>
|
||||||
void
|
void
|
||||||
Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::before_handle_event(Event* event)
|
Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::before_handle_event(Event* event) {
|
||||||
{
|
|
||||||
// Let the base construction visitor do the work (and also inform its helper
|
// Let the base construction visitor do the work (and also inform its helper
|
||||||
// class on the event).
|
// class on the event).
|
||||||
Base::before_handle_event(event);
|
Base::before_handle_event(event);
|
||||||
|
|
@ -441,8 +426,7 @@ Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::before_handle_event(Event* event)
|
||||||
//
|
//
|
||||||
template <typename OvlHlpr, typename OvlTr, typename Vis>
|
template <typename OvlHlpr, typename OvlTr, typename Vis>
|
||||||
bool Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::
|
bool Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::
|
||||||
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.
|
// Let the base construction visitor handle the event.
|
||||||
bool res = Base::after_handle_event(event, iter, flag);
|
bool res = Base::after_handle_event(event, iter, flag);
|
||||||
|
|
||||||
|
|
@ -497,8 +481,7 @@ update_event(Event* e,
|
||||||
const Point_2& end_point,
|
const Point_2& end_point,
|
||||||
const X_monotone_curve_2& /* cv */,
|
const X_monotone_curve_2& /* cv */,
|
||||||
Arr_curve_end /* cv_end */,
|
Arr_curve_end /* cv_end */,
|
||||||
bool /* is_new */)
|
bool /* is_new */) {
|
||||||
{
|
|
||||||
// Nothing to do in case of an event at infinity.
|
// Nothing to do in case of an event at infinity.
|
||||||
CGAL_assertion(e->is_closed());
|
CGAL_assertion(e->is_closed());
|
||||||
|
|
||||||
|
|
@ -513,8 +496,7 @@ update_event(Event* e,
|
||||||
//
|
//
|
||||||
template <typename OvlHlpr, typename OvlTr, typename Vis>
|
template <typename OvlHlpr, typename OvlTr, typename Vis>
|
||||||
void Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::update_event(Event* e,
|
void Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::update_event(Event* e,
|
||||||
Subcurve* sc)
|
Subcurve* sc) {
|
||||||
{
|
|
||||||
// Update the red and blue halfedges associated with the point as necessary.
|
// Update the red and blue halfedges associated with the point as necessary.
|
||||||
Point_2& pt = e->point();
|
Point_2& pt = e->point();
|
||||||
|
|
||||||
|
|
@ -538,8 +520,7 @@ template <typename OvlHlpr, typename OvlTr, typename Vis>
|
||||||
void
|
void
|
||||||
Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::update_event(Event* e,
|
Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::update_event(Event* e,
|
||||||
const Point_2& p,
|
const Point_2& p,
|
||||||
bool /* is_new */)
|
bool /* is_new */) {
|
||||||
{
|
|
||||||
// Update the red and blue objects associated with the point as necessary.
|
// Update the red and blue objects associated with the point as necessary.
|
||||||
Point_2& pt = e->point();
|
Point_2& pt = e->point();
|
||||||
if (pt.is_red_cell_empty()) pt.set_red_cell(p.red_cell());
|
if (pt.is_red_cell_empty()) pt.set_red_cell(p.red_cell());
|
||||||
|
|
@ -550,8 +531,7 @@ Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::update_event(Event* e,
|
||||||
// A notification issued when the sweep process has ended.
|
// A notification issued when the sweep process has ended.
|
||||||
//
|
//
|
||||||
template <typename OvlHlpr, typename OvlTr, typename Vis>
|
template <typename OvlHlpr, typename OvlTr, typename Vis>
|
||||||
void Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::after_sweep()
|
void Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::after_sweep() {
|
||||||
{
|
|
||||||
Base::after_sweep();
|
Base::after_sweep();
|
||||||
|
|
||||||
// Notify boundary vertices:
|
// Notify boundary vertices:
|
||||||
|
|
@ -580,8 +560,7 @@ void Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::after_sweep()
|
||||||
template <typename OvlHlpr, typename OvlTr, typename Vis>
|
template <typename OvlHlpr, typename OvlTr, typename Vis>
|
||||||
typename Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::Halfedge_handle
|
typename Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::Halfedge_handle
|
||||||
Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::
|
Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::
|
||||||
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.
|
// Insert the halfedge using the base construction visitor.
|
||||||
Halfedge_handle new_he = Base::insert_in_face_interior(cv, sc);
|
Halfedge_handle new_he = Base::insert_in_face_interior(cv, sc);
|
||||||
_map_halfedge_and_twin(new_he,
|
_map_halfedge_and_twin(new_he,
|
||||||
|
|
@ -615,8 +594,7 @@ typename Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::Halfedge_handle
|
||||||
Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::
|
Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::
|
||||||
insert_from_left_vertex(const X_monotone_curve_2& cv,
|
insert_from_left_vertex(const X_monotone_curve_2& cv,
|
||||||
Halfedge_handle prev,
|
Halfedge_handle prev,
|
||||||
Subcurve* sc)
|
Subcurve* sc) {
|
||||||
{
|
|
||||||
_map_boundary_vertices(this->last_event_on_subcurve(sc), prev->target(),
|
_map_boundary_vertices(this->last_event_on_subcurve(sc), prev->target(),
|
||||||
Has_identified_sides_category());
|
Has_identified_sides_category());
|
||||||
|
|
||||||
|
|
@ -647,8 +625,7 @@ typename Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::Halfedge_handle
|
||||||
Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::
|
Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::
|
||||||
insert_from_right_vertex(const X_monotone_curve_2& cv,
|
insert_from_right_vertex(const X_monotone_curve_2& cv,
|
||||||
Halfedge_handle prev,
|
Halfedge_handle prev,
|
||||||
Subcurve* sc)
|
Subcurve* sc) {
|
||||||
{
|
|
||||||
_map_boundary_vertices(this->current_event(), prev->target(),
|
_map_boundary_vertices(this->current_event(), prev->target(),
|
||||||
Has_identified_sides_category());
|
Has_identified_sides_category());
|
||||||
|
|
||||||
|
|
@ -680,8 +657,7 @@ insert_at_vertices(const X_monotone_curve_2& cv,
|
||||||
Halfedge_handle prev1,
|
Halfedge_handle prev1,
|
||||||
Halfedge_handle prev2,
|
Halfedge_handle prev2,
|
||||||
Subcurve* sc,
|
Subcurve* sc,
|
||||||
bool& new_face_created)
|
bool& new_face_created) {
|
||||||
{
|
|
||||||
// Insert the halfedge using the base construction visitor. Note that the
|
// Insert the halfedge using the base construction visitor. Note that the
|
||||||
// resulting halfedge is always incident to the new face (if one created).
|
// resulting halfedge is always incident to the new face (if one created).
|
||||||
Halfedge_handle new_he =
|
Halfedge_handle new_he =
|
||||||
|
|
@ -795,8 +771,7 @@ template <typename OvlHlpr, typename OvlTr, typename Vis>
|
||||||
typename Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::Vertex_handle
|
typename Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::Vertex_handle
|
||||||
Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::
|
Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::
|
||||||
insert_isolated_vertex(const Point_2& pt,
|
insert_isolated_vertex(const Point_2& pt,
|
||||||
Status_line_iterator iter)
|
Status_line_iterator iter) {
|
||||||
{
|
|
||||||
// Insert the isolated vertex using the base construction visitor.
|
// Insert the isolated vertex using the base construction visitor.
|
||||||
Vertex_handle new_v = Base::insert_isolated_vertex(pt, iter);
|
Vertex_handle new_v = Base::insert_isolated_vertex(pt, iter);
|
||||||
|
|
||||||
|
|
@ -897,8 +872,7 @@ template <typename OvlHlpr, typename OvlTr, typename Vis>
|
||||||
void Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::
|
void Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::
|
||||||
_map_halfedge_and_twin(Halfedge_handle he,
|
_map_halfedge_and_twin(Halfedge_handle he,
|
||||||
Halfedge_handle_red red_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();
|
if (he->direction() == ARR_LEFT_TO_RIGHT) he = he->twin();
|
||||||
|
|
||||||
// Obtain the twin red and blue halfedges (if they are valid). Note that
|
// Obtain the twin red and blue halfedges (if they are valid). Note that
|
||||||
|
|
@ -922,8 +896,7 @@ _map_halfedge_and_twin(Halfedge_handle he,
|
||||||
//
|
//
|
||||||
template <typename OvlHlpr, typename OvlTr, typename Vis>
|
template <typename OvlHlpr, typename OvlTr, typename Vis>
|
||||||
void Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::
|
void Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::
|
||||||
_map_boundary_vertices(Event* event, Vertex_handle v, std::bool_constant<true>)
|
_map_boundary_vertices(Event* event, Vertex_handle v, std::bool_constant<true>) {
|
||||||
{
|
|
||||||
// Update the red and blue object if the last event on sc is on the boundary.
|
// Update the red and blue object if the last event on sc is on the boundary.
|
||||||
if ((event->parameter_space_in_x() != ARR_INTERIOR) ||
|
if ((event->parameter_space_in_x() != ARR_INTERIOR) ||
|
||||||
(event->parameter_space_in_y() != ARR_INTERIOR))
|
(event->parameter_space_in_y() != ARR_INTERIOR))
|
||||||
|
|
@ -938,8 +911,7 @@ _map_boundary_vertices(Event* event, Vertex_handle v, std::bool_constant<true>)
|
||||||
if (red_handle_p) info.first = *red_handle_p;
|
if (red_handle_p) info.first = *red_handle_p;
|
||||||
|
|
||||||
if (!std::get_if<Face_handle_red>(&(info.first)) &&
|
if (!std::get_if<Face_handle_red>(&(info.first)) &&
|
||||||
!std::get_if<Face_handle_blue>(&(info.second)))
|
!std::get_if<Face_handle_blue>(&(info.second))) {
|
||||||
{
|
|
||||||
// If both, the red and blue, variants do not represent face handles,
|
// 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
|
// 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,
|
// safe to apply the call to the overlay traits and erase the record,
|
||||||
|
|
@ -974,8 +946,7 @@ void Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::
|
||||||
_create_vertex(Event* event,
|
_create_vertex(Event* event,
|
||||||
Vertex_handle new_v,
|
Vertex_handle new_v,
|
||||||
Subcurve* sc,
|
Subcurve* sc,
|
||||||
std::bool_constant<true>)
|
std::bool_constant<true>) {
|
||||||
{
|
|
||||||
const Point_2& pt = event->point();
|
const Point_2& pt = event->point();
|
||||||
const Cell_handle_red* red_handle = pt.red_cell_handle();
|
const Cell_handle_red* red_handle = pt.red_cell_handle();
|
||||||
const Cell_handle_blue* blue_handle = pt.blue_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
|
// If the vertex is on the boundary, postpone the notification, but
|
||||||
// update the red and objects in case they are empty.
|
// update the red and objects in case they are empty.
|
||||||
if ((event->parameter_space_in_x() != ARR_INTERIOR) ||
|
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) {
|
if (!red_handle) {
|
||||||
CGAL_assertion(blue_handle != nullptr);
|
CGAL_assertion(blue_handle != nullptr);
|
||||||
// Obtain the red face by looking for a subcurve above.
|
// Obtain the red face by looking for a subcurve above.
|
||||||
|
|
@ -1020,8 +990,7 @@ void Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::
|
||||||
_create_vertex(Event* event,
|
_create_vertex(Event* event,
|
||||||
Vertex_handle new_v,
|
Vertex_handle new_v,
|
||||||
Subcurve* sc,
|
Subcurve* sc,
|
||||||
std::bool_constant<false>)
|
std::bool_constant<false>) {
|
||||||
{
|
|
||||||
const Point_2& pt = event->point();
|
const Point_2& pt = event->point();
|
||||||
const Cell_handle_red* red_handle = pt.red_cell_handle();
|
const Cell_handle_red* red_handle = pt.red_cell_handle();
|
||||||
const Cell_handle_blue* blue_handle = pt.blue_cell_handle();
|
const Cell_handle_blue* blue_handle = pt.blue_cell_handle();
|
||||||
|
|
@ -1063,8 +1032,7 @@ _create_vertex(Event* event,
|
||||||
template <typename OvlHlpr, typename OvlTr, typename Vis>
|
template <typename OvlHlpr, typename OvlTr, typename Vis>
|
||||||
void Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::
|
void Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::
|
||||||
_create_edge(Subcurve* sc,
|
_create_edge(Subcurve* sc,
|
||||||
Halfedge_handle new_he)
|
Halfedge_handle new_he) {
|
||||||
{
|
|
||||||
// Note that the "red" and "blue" halfedges are always directed from right
|
// 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
|
// to left, so we make sure the overlaid halfedge is also directed from
|
||||||
// right to left.
|
// right to left.
|
||||||
|
|
|
||||||
|
|
@ -700,15 +700,29 @@ swap its source and target points).
|
||||||
The traits classes `Arr_segment_traits_2`,
|
The traits classes `Arr_segment_traits_2`,
|
||||||
`Arr_non_caching_segment_traits_2`, `Arr_circle_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
|
`Arr_conic_traits_2` and `Arr_rational_function_traits_2`, which are
|
||||||
bundled in the `Arrangement_2` package and distributed with \cgal,
|
bundled in the `Arrangement_2` package and distributed with \cgal, are
|
||||||
are all models of the refined concept
|
all models of the refined concept
|
||||||
`AosDirectionalXMonotoneTraits_2`.\cgalFootnote{The \cgalFootnoteCode{Arr_polyline_traits_2} class is <I>not</I> 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.}
|
`AosDirectionalXMonotoneTraits_2`.\cgalFootnote{The
|
||||||
|
\cgalFootnoteCode{Arr_polyline_traits_2} class is <I>not</I> 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
|
Operations on polygons (or general polygons) are guaranteed to be
|
||||||
`AosXMonotoneTraits_2` concept, operations are robust only
|
robust only if the operations of the geometry traits used to carry out
|
||||||
when exact arithmetic is used. When inexact arithmetic is used,
|
the high-level operations are robust. Most operations on polygons use
|
||||||
(nearly) degenerate configurations may result in abnormal termination
|
geometry traits constructors, as they generate new polygons; such
|
||||||
of the program or even incorrect results.
|
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
|
\subsection bso_sseccirc_seg Operating on Polygons with Circular Arcs
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,10 @@ namespace CGAL {
|
||||||
* <tr><td align="right"><b>2.</b></td><td>`void complement(const Type1& pgn, Type2& res, const GpsTraits& traits);`</td></tr>
|
* <tr><td align="right"><b>2.</b></td><td>`void complement(const Type1& pgn, Type2& res, const GpsTraits& traits);`</td></tr>
|
||||||
* </table>
|
* </table>
|
||||||
*
|
*
|
||||||
|
* \tparam Kernel a model of the concept `PolygonTraits_2`.
|
||||||
|
* \tparam Container a model of the concept `Container`; defaults to `std::vector<Kernel::Point_2`>.
|
||||||
|
* \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
|
* \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
|
* 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
|
* 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
|
* 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.
|
* 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.
|
* types specified in a row in the table below, respectively.
|
||||||
* - The types that apply to signature (<b>1.1.</b>) above are restricted to those
|
* - The types that apply to signature (<b>1.1.</b>) above are restricted to those
|
||||||
* listed in rows <b>1</b> and <b>2</b> in the table below.
|
* listed in rows <b>1</b> and <b>2</b> in the table below.
|
||||||
|
|
@ -54,6 +58,8 @@ namespace CGAL {
|
||||||
* \sa \link boolean_join `CGAL::join()` \endlink
|
* \sa \link boolean_join `CGAL::join()` \endlink
|
||||||
* \sa \link boolean_difference `CGAL::difference()` \endlink
|
* \sa \link boolean_difference `CGAL::difference()` \endlink
|
||||||
* \sa \link boolean_symmetric_difference `CGAL::symmetric_difference()` \endlink
|
* \sa \link boolean_symmetric_difference `CGAL::symmetric_difference()` \endlink
|
||||||
|
* \sa Polygon_2<Kernel, Container>
|
||||||
|
* \sa Polygon_with_holes_2<Kernel, Container>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/// @{
|
/// @{
|
||||||
|
|
@ -224,6 +230,10 @@ namespace CGAL {
|
||||||
* <tr><td align="right"><b>2.</b></td><td>`OutputIterator difference(const Type1& pgn1, const Type2& pgn2, OutputIterator oi, const GpsTraits& traits);`</td></tr>
|
* <tr><td align="right"><b>2.</b></td><td>`OutputIterator difference(const Type1& pgn1, const Type2& pgn2, OutputIterator oi, const GpsTraits& traits);`</td></tr>
|
||||||
* </table>
|
* </table>
|
||||||
*
|
*
|
||||||
|
* \tparam Kernel a model of the concept `PolygonTraits_2`
|
||||||
|
* \tparam Container a model of the concept `Container`; defaults to `std::vector<Kernel::Point_2`>.
|
||||||
|
* \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
|
* \tparam UsePolylines determines whether the boundaries of the input polygons
|
||||||
* are treated as cyclic sequences of single (\f$x\f$-monotone) segments or as
|
* 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
|
* 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_intersection `CGAL::intersection()` \endlink
|
||||||
* \sa \link boolean_join `CGAL::join()` \endlink
|
* \sa \link boolean_join `CGAL::join()` \endlink
|
||||||
* \sa \link boolean_symmetric_difference `CGAL::symmetric_difference()` \endlink
|
* \sa \link boolean_symmetric_difference `CGAL::symmetric_difference()` \endlink
|
||||||
|
* \sa Polygon_2<Kernel, Container>
|
||||||
|
* \sa Polygon_with_holes_2<Kernel, Container>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/// @{
|
/// @{
|
||||||
|
|
@ -660,48 +672,22 @@ namespace CGAL {
|
||||||
* A function template in this group that accepts two input polygons has one of
|
* A function template in this group that accepts two input polygons has one of
|
||||||
* the following signatures:
|
* the following signatures:
|
||||||
* <table cellpadding=3 border="0">
|
* <table cellpadding=3 border="0">
|
||||||
* <tr><td align="right"><b>1.1.</b></td><td>`bool do_intersect(const Type1& pgn1, const Type2& pgn2, UsePolylines = Tag_true());`</td></tr>
|
* <tr><td align="right"><b>1.</b></td><td>`bool do_intersect(const Type1& pgn1, const Type2& pgn2);`</td></tr>
|
||||||
* <tr><td align="right"><b>1.2.</b></td><td>`bool do_intersect(const Type1& pgn1, const Type2& pgn2);`</td></tr>
|
|
||||||
* <tr><td align="right"><b>2.</b></td><td>`bool do_intersect(const Type1& pgn1, const Type2& pgn2, const GpsTraits& traits);`</td></tr>
|
* <tr><td align="right"><b>2.</b></td><td>`bool do_intersect(const Type1& pgn1, const Type2& pgn2, const GpsTraits& traits);`</td></tr>
|
||||||
* </table>
|
* </table>
|
||||||
*
|
*
|
||||||
* There are also function templates that accept one or two ranges of input polygons:
|
* There are also function templates that accept one or two ranges of input polygons:
|
||||||
* <table cellpadding=3 border="0">
|
* <table cellpadding=3 border="0">
|
||||||
* <tr><td align="right"><b>3.1.</b></td><td>`bool do_intersect(InputIterator begin, InputIterator end, UsePolylines = Tag_true());`</td></tr>
|
* <tr><td align="right"><b>3.</b></td><td>`bool do_intersect(InputIterator begin, InputIterator end);`</td></tr>
|
||||||
* <tr><td align="right"><b>3.2.</b></td><td>`bool do_intersect(InputIterator begin, InputIterator end);`</td></tr>
|
|
||||||
* <tr><td align="right"><b>4.</b></td><td>`bool do_intersect(InputIterator begin, InputIterator end, const GpsTraits& traits);`</td></tr>
|
* <tr><td align="right"><b>4.</b></td><td>`bool do_intersect(InputIterator begin, InputIterator end, const GpsTraits& traits);`</td></tr>
|
||||||
* <tr><td align="right"><b>5.1.</b></td><td>`bool do_intersect(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, InputIterator2 end2, UsePolylines = Tag_true());`</td></tr>
|
* <tr><td align="right"><b>5.</b></td><td>`bool do_intersect(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, InputIterator2 end2);`</td></tr>
|
||||||
* <tr><td align="right"><b>5.2.</b></td><td>`bool do_intersect(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, InputIterator2 end2);`</td></tr>
|
|
||||||
* <tr><td align="right"><b>6.</b></td><td>`bool do_intersect(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, InputIterator2 end2, const GpsTraits& traits);`</td></tr>
|
* <tr><td align="right"><b>6.</b></td><td>`bool do_intersect(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, InputIterator2 end2, const GpsTraits& traits);`</td></tr>
|
||||||
* </table>
|
* </table>
|
||||||
*
|
*
|
||||||
* \tparam UsePolylines determines whether the boundary of the input polygons
|
* \tparam Kernel a model of the concept `PolygonTraits_2`.
|
||||||
* are treated as a cyclic sequence of single (\f$x\f$-monotone) segments or as
|
* \tparam Container a model of the concept `Container`; defaults to `std::vector<Kernel::Point_2`>.
|
||||||
* a cyclic sequence of (\f$x\f$-monotone) polylines. If substituted with
|
* \tparam ArrTraits a model of the concept `AosDirectionalXMonotoneTraits_2`.
|
||||||
* `CGAL::Tag_true`, which is the default, the input polygons are converted to
|
* \tparam GpsTraits a model of the concept `GeneralPolygonSetTraits_2`, which must be convertible to `ArrTraits`.
|
||||||
* 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 (<b>1.1.</b>) and (<b>5.1.</b>) above
|
|
||||||
* are restricted to those listed in rows <b>1–4</b> in the table
|
|
||||||
* below.
|
|
||||||
*
|
|
||||||
* - The types that apply to signatures (<b>1.2.</b>) and (<b>5.2.</b>) above
|
|
||||||
* are restricted to those listed in rows <b>5–8</b> in the table
|
|
||||||
* below.
|
|
||||||
*
|
|
||||||
* - The type of `InputIterator::value_type` in (<b>3.1.</b>) above
|
|
||||||
* must be convertible to either `Polygon_2` or `Polygon_with_holes_2`.
|
|
||||||
*
|
|
||||||
* - The type of `InputIterator::value_type` in (<b>3.2.</b>) above must be
|
|
||||||
* convertible to either `General_polygon_2` or
|
|
||||||
* `General_polygon_with_holes_2`.
|
|
||||||
*
|
*
|
||||||
* <div align="left">
|
* <div align="left">
|
||||||
* <table cellpadding=3 border="1">
|
* <table cellpadding=3 border="1">
|
||||||
|
|
@ -728,6 +714,8 @@ namespace CGAL {
|
||||||
* \sa \link boolean_join `CGAL::join()` \endlink
|
* \sa \link boolean_join `CGAL::join()` \endlink
|
||||||
* \sa \link boolean_difference `CGAL::difference()` \endlink
|
* \sa \link boolean_difference `CGAL::difference()` \endlink
|
||||||
* \sa \link boolean_symmetric_difference `CGAL::symmetric_difference()` \endlink
|
* \sa \link boolean_symmetric_difference `CGAL::symmetric_difference()` \endlink
|
||||||
|
* \sa Polygon_2<Kernel, Container>
|
||||||
|
* \sa Polygon_with_holes_2<Kernel, Container>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/// @{
|
/// @{
|
||||||
|
|
@ -735,6 +723,11 @@ namespace CGAL {
|
||||||
//////// Traits-less
|
//////// Traits-less
|
||||||
|
|
||||||
/*! determines whether two polygons intersect in their interior.
|
/*! 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 pgn1 the 1st input polygon.
|
||||||
* \param pgn2 the 2nd input polygon.
|
* \param pgn2 the 2nd input polygon.
|
||||||
* \return `true` if `pgn1` and `pgn2` intersect in their interior and `false`
|
* \return `true` if `pgn1` and `pgn2` intersect in their interior and `false`
|
||||||
|
|
@ -745,25 +738,11 @@ bool do_intersect(const Polygon_2<Kernel, Container>& pgn1,
|
||||||
const Polygon_2<Kernel, Container>& pgn2);
|
const Polygon_2<Kernel, Container>& pgn2);
|
||||||
|
|
||||||
/*! determines whether two polygons intersect in their interior.
|
/*! 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
|
* The kernel used to instantiate the type of the input polygons must support
|
||||||
* or as a cyclic sequences of (\f$x\f$-monotone) polylines. If
|
* exact predicates to guarantee correct results; however, inexact constructions
|
||||||
* substituted with `CGAL::Tag_true`, which is the default, `pgn1` and
|
* are tolerated.
|
||||||
* `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 <typename Kernel, typename Container, typename UsePolylines>
|
|
||||||
bool do_intersect(const Polygon_2<Kernel, Container>& pgn1,
|
|
||||||
const Polygon_2<Kernel, Container>& pgn2,
|
|
||||||
UsePolylines = Tag_true());
|
|
||||||
|
|
||||||
/*! determines whether two polygons intersect in their interior.
|
|
||||||
* \param pgn1 the 1st input polygon.
|
* \param pgn1 the 1st input polygon.
|
||||||
* \param pgn2 the 2nd input polygon.
|
* \param pgn2 the 2nd input polygon.
|
||||||
* \return `true` if `pgn1` and `pgn2` intersect in their interior and `false`
|
* \return `true` if `pgn1` and `pgn2` intersect in their interior and `false`
|
||||||
|
|
@ -774,26 +753,11 @@ bool do_intersect(const Polygon_2<Kernel, Container>& pgn1,
|
||||||
const Polygon_with_holes_2<Kernel, Container>& pgn2);
|
const Polygon_with_holes_2<Kernel, Container>& pgn2);
|
||||||
|
|
||||||
/*! determines whether two polygons intersect in their interior.
|
/*! 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
|
* The kernel used to instantiate the type of the input polygons must support
|
||||||
* or as a cyclic sequences of (\f$x\f$-monotone) polylines. If
|
* exact predicates to guarantee correct results; however, inexact constructions
|
||||||
* substituted with `CGAL::Tag_true`, which is the default, `pgn1` and
|
* are tolerated.
|
||||||
* `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 <typename Kernel, typename Container, typename UsePolylines>
|
|
||||||
bool do_intersect(const Polygon_2<Kernel, Container>& pgn1,
|
|
||||||
const Polygon_with_holes_2<Kernel, Container>& pgn2,
|
|
||||||
UsePolylines = Tag_true());
|
|
||||||
|
|
||||||
/*! determines whether two polygons intersect in their interior.
|
|
||||||
* \param pgn1 the 1st input polygon.
|
* \param pgn1 the 1st input polygon.
|
||||||
* \param pgn2 the 2nd input polygon.
|
* \param pgn2 the 2nd input polygon.
|
||||||
* \return `true` if `pgn1` and `pgn2` intersect in their interior and `false`
|
* \return `true` if `pgn1` and `pgn2` intersect in their interior and `false`
|
||||||
|
|
@ -803,27 +767,12 @@ template <typename Kernel, typename Container>
|
||||||
bool do_intersect(const Polygon_with_holes_2<Kernel, Container>& pgn1,
|
bool do_intersect(const Polygon_with_holes_2<Kernel, Container>& pgn1,
|
||||||
const Polygon_2<Kernel, Container>& pgn2);
|
const Polygon_2<Kernel, Container>& 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 <typename Kernel, typename Container, typename UsePolylines>
|
|
||||||
bool do_intersect(const Polygon_with_holes_2<Kernel, Container>& pgn1,
|
|
||||||
const Polygon_2<Kernel, Container>& pgn2,
|
|
||||||
UsePolylines = Tag_true());
|
|
||||||
|
|
||||||
/*! determines whether two polygons with holes intersect in their interior.
|
/*! 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 pgn1 the 1st input polygon.
|
||||||
* \param pgn2 the 2nd input polygon.
|
* \param pgn2 the 2nd input polygon.
|
||||||
* \return `true` if `pgn1` and `pgn2` intersect in their interior and `false`
|
* \return `true` if `pgn1` and `pgn2` intersect in their interior and `false`
|
||||||
|
|
@ -833,25 +782,6 @@ template <typename Kernel, typename Container>
|
||||||
bool do_intersect(const Polygon_with_holes_2<Kernel, Container>& pgn1,
|
bool do_intersect(const Polygon_with_holes_2<Kernel, Container>& pgn1,
|
||||||
const Polygon_with_holes_2<Kernel, Container>& pgn2);
|
const Polygon_with_holes_2<Kernel, Container>& 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 <typename Kernel, typename Container, typename UsePolylines>
|
|
||||||
bool do_intersect(const Polygon_with_holes_2<Kernel, Container>& pgn1,
|
|
||||||
const Polygon_with_holes_2<Kernel, Container>& pgn2,
|
|
||||||
UsePolylines = Tag_true());
|
|
||||||
|
|
||||||
/*! determines whether two general polygons intersect in their interior.
|
/*! determines whether two general polygons intersect in their interior.
|
||||||
* \param pgn1 the 1st input polygon.
|
* \param pgn1 the 1st input polygon.
|
||||||
* \param pgn2 the 2nd input polygon.
|
* \param pgn2 the 2nd input polygon.
|
||||||
|
|
@ -904,6 +834,13 @@ bool do_intersect(const General_polygon_with_holes_2<Polygon>& pgn1,
|
||||||
* of general polygons or a range of general polygons with holes) determines
|
* 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
|
* whether the open polygons (respectively general polygons) in the range have a common
|
||||||
* point.
|
* 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
|
* \param begin the first iterator of the input range. Its value type is
|
||||||
* either `Polygon_2` (respectively `General_polygon_2`) or
|
* either `Polygon_2` (respectively `General_polygon_2`) or
|
||||||
* `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
* `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||||
|
|
@ -917,36 +854,16 @@ bool do_intersect(const General_polygon_with_holes_2<Polygon>& pgn1,
|
||||||
template <typename InputIterator>
|
template <typename InputIterator>
|
||||||
bool do_intersect(InputIterator begin, InputIterator end);
|
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 <typename InputIterator, typename UsePolylines>
|
|
||||||
bool do_intersect(InputIterator begin, InputIterator end,
|
|
||||||
UsePolylines = Tag_true());
|
|
||||||
|
|
||||||
/*! Given a range of polygons (respectively general polygons) and a range of polygons
|
/*! Given a range of polygons (respectively general polygons) and a range of polygons
|
||||||
* with holes (respectively general polygons with holes) determines whether the open
|
* with holes (respectively general polygons with holes) determines whether the open
|
||||||
* polygons (respectively general polygons) in the two ranges have a common point.
|
* 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
|
* \param begin1 the first iterator of the 1st input range. Its value type is
|
||||||
* `Polygon_2` (respectively `General_polygon_2`).
|
* `Polygon_2` (respectively `General_polygon_2`).
|
||||||
* \param end1 the past-the-end iterator of the 1st input range. Its value
|
* \param end1 the past-the-end iterator of the 1st input range. Its value
|
||||||
|
|
@ -964,40 +881,14 @@ template <typename InputIterator1, typename InputIterator2>
|
||||||
bool do_intersect(InputIterator1 begin1, InputIterator1 end1,
|
bool do_intersect(InputIterator1 begin1, InputIterator1 end1,
|
||||||
InputIterator2 begin2, InputIterator2 end2);
|
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 <typename InputIterator1, typename InputIterator2,
|
|
||||||
typename UsePolylines>
|
|
||||||
bool do_intersect(InputIterator1 begin1, InputIterator1 end1,
|
|
||||||
InputIterator2 begin2, InputIterator2 end2,
|
|
||||||
UsePolylines = Tag_true());
|
|
||||||
|
|
||||||
//////// With Traits
|
//////// With Traits
|
||||||
|
|
||||||
/*! determines whether two polygons intersect in their interior.
|
/*! 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 pgn1 the 1st input polygon.
|
||||||
* \param pgn2 the 2nd input polygon.
|
* \param pgn2 the 2nd input polygon.
|
||||||
* \param traits a traits object.
|
* \param traits a traits object.
|
||||||
|
|
@ -1011,6 +902,11 @@ bool do_intersect(const Polygon_2<Kernel, Container>& pgn1,
|
||||||
const GpsTraits& traits);
|
const GpsTraits& traits);
|
||||||
|
|
||||||
/*! determines whether two polygons intersect in their interior.
|
/*! 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 pgn1 the 1st input polygon.
|
||||||
* \param pgn2 the 2nd input polygon.
|
* \param pgn2 the 2nd input polygon.
|
||||||
* \param traits a traits object.
|
* \param traits a traits object.
|
||||||
|
|
@ -1021,10 +917,14 @@ bool do_intersect(const Polygon_2<Kernel, Container>& pgn1,
|
||||||
template <typename Kernel, typename Container, typename GpsTraits>
|
template <typename Kernel, typename Container, typename GpsTraits>
|
||||||
bool do_intersect(const Polygon_2<Kernel, Container>& pgn1,
|
bool do_intersect(const Polygon_2<Kernel, Container>& pgn1,
|
||||||
const Polygon_with_holes_2<Kernel, Container>& pgn2,
|
const Polygon_with_holes_2<Kernel, Container>& pgn2,
|
||||||
const GpsTraits& traits,
|
|
||||||
const GpsTraits& traits);
|
const GpsTraits& traits);
|
||||||
|
|
||||||
/*! determines whether two polygons intersect in their interior.
|
/*! 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 pgn1 the 1st input polygon.
|
||||||
* \param pgn2 the 2nd input polygon.
|
* \param pgn2 the 2nd input polygon.
|
||||||
* \param traits a traits object.
|
* \param traits a traits object.
|
||||||
|
|
@ -1038,6 +938,11 @@ bool do_intersect(const Polygon_with_holes_2<Kernel, Container>& pgn1,
|
||||||
const GpsTraits& traits);
|
const GpsTraits& traits);
|
||||||
|
|
||||||
/*! determines whether two polygons with holes intersect in their interior.
|
/*! 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 pgn1 the 1st input polygon.
|
||||||
* \param pgn2 the 2nd input polygon.
|
* \param pgn2 the 2nd input polygon.
|
||||||
* \param traits a traits object.
|
* \param traits a traits object.
|
||||||
|
|
@ -1116,6 +1021,12 @@ bool do_intersect(const General_polygon_with_holes_2<Polygon>& pgn1,
|
||||||
* of general polygons or a range of general polygons with holes) determines
|
* 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
|
* whether the open polygons (respectively general polygons) in the range have a common
|
||||||
* point.
|
* 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
|
* \param begin the first iterator of the input range. Its value type is
|
||||||
* either `Polygon_2` (respectively `General_polygon_2`) or
|
* either `Polygon_2` (respectively `General_polygon_2`) or
|
||||||
* `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
* `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
|
/*! Given a range of polygons (respectively general polygons) and a range of polygons
|
||||||
* with holes (respectively general polygons with holes) determines whether the open
|
* with holes (respectively general polygons with holes) determines whether the open
|
||||||
* polygons (respectively general polygons) in the two ranges have a common point.
|
* 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
|
* \param begin1 the first iterator of the 1st input range. Its value type is
|
||||||
* `Polygon_2` (respectively `General_polygon_2`).
|
* `Polygon_2` (respectively `General_polygon_2`).
|
||||||
* \param end1 the past-the-end iterator of the 1st input range. Its value
|
* \param end1 the past-the-end iterator of the 1st input range. Its value
|
||||||
|
|
@ -1186,6 +1103,10 @@ namespace CGAL {
|
||||||
* <tr><td align="right"><b>6.</b></td><td>`OutputIterator intersection(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, InputIterator2 end2, OutputIterator oi, const GpsTraits& traits);`</td></tr>
|
* <tr><td align="right"><b>6.</b></td><td>`OutputIterator intersection(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, InputIterator2 end2, OutputIterator oi, const GpsTraits& traits);`</td></tr>
|
||||||
* </table>
|
* </table>
|
||||||
*
|
*
|
||||||
|
* \tparam Kernel a model of the concept `PolygonTraits_2`.
|
||||||
|
* \tparam Container a model of the concept `Container`; defaults to `std::vector<Kernel::Point_2`>.
|
||||||
|
* \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
|
* \tparam UsePolylines determines whether the boundaries of the input polygons
|
||||||
* are treated as cyclic sequences of single (\f$x\f$-monotone) segments or as
|
* 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
|
* 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_join `CGAL::join()` \endlink
|
||||||
* \sa \link boolean_difference `CGAL::difference()` \endlink
|
* \sa \link boolean_difference `CGAL::difference()` \endlink
|
||||||
* \sa \link boolean_symmetric_difference `CGAL::symmetric_difference()` \endlink
|
* \sa \link boolean_symmetric_difference `CGAL::symmetric_difference()` \endlink
|
||||||
|
* \sa Polygon_2<Kernel, Container>
|
||||||
|
* \sa Polygon_with_holes_2<Kernel, Container>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/// @{
|
/// @{
|
||||||
|
|
@ -1825,6 +1748,10 @@ namespace CGAL {
|
||||||
* <tr><td align="right"><b>6.</b></td><td>`OutputIterator join(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, InputIterator2 end2, OutputIterator oi, const GpsTraits& traits);`</td></tr>
|
* <tr><td align="right"><b>6.</b></td><td>`OutputIterator join(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, InputIterator2 end2, OutputIterator oi, const GpsTraits& traits);`</td></tr>
|
||||||
* </table>
|
* </table>
|
||||||
*
|
*
|
||||||
|
* \tparam Kernel a model of the concept `PolygonTraits_2`.
|
||||||
|
* \tparam Container a model of the concept `Container`; defaults to `std::vector<Kernel::Point_2`>.
|
||||||
|
* \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
|
* \tparam UsePolylines determines whether the boundaries of the input polygons
|
||||||
* are treated as cyclic sequences of single (\f$x\f$-monotone) segments or as
|
* 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
|
* 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_intersection `CGAL::intersection()` \endlink
|
||||||
* \sa \link boolean_difference `CGAL::difference()` \endlink
|
* \sa \link boolean_difference `CGAL::difference()` \endlink
|
||||||
* \sa \link boolean_symmetric_difference `CGAL::symmetric_difference()` \endlink
|
* \sa \link boolean_symmetric_difference `CGAL::symmetric_difference()` \endlink
|
||||||
|
* \sa Polygon_2<Kernel, Container>
|
||||||
|
* \sa Polygon_with_holes_2<Kernel, Container>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/// @{
|
/// @{
|
||||||
|
|
@ -2407,6 +2336,10 @@ namespace CGAL {
|
||||||
* <tr><td align="right"><b> 4.</b></td><td>`Oriented_side oriented_side(const Point_2& p, const Type& pgn, const GpsTraits& traits);`</td></tr>
|
* <tr><td align="right"><b> 4.</b></td><td>`Oriented_side oriented_side(const Point_2& p, const Type& pgn, const GpsTraits& traits);`</td></tr>
|
||||||
* </table>
|
* </table>
|
||||||
*
|
*
|
||||||
|
* \tparam Kernel a model of the concept `PolygonTraits_2`.
|
||||||
|
* \tparam Container a model of the concept `Container`; defaults to `std::vector<Kernel::Point_2`>.
|
||||||
|
* \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
|
* \tparam UsePolylines determines whether the boundaries of the input polygons
|
||||||
* are treated as cyclic sequences of single (\f$x\f$-monotone) segments or as
|
* 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
|
* cyclic sequences of (\f$x\f$-monotone) polylines. If substituted with
|
||||||
|
|
@ -2446,6 +2379,8 @@ namespace CGAL {
|
||||||
* \param traits an optional traits object.
|
* \param traits an optional traits object.
|
||||||
*
|
*
|
||||||
* \sa \link boolean_do_intersect `CGAL::do_intersect()` \endlink
|
* \sa \link boolean_do_intersect `CGAL::do_intersect()` \endlink
|
||||||
|
* \sa Polygon_2<Kernel, Container>
|
||||||
|
* \sa Polygon_with_holes_2<Kernel, Container>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/// @{
|
/// @{
|
||||||
|
|
@ -2823,6 +2758,10 @@ namespace CGAL {
|
||||||
* <tr><td align="right"><b>6.</b></td><td>`OutputIterator symmetric_difference(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, InputIterator2 end2, OutputIterator oi, const GpsTraits& traits);`</td></tr>
|
* <tr><td align="right"><b>6.</b></td><td>`OutputIterator symmetric_difference(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, InputIterator2 end2, OutputIterator oi, const GpsTraits& traits);`</td></tr>
|
||||||
* </table>
|
* </table>
|
||||||
*
|
*
|
||||||
|
* \tparam Kernel a model of the concept `PolygonTraits_2`.
|
||||||
|
* \tparam Container a model of the concept `Container`; defaults to `std::vector<Kernel::Point_2`>.
|
||||||
|
* \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
|
* \tparam UsePolylines determines whether the boundaries of the input polygons
|
||||||
* are treated as cyclic sequences of single (\f$x\f$-monotone) segments or as
|
* 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
|
* 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_intersection `CGAL::intersection()` \endlink
|
||||||
* \sa \link boolean_join `CGAL::join()` \endlink
|
* \sa \link boolean_join `CGAL::join()` \endlink
|
||||||
* \sa \link boolean_difference `CGAL::difference()` \endlink
|
* \sa \link boolean_difference `CGAL::difference()` \endlink
|
||||||
|
* \sa Polygon_2<Kernel, Container>
|
||||||
|
* \sa Polygon_with_holes_2<Kernel, Container>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/// @{
|
/// @{
|
||||||
|
|
|
||||||
|
|
@ -5,14 +5,13 @@
|
||||||
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
||||||
#include <CGAL/Boolean_set_operations_2.h>
|
#include <CGAL/Boolean_set_operations_2.h>
|
||||||
|
|
||||||
typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel;
|
using Kernel = CGAL::Exact_predicates_exact_constructions_kernel;
|
||||||
typedef Kernel::Point_2 Point_2;
|
using Point_2 = Kernel::Point_2;
|
||||||
typedef CGAL::Polygon_2<Kernel> Polygon_2;
|
using Polygon_2 = CGAL::Polygon_2<Kernel>;
|
||||||
|
|
||||||
#include "print_utils.h"
|
#include "print_utils.h"
|
||||||
|
|
||||||
int main ()
|
int main() {
|
||||||
{
|
|
||||||
Polygon_2 P;
|
Polygon_2 P;
|
||||||
P.push_back(Point_2(-1, 1));
|
P.push_back(Point_2(-1, 1));
|
||||||
P.push_back(Point_2(0, -1));
|
P.push_back(Point_2(0, -1));
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ namespace CGAL {
|
||||||
|
|
||||||
// Single
|
// Single
|
||||||
// With Traits
|
// With Traits
|
||||||
template <typename Pgn1, class Pgn2, typename Traits>
|
template <typename Pgn1, typename Pgn2, typename Traits>
|
||||||
inline bool s_do_intersect(const Pgn1& pgn1, const Pgn2& pgn2, Traits& traits) {
|
inline bool s_do_intersect(const Pgn1& pgn1, const Pgn2& pgn2, Traits& traits) {
|
||||||
General_polygon_set_2<Traits> gps(pgn1, traits);
|
General_polygon_set_2<Traits> gps(pgn1, traits);
|
||||||
return gps.do_intersect(pgn2);
|
return gps.do_intersect(pgn2);
|
||||||
|
|
@ -52,7 +52,7 @@ inline bool s_do_intersect(const Pgn1& pgn1, const Pgn2& pgn2) {
|
||||||
// With Traits
|
// With Traits
|
||||||
template <typename InputIterator, typename Traits>
|
template <typename InputIterator, typename Traits>
|
||||||
inline bool r_do_intersect(InputIterator begin, InputIterator end,
|
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;
|
if (begin == end) return false;
|
||||||
General_polygon_set_2<Traits> gps(*begin, traits);
|
General_polygon_set_2<Traits> gps(*begin, traits);
|
||||||
return gps.do_intersect(std::next(begin), end, k);
|
return gps.do_intersect(std::next(begin), end, k);
|
||||||
|
|
@ -61,8 +61,8 @@ inline bool r_do_intersect(InputIterator begin, InputIterator end,
|
||||||
// Without Traits
|
// Without Traits
|
||||||
template <typename InputIterator>
|
template <typename InputIterator>
|
||||||
inline bool r_do_intersect(InputIterator begin, InputIterator end,
|
inline bool r_do_intersect(InputIterator begin, InputIterator end,
|
||||||
unsigned int k=5) {
|
std::size_t k = 5) {
|
||||||
typedef typename std::iterator_traits<InputIterator>::value_type Pgn;
|
using Pgn = typename std::iterator_traits<InputIterator>::value_type;
|
||||||
typename Gps_polyline_traits<Pgn>::Traits traits;
|
typename Gps_polyline_traits<Pgn>::Traits traits;
|
||||||
const typename Gps_polyline_traits<Pgn>::Polyline_traits& ptraits(traits);
|
const typename Gps_polyline_traits<Pgn>::Polyline_traits& ptraits(traits);
|
||||||
return r_do_intersect(convert_polygon_iterator(begin, ptraits),
|
return r_do_intersect(convert_polygon_iterator(begin, ptraits),
|
||||||
|
|
@ -74,7 +74,7 @@ inline bool r_do_intersect(InputIterator begin, InputIterator end,
|
||||||
template <typename InputIterator1, typename InputIterator2, typename Traits>
|
template <typename InputIterator1, typename InputIterator2, typename Traits>
|
||||||
inline bool r_do_intersect(InputIterator1 begin1, InputIterator1 end1,
|
inline bool r_do_intersect(InputIterator1 begin1, InputIterator1 end1,
|
||||||
InputIterator2 begin2, InputIterator2 end2,
|
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);
|
if (begin1 == end1) return do_intersect(begin2, end2, traits, k);
|
||||||
General_polygon_set_2<Traits> gps(*begin1, traits);
|
General_polygon_set_2<Traits> gps(*begin1, traits);
|
||||||
return gps.do_intersect(std::next(begin1), end1, begin2, end2, k);
|
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 <typename InputIterator1, typename InputIterator2>
|
template <typename InputIterator1, typename InputIterator2>
|
||||||
inline bool r_do_intersect (InputIterator1 begin1, InputIterator1 end1,
|
inline bool r_do_intersect (InputIterator1 begin1, InputIterator1 end1,
|
||||||
InputIterator2 begin2, InputIterator2 end2,
|
InputIterator2 begin2, InputIterator2 end2,
|
||||||
unsigned int k=5) {
|
std::size_t k = 5) {
|
||||||
typedef typename std::iterator_traits<InputIterator1>::value_type Pgn;
|
using Pgn = typename std::iterator_traits<InputIterator1>::value_type;
|
||||||
typename Gps_polyline_traits<Pgn>::Traits traits;
|
typename Gps_polyline_traits<Pgn>::Traits traits;
|
||||||
const typename Gps_polyline_traits<Pgn>::Polyline_traits& ptraits(traits);
|
const typename Gps_polyline_traits<Pgn>::Polyline_traits& ptraits(traits);
|
||||||
return r_do_intersect(convert_polygon_iterator(begin1, ptraits),
|
return r_do_intersect(convert_polygon_iterator(begin1, ptraits),
|
||||||
|
|
@ -119,8 +119,7 @@ inline Oriented_side _oriented_side(const Point_2<Kernel>& point,
|
||||||
|
|
||||||
// Without Traits (polygon, polygon)
|
// Without Traits (polygon, polygon)
|
||||||
template <typename Pgn1, typename Pgn2>
|
template <typename Pgn1, typename Pgn2>
|
||||||
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
|
// Use the first polygon to determine the (default) traits
|
||||||
typename Gps_polyline_traits<Pgn1>::Traits traits;
|
typename Gps_polyline_traits<Pgn1>::Traits traits;
|
||||||
const typename Gps_polyline_traits<Pgn1>::Polyline_traits& ptraits(traits);
|
const typename Gps_polyline_traits<Pgn1>::Polyline_traits& ptraits(traits);
|
||||||
|
|
@ -149,7 +148,7 @@ template <typename Kernel, typename Container,
|
||||||
inline OutputIterator s_intersection(const Pgn1& pgn1, const Pgn2& pgn2,
|
inline OutputIterator s_intersection(const Pgn1& pgn1, const Pgn2& pgn2,
|
||||||
OutputIterator oi) {
|
OutputIterator oi) {
|
||||||
// Use the first polygon to determine the (default) traits
|
// Use the first polygon to determine the (default) traits
|
||||||
typedef typename Gps_polyline_traits<Pgn1>::Polyline_traits Polyline_traits;
|
using Polyline_traits = typename Gps_polyline_traits<Pgn1>::Polyline_traits;
|
||||||
|
|
||||||
typename Gps_polyline_traits<Pgn1>::Traits traits;
|
typename Gps_polyline_traits<Pgn1>::Traits traits;
|
||||||
const Polyline_traits& ptraits(traits);
|
const Polyline_traits& ptraits(traits);
|
||||||
|
|
@ -163,7 +162,7 @@ inline OutputIterator s_intersection(const Pgn1& pgn1, const Pgn2& pgn2,
|
||||||
template <typename InputIterator, typename OutputIterator, typename Traits>
|
template <typename InputIterator, typename OutputIterator, typename Traits>
|
||||||
inline OutputIterator r_intersection(InputIterator begin, InputIterator end,
|
inline OutputIterator r_intersection(InputIterator begin, InputIterator end,
|
||||||
OutputIterator oi, Traits& traits,
|
OutputIterator oi, Traits& traits,
|
||||||
unsigned int k=5) {
|
std::size_t k = 5) {
|
||||||
if (begin == end) return (oi);
|
if (begin == end) return (oi);
|
||||||
General_polygon_set_2<Traits> gps(*begin, traits);
|
General_polygon_set_2<Traits> gps(*begin, traits);
|
||||||
gps.intersection(std::next(begin), end, k);
|
gps.intersection(std::next(begin), end, k);
|
||||||
|
|
@ -173,8 +172,8 @@ inline OutputIterator r_intersection(InputIterator begin, InputIterator end,
|
||||||
// Without Traits
|
// Without Traits
|
||||||
template <typename InputIterator, typename OutputIterator>
|
template <typename InputIterator, typename OutputIterator>
|
||||||
inline OutputIterator r_intersection(InputIterator begin, InputIterator end,
|
inline OutputIterator r_intersection(InputIterator begin, InputIterator end,
|
||||||
OutputIterator oi, unsigned int k=5) {
|
OutputIterator oi, std::size_t k = 5) {
|
||||||
typedef typename std::iterator_traits<InputIterator>::value_type Pgn;
|
using Pgn = typename std::iterator_traits<InputIterator>::value_type;
|
||||||
typename Gps_polyline_traits<Pgn>::Traits traits;
|
typename Gps_polyline_traits<Pgn>::Traits traits;
|
||||||
const typename Gps_polyline_traits<Pgn>::Polyline_traits& ptraits(traits);
|
const typename Gps_polyline_traits<Pgn>::Polyline_traits& ptraits(traits);
|
||||||
if (begin == end) return (oi);
|
if (begin == end) return (oi);
|
||||||
|
|
@ -190,7 +189,7 @@ template <typename InputIterator1, typename InputIterator2,
|
||||||
inline OutputIterator r_intersection(InputIterator1 begin1, InputIterator1 end1,
|
inline OutputIterator r_intersection(InputIterator1 begin1, InputIterator1 end1,
|
||||||
InputIterator2 begin2, InputIterator2 end2,
|
InputIterator2 begin2, InputIterator2 end2,
|
||||||
OutputIterator oi, Traits& traits,
|
OutputIterator oi, Traits& traits,
|
||||||
unsigned int k=5) {
|
std::size_t k = 5) {
|
||||||
if (begin1 == end1) return r_intersection(begin2, end2, oi, traits, k);
|
if (begin1 == end1) return r_intersection(begin2, end2, oi, traits, k);
|
||||||
General_polygon_set_2<Traits> gps(*begin1, traits);
|
General_polygon_set_2<Traits> gps(*begin1, traits);
|
||||||
gps.intersection(std::next(begin1), end1, begin2, end2, k);
|
gps.intersection(std::next(begin1), end1, begin2, end2, k);
|
||||||
|
|
@ -203,8 +202,8 @@ template <typename InputIterator1, typename InputIterator2,
|
||||||
inline OutputIterator
|
inline OutputIterator
|
||||||
r_intersection(InputIterator1 begin1, InputIterator1 end1,
|
r_intersection(InputIterator1 begin1, InputIterator1 end1,
|
||||||
InputIterator2 begin2, InputIterator2 end2,
|
InputIterator2 begin2, InputIterator2 end2,
|
||||||
OutputIterator oi, unsigned int k=5) {
|
OutputIterator oi, std::size_t k = 5) {
|
||||||
typedef typename std::iterator_traits<InputIterator1>::value_type Pgn;
|
using Pgn = typename std::iterator_traits<InputIterator1>::value_type;
|
||||||
typename Gps_polyline_traits<Pgn>::Traits traits;
|
typename Gps_polyline_traits<Pgn>::Traits traits;
|
||||||
const typename Gps_polyline_traits<Pgn>::Polyline_traits& ptraits(traits);
|
const typename Gps_polyline_traits<Pgn>::Polyline_traits& ptraits(traits);
|
||||||
if (begin1 == end1) {
|
if (begin1 == end1) {
|
||||||
|
|
@ -228,7 +227,7 @@ r_intersection(InputIterator1 begin1, InputIterator1 end1,
|
||||||
// Polygon_2
|
// Polygon_2
|
||||||
template <typename Traits>
|
template <typename Traits>
|
||||||
inline bool _is_empty(const typename Traits::Polygon_2& pgn, Traits& traits) {
|
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<Curve_const_iterator, Curve_const_iterator>& itr_pair =
|
const std::pair<Curve_const_iterator, Curve_const_iterator>& itr_pair =
|
||||||
traits.construct_curves_2_object()(pgn);
|
traits.construct_curves_2_object()(pgn);
|
||||||
return (itr_pair.first == itr_pair.second);
|
return (itr_pair.first == itr_pair.second);
|
||||||
|
|
@ -268,9 +267,9 @@ template <typename Kernel, typename Container,
|
||||||
typename Pgn1, typename Pgn2, typename Pwh>
|
typename Pgn1, typename Pgn2, typename Pwh>
|
||||||
inline bool s_join(const Pgn1& pgn1, const Pgn2& pgn2, Pwh& pwh) {
|
inline bool s_join(const Pgn1& pgn1, const Pgn2& pgn2, Pwh& pwh) {
|
||||||
// Use the first polygon to determine the (default) traits
|
// Use the first polygon to determine the (default) traits
|
||||||
typedef typename Gps_polyline_traits<Pgn1>::Polyline_traits Polyline_traits;
|
using Polyline_traits = typename Gps_polyline_traits<Pgn1>::Polyline_traits;
|
||||||
typedef General_polygon_2<Polyline_traits> General_pgn;
|
using General_pgn = General_polygon_2<Polyline_traits>;
|
||||||
typedef General_polygon_with_holes_2<General_pgn> General_pwh;
|
using General_pwh = General_polygon_with_holes_2<General_pgn>;
|
||||||
|
|
||||||
General_pwh general_pwh;
|
General_pwh general_pwh;
|
||||||
typename Gps_polyline_traits<Pgn1>::Traits traits;
|
typename Gps_polyline_traits<Pgn1>::Traits traits;
|
||||||
|
|
@ -287,7 +286,7 @@ inline bool s_join(const Pgn1& pgn1, const Pgn2& pgn2, Pwh& pwh) {
|
||||||
template <typename InputIterator, typename OutputIterator, typename Traits>
|
template <typename InputIterator, typename OutputIterator, typename Traits>
|
||||||
inline OutputIterator r_join(InputIterator begin, InputIterator end,
|
inline OutputIterator r_join(InputIterator begin, InputIterator end,
|
||||||
OutputIterator oi, Traits& traits,
|
OutputIterator oi, Traits& traits,
|
||||||
unsigned int k=5) {
|
std::size_t k = 5) {
|
||||||
if (begin == end) return oi;
|
if (begin == end) return oi;
|
||||||
General_polygon_set_2<Traits> gps(*begin, traits);
|
General_polygon_set_2<Traits> gps(*begin, traits);
|
||||||
gps.join(std::next(begin), end, k);
|
gps.join(std::next(begin), end, k);
|
||||||
|
|
@ -297,8 +296,8 @@ inline OutputIterator r_join(InputIterator begin, InputIterator end,
|
||||||
// Without traits
|
// Without traits
|
||||||
template <typename InputIterator, typename OutputIterator>
|
template <typename InputIterator, typename OutputIterator>
|
||||||
inline OutputIterator r_join(InputIterator begin, InputIterator end,
|
inline OutputIterator r_join(InputIterator begin, InputIterator end,
|
||||||
OutputIterator oi, unsigned int k=5) {
|
OutputIterator oi, std::size_t k = 5) {
|
||||||
typedef typename std::iterator_traits<InputIterator>::value_type Pgn;
|
using Pgn = typename std::iterator_traits<InputIterator>::value_type;
|
||||||
typename Gps_polyline_traits<Pgn>::Traits traits;
|
typename Gps_polyline_traits<Pgn>::Traits traits;
|
||||||
const typename Gps_polyline_traits<Pgn>::Polyline_traits& ptraits(traits);
|
const typename Gps_polyline_traits<Pgn>::Polyline_traits& ptraits(traits);
|
||||||
|
|
||||||
|
|
@ -316,7 +315,7 @@ template <typename InputIterator1, typename InputIterator2,
|
||||||
inline OutputIterator r_join(InputIterator1 begin1, InputIterator1 end1,
|
inline OutputIterator r_join(InputIterator1 begin1, InputIterator1 end1,
|
||||||
InputIterator2 begin2, InputIterator2 end2,
|
InputIterator2 begin2, InputIterator2 end2,
|
||||||
OutputIterator oi, Traits& traits,
|
OutputIterator oi, Traits& traits,
|
||||||
unsigned int k=5) {
|
std::size_t k = 5) {
|
||||||
if (begin1 == end1) return r_join(begin2, end2, oi, traits, k);
|
if (begin1 == end1) return r_join(begin2, end2, oi, traits, k);
|
||||||
General_polygon_set_2<Traits> gps(*begin1, traits);
|
General_polygon_set_2<Traits> gps(*begin1, traits);
|
||||||
gps.join(std::next(begin1), end1, begin2, end2, k);
|
gps.join(std::next(begin1), end1, begin2, end2, k);
|
||||||
|
|
@ -328,8 +327,8 @@ template <typename InputIterator1, typename InputIterator2,
|
||||||
typename OutputIterator>
|
typename OutputIterator>
|
||||||
inline OutputIterator r_join(InputIterator1 begin1, InputIterator1 end1,
|
inline OutputIterator r_join(InputIterator1 begin1, InputIterator1 end1,
|
||||||
InputIterator2 begin2, InputIterator2 end2,
|
InputIterator2 begin2, InputIterator2 end2,
|
||||||
OutputIterator oi, unsigned int k=5) {
|
OutputIterator oi, std::size_t k = 5) {
|
||||||
typedef typename std::iterator_traits<InputIterator1>::value_type Pgn;
|
using Pgn = typename std::iterator_traits<InputIterator1>::value_type;
|
||||||
typename Gps_polyline_traits<Pgn>::Traits traits;
|
typename Gps_polyline_traits<Pgn>::Traits traits;
|
||||||
const typename Gps_polyline_traits<Pgn>::Polyline_traits& ptraits(traits);
|
const typename Gps_polyline_traits<Pgn>::Polyline_traits& ptraits(traits);
|
||||||
if (begin1 == end1) {
|
if (begin1 == end1) {
|
||||||
|
|
@ -361,10 +360,9 @@ inline OutputIterator _difference(const Pgn1& pgn1, const Pgn2& pgn2,
|
||||||
template <typename Kernel, typename Container,
|
template <typename Kernel, typename Container,
|
||||||
typename Pgn1, typename Pgn2, typename OutputIterator>
|
typename Pgn1, typename Pgn2, typename OutputIterator>
|
||||||
inline OutputIterator _difference(const Pgn1& pgn1, const Pgn2& pgn2,
|
inline OutputIterator _difference(const Pgn1& pgn1, const Pgn2& pgn2,
|
||||||
OutputIterator oi)
|
OutputIterator oi) {
|
||||||
{
|
|
||||||
// Use the first polygon to determine the (default) traits
|
// Use the first polygon to determine the (default) traits
|
||||||
typedef typename Gps_polyline_traits<Pgn1>::Polyline_traits Polyline_traits;
|
using Polyline_traits = typename Gps_polyline_traits<Pgn1>::Polyline_traits;
|
||||||
|
|
||||||
typename Gps_polyline_traits<Pgn1>::Traits traits;
|
typename Gps_polyline_traits<Pgn1>::Traits traits;
|
||||||
const Polyline_traits& ptraits(traits);
|
const Polyline_traits& ptraits(traits);
|
||||||
|
|
@ -394,7 +392,7 @@ template <typename Kernel, typename Container,
|
||||||
inline OutputIterator s_symmetric_difference(const Pgn1& pgn1, const Pgn2& pgn2,
|
inline OutputIterator s_symmetric_difference(const Pgn1& pgn1, const Pgn2& pgn2,
|
||||||
OutputIterator oi) {
|
OutputIterator oi) {
|
||||||
// Use the first polygon to determine the (default) traits
|
// Use the first polygon to determine the (default) traits
|
||||||
typedef typename Gps_polyline_traits<Pgn1>::Polyline_traits Polyline_traits;
|
using Polyline_traits = typename Gps_polyline_traits<Pgn1>::Polyline_traits;
|
||||||
typename Gps_polyline_traits<Pgn1>::Traits traits;
|
typename Gps_polyline_traits<Pgn1>::Traits traits;
|
||||||
const Polyline_traits& ptraits(traits);
|
const Polyline_traits& ptraits(traits);
|
||||||
s_symmetric_difference(convert_polygon(pgn1, ptraits),
|
s_symmetric_difference(convert_polygon(pgn1, ptraits),
|
||||||
|
|
@ -409,7 +407,7 @@ template <typename InputIterator, typename OutputIterator, typename Traits>
|
||||||
inline
|
inline
|
||||||
OutputIterator r_symmetric_difference(InputIterator begin, InputIterator end,
|
OutputIterator r_symmetric_difference(InputIterator begin, InputIterator end,
|
||||||
OutputIterator oi, Traits& traits,
|
OutputIterator oi, Traits& traits,
|
||||||
unsigned int k=5) {
|
std::size_t k = 5) {
|
||||||
if (begin == end) return (oi);
|
if (begin == end) return (oi);
|
||||||
General_polygon_set_2<Traits> gps(*begin, traits);
|
General_polygon_set_2<Traits> gps(*begin, traits);
|
||||||
gps.symmetric_difference(std::next(begin), end, k);
|
gps.symmetric_difference(std::next(begin), end, k);
|
||||||
|
|
@ -421,9 +419,8 @@ template <typename InputIterator, typename OutputIterator>
|
||||||
inline OutputIterator r_symmetric_difference(InputIterator begin,
|
inline OutputIterator r_symmetric_difference(InputIterator begin,
|
||||||
InputIterator end,
|
InputIterator end,
|
||||||
OutputIterator oi,
|
OutputIterator oi,
|
||||||
unsigned int k=5)
|
std::size_t k = 5) {
|
||||||
{
|
using Pgn = typename std::iterator_traits<InputIterator>::value_type;
|
||||||
typedef typename std::iterator_traits<InputIterator>::value_type Pgn;
|
|
||||||
typename Gps_polyline_traits<Pgn>::Traits traits;
|
typename Gps_polyline_traits<Pgn>::Traits traits;
|
||||||
const typename Gps_polyline_traits<Pgn>::Polyline_traits& ptraits(traits);
|
const typename Gps_polyline_traits<Pgn>::Polyline_traits& ptraits(traits);
|
||||||
if (begin == end) return (oi);
|
if (begin == end) return (oi);
|
||||||
|
|
@ -441,8 +438,7 @@ inline OutputIterator r_symmetric_difference(InputIterator1 begin1,
|
||||||
InputIterator2 begin2,
|
InputIterator2 begin2,
|
||||||
InputIterator2 end2,
|
InputIterator2 end2,
|
||||||
OutputIterator oi, Traits& traits,
|
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);
|
if (begin1 == end1) return r_symmetric_difference(begin2, end2, oi, traits, k);
|
||||||
General_polygon_set_2<Traits> gps(*begin1, traits);
|
General_polygon_set_2<Traits> gps(*begin1, traits);
|
||||||
gps.symmetric_difference(std::next(begin1), end1, begin2, end2, k);
|
gps.symmetric_difference(std::next(begin1), end1, begin2, end2, k);
|
||||||
|
|
@ -457,8 +453,8 @@ inline OutputIterator r_symmetric_difference(InputIterator1 begin1,
|
||||||
InputIterator2 begin2,
|
InputIterator2 begin2,
|
||||||
InputIterator2 end2,
|
InputIterator2 end2,
|
||||||
OutputIterator oi,
|
OutputIterator oi,
|
||||||
unsigned int k=5) {
|
std::size_t k = 5) {
|
||||||
typedef typename std::iterator_traits<InputIterator1>::value_type Pgn;
|
using Pgn = typename std::iterator_traits<InputIterator1>::value_type;
|
||||||
typename Gps_polyline_traits<Pgn>::Traits traits;
|
typename Gps_polyline_traits<Pgn>::Traits traits;
|
||||||
const typename Gps_polyline_traits<Pgn>::Polyline_traits& ptraits(traits);
|
const typename Gps_polyline_traits<Pgn>::Polyline_traits& ptraits(traits);
|
||||||
if (begin1 == end1){
|
if (begin1 == end1){
|
||||||
|
|
@ -522,10 +518,10 @@ OutputIterator _complement(const General_polygon_with_holes_2<Pgn>& pgn,
|
||||||
template <typename Kernel, typename Container, typename Pwh>
|
template <typename Kernel, typename Container, typename Pwh>
|
||||||
void _complement(const Polygon_2<Kernel, Container>& pgn, Pwh& pwh) {
|
void _complement(const Polygon_2<Kernel, Container>& pgn, Pwh& pwh) {
|
||||||
// Use the polygon to determine the (default) traits
|
// Use the polygon to determine the (default) traits
|
||||||
typedef Polygon_2<Kernel, Container> Pgn;
|
using Pgn = Polygon_2<Kernel, Container>;
|
||||||
typedef typename Gps_polyline_traits<Pgn>::Polyline_traits Polyline_traits;
|
using Polyline_traits = typename Gps_polyline_traits<Pgn>::Polyline_traits;
|
||||||
typedef General_polygon_2<Polyline_traits> General_pgn;
|
using General_pgn = General_polygon_2<Polyline_traits>;
|
||||||
typedef General_polygon_with_holes_2<General_pgn> General_pwh;
|
using General_pwh = General_polygon_with_holes_2<General_pgn>;
|
||||||
|
|
||||||
General_pwh general_pwh;
|
General_pwh general_pwh;
|
||||||
typename Gps_polyline_traits<Pgn>::Traits traits;
|
typename Gps_polyline_traits<Pgn>::Traits traits;
|
||||||
|
|
@ -539,8 +535,8 @@ template <typename Kernel, typename Container, typename OutputIterator>
|
||||||
OutputIterator _complement(const Polygon_with_holes_2<Kernel, Container>& pgn,
|
OutputIterator _complement(const Polygon_with_holes_2<Kernel, Container>& pgn,
|
||||||
OutputIterator oi) {
|
OutputIterator oi) {
|
||||||
// Use the polygon with holes to determine the (default) traits
|
// Use the polygon with holes to determine the (default) traits
|
||||||
typedef Polygon_with_holes_2<Kernel, Container> Pgn;
|
using Pgn = Polygon_with_holes_2<Kernel, Container>;
|
||||||
typedef typename Gps_polyline_traits<Pgn>::Polyline_traits Polyline_traits;
|
using Polyline_traits = typename Gps_polyline_traits<Pgn>::Polyline_traits;
|
||||||
|
|
||||||
typename Gps_polyline_traits<Pgn>::Traits traits;
|
typename Gps_polyline_traits<Pgn>::Traits traits;
|
||||||
const Polyline_traits& ptraits(traits);
|
const Polyline_traits& ptraits(traits);
|
||||||
|
|
|
||||||
|
|
@ -7,12 +7,11 @@
|
||||||
// $Id$
|
// $Id$
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
//
|
//
|
||||||
//
|
|
||||||
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||||
// Efi Fogel <efifogel@gmail.com>
|
// Efi Fogel <efifogel@gmail.com>
|
||||||
|
|
||||||
#ifndef CGAL_BSO_2_GPS_AGG_META_TRAITS_H
|
#ifndef CGAL_GPS_AGG_META_TRAITS_H
|
||||||
#define CGAL_BSO_2_GPS_AGG_META_TRAITS_H
|
#define CGAL_GPS_AGG_META_TRAITS_H
|
||||||
|
|
||||||
#include <CGAL/license/Boolean_set_operations_2.h>
|
#include <CGAL/license/Boolean_set_operations_2.h>
|
||||||
|
|
||||||
|
|
@ -24,18 +23,17 @@
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
|
|
||||||
template <typename Arrangement_>
|
template <typename Arrangement_>
|
||||||
class Gps_agg_curve_data : public Curve_with_halfedge<Arrangement_>
|
class Gps_agg_curve_data : public Curve_with_halfedge<Arrangement_> {
|
||||||
{
|
|
||||||
protected:
|
protected:
|
||||||
typedef Arrangement_ Arrangement;
|
using Arrangement = Arrangement_;
|
||||||
typedef typename Arrangement::Halfedge_handle Halfedge_handle;
|
using Halfedge_handle = typename Arrangement::Halfedge_handle;
|
||||||
typedef Curve_with_halfedge<Arrangement_> Base;
|
using Base = Curve_with_halfedge<Arrangement_>;
|
||||||
|
|
||||||
const Arrangement* m_arr; // pointer to the arrangement containing the edge.
|
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
|
// 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
|
// direction as the curve
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -47,24 +45,24 @@ public:
|
||||||
{}
|
{}
|
||||||
|
|
||||||
Gps_agg_curve_data(const Arrangement* arr, Halfedge_handle he,
|
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),
|
Base(he),
|
||||||
m_arr(arr),
|
m_arr(arr),
|
||||||
m_bc(bc),
|
m_bc(bc),
|
||||||
m_twin_bc(twin_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; }
|
const Arrangement* arr() const { return m_arr; }
|
||||||
};
|
};
|
||||||
|
|
@ -73,54 +71,50 @@ template <typename Arrangement_>
|
||||||
class Gps_agg_meta_traits :
|
class Gps_agg_meta_traits :
|
||||||
public Gps_traits_decorator<typename Arrangement_::Traits_adaptor_2,
|
public Gps_traits_decorator<typename Arrangement_::Traits_adaptor_2,
|
||||||
Gps_agg_curve_data<Arrangement_>,
|
Gps_agg_curve_data<Arrangement_>,
|
||||||
Point_with_vertex<Arrangement_> >
|
Point_with_vertex<Arrangement_>> {
|
||||||
{
|
using Arrangement = Arrangement_;
|
||||||
typedef Arrangement_ Arrangement;
|
using Arr = Arrangement;
|
||||||
typedef Arrangement Arr;
|
|
||||||
|
|
||||||
typedef typename Arr::Traits_adaptor_2 Traits;
|
using Traits = typename Arr::Traits_adaptor_2;
|
||||||
typedef Traits Gt2;
|
using Gt2 = Traits;
|
||||||
|
|
||||||
typedef typename Gt2::X_monotone_curve_2 Base_x_monotone_curve_2;
|
using Base_x_monotone_curve_2 = typename Gt2::X_monotone_curve_2;
|
||||||
typedef typename Gt2::Point_2 Base_point_2;
|
using Base_point_2 = typename Gt2::Point_2;
|
||||||
typedef typename Gt2::Construct_min_vertex_2 Base_Construct_min_vertex_2;
|
using Base_Construct_min_vertex_2 = typename Gt2::Construct_min_vertex_2;
|
||||||
typedef typename Gt2::Construct_max_vertex_2 Base_Construct_max_vertex_2;
|
using Base_Construct_max_vertex_2 = typename Gt2::Construct_max_vertex_2;
|
||||||
typedef typename Gt2::Compare_endpoints_xy_2 Base_Compare_endpoints_xy_2;
|
using Base_Compare_endpoints_xy_2 = typename Gt2::Compare_endpoints_xy_2;
|
||||||
typedef typename Gt2::Compare_xy_2 Base_Compare_xy_2;
|
using Base_Compare_xy_2 = typename Gt2::Compare_xy_2;
|
||||||
typedef typename Gt2::Compare_y_at_x_right_2 Base_Compare_y_at_x_right_2;
|
using Base_Compare_y_at_x_right_2 = typename Gt2::Compare_y_at_x_right_2;
|
||||||
typedef typename Gt2::Compare_y_at_x_2 Base_Compare_y_at_x_2;
|
using Base_Compare_y_at_x_2 = typename Gt2::Compare_y_at_x_2;
|
||||||
typedef typename Gt2::Intersect_2 Base_Intersect_2;
|
using Base_Intersect_2 = typename Gt2::Intersect_2;
|
||||||
typedef typename Gt2::Split_2 Base_Split_2;
|
using Base_Split_2 = typename Gt2::Split_2;
|
||||||
|
|
||||||
typedef typename Gt2::Parameter_space_in_x_2 Base_Parameter_space_in_x_2;
|
using Base_Parameter_space_in_x_2 = typename Gt2::Parameter_space_in_x_2;
|
||||||
typedef typename Gt2::Compare_y_near_boundary_2
|
using Base_Compare_y_near_boundary_2 = typename Gt2::Compare_y_near_boundary_2;
|
||||||
Base_Compare_y_near_boundary_2;
|
|
||||||
|
|
||||||
typedef typename Gt2::Parameter_space_in_y_2 Base_Parameter_space_in_y_2;
|
using Base_Parameter_space_in_y_2 = typename Gt2::Parameter_space_in_y_2;
|
||||||
typedef typename Gt2::Compare_x_near_boundary_2
|
using Base_Compare_x_near_boundary_2 = typename Gt2::Compare_x_near_boundary_2;
|
||||||
Base_Compare_x_near_boundary_2;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef typename Gt2::Multiplicity Multiplicity;
|
using Multiplicity = typename Gt2::Multiplicity;
|
||||||
typedef Gps_agg_curve_data<Arr> Curve_data;
|
using Curve_data = Gps_agg_curve_data<Arr>;
|
||||||
typedef Point_with_vertex<Arr> Point_data;
|
using Point_data = Point_with_vertex<Arr>;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef Gps_agg_meta_traits<Arrangement> Self;
|
using Self = Gps_agg_meta_traits<Arrangement>;
|
||||||
typedef Gps_traits_decorator<Gt2, Curve_data, Point_data> Base;
|
using Base = Gps_traits_decorator<Gt2, Curve_data, Point_data>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef typename Base::X_monotone_curve_2 X_monotone_curve_2;
|
using X_monotone_curve_2 = typename Base::X_monotone_curve_2;
|
||||||
typedef typename Base::Point_2 Point_2;
|
using Point_2 = typename Base::Point_2;
|
||||||
typedef typename Gt2::Has_left_category Has_left_category;
|
using Has_left_category = typename Gt2::Has_left_category;
|
||||||
typedef typename Gt2::Has_merge_category Has_merge_category;
|
using Has_merge_category = typename Gt2::Has_merge_category;
|
||||||
typedef typename Gt2::Has_do_intersect_category
|
using Has_do_intersect_category = typename Gt2::Has_do_intersect_category;
|
||||||
Has_do_intersect_category;
|
|
||||||
|
|
||||||
typedef typename Arr::Left_side_category Left_side_category;
|
using Left_side_category = typename Arr::Left_side_category;
|
||||||
typedef typename Arr::Bottom_side_category Bottom_side_category;
|
using Bottom_side_category = typename Arr::Bottom_side_category;
|
||||||
typedef typename Arr::Top_side_category Top_side_category;
|
using Top_side_category = typename Arr::Top_side_category;
|
||||||
typedef typename Arr::Right_side_category Right_side_category;
|
using Right_side_category = typename Arr::Right_side_category;
|
||||||
|
|
||||||
// a side is either oblivious or open (unbounded)
|
// a side is either oblivious or open (unbounded)
|
||||||
static_assert(std::is_same<Left_side_category, Arr_oblivious_side_tag>::value ||
|
static_assert(std::is_same<Left_side_category, Arr_oblivious_side_tag>::value ||
|
||||||
|
|
@ -132,8 +126,8 @@ public:
|
||||||
static_assert(std::is_same<Right_side_category, Arr_oblivious_side_tag>::value ||
|
static_assert(std::is_same<Right_side_category, Arr_oblivious_side_tag>::value ||
|
||||||
std::is_same<Right_side_category, Arr_open_side_tag>::value);
|
std::is_same<Right_side_category, Arr_open_side_tag>::value);
|
||||||
|
|
||||||
typedef typename Arr::Halfedge_handle Halfedge_handle;
|
using Halfedge_handle = typename Arr::Halfedge_handle;
|
||||||
typedef typename Arr::Vertex_handle Vertex_handle;
|
using Vertex_handle = typename Arr::Vertex_handle;
|
||||||
|
|
||||||
Gps_agg_meta_traits() {}
|
Gps_agg_meta_traits() {}
|
||||||
|
|
||||||
|
|
@ -152,16 +146,13 @@ public:
|
||||||
template <typename OutputIterator>
|
template <typename OutputIterator>
|
||||||
OutputIterator operator()(const X_monotone_curve_2& cv1,
|
OutputIterator operator()(const X_monotone_curve_2& cv1,
|
||||||
const X_monotone_curve_2& cv2,
|
const X_monotone_curve_2& cv2,
|
||||||
OutputIterator oi) const
|
OutputIterator oi) const {
|
||||||
{
|
|
||||||
// Check whether the curves are already in the same arrangement, and thus
|
// Check whether the curves are already in the same arrangement, and thus
|
||||||
// must be interior-disjoint
|
// must be interior-disjoint
|
||||||
if (cv1.data().arr() == cv2.data().arr()) return oi;
|
if (cv1.data().arr() == cv2.data().arr()) return oi;
|
||||||
|
|
||||||
typedef const std::pair<Base_point_2, Multiplicity>
|
using Intersection_base_point = const std::pair<Base_point_2, Multiplicity>;
|
||||||
Intersection_base_point;
|
using Intersection_base_result = std::variant<Intersection_base_point, Base_x_monotone_curve_2>;
|
||||||
typedef std::variant<Intersection_base_point, Base_x_monotone_curve_2>
|
|
||||||
Intersection_base_result;
|
|
||||||
|
|
||||||
const auto* base_traits = m_traits.m_base_traits;
|
const auto* base_traits = m_traits.m_base_traits;
|
||||||
auto base_cmp_xy = base_traits->compare_xy_2_object();
|
auto base_cmp_xy = base_traits->compare_xy_2_object();
|
||||||
|
|
@ -191,8 +182,8 @@ public:
|
||||||
const Base_x_monotone_curve_2* overlap_cv =
|
const Base_x_monotone_curve_2* overlap_cv =
|
||||||
std::get_if<Base_x_monotone_curve_2>(&xection);
|
std::get_if<Base_x_monotone_curve_2>(&xection);
|
||||||
CGAL_assertion(overlap_cv != nullptr);
|
CGAL_assertion(overlap_cv != nullptr);
|
||||||
unsigned int ov_bc;
|
std::size_t ov_bc;
|
||||||
unsigned int ov_twin_bc;
|
std::size_t ov_twin_bc;
|
||||||
if (base_cmp_endpoints(cv1) == base_cmp_endpoints(cv2)) {
|
if (base_cmp_endpoints(cv1) == base_cmp_endpoints(cv2)) {
|
||||||
// cv1 and cv2 have the same directions
|
// cv1 and cv2 have the same directions
|
||||||
ov_bc = cv1.data().bc() + cv2.data().bc();
|
ov_bc = cv1.data().bc() + cv2.data().bc();
|
||||||
|
|
@ -230,8 +221,7 @@ public:
|
||||||
Split_2(const Base_Split_2& base) : m_base_split(base) {}
|
Split_2(const Base_Split_2& base) : m_base_split(base) {}
|
||||||
|
|
||||||
void operator()(const X_monotone_curve_2& cv, const Point_2 & p,
|
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());
|
m_base_split(cv.base(), p.base(), c1.base(), c2.base());
|
||||||
const Curve_data& cv_data = cv.data();
|
const Curve_data& cv_data = cv.data();
|
||||||
c1.set_data(Curve_data(cv_data.arr(), Halfedge_handle(), cv_data.bc(),
|
c1.set_data(Curve_data(cv_data.arr(), Halfedge_handle(), cv_data.bc(),
|
||||||
|
|
@ -259,8 +249,7 @@ public:
|
||||||
* \param cv The curve.
|
* \param cv The curve.
|
||||||
* \return The left endpoint.
|
* \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())
|
if (cv.data().halfedge() == Halfedge_handle())
|
||||||
return (Point_2(m_base(cv.base())));
|
return (Point_2(m_base(cv.base())));
|
||||||
|
|
||||||
|
|
@ -272,8 +261,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
/*! Get a Construct_min_vertex_2 functor object. */
|
/*! 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->
|
return Construct_min_vertex_2(this->m_base_traits->
|
||||||
construct_min_vertex_2_object());
|
construct_min_vertex_2_object());
|
||||||
}
|
}
|
||||||
|
|
@ -292,8 +280,7 @@ public:
|
||||||
* \param cv The curve.
|
* \param cv The curve.
|
||||||
* \return The right endpoint.
|
* \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())
|
if (cv.data().halfedge() == Halfedge_handle())
|
||||||
return (Point_2(m_base(cv.base())));
|
return (Point_2(m_base(cv.base())));
|
||||||
|
|
||||||
|
|
@ -304,8 +291,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
/*! Get a Construct_min_vertex_2 functor object. */
|
/*! 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->
|
return Construct_max_vertex_2(this->m_base_traits->
|
||||||
construct_max_vertex_2_object());
|
construct_max_vertex_2_object());
|
||||||
}
|
}
|
||||||
|
|
@ -321,8 +307,7 @@ public:
|
||||||
* \param cv The curve.
|
* \param cv The curve.
|
||||||
* \return The left endpoint.
|
* \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& inf1 = p1.data();
|
||||||
const Point_data& inf2 = p2.data();
|
const Point_data& inf2 = p2.data();
|
||||||
|
|
||||||
|
|
@ -390,8 +375,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
/*! Obtain a Construct_min_vertex_2 functor object. */
|
/*! 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->
|
return Compare_y_near_boundary_2(this->m_base_traits->
|
||||||
compare_y_near_boundary_2_object()
|
compare_y_near_boundary_2_object()
|
||||||
);
|
);
|
||||||
|
|
@ -429,8 +413,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
/*! Obtain a Construct_min_vertex_2 functor object. */
|
/*! 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->
|
return Parameter_space_in_y_2(this->m_base_traits->
|
||||||
parameter_space_in_y_2_object());
|
parameter_space_in_y_2_object());
|
||||||
}
|
}
|
||||||
|
|
@ -462,8 +445,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
/*! Obtain a Construct_min_vertex_2 functor object. */
|
/*! 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->
|
return Compare_x_near_boundary_2(this->m_base_traits->
|
||||||
compare_x_near_boundary_2_object());
|
compare_x_near_boundary_2_object());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,9 +9,10 @@
|
||||||
//
|
//
|
||||||
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||||
// Ophir Setter <ophir.setter@cs.tau.ac.il>
|
// Ophir Setter <ophir.setter@cs.tau.ac.il>
|
||||||
|
// Efi Fogel <efifogel@gmail.com>
|
||||||
|
|
||||||
#ifndef CGAL_BSO_2_GPS_AGG_OP_H
|
#ifndef CGAL_GPS_AGG_OP_H
|
||||||
#define CGAL_BSO_2_GPS_AGG_OP_H
|
#define CGAL_GPS_AGG_OP_H
|
||||||
|
|
||||||
#include <CGAL/license/Boolean_set_operations_2.h>
|
#include <CGAL/license/Boolean_set_operations_2.h>
|
||||||
|
|
||||||
|
|
@ -19,8 +20,8 @@
|
||||||
*
|
*
|
||||||
* The class Gps_agg_op is responsible for aggregated Boolean set operations
|
* The class Gps_agg_op is responsible for aggregated Boolean set operations
|
||||||
* depending on a visitor template parameter. It uses the surface-sweep
|
* depending on a visitor template parameter. It uses the surface-sweep
|
||||||
* algorithm from the arrangement packages to overlay all the polygon sets, and
|
* algorithm from the surface-sweep package to overlay all the polygon sets, and
|
||||||
* then it uses a BFS that determines which of the faces is contained in the
|
* then it uses a BFS that determines which of the faces are contained in the
|
||||||
* result using the visitor.
|
* result using the visitor.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -37,31 +38,31 @@
|
||||||
|
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
|
|
||||||
template <typename Arrangement_, typename BfsVisitor>
|
template <typename Arrangement_, typename BfsVisitor, template <typename, typename, typename> class SweepVisitor>
|
||||||
class Gps_agg_op {
|
class Gps_agg_op {
|
||||||
typedef Arrangement_ Arrangement_2;
|
using Arrangement_2 = Arrangement_;
|
||||||
typedef BfsVisitor Bfs_visitor;
|
using Bfs_visitor = BfsVisitor;
|
||||||
|
|
||||||
typedef typename Arrangement_2::Traits_adaptor_2 Geometry_traits_2;
|
using Geometry_traits_2 = typename Arrangement_2::Traits_adaptor_2;
|
||||||
typedef typename Arrangement_2::Topology_traits Topology_traits;
|
using Topology_traits = typename Arrangement_2::Topology_traits;
|
||||||
|
|
||||||
typedef Arrangement_2 Arr;
|
using Arr = Arrangement_2;
|
||||||
typedef Geometry_traits_2 Gt2;
|
using Gt2 = Geometry_traits_2;
|
||||||
typedef Topology_traits Tt;
|
using Tt = Topology_traits;
|
||||||
|
|
||||||
typedef typename Gt2::Curve_const_iterator Curve_const_iterator;
|
using Curve_const_iterator = typename Gt2::Curve_const_iterator;
|
||||||
typedef Gps_agg_meta_traits<Arr> Mgt2;
|
using Mgt2 = Gps_agg_meta_traits<Arr>;
|
||||||
typedef typename Mgt2::Curve_data Curve_data;
|
using Curve_data = typename Mgt2::Curve_data;
|
||||||
typedef typename Mgt2::X_monotone_curve_2 Meta_X_monotone_curve_2;
|
using Meta_X_monotone_curve_2 = typename Mgt2::X_monotone_curve_2;
|
||||||
|
|
||||||
typedef typename Arr::Halfedge_handle Halfedge_handle;
|
using Halfedge_handle = typename Arr::Halfedge_handle;
|
||||||
typedef typename Arr::Halfedge_iterator Halfedge_iterator;
|
using Halfedge_iterator = typename Arr::Halfedge_iterator;
|
||||||
typedef typename Arr::Face_handle Face_handle;
|
using Face_handle = typename Arr::Face_handle;
|
||||||
typedef typename Arr::Edge_iterator Edge_iterator;
|
using Edge_iterator = typename Arr::Edge_iterator;
|
||||||
typedef typename Arr::Vertex_handle Vertex_handle;
|
using Vertex_handle = typename Arr::Vertex_handle;
|
||||||
typedef typename Arr::Allocator Allocator;
|
using Allocator = typename Arr::Allocator;
|
||||||
|
|
||||||
typedef std::pair<Arr*, std::vector<Vertex_handle> *> Arr_entry;
|
using Arr_entry = std::pair<Arr*, std::vector<Vertex_handle> *>;
|
||||||
|
|
||||||
// We obtain a proper helper type from the topology traits of the arrangement.
|
// We obtain a proper helper type from the topology traits of the arrangement.
|
||||||
// However, the arrangement is parametrized with the Gt2 geometry traits,
|
// 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
|
// We cannot parameterized the arrangement with the Mgt2 geometry
|
||||||
// traits to start with, because it extends the curve type with arrangement
|
// traits to start with, because it extends the curve type with arrangement
|
||||||
// dependent types. (It is parameterized with the arrangement type.)
|
// dependent types. (It is parameterized with the arrangement type.)
|
||||||
typedef Indexed_event<Mgt2, Arr, Allocator> Event;
|
using Event = Indexed_event<Mgt2, Arr, Allocator>;
|
||||||
typedef Arr_construction_subcurve<Mgt2, Event, Allocator>
|
using Subcurve = Arr_construction_subcurve<Mgt2, Event, Allocator>;
|
||||||
Subcurve;
|
using Helper_tmp = typename Tt::template Construction_helper<Event, Subcurve>;
|
||||||
typedef typename Tt::template Construction_helper<Event, Subcurve>
|
using Helper = typename Helper_tmp::template rebind<Mgt2, Arr, Event, Subcurve>::other;
|
||||||
Helper_tmp;
|
using Visitor = SweepVisitor<Helper, Arr, Default>;
|
||||||
typedef typename Helper_tmp::template rebind<Mgt2, Arr, Event, Subcurve>::other
|
using Surface_sweep_2 = Gps_agg_op_surface_sweep_2<Arr, Visitor>;
|
||||||
Helper;
|
|
||||||
typedef Gps_agg_op_visitor<Helper, Arr> Visitor;
|
|
||||||
typedef Gps_agg_op_surface_sweep_2<Arr, Visitor> Surface_sweep_2;
|
|
||||||
|
|
||||||
typedef Unique_hash_map<Halfedge_handle, unsigned int>
|
using Edges_hash = Unique_hash_map<Halfedge_handle, std::size_t>;
|
||||||
Edges_hash;
|
using Faces_hash = Unique_hash_map<Face_handle, std::size_t>;
|
||||||
|
using Bfs_scanner = Gps_bfs_scanner<Arr, Bfs_visitor>;
|
||||||
typedef Unique_hash_map<Face_handle, unsigned int> Faces_hash;
|
|
||||||
typedef Gps_bfs_scanner<Arr, Bfs_visitor> Bfs_scanner;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Arr* m_arr;
|
Arr* m_arr;
|
||||||
|
|
@ -95,7 +91,7 @@ protected:
|
||||||
Faces_hash m_faces_hash; // maps face to its IC (inside count)
|
Faces_hash m_faces_hash; // maps face to its IC (inside count)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*! Constructor. */
|
/*! constructs. */
|
||||||
Gps_agg_op(Arr& arr, std::vector<Vertex_handle>& vert_vec, const Gt2& tr) :
|
Gps_agg_op(Arr& arr, std::vector<Vertex_handle>& vert_vec, const Gt2& tr) :
|
||||||
m_arr(&arr),
|
m_arr(&arr),
|
||||||
m_traits(new Mgt2(tr)),
|
m_traits(new Mgt2(tr)),
|
||||||
|
|
@ -103,40 +99,40 @@ public:
|
||||||
m_surface_sweep(m_traits, &m_visitor)
|
m_surface_sweep(m_traits, &m_visitor)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void sweep_arrangements(unsigned int lower, unsigned int upper,
|
std::pair<std::size_t, std::size_t>
|
||||||
unsigned int jump, std::vector<Arr_entry>& arr_vec)
|
prepare(std::size_t lower, std::size_t upper, std::size_t jump,
|
||||||
{
|
std::vector<Arr_entry>& arr_vec, std::list<Meta_X_monotone_curve_2>& curves_list) {
|
||||||
std::list<Meta_X_monotone_curve_2> curves_list;
|
std::size_t n_inf_pgn = 0; // number of infinite polygons (arrangement
|
||||||
|
|
||||||
unsigned int n_inf_pgn = 0; // number of infinite polygons (arrangement
|
|
||||||
// with a contained unbounded face
|
// with a contained unbounded face
|
||||||
unsigned int n_pgn = 0; // number of polygons (arrangements)
|
std::size_t n_pgn = 0; // number of polygons (arrangements)
|
||||||
unsigned int i;
|
for (auto i = lower; i <= upper; i += jump, ++n_pgn) {
|
||||||
|
|
||||||
for (i = lower; i <= upper; i += jump, ++n_pgn) {
|
|
||||||
// The BFS scan (after the loop) starts in the reference face,
|
// The BFS scan (after the loop) starts in the reference face,
|
||||||
// so we count the number of polygons that contain the reference face.
|
// so we count the number of polygons that contain the reference face.
|
||||||
Arr* arr = (arr_vec[i]).first;
|
Arr* arr = (arr_vec[i]).first;
|
||||||
if (arr->reference_face()->contained()) ++n_inf_pgn;
|
if (arr->reference_face()->contained()) ++n_inf_pgn;
|
||||||
|
|
||||||
Edge_iterator itr = arr->edges_begin();
|
for (auto itr = arr->edges_begin(); itr != arr->edges_end(); ++itr) {
|
||||||
for(; itr != arr->edges_end(); ++itr) {
|
|
||||||
// take only relevant edges (which separate between contained and
|
// take only relevant edges (which separate between contained and
|
||||||
// non-contained faces.
|
// non-contained faces.
|
||||||
Halfedge_iterator he = itr;
|
Halfedge_handle he = itr;
|
||||||
if(he->face()->contained() == he->twin()->face()->contained())
|
if (he->face()->contained() == he->twin()->face()->contained()) continue;
|
||||||
continue;
|
if ((Arr_halfedge_direction)he->direction() == ARR_RIGHT_TO_LEFT) he = he->twin();
|
||||||
if ((Arr_halfedge_direction)he->direction() == ARR_RIGHT_TO_LEFT)
|
|
||||||
he = he->twin();
|
|
||||||
|
|
||||||
Curve_data cv_data(arr, he, 1, 0);
|
Curve_data cv_data(arr, he, 1, 0);
|
||||||
curves_list.push_back(Meta_X_monotone_curve_2(he->curve(), cv_data));
|
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(),
|
/*! sweeps the plane without interceptions.
|
||||||
lower, upper, jump, arr_vec);
|
*/
|
||||||
|
void sweep_arrangements(std::size_t lower, std::size_t upper, std::size_t jump,
|
||||||
|
std::vector<Arr_entry>& arr_vec) {
|
||||||
|
std::size_t n_inf_pgn, n_pgn;
|
||||||
|
std::list<Meta_X_monotone_curve_2> 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;
|
m_faces_hash[m_arr->reference_face()] = n_inf_pgn;
|
||||||
Bfs_visitor visitor(&m_edges_hash, &m_faces_hash, n_pgn);
|
Bfs_visitor visitor(&m_edges_hash, &m_faces_hash, n_pgn);
|
||||||
visitor.visit_ubf(m_arr->faces_begin(), n_inf_pgn);
|
visitor.visit_ubf(m_arr->faces_begin(), n_inf_pgn);
|
||||||
|
|
@ -145,7 +141,69 @@ public:
|
||||||
visitor.after_scan(*m_arr);
|
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_entry>& arr_vec) {
|
||||||
|
std::size_t n_inf_pgn, n_pgn;
|
||||||
|
std::list<Meta_X_monotone_curve_2> 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 <typename InputIterator>
|
||||||
|
std::size_t prepare2(InputIterator begin, InputIterator end, std::list<Meta_X_monotone_curve_2>& 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 <typename InputIterator>
|
||||||
|
bool sweep_intercept_arrangements2(InputIterator begin, InputIterator end) {
|
||||||
|
std::list<Meta_X_monotone_curve_2> 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; }
|
~Gps_agg_op() { delete m_traits; }
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -9,9 +9,10 @@
|
||||||
//
|
//
|
||||||
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||||
// Ron Wein <wein@post.tau.ac.il>
|
// Ron Wein <wein@post.tau.ac.il>
|
||||||
|
// Efi Fogel <efifogel@gmail.com>
|
||||||
|
|
||||||
#ifndef CGAL_BSO_2_GSP_AGG_OP_SURFACE_SWEEP_2_H
|
#ifndef CGAL_GSP_AGG_OP_SURFACE_SWEEP_2_H
|
||||||
#define CGAL_BSO_2_GSP_AGG_OP_SURFACE_SWEEP_2_H
|
#define CGAL_GSP_AGG_OP_SURFACE_SWEEP_2_H
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|
@ -27,34 +28,34 @@ namespace Ss2 = Surface_sweep_2;
|
||||||
template <typename Arrangement_, typename Visitor_>
|
template <typename Arrangement_, typename Visitor_>
|
||||||
class Gps_agg_op_surface_sweep_2 : public Ss2::Surface_sweep_2<Visitor_> {
|
class Gps_agg_op_surface_sweep_2 : public Ss2::Surface_sweep_2<Visitor_> {
|
||||||
public:
|
public:
|
||||||
typedef Arrangement_ Arrangement_2;
|
using Arrangement_2 = Arrangement_;
|
||||||
typedef Visitor_ Visitor;
|
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;
|
using Arr = Arrangement_2;
|
||||||
typedef Geometry_traits_2 Gt2;
|
using Gt2 = Geometry_traits_2;
|
||||||
|
|
||||||
typedef typename Gt2::Point_2 Point_2;
|
using Point_2 = typename Gt2::Point_2;
|
||||||
typedef typename Gt2::X_monotone_curve_2 X_monotone_curve_2;
|
using X_monotone_curve_2 = typename Gt2::X_monotone_curve_2;
|
||||||
|
|
||||||
typedef typename Arr::Vertex_handle Vertex_handle;
|
using Vertex_handle = typename Arr::Vertex_handle;
|
||||||
typedef typename Arr::Halfedge_handle Halfedge_handle;
|
using Halfedge_handle = typename Arr::Halfedge_handle;
|
||||||
|
|
||||||
typedef std::pair<Arr*, std::vector<Vertex_handle> *> Arr_entry;
|
using Arr_entry = std::pair<Arr*, std::vector<Vertex_handle> *>;
|
||||||
|
|
||||||
typedef Ss2::Surface_sweep_2<Visitor> Base;
|
using Base = Ss2::Surface_sweep_2<Visitor>;
|
||||||
|
|
||||||
typedef typename Visitor::Event Event;
|
using Event = typename Visitor::Event;
|
||||||
typedef typename Visitor::Subcurve Subcurve;
|
using Subcurve = typename Visitor::Subcurve;
|
||||||
|
|
||||||
typedef typename Base::Event_queue_iterator EventQueueIter;
|
using EventQueueIter = typename Base::Event_queue_iterator;
|
||||||
typedef typename Event::Subcurve_iterator EventCurveIter;
|
using EventCurveIter = typename Event::Subcurve_iterator;
|
||||||
|
|
||||||
typedef typename Event::Attribute Attribute;
|
using Attribute = typename Event::Attribute;
|
||||||
|
|
||||||
typedef std::list<Subcurve*> SubCurveList;
|
using SubCurveList = std::list<Subcurve*>;
|
||||||
typedef typename SubCurveList::iterator SubCurveListIter;
|
using SubCurveListIter = typename SubCurveList::iterator;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*! Constructor.
|
/*! Constructor.
|
||||||
|
|
@ -70,21 +71,17 @@ public:
|
||||||
Base(traits, visitor)
|
Base(traits, visitor)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/*! Perform the sweep. */
|
template <typename CurveInputIterator>
|
||||||
template <class CurveInputIterator>
|
void pre_process(CurveInputIterator curves_begin, CurveInputIterator curves_end,
|
||||||
void sweep(CurveInputIterator curves_begin, CurveInputIterator curves_end,
|
std::size_t lower, std::size_t upper, std::size_t jump,
|
||||||
unsigned int lower, unsigned int upper, unsigned int jump,
|
std::vector<Arr_entry>& arr_vec) {
|
||||||
std::vector<Arr_entry>& arr_vec)
|
|
||||||
{
|
|
||||||
CGAL_assertion(this->m_queue->empty() && this->m_statusLine.size() == 0);
|
CGAL_assertion(this->m_queue->empty() && this->m_statusLine.size() == 0);
|
||||||
|
|
||||||
typedef Unique_hash_map<Vertex_handle, Event*> Vertices_map;
|
using Vertices_map = Unique_hash_map<Vertex_handle, Event*>;
|
||||||
typedef typename Gt2::Compare_xy_2 Compare_xy_2;
|
using Compare_xy_2 = typename Gt2::Compare_xy_2;
|
||||||
|
|
||||||
this->m_visitor->before_sweep();
|
|
||||||
// Allocate all of the Subcurve objects as one block.
|
// Allocate all of the Subcurve objects as one block.
|
||||||
this->m_num_of_subCurves =
|
this->m_num_of_subCurves = static_cast<unsigned int>(std::distance(curves_begin, curves_end));
|
||||||
static_cast<unsigned int>(std::distance(curves_begin, curves_end));
|
|
||||||
if (this->m_num_of_subCurves > 0)
|
if (this->m_num_of_subCurves > 0)
|
||||||
this->m_subCurves =
|
this->m_subCurves =
|
||||||
this->m_subCurveAlloc.allocate(this->m_num_of_subCurves);
|
this->m_subCurveAlloc.allocate(this->m_num_of_subCurves);
|
||||||
|
|
@ -95,9 +92,9 @@ public:
|
||||||
Vertices_map vert_map;
|
Vertices_map vert_map;
|
||||||
Vertex_handle vh;
|
Vertex_handle vh;
|
||||||
Vertex_handle invalid_v;
|
Vertex_handle invalid_v;
|
||||||
unsigned int i = lower;
|
std::size_t i = lower;
|
||||||
unsigned int n = static_cast<unsigned int>((arr_vec[i].second)->size());
|
auto n = (arr_vec[i].second)->size();
|
||||||
unsigned int j;
|
std::size_t j;
|
||||||
EventQueueIter q_iter;
|
EventQueueIter q_iter;
|
||||||
bool first = true;
|
bool first = true;
|
||||||
Attribute event_type;
|
Attribute event_type;
|
||||||
|
|
@ -135,7 +132,7 @@ public:
|
||||||
for (i += jump; i <= upper; i += jump) {
|
for (i += jump; i <= upper; i += jump) {
|
||||||
// Merge the vertices of the other vectors into the existing queue.
|
// Merge the vertices of the other vectors into the existing queue.
|
||||||
q_iter = this->m_queue->begin();
|
q_iter = this->m_queue->begin();
|
||||||
n = static_cast<unsigned int>((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++) {
|
for (j = 0; j < n && (vh = (*(arr_vec[i].second))[j]) != invalid_v; j++) {
|
||||||
event_type = _type_of_vertex(vh);
|
event_type = _type_of_vertex(vh);
|
||||||
|
|
@ -170,7 +167,7 @@ public:
|
||||||
|
|
||||||
// Go over all curves (which are associated with halfedges) and associate
|
// Go over all curves (which are associated with halfedges) and associate
|
||||||
// them with the events we have just created.
|
// them with the events we have just created.
|
||||||
unsigned int index = 0;
|
std::size_t index = 0;
|
||||||
CurveInputIterator iter;
|
CurveInputIterator iter;
|
||||||
Halfedge_handle he;
|
Halfedge_handle he;
|
||||||
Event* e_left;
|
Event* e_left;
|
||||||
|
|
@ -194,8 +191,9 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the subcurve object.
|
// Create the subcurve object.
|
||||||
typedef decltype(this->m_subCurveAlloc) Subcurve_alloc;
|
using Subcurve_alloc = decltype(this->m_subCurveAlloc);
|
||||||
std::allocator_traits<Subcurve_alloc>::construct(this->m_subCurveAlloc, this->m_subCurves + index,
|
std::allocator_traits<Subcurve_alloc>::construct(this->m_subCurveAlloc,
|
||||||
|
this->m_subCurves + index,
|
||||||
this->m_masterSubcurve);
|
this->m_masterSubcurve);
|
||||||
(this->m_subCurves + index)->init(*iter);
|
(this->m_subCurves + index)->init(*iter);
|
||||||
(this->m_subCurves + index)->set_left_event(e_left);
|
(this->m_subCurves + index)->set_left_event(e_left);
|
||||||
|
|
@ -204,13 +202,174 @@ public:
|
||||||
e_right->add_curve_to_left(this->m_subCurves + index);
|
e_right->add_curve_to_left(this->m_subCurves + index);
|
||||||
this->_add_curve_to_right(e_left, this->m_subCurves + index);
|
this->_add_curve_to_right(e_left, this->m_subCurves + index);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Perform the sweep:
|
template <typename CurveInputIterator, typename InputIterator>
|
||||||
|
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<Vertex_handle, Event*>;
|
||||||
|
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<Subcurve_alloc>::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 <typename CurveInputIterator>
|
||||||
|
void sweep(CurveInputIterator curves_begin, CurveInputIterator curves_end,
|
||||||
|
std::size_t lower, std::size_t upper, std::size_t jump, std::vector<Arr_entry>& arr_vec) {
|
||||||
|
this->m_visitor->before_sweep();
|
||||||
|
pre_process(curves_begin, curves_end,lower, upper, jump, arr_vec);
|
||||||
this->_sweep();
|
this->_sweep();
|
||||||
this->_complete_sweep();
|
this->_complete_sweep();
|
||||||
this->m_visitor->after_sweep();
|
this->m_visitor->after_sweep();
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
/*! Perform the sweep. */
|
||||||
|
template <typename CurveInputIterator>
|
||||||
|
bool sweep_intercept(CurveInputIterator curves_begin, CurveInputIterator curves_end,
|
||||||
|
std::size_t lower, std::size_t upper, std::size_t jump, std::vector<Arr_entry>& 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 <typename CurveInputIterator, typename InputIterator>
|
||||||
|
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:
|
private:
|
||||||
|
|
@ -218,8 +377,7 @@ private:
|
||||||
* Check if the given vertex is an endpoint of an edge we are going
|
* Check if the given vertex is an endpoint of an edge we are going
|
||||||
* to use in the sweep.
|
* 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;
|
typename Arr::Halfedge_around_vertex_circulator first, circ;
|
||||||
|
|
||||||
circ = first = v->incident_halfedges();
|
circ = first = v->incident_halfedges();
|
||||||
|
|
@ -232,7 +390,6 @@ private:
|
||||||
else return (Event::LEFT_END);
|
else return (Event::LEFT_END);
|
||||||
}
|
}
|
||||||
++circ;
|
++circ;
|
||||||
|
|
||||||
} while (circ != first);
|
} while (circ != first);
|
||||||
|
|
||||||
// If we reached here, we should not keep this vertex.
|
// If we reached here, we should not keep this vertex.
|
||||||
|
|
|
||||||
|
|
@ -7,12 +7,12 @@
|
||||||
// $Id$
|
// $Id$
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
//
|
//
|
||||||
//
|
|
||||||
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||||
// Ron Wein <wein@post.tau.ac.il>
|
// Ron Wein <wein@post.tau.ac.il>
|
||||||
|
// Efi Fogel <efifogel@gmail.com>
|
||||||
|
|
||||||
#ifndef CGAL_BSO_2_GSP_AGG_OP_VISITOR_H
|
#ifndef CGAL_GSP_AGG_OP_VISITOR_H
|
||||||
#define CGAL_BSO_2_GSP_AGG_OP_VISITOR_H
|
#define CGAL_GSP_AGG_OP_VISITOR_H
|
||||||
|
|
||||||
#include <CGAL/license/Boolean_set_operations_2.h>
|
#include <CGAL/license/Boolean_set_operations_2.h>
|
||||||
|
|
||||||
|
|
@ -31,33 +31,29 @@ class Gps_agg_op_base_visitor :
|
||||||
Helper_,
|
Helper_,
|
||||||
typename Default::Get<Visitor_, Gps_agg_op_base_visitor<Helper_,
|
typename Default::Get<Visitor_, Gps_agg_op_base_visitor<Helper_,
|
||||||
Arrangement_,
|
Arrangement_,
|
||||||
Visitor_> >::type>
|
Visitor_>>::type> {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
typedef Helper_ Helper;
|
using Helper = Helper_;
|
||||||
typedef Arrangement_ Arrangement_2;
|
using Arrangement_2 = Arrangement_;
|
||||||
|
|
||||||
typedef typename Helper::Geometry_traits_2 Geometry_traits_2;
|
using Geometry_traits_2 = typename Helper::Geometry_traits_2;
|
||||||
typedef typename Helper::Event Event;
|
using Event = typename Helper::Event;
|
||||||
typedef typename Helper::Subcurve Subcurve;
|
using Subcurve = typename Helper::Subcurve;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef Geometry_traits_2 Gt2;
|
using Gt2 = Geometry_traits_2;
|
||||||
typedef Arrangement_2 Arr;
|
using Arr = Arrangement_2;
|
||||||
|
using Self = Gps_agg_op_base_visitor<Helper, Arr, Visitor_>;
|
||||||
typedef Gps_agg_op_base_visitor<Helper, Arr, Visitor_>
|
using Visitor = typename Default::Get<Visitor_, Self>::type;
|
||||||
Self;
|
using Base = Arr_construction_ss_visitor<Helper, Visitor>;
|
||||||
typedef typename Default::Get<Visitor_, Self>::type Visitor;
|
|
||||||
typedef Arr_construction_ss_visitor<Helper, Visitor> Base;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef typename Arr::Halfedge_handle Halfedge_handle;
|
using Halfedge_handle = typename Arr::Halfedge_handle;
|
||||||
typedef typename Arr::Vertex_handle Vertex_handle;
|
using Vertex_handle = typename Arr::Vertex_handle;
|
||||||
typedef typename Gt2::X_monotone_curve_2 X_monotone_curve_2;
|
using X_monotone_curve_2 = typename Gt2::X_monotone_curve_2;
|
||||||
typedef typename Gt2::Point_2 Point_2;
|
using Point_2 = typename Gt2::Point_2;
|
||||||
|
|
||||||
typedef Unique_hash_map<Halfedge_handle, unsigned int>
|
using Edges_hash = Unique_hash_map<Halfedge_handle, std::size_t>;
|
||||||
Edges_hash;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Edges_hash* m_edges_hash; // maps halfedges to their BC (coundary counter)
|
Edges_hash* m_edges_hash; // maps halfedges to their BC (coundary counter)
|
||||||
|
|
@ -72,8 +68,7 @@ public:
|
||||||
// TODO add mpl-warning
|
// TODO add mpl-warning
|
||||||
|
|
||||||
virtual Halfedge_handle insert_in_face_interior(const X_monotone_curve_2& cv,
|
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);
|
Halfedge_handle he = Base::insert_in_face_interior(cv, sc);
|
||||||
insert_edge_to_hash(he, cv);
|
insert_edge_to_hash(he, cv);
|
||||||
return he;
|
return he;
|
||||||
|
|
@ -83,8 +78,7 @@ public:
|
||||||
Halfedge_handle hhandle,
|
Halfedge_handle hhandle,
|
||||||
Halfedge_handle prev,
|
Halfedge_handle prev,
|
||||||
Subcurve* sc,
|
Subcurve* sc,
|
||||||
bool& new_face_created)
|
bool& new_face_created) {
|
||||||
{
|
|
||||||
Halfedge_handle res_he =
|
Halfedge_handle res_he =
|
||||||
Base::insert_at_vertices(cv, hhandle, prev, sc, new_face_created);
|
Base::insert_at_vertices(cv, hhandle, prev, sc, new_face_created);
|
||||||
insert_edge_to_hash(res_he, cv);
|
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,
|
virtual Halfedge_handle insert_from_right_vertex(const X_monotone_curve_2& cv,
|
||||||
Halfedge_handle he,
|
Halfedge_handle he,
|
||||||
Subcurve* sc)
|
Subcurve* sc) {
|
||||||
{
|
|
||||||
Halfedge_handle res_he = Base::insert_from_right_vertex(cv, he, sc);
|
Halfedge_handle res_he = Base::insert_from_right_vertex(cv, he, sc);
|
||||||
insert_edge_to_hash(res_he, cv);
|
insert_edge_to_hash(res_he, cv);
|
||||||
return res_he;
|
return res_he;
|
||||||
|
|
@ -102,16 +95,14 @@ public:
|
||||||
|
|
||||||
virtual Halfedge_handle insert_from_left_vertex(const X_monotone_curve_2& cv,
|
virtual Halfedge_handle insert_from_left_vertex(const X_monotone_curve_2& cv,
|
||||||
Halfedge_handle he,
|
Halfedge_handle he,
|
||||||
Subcurve* sc)
|
Subcurve* sc) {
|
||||||
{
|
|
||||||
Halfedge_handle res_he = Base::insert_from_left_vertex(cv, he, sc);
|
Halfedge_handle res_he = Base::insert_from_left_vertex(cv, he, sc);
|
||||||
insert_edge_to_hash(res_he, cv);
|
insert_edge_to_hash(res_he, cv);
|
||||||
return res_he;
|
return res_he;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
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 =
|
const Comparison_result he_dir =
|
||||||
((Arr_halfedge_direction)he->direction() == ARR_LEFT_TO_RIGHT) ?
|
((Arr_halfedge_direction)he->direction() == ARR_LEFT_TO_RIGHT) ?
|
||||||
SMALLER : LARGER;
|
SMALLER : LARGER;
|
||||||
|
|
@ -133,54 +124,53 @@ private:
|
||||||
|
|
||||||
template <typename Helper_, typename Arrangement_, typename Visitor_ = Default>
|
template <typename Helper_, typename Arrangement_, typename Visitor_ = Default>
|
||||||
class Gps_agg_op_visitor :
|
class Gps_agg_op_visitor :
|
||||||
public Gps_agg_op_base_visitor<Helper_, Arrangement_,
|
public Gps_agg_op_base_visitor<
|
||||||
Gps_agg_op_visitor<Helper_, Arrangement_,
|
Helper_, Arrangement_,
|
||||||
Visitor_> >
|
typename Default::Get<Visitor_,
|
||||||
{
|
Gps_agg_op_visitor<Helper_, Arrangement_, Visitor_>>::type> {
|
||||||
public:
|
public:
|
||||||
typedef Helper_ Helper;
|
using Helper = Helper_;
|
||||||
typedef Arrangement_ Arrangement_2;
|
using Arrangement_2 = Arrangement_;
|
||||||
|
|
||||||
typedef typename Helper::Geometry_traits_2 Geometry_traits_2;
|
using Geometry_traits_2 = typename Helper::Geometry_traits_2;
|
||||||
typedef typename Helper::Event Event;
|
using Event = typename Helper::Event;
|
||||||
typedef typename Helper::Subcurve Subcurve;
|
using Subcurve = typename Helper::Subcurve;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef Geometry_traits_2 Gt2;
|
using Gt2 = Geometry_traits_2;
|
||||||
typedef Arrangement_2 Arr;
|
using Arr = Arrangement_2;
|
||||||
|
|
||||||
typedef Gps_agg_op_visitor<Helper, Arr, Visitor_> Self;
|
using Self = Gps_agg_op_visitor<Helper, Arr, Visitor_>;
|
||||||
typedef typename Default::Get<Visitor_, Self>::type Visitor;
|
using Visitor = typename Default::Get<Visitor_, Self>::type;
|
||||||
typedef Gps_agg_op_base_visitor<Helper, Arr, Visitor> Base;
|
using Base = Gps_agg_op_base_visitor<Helper, Arr, Visitor>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef typename Base::Halfedge_handle Halfedge_handle;
|
using Edges_hash = typename Base::Edges_hash;
|
||||||
typedef typename Base::Vertex_handle Vertex_handle;
|
using Halfedge_handle = typename Base::Halfedge_handle;
|
||||||
typedef typename Gt2::X_monotone_curve_2 X_monotone_curve_2;
|
using Vertex_handle = typename Base::Vertex_handle;
|
||||||
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;
|
||||||
|
|
||||||
protected:
|
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<Vertex_handle>* m_vertices_vec; // The vertices, sorted in
|
std::vector<Vertex_handle>* m_vertices_vec; // The vertices, sorted in
|
||||||
// ascending order.
|
// ascending order.
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Gps_agg_op_visitor(Arr* arr, typename Base::Edges_hash* hash,
|
Gps_agg_op_visitor(Arr* arr, Edges_hash* hash,
|
||||||
std::vector<Vertex_handle>* vertices_vec) :
|
std::vector<Vertex_handle>* vertices_vec) :
|
||||||
Base(arr, hash),
|
Base(arr, hash),
|
||||||
m_event_count(0),
|
m_event_count(0),
|
||||||
m_vertices_vec(vertices_vec)
|
m_vertices_vec(vertices_vec)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void before_handle_event(Event* event)
|
void before_handle_event(Event* event) {
|
||||||
{
|
|
||||||
event->set_index(m_event_count);
|
event->set_index(m_event_count);
|
||||||
m_event_count++;
|
m_event_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Halfedge_handle
|
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);
|
Halfedge_handle res_he = Base::insert_in_face_interior(cv, sc);
|
||||||
|
|
||||||
// We now have a halfedge whose source vertex is associated with the
|
// 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,
|
virtual Halfedge_handle insert_from_right_vertex(const X_monotone_curve_2& cv,
|
||||||
Halfedge_handle he,
|
Halfedge_handle he,
|
||||||
Subcurve* sc)
|
Subcurve* sc) {
|
||||||
{
|
|
||||||
Halfedge_handle res_he = Base::insert_from_right_vertex(cv, he, 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
|
// We now have a halfedge whose target vertex is associated with the
|
||||||
|
|
@ -213,8 +202,7 @@ public:
|
||||||
|
|
||||||
virtual Halfedge_handle insert_from_left_vertex(const X_monotone_curve_2& cv,
|
virtual Halfedge_handle insert_from_left_vertex(const X_monotone_curve_2& cv,
|
||||||
Halfedge_handle he,
|
Halfedge_handle he,
|
||||||
Subcurve* sc)
|
Subcurve* sc) {
|
||||||
{
|
|
||||||
Halfedge_handle res_he = Base::insert_from_left_vertex(cv, he, 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
|
// We now have a halfedge whose target vertex is associated with the
|
||||||
|
|
@ -228,13 +216,11 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void _insert_vertex(const Event* event, Vertex_handle v)
|
void _insert_vertex(const Event* event, Vertex_handle v) {
|
||||||
{
|
const auto index = event->index();
|
||||||
const unsigned int index = event->index();
|
|
||||||
if (index >= m_vertices_vec->size()) m_vertices_vec->resize(2 * (index + 1));
|
if (index >= m_vertices_vec->size()) m_vertices_vec->resize(2 * (index + 1));
|
||||||
(*m_vertices_vec)[index] = v;
|
(*m_vertices_vec)[index] = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace CGAL
|
} // namespace CGAL
|
||||||
|
|
|
||||||
|
|
@ -16,82 +16,75 @@
|
||||||
|
|
||||||
#include <CGAL/license/Boolean_set_operations_2.h>
|
#include <CGAL/license/Boolean_set_operations_2.h>
|
||||||
|
|
||||||
|
|
||||||
#include <CGAL/Unique_hash_map.h>
|
#include <CGAL/Unique_hash_map.h>
|
||||||
|
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
|
|
||||||
//! Gps_bfs_base_visitor
|
//! Gps_bfs_base_visitor
|
||||||
/*! This is a base class for all visitors that are responsible for merging
|
/*! This is a base class for all visitors that are responsible for merging
|
||||||
polygon sets.
|
* polygon sets.
|
||||||
We use DerivedVisitor for static polymorphism for using contained_criteria
|
* We use DerivedVisitor for static polymorphism for using contained_criteria
|
||||||
which determines if we should mark the face as contained given the inside
|
* which determines if we should mark the face as contained given the inside
|
||||||
count of the face.
|
* count of the face.
|
||||||
*/
|
*/
|
||||||
template <class Arrangement_, class DerivedVisitor>
|
template <typename Arrangement_, typename DerivedVisitor>
|
||||||
class Gps_bfs_base_visitor
|
class Gps_bfs_base_visitor {
|
||||||
{
|
using Arrangement = Arrangement_;
|
||||||
typedef Arrangement_ Arrangement;
|
using Face_iterator = typename Arrangement::Face_iterator;
|
||||||
typedef typename Arrangement::Face_iterator Face_iterator;
|
using Halfedge_iterator = typename Arrangement::Halfedge_iterator;
|
||||||
typedef typename Arrangement::Halfedge_iterator Halfedge_iterator;
|
|
||||||
public:
|
public:
|
||||||
typedef Unique_hash_map<Halfedge_iterator, unsigned int> Edges_hash;
|
using Edges_hash = Unique_hash_map<Halfedge_iterator, std::size_t>;
|
||||||
typedef Unique_hash_map<Face_iterator, unsigned int> Faces_hash;
|
using Faces_hash = Unique_hash_map<Face_iterator, std::size_t>;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Edges_hash* m_edges_hash;
|
Edges_hash* m_edges_hash;
|
||||||
Faces_hash* m_faces_hash;
|
Faces_hash* m_faces_hash;
|
||||||
unsigned int m_num_of_polygons; // number of polygons
|
std::size_t m_num_of_polygons; // number of polygons
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Gps_bfs_base_visitor(Edges_hash* edges_hash,
|
Gps_bfs_base_visitor(Edges_hash* edges_hash,
|
||||||
Faces_hash* faces_hash,
|
Faces_hash* faces_hash,
|
||||||
unsigned int n_pgn):
|
std::size_t n_pgn):
|
||||||
m_edges_hash(edges_hash),
|
m_edges_hash(edges_hash),
|
||||||
m_faces_hash(faces_hash),
|
m_faces_hash(faces_hash),
|
||||||
m_num_of_polygons(n_pgn)
|
m_num_of_polygons(n_pgn)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
//! discovered_face
|
//! discovered_face
|
||||||
/*! discovered_face is called by Gps_bfs_scanner when it reveals a new 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
|
* during a BFS scan. In the BFS traversal we are going from old_face to
|
||||||
new_face through the half-edge he.
|
* new_face through the half-edge he.
|
||||||
\param old_face The face that was already revealed
|
* \param old_face The face that was already revealed
|
||||||
\param new_face The face that we have just now revealed
|
* \param new_face The face that we have just now revealed
|
||||||
\param he The half-edge that is used to traverse between them.
|
* \param he The half-edge that is used to traverse between them.
|
||||||
*/
|
*/
|
||||||
void discovered_face(Face_iterator old_face,
|
void discovered_face(Face_iterator old_face,
|
||||||
Face_iterator new_face,
|
Face_iterator new_face,
|
||||||
Halfedge_iterator he)
|
Halfedge_iterator he) {
|
||||||
{
|
std::size_t ic = compute_ic(old_face, new_face, he);
|
||||||
unsigned int ic = compute_ic(old_face, new_face, he);
|
|
||||||
|
|
||||||
if (static_cast<DerivedVisitor*>(this)->contained_criteria(ic))
|
if (static_cast<DerivedVisitor*>(this)->contained_criteria(ic))
|
||||||
new_face->set_contained(true);
|
new_face->set_contained(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// mark the unbounded_face (true iff contained)
|
// 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());
|
CGAL_assertion(ubf->is_unbounded());
|
||||||
if (static_cast<DerivedVisitor*>(this)->contained_criteria(ubf_ic))
|
if (static_cast<DerivedVisitor*>(this)->contained_criteria(ubf_ic))
|
||||||
ubf->set_contained(true);
|
ubf->set_contained(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// compute the inside count of a face
|
// compute the inside count of a face
|
||||||
unsigned int compute_ic(Face_iterator f1,
|
std::size_t compute_ic(Face_iterator f1,
|
||||||
Face_iterator f2,
|
Face_iterator f2,
|
||||||
Halfedge_iterator he)
|
Halfedge_iterator he) {
|
||||||
{
|
|
||||||
CGAL_assertion(m_edges_hash->is_defined(he) &&
|
CGAL_assertion(m_edges_hash->is_defined(he) &&
|
||||||
m_edges_hash->is_defined(he->twin()) &&
|
m_edges_hash->is_defined(he->twin()) &&
|
||||||
m_faces_hash->is_defined(f1) &&
|
m_faces_hash->is_defined(f1) &&
|
||||||
! m_faces_hash->is_defined(f2));
|
! m_faces_hash->is_defined(f2));
|
||||||
unsigned int ic_f2 =
|
std::size_t ic_f2 =
|
||||||
(*m_faces_hash)[f1] - (*m_edges_hash)[he] + (*m_edges_hash)[he->twin()];
|
(*m_faces_hash)[f1] - (*m_edges_hash)[he] + (*m_edges_hash)[he->twin()];
|
||||||
(*m_faces_hash)[f2] = ic_f2;
|
(*m_faces_hash)[f2] = ic_f2;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,59 +7,50 @@
|
||||||
// $Id$
|
// $Id$
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
//
|
//
|
||||||
//
|
|
||||||
|
|
||||||
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||||
// Ophir Setter <ophir.setter@cs.tau.ac.il>
|
// Ophir Setter <ophir.setter@cs.tau.ac.il>
|
||||||
|
// Efi Fogel <efifogel@gmail.com>
|
||||||
|
|
||||||
#ifndef CGAL_GPS_BFS_INTERSECTION_VISITOR_H
|
#ifndef CGAL_GPS_BFS_INTERSECTION_VISITOR_H
|
||||||
#define CGAL_GPS_BFS_INTERSECTION_VISITOR_H
|
#define CGAL_GPS_BFS_INTERSECTION_VISITOR_H
|
||||||
|
|
||||||
#include <CGAL/license/Boolean_set_operations_2.h>
|
#include <CGAL/license/Boolean_set_operations_2.h>
|
||||||
|
|
||||||
|
|
||||||
#include <CGAL/Boolean_set_operations_2/Gps_bfs_base_visitor.h>
|
#include <CGAL/Boolean_set_operations_2/Gps_bfs_base_visitor.h>
|
||||||
|
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
|
|
||||||
template <class Arrangement_>
|
template <typename Arrangement_>
|
||||||
class Gps_bfs_intersection_visitor :
|
class Gps_bfs_intersection_visitor :
|
||||||
public Gps_bfs_base_visitor<Arrangement_, Gps_bfs_intersection_visitor<Arrangement_> >
|
public Gps_bfs_base_visitor<Arrangement_, Gps_bfs_intersection_visitor<Arrangement_>> {
|
||||||
{
|
using Arrangement = Arrangement_;
|
||||||
typedef Arrangement_ Arrangement;
|
using Face_iterator = typename Arrangement::Face_iterator;
|
||||||
typedef typename Arrangement::Face_iterator Face_iterator;
|
using Halfedge_iterator = typename Arrangement::Halfedge_iterator;
|
||||||
typedef typename Arrangement::Halfedge_iterator Halfedge_iterator;
|
using Self = Gps_bfs_intersection_visitor<Arrangement>;
|
||||||
typedef Gps_bfs_intersection_visitor<Arrangement> Self;
|
using Base = Gps_bfs_base_visitor<Arrangement, Self>;
|
||||||
typedef Gps_bfs_base_visitor<Arrangement, Self> Base;
|
using Edges_hash = typename Base::Edges_hash;
|
||||||
typedef typename Base::Edges_hash Edges_hash;
|
using Faces_hash = typename Base::Faces_hash;
|
||||||
typedef typename Base::Faces_hash Faces_hash;
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Gps_bfs_intersection_visitor(Edges_hash* edges_hash,
|
Gps_bfs_intersection_visitor(Edges_hash* edges_hash,
|
||||||
Faces_hash* faces_hash,
|
Faces_hash* faces_hash,
|
||||||
unsigned int n_polygons):
|
std::size_t n_polygons):
|
||||||
Base(edges_hash, faces_hash, n_polygons)
|
Base(edges_hash, faces_hash, n_polygons)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
//! contained_criteria
|
//! contained_criteria
|
||||||
/*! contained_criteria is used to the determine if the face which has
|
/*! contained_criteria is used to the determine if the face which has
|
||||||
inside count should be marked as contained.
|
* inside count should be marked as contained.
|
||||||
\param ic the inner count of the talked-about face.
|
* \param ic the inner count of the talked-about face.
|
||||||
\return true if the face of ic, otherwise false.
|
* \return true if the face of ic, otherwise false.
|
||||||
*/
|
*/
|
||||||
bool contained_criteria(unsigned int ic)
|
bool contained_criteria(std::size_t ic) {
|
||||||
{
|
|
||||||
// intersection means that all polygons contain the face.
|
// intersection means that all polygons contain the face.
|
||||||
CGAL_assertion(ic <= this->m_num_of_polygons);
|
CGAL_assertion(ic <= this->m_num_of_polygons);
|
||||||
return (ic == this->m_num_of_polygons);
|
return (ic == this->m_num_of_polygons);
|
||||||
}
|
}
|
||||||
|
|
||||||
void after_scan(Arrangement&)
|
void after_scan(Arrangement&) {}
|
||||||
{}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} //namespace CGAL
|
} //namespace CGAL
|
||||||
|
|
|
||||||
|
|
@ -16,44 +16,38 @@
|
||||||
|
|
||||||
#include <CGAL/license/Boolean_set_operations_2.h>
|
#include <CGAL/license/Boolean_set_operations_2.h>
|
||||||
|
|
||||||
|
|
||||||
#include <CGAL/Boolean_set_operations_2/Gps_bfs_base_visitor.h>
|
#include <CGAL/Boolean_set_operations_2/Gps_bfs_base_visitor.h>
|
||||||
|
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
|
|
||||||
template <class Arrangement_>
|
template <typename Arrangement_>
|
||||||
class Gps_bfs_join_visitor :
|
class Gps_bfs_join_visitor :
|
||||||
public Gps_bfs_base_visitor<Arrangement_, Gps_bfs_join_visitor<Arrangement_> >
|
public Gps_bfs_base_visitor<Arrangement_, Gps_bfs_join_visitor<Arrangement_>> {
|
||||||
{
|
using Arrangement = Arrangement_;
|
||||||
typedef Arrangement_ Arrangement;
|
using Face_iterator = typename Arrangement::Face_iterator;
|
||||||
typedef typename Arrangement::Face_iterator Face_iterator;
|
using Halfedge_iterator = typename Arrangement::Halfedge_iterator;
|
||||||
typedef typename Arrangement::Halfedge_iterator Halfedge_iterator;
|
using Self = Gps_bfs_join_visitor<Arrangement>;
|
||||||
typedef Gps_bfs_join_visitor<Arrangement> Self;
|
using Base = Gps_bfs_base_visitor<Arrangement, Self>;
|
||||||
typedef Gps_bfs_base_visitor<Arrangement, Self> Base;
|
using Edges_hash = typename Base::Edges_hash;
|
||||||
typedef typename Base::Edges_hash Edges_hash;
|
using Faces_hash = typename Base::Faces_hash;
|
||||||
typedef typename Base::Faces_hash Faces_hash;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
Gps_bfs_join_visitor(Edges_hash* edges_hash, Faces_hash* faces_hash, std::size_t n_pgn):
|
||||||
Gps_bfs_join_visitor(Edges_hash* edges_hash, Faces_hash* faces_hash, unsigned int n_pgn):
|
|
||||||
Base(edges_hash, faces_hash, 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
|
/*! contained_criteria is used to the determine if the face which has
|
||||||
inside count should be marked as contained.
|
* inside count should be marked as contained.
|
||||||
\param ic the inner count of the talked-about face.
|
* \param ic the inner count of the talked-about face.
|
||||||
\return true if the face of ic, otherwise false.
|
* \return true if the face of ic, otherwise false.
|
||||||
*/
|
*/
|
||||||
bool contained_criteria(unsigned int ic)
|
bool contained_criteria(std::size_t ic) {
|
||||||
{
|
|
||||||
// at least one polygon contains the face.
|
// at least one polygon contains the face.
|
||||||
return (ic > 0);
|
return (ic > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void after_scan(Arrangement&)
|
void after_scan(Arrangement&) {}
|
||||||
{}
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} //namespace CGAL
|
} //namespace CGAL
|
||||||
|
|
|
||||||
|
|
@ -21,22 +21,20 @@
|
||||||
|
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
|
|
||||||
template <class Arrangement_>
|
template <typename Arrangement_>
|
||||||
class Gps_bfs_xor_visitor :
|
class Gps_bfs_xor_visitor :
|
||||||
public Gps_bfs_base_visitor<Arrangement_, Gps_bfs_xor_visitor<Arrangement_> >
|
public Gps_bfs_base_visitor<Arrangement_, Gps_bfs_xor_visitor<Arrangement_>> {
|
||||||
{
|
using Arrangement = Arrangement_;
|
||||||
typedef Arrangement_ Arrangement;
|
using Face_iterator = typename Arrangement::Face_iterator;
|
||||||
typedef typename Arrangement::Face_iterator Face_iterator;
|
using Halfedge_iterator = typename Arrangement::Halfedge_iterator;
|
||||||
typedef typename Arrangement::Halfedge_iterator Halfedge_iterator;
|
using Self = Gps_bfs_xor_visitor<Arrangement>;
|
||||||
typedef Gps_bfs_xor_visitor<Arrangement> Self;
|
using Base = Gps_bfs_base_visitor<Arrangement, Self>;
|
||||||
typedef Gps_bfs_base_visitor<Arrangement, Self> Base;
|
using Edges_hash = typename Base::Edges_hash;
|
||||||
typedef typename Base::Edges_hash Edges_hash;
|
using Faces_hash = typename Base::Faces_hash;
|
||||||
typedef typename Base::Faces_hash Faces_hash;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Gps_bfs_xor_visitor(Edges_hash* edges_hash, Faces_hash* faces_hash,
|
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)
|
Base(edges_hash, faces_hash, n_pgn)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
@ -46,35 +44,26 @@ public:
|
||||||
\param ic the inner count of the talked-about face.
|
\param ic the inner count of the talked-about face.
|
||||||
\return true if the face of ic, otherwise false.
|
\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.
|
// xor means odd number of polygons.
|
||||||
return (ic % 2) == 1;
|
return (ic % 2) == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! after_scan postprocessing after bfs scan.
|
//! after_scan postprocessing after bfs scan.
|
||||||
/*! The function fixes some of the curves, to be in the same direction as the
|
/*! The function fixes some of the curves, to be in the same direction as the
|
||||||
half-edges.
|
* half-edges.
|
||||||
|
*
|
||||||
\param arr The given arrangement.
|
* \param arr The given arrangement.
|
||||||
*/
|
*/
|
||||||
void after_scan(Arrangement& arr)
|
void after_scan(Arrangement& arr) {
|
||||||
{
|
using Traits = typename Arrangement::Geometry_traits_2;
|
||||||
typedef typename Arrangement::Geometry_traits_2 Traits;
|
using X_monotone_curve_2 = typename Traits::X_monotone_curve_2;
|
||||||
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;
|
|
||||||
|
|
||||||
Traits tr;
|
Traits tr;
|
||||||
Compare_endpoints_xy_2 cmp_endpoints =
|
auto cmp_endpoints = tr.compare_endpoints_xy_2_object();
|
||||||
tr.compare_endpoints_xy_2_object();
|
auto ctr_opp = tr.construct_opposite_2_object();
|
||||||
Construct_opposite_2 ctr_opp = tr.construct_opposite_2_object();
|
|
||||||
|
|
||||||
for(Edge_iterator eit = arr.edges_begin();
|
for (auto eit = arr.edges_begin(); eit != arr.edges_end(); ++eit) {
|
||||||
eit != arr.edges_end();
|
|
||||||
++eit)
|
|
||||||
{
|
|
||||||
Halfedge_iterator he = eit;
|
Halfedge_iterator he = eit;
|
||||||
const X_monotone_curve_2& cv = he->curve();
|
const X_monotone_curve_2& cv = he->curve();
|
||||||
const bool is_cont = he->face()->contained();
|
const bool is_cont = he->face()->contained();
|
||||||
|
|
@ -87,7 +76,6 @@ public:
|
||||||
arr.modify_edge(he, ctr_opp(cv));
|
arr.modify_edge(he, ctr_opp(cv));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} //namespace CGAL
|
} //namespace CGAL
|
||||||
|
|
|
||||||
|
|
@ -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 <efifogel@gmail.com>
|
||||||
|
|
||||||
|
#ifndef CGAL_GSP_DO_INTERSECT_AGG_OP_VISITOR_H
|
||||||
|
#define CGAL_GSP_DO_INTERSECT_AGG_OP_VISITOR_H
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <CGAL/license/Boolean_set_operations_2.h>
|
||||||
|
#include <CGAL/Boolean_set_operations_2/Gps_agg_op_visitor.h>
|
||||||
|
#include <CGAL/Default.h>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
|
||||||
|
template <typename Helper_, typename Arrangement_, typename Visitor_ = Default>
|
||||||
|
class Gps_do_intersect_agg_op_visitor :
|
||||||
|
public Gps_agg_op_visitor<
|
||||||
|
Helper_, Arrangement_,
|
||||||
|
typename Default::Get<Visitor_, Gps_do_intersect_agg_op_visitor<Helper_, Arrangement_, Visitor_>>::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<Helper, Arr, Visitor_>;
|
||||||
|
using Visitor = typename Default::Get<Visitor_, Self>::type;
|
||||||
|
using Base = Gps_agg_op_visitor<Helper, Arr, 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<Vertex_handle>* 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
|
||||||
|
|
@ -15,112 +15,61 @@
|
||||||
|
|
||||||
#include <CGAL/license/Boolean_set_operations_2.h>
|
#include <CGAL/license/Boolean_set_operations_2.h>
|
||||||
|
|
||||||
|
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
|
|
||||||
template <class Arrangement_>
|
template <typename Arrangement_>
|
||||||
class Gps_do_intersect_functor
|
class Gps_do_intersect_functor {
|
||||||
{
|
|
||||||
public:
|
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;
|
using Face_handle = typename Arrangement_2::Face_handle;
|
||||||
typedef typename Arrangement_2::Vertex_const_handle Vertex_const_handle;
|
using Halfedge_handle = typename Arrangement_2::Halfedge_handle;
|
||||||
typedef typename Arrangement_2::Halfedge_const_handle Halfedge_const_handle;
|
using Vertex_handle = typename Arrangement_2::Vertex_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;
|
|
||||||
|
|
||||||
// default constructor
|
// default constructor
|
||||||
Gps_do_intersect_functor() : m_found_reg_intersection(false),
|
Gps_do_intersect_functor() :
|
||||||
|
m_found_reg_intersection(false),
|
||||||
m_found_boudary_intersection(false)
|
m_found_boudary_intersection(false)
|
||||||
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void create_face (Face_const_handle f1,
|
void create_face(Face_const_handle f1, Face_const_handle f2, Face_handle)
|
||||||
Face_const_handle f2,
|
{ if (f1->contained() && f2->contained()) m_found_reg_intersection = true; }
|
||||||
Face_handle )
|
|
||||||
{
|
|
||||||
if(f1->contained() && f2->contained())
|
|
||||||
// found intersection
|
|
||||||
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 ,
|
void create_vertex(Vertex_const_handle, Halfedge_const_handle, Vertex_handle)
|
||||||
Vertex_const_handle ,
|
{ m_found_boudary_intersection = true; }
|
||||||
Vertex_handle )
|
|
||||||
{
|
|
||||||
m_found_boudary_intersection = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void create_vertex(Vertex_const_handle ,
|
void create_vertex(Halfedge_const_handle, Vertex_const_handle, Vertex_handle)
|
||||||
Halfedge_const_handle ,
|
{ m_found_boudary_intersection = true; }
|
||||||
Vertex_handle )
|
|
||||||
{
|
|
||||||
m_found_boudary_intersection = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void create_vertex(Halfedge_const_handle ,
|
void create_vertex(Halfedge_const_handle, Halfedge_const_handle, Vertex_handle) {}
|
||||||
Vertex_const_handle ,
|
|
||||||
Vertex_handle )
|
|
||||||
{
|
|
||||||
m_found_boudary_intersection = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void create_vertex(Halfedge_const_handle ,
|
void create_vertex(Face_const_handle, Vertex_const_handle, Vertex_handle) {}
|
||||||
Halfedge_const_handle ,
|
|
||||||
Vertex_handle )
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
void create_vertex(Vertex_const_handle, Face_const_handle, Vertex_handle) {}
|
||||||
|
|
||||||
void create_vertex(Face_const_handle ,
|
void create_edge(Halfedge_const_handle, Halfedge_const_handle, Halfedge_handle)
|
||||||
Vertex_const_handle ,
|
{ m_found_boudary_intersection = true; }
|
||||||
Vertex_handle )
|
|
||||||
{}
|
|
||||||
|
|
||||||
void create_vertex(Vertex_const_handle ,
|
void create_edge(Halfedge_const_handle, Face_const_handle, Halfedge_handle) {}
|
||||||
Face_const_handle ,
|
|
||||||
Vertex_handle )
|
|
||||||
{}
|
|
||||||
|
|
||||||
void create_edge(Halfedge_const_handle ,
|
void create_edge(Face_const_handle, Halfedge_const_handle, Halfedge_handle) {}
|
||||||
Halfedge_const_handle ,
|
|
||||||
Halfedge_handle )
|
|
||||||
{
|
|
||||||
m_found_boudary_intersection = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void create_edge(Halfedge_const_handle ,
|
bool found_reg_intersection() const { return m_found_reg_intersection; }
|
||||||
Face_const_handle ,
|
|
||||||
Halfedge_handle )
|
|
||||||
{}
|
|
||||||
|
|
||||||
void create_edge(Face_const_handle ,
|
bool found_boundary_intersection() const { return m_found_boudary_intersection; }
|
||||||
Halfedge_const_handle ,
|
|
||||||
Halfedge_handle )
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
bool found_reg_intersection() const
|
|
||||||
{
|
|
||||||
return m_found_reg_intersection;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool found_boundary_intersection() const
|
|
||||||
{
|
|
||||||
return m_found_boudary_intersection;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
bool m_found_reg_intersection;
|
bool m_found_reg_intersection;
|
||||||
bool m_found_boudary_intersection;
|
bool m_found_boudary_intersection;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
} //namespace CGAL
|
} //namespace CGAL
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -8,14 +8,16 @@
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
//
|
//
|
||||||
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||||
|
// Efi Fogel <efifogel@gmail.com>
|
||||||
|
|
||||||
#ifndef CGAL_GPS_MERGE_H
|
#ifndef CGAL_GPS_MERGE_H
|
||||||
#define CGAL_GPS_MERGE_H
|
#define CGAL_GPS_MERGE_H
|
||||||
|
|
||||||
#include <CGAL/license/Boolean_set_operations_2.h>
|
#include <CGAL/license/Boolean_set_operations_2.h>
|
||||||
|
|
||||||
|
|
||||||
#include <CGAL/Boolean_set_operations_2/Gps_agg_op.h>
|
#include <CGAL/Boolean_set_operations_2/Gps_agg_op.h>
|
||||||
|
#include <CGAL/Boolean_set_operations_2/Gps_agg_op_visitor.h>
|
||||||
|
#include <CGAL/Boolean_set_operations_2/Gps_do_intersect_agg_op_visitor.h>
|
||||||
#include <CGAL/Boolean_set_operations_2/Gps_bfs_join_visitor.h>
|
#include <CGAL/Boolean_set_operations_2/Gps_bfs_join_visitor.h>
|
||||||
#include <CGAL/Boolean_set_operations_2/Gps_bfs_xor_visitor.h>
|
#include <CGAL/Boolean_set_operations_2/Gps_bfs_xor_visitor.h>
|
||||||
#include <CGAL/Boolean_set_operations_2/Gps_bfs_intersection_visitor.h>
|
#include <CGAL/Boolean_set_operations_2/Gps_bfs_intersection_visitor.h>
|
||||||
|
|
@ -23,50 +25,40 @@
|
||||||
|
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
|
|
||||||
/*!
|
/*! \file Gps_merge.h
|
||||||
\file Gps_merge.h
|
*
|
||||||
\brief This file contains classes that are responsible for merging
|
* This file contains classes that are responsible for merging two sets of
|
||||||
two sets of polygons in the divide-and-conquer algorithm.
|
* polygons in the divide-and-conquer algorithm. The file contains 3 mergers:
|
||||||
The file contains 3 mergers: Join_merge, Intersection_merge and
|
* Join_merge, Intersection_merge and Xor_merge. Join_merge is used when we want
|
||||||
Xor_merge. Join_merge is used when we want to merge the two sets,
|
* to merge the two sets, Intersection_merge is used for intersection, and
|
||||||
Intersection_merge is used for intersection, and Xor_merge is used
|
* Xor_merge is used for symmetric difference.
|
||||||
for symmetric difference.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//! Base_merge
|
/*! Base_merge
|
||||||
/*! Base_merge is the base class for all merger classes.
|
* Base_merge is the base class for all merger classes.
|
||||||
All merges used BFS algorithm with a different visitor when discovering
|
* All merges used BFS algorithm with a different visitor when discovering
|
||||||
a new face.
|
* a new face.
|
||||||
*/
|
*/
|
||||||
template <class Arrangement_, class Visitor_>
|
template <typename Arrangement_, typename Visitor_>
|
||||||
class Base_merge
|
class Base_merge {
|
||||||
{
|
using Arrangement_2 = Arrangement_;
|
||||||
typedef Arrangement_ Arrangement_2;
|
using Visitor = Visitor_;
|
||||||
typedef Visitor_ Visitor;
|
using Vertex_handle = typename Arrangement_2::Vertex_handle;
|
||||||
typedef typename Arrangement_2::Vertex_handle Vertex_handle;
|
using Arr_entry = std::pair<Arrangement_2*, std::vector<Vertex_handle>*>;
|
||||||
typedef std::pair<Arrangement_2 *,
|
|
||||||
std::vector<Vertex_handle> *> Arr_entry;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void operator()(unsigned int i,
|
void operator()(std::size_t i, std::size_t j, std::size_t jump, std::vector<Arr_entry>& arr_vec) {
|
||||||
unsigned int j,
|
if (i == j) return;
|
||||||
unsigned int jump,
|
|
||||||
std::vector<Arr_entry>& arr_vec)
|
|
||||||
{
|
|
||||||
if(i==j)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const typename Arrangement_2::Geometry_traits_2 * tr =
|
const auto* tr = arr_vec[i].first->geometry_traits();
|
||||||
arr_vec[i].first->geometry_traits();
|
|
||||||
Arrangement_2* res = new Arrangement_2(tr);
|
Arrangement_2* res = new Arrangement_2(tr);
|
||||||
std::vector<Vertex_handle>* verts = new std::vector<Vertex_handle>;
|
std::vector<Vertex_handle>* verts = new std::vector<Vertex_handle>;
|
||||||
|
|
||||||
Gps_agg_op<Arrangement_2, Visitor>
|
using Agg_op = Gps_agg_op<Arrangement_2, Visitor, Gps_agg_op_visitor>;
|
||||||
agg_op(*res, *verts, *(res->traits_adaptor()));
|
Agg_op agg_op(*res, *verts, *(res->traits_adaptor()));
|
||||||
agg_op.sweep_arrangements(i, j, jump, arr_vec);
|
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].first);
|
||||||
delete (arr_vec[count].second);
|
delete (arr_vec[count].second);
|
||||||
}
|
}
|
||||||
|
|
@ -74,38 +66,92 @@ public:
|
||||||
arr_vec[i].first = res;
|
arr_vec[i].first = res;
|
||||||
arr_vec[i].second = verts;
|
arr_vec[i].second = verts;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Join_merge
|
/*! Base_intercepted_merge
|
||||||
/*! Join_merge is used to join two sets of polygons together in the D&C
|
* Base_intercepted_merge is the base class for all merger classes that can be
|
||||||
algorithm. It is a base merge with a visitor that joins faces.
|
* interceted (e.g., when an intersection is detected). All merges used BFS
|
||||||
|
* algorithm with a different visitor when discovering a new face.
|
||||||
*/
|
*/
|
||||||
template <class Arrangement_>
|
template <typename Arrangement_, typename Visitor_>
|
||||||
class Join_merge : public Base_merge<Arrangement_,
|
class Base_intercepted_merge {
|
||||||
Gps_bfs_join_visitor<Arrangement_> >
|
using Arrangement_2 = Arrangement_;
|
||||||
{};
|
using Visitor = Visitor_;
|
||||||
|
using Vertex_handle = typename Arrangement_2::Vertex_handle;
|
||||||
|
using Arr_entry = std::pair<Arrangement_2*, std::vector<Vertex_handle>*>;
|
||||||
|
|
||||||
|
public:
|
||||||
|
template <typename InputIterator>
|
||||||
|
bool operator()(InputIterator begin, InputIterator end) {
|
||||||
|
CGAL_assertion(begin != end);
|
||||||
|
|
||||||
//! Intersection_merge
|
const auto* tr = begin->first->geometry_traits();
|
||||||
/*! Intersection_merge is used to merge two sets of polygons creating their
|
Arrangement_2* arr = new Arrangement_2(tr);
|
||||||
intersection.
|
std::vector<Vertex_handle>* verts = new std::vector<Vertex_handle>;
|
||||||
*/
|
|
||||||
template <class Arrangement_>
|
|
||||||
class Intersection_merge : public Base_merge<Arrangement_,
|
|
||||||
Gps_bfs_intersection_visitor<Arrangement_> >
|
|
||||||
{};
|
|
||||||
|
|
||||||
//! Xor_merge
|
using Agg_op = Gps_agg_op<Arrangement_2, Visitor, Gps_do_intersect_agg_op_visitor>;
|
||||||
/*! Xor_merge is used to merge two sets of polygons creating their
|
Agg_op agg_op(*arr, *verts, *(arr->traits_adaptor()));
|
||||||
symmetric difference.
|
auto res = agg_op.sweep_intercept_arrangements2(begin, end);
|
||||||
*/
|
|
||||||
template <class Arrangement_>
|
begin->first = arr;
|
||||||
class Xor_merge : public Base_merge<Arrangement_,
|
begin->second = verts;
|
||||||
Gps_bfs_xor_visitor<Arrangement_> >
|
|
||||||
{
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator()(std::size_t i, std::size_t j, std::size_t jump, std::vector<Arr_entry>& 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<Vertex_handle>* verts = new std::vector<Vertex_handle>;
|
||||||
|
|
||||||
|
using Agg_op = Gps_agg_op<Arrangement_2, Visitor, Gps_do_intersect_agg_op_visitor>;
|
||||||
|
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 <typename Arrangement_>
|
||||||
|
class Join_merge : public Base_merge<Arrangement_, Gps_bfs_join_visitor<Arrangement_>>{};
|
||||||
|
|
||||||
|
/*! Intersection_merge
|
||||||
|
* Intersection_merge is used to merge two sets of polygons creating their
|
||||||
|
* intersection.
|
||||||
|
*/
|
||||||
|
template <typename Arrangement_>
|
||||||
|
class Intersection_merge : public Base_merge<Arrangement_, Gps_bfs_intersection_visitor<Arrangement_>>{};
|
||||||
|
|
||||||
|
/*! 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 <typename Arrangement_>
|
||||||
|
class Do_intersect_merge : public Base_intercepted_merge<Arrangement_, Gps_bfs_intersection_visitor<Arrangement_>>{};
|
||||||
|
|
||||||
|
/*! Xor_merge
|
||||||
|
* Xor_merge is used to merge two sets of polygons creating their
|
||||||
|
* symmetric difference.
|
||||||
|
*/
|
||||||
|
template <typename Arrangement_>
|
||||||
|
class Xor_merge : public Base_merge<Arrangement_, Gps_bfs_xor_visitor<Arrangement_>>{};
|
||||||
|
|
||||||
} //namespace CGAL
|
} //namespace CGAL
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -7,11 +7,10 @@
|
||||||
// $Id$
|
// $Id$
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
//
|
//
|
||||||
//
|
|
||||||
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||||
|
|
||||||
#ifndef CGAL_BSO_2_GPS_POLYGON_SIMPILFIER_H
|
#ifndef CGAL_GPS_POLYGON_SIMPILFIER_H
|
||||||
#define CGAL_BSO_2_GPS_POLYGON_SIMPILFIER_H
|
#define CGAL_GPS_POLYGON_SIMPILFIER_H
|
||||||
|
|
||||||
#include <CGAL/license/Boolean_set_operations_2.h>
|
#include <CGAL/license/Boolean_set_operations_2.h>
|
||||||
|
|
||||||
|
|
@ -31,34 +30,33 @@ namespace Ss2 = Surface_sweep_2;
|
||||||
|
|
||||||
template <typename Arrangement_>
|
template <typename Arrangement_>
|
||||||
class Gps_polygon_simplifier {
|
class Gps_polygon_simplifier {
|
||||||
typedef Arrangement_ Arrangement_2;
|
using Arrangement_2 = Arrangement_;
|
||||||
|
|
||||||
typedef typename Arrangement_2::Geometry_traits_2 Geometry_traits_2;
|
using Geometry_traits_2 = typename Arrangement_2::Geometry_traits_2;
|
||||||
typedef typename Arrangement_2::Topology_traits Topology_traits;
|
using Topology_traits = typename Arrangement_2::Topology_traits;
|
||||||
|
|
||||||
typedef Arrangement_2 Arr;
|
using Arr = Arrangement_2;
|
||||||
typedef Geometry_traits_2 Gt2;
|
using Gt2 = Geometry_traits_2;
|
||||||
typedef Topology_traits Tt;
|
using Tt = Topology_traits;
|
||||||
|
|
||||||
typedef typename Gt2::Curve_const_iterator Curve_const_iterator;
|
using Curve_const_iterator = typename Gt2::Curve_const_iterator;
|
||||||
typedef typename Gt2::Polygon_2 Polygon_2;
|
using Polygon_2 = typename Gt2::Polygon_2;
|
||||||
typedef typename Gt2::Polygon_with_holes_2 Polygon_with_holes_2;
|
using Polygon_with_holes_2 = typename Gt2::Polygon_with_holes_2;
|
||||||
typedef typename Gt2::Construct_curves_2 Construct_curves_2;
|
using Construct_curves_2 = typename Gt2::Construct_curves_2;
|
||||||
|
|
||||||
typedef Gps_simplifier_traits<Gt2> Mgt2;
|
using Mgt2 = Gps_simplifier_traits<Gt2>;
|
||||||
typedef typename Mgt2::Curve_data Curve_data;
|
using Curve_data = typename Mgt2::Curve_data;
|
||||||
typedef typename Mgt2::X_monotone_curve_2 Meta_X_monotone_curve_2;
|
using Meta_X_monotone_curve_2 = typename Mgt2::X_monotone_curve_2;
|
||||||
|
|
||||||
typedef typename Arr::Halfedge_handle Halfedge_handle;
|
using Halfedge_handle = typename Arr::Halfedge_handle;
|
||||||
typedef typename Arr::Halfedge_iterator Halfedge_iterator;
|
using Halfedge_iterator = typename Arr::Halfedge_iterator;
|
||||||
typedef typename Arr::Face_handle Face_handle;
|
using Face_handle = typename Arr::Face_handle;
|
||||||
typedef typename Arr::Face_iterator Face_iterator;
|
using Face_iterator = typename Arr::Face_iterator;
|
||||||
typedef typename Arr::Edge_iterator Edge_iterator;
|
using Edge_iterator = typename Arr::Edge_iterator;
|
||||||
typedef typename Arr::Vertex_handle Vertex_handle;
|
using Vertex_handle = typename Arr::Vertex_handle;
|
||||||
typedef typename Arr::Ccb_halfedge_const_circulator
|
using Ccb_halfedge_const_circulator = typename Arr::Ccb_halfedge_const_circulator;
|
||||||
Ccb_halfedge_const_circulator;
|
using Ccb_halfedge_circulator = typename Arr::Ccb_halfedge_circulator;
|
||||||
typedef typename Arr::Ccb_halfedge_circulator Ccb_halfedge_circulator;
|
using Allocator = typename Arr::Allocator;
|
||||||
typedef typename Arr::Allocator Allocator;
|
|
||||||
|
|
||||||
// We obtain a proper helper type from the topology traits of the arrangement.
|
// We obtain a proper helper type from the topology traits of the arrangement.
|
||||||
// However, the arrangement is parametrized with the Gt2 geometry traits,
|
// 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
|
// We cannot parameterized the arrangement with the Mgt2 geometry
|
||||||
// traits to start with, because it extends the curve type with arrangement
|
// traits to start with, because it extends the curve type with arrangement
|
||||||
// dependent types. (It is parameterized with the arrangement type.)
|
// dependent types. (It is parameterized with the arrangement type.)
|
||||||
typedef Indexed_event<Mgt2, Arr, Allocator> Event;
|
using Event = Indexed_event<Mgt2, Arr, Allocator>;
|
||||||
typedef Arr_construction_subcurve<Mgt2, Event, Allocator>
|
using Subcurve = Arr_construction_subcurve<Mgt2, Event, Allocator>;
|
||||||
Subcurve;
|
using Helper_tmp = typename Tt::template Construction_helper<Event, Subcurve>;
|
||||||
typedef typename Tt::template Construction_helper<Event, Subcurve>
|
using Helper = typename Helper_tmp::template rebind<Mgt2, Arr, Event, Subcurve>::other;
|
||||||
Helper_tmp;
|
using Visitor = Gps_agg_op_base_visitor<Helper, Arr>;
|
||||||
typedef typename Helper_tmp::template rebind<Mgt2, Arr, Event, Subcurve>::other
|
using Surface_sweep_2 = Ss2::Surface_sweep_2<Visitor>;
|
||||||
Helper;
|
|
||||||
typedef Gps_agg_op_base_visitor<Helper, Arr> Visitor;
|
|
||||||
typedef Ss2::Surface_sweep_2<Visitor> Surface_sweep_2;
|
|
||||||
|
|
||||||
typedef Unique_hash_map<Halfedge_handle, unsigned int>
|
using Edges_hash = Unique_hash_map<Halfedge_handle, std::size_t>;
|
||||||
Edges_hash;
|
|
||||||
|
|
||||||
typedef Unique_hash_map<Face_handle, unsigned int> Faces_hash;
|
using Faces_hash = Unique_hash_map<Face_handle, std::size_t>;
|
||||||
typedef Gps_bfs_join_visitor<Arr> Bfs_visitor;
|
using Bfs_visitor = Gps_bfs_join_visitor<Arr>;
|
||||||
typedef Gps_bfs_scanner<Arr, Bfs_visitor> Bfs_scanner;
|
using Bfs_scanner = Gps_bfs_scanner<Arr, Bfs_visitor>;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Arr* m_arr;
|
Arr* m_arr;
|
||||||
|
|
@ -104,16 +98,14 @@ public:
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/*! Destructor. */
|
/*! Destructor. */
|
||||||
~Gps_polygon_simplifier()
|
~Gps_polygon_simplifier() {
|
||||||
{
|
|
||||||
if (m_own_traits && (m_traits != nullptr)) {
|
if (m_own_traits && (m_traits != nullptr)) {
|
||||||
delete m_traits;
|
delete m_traits;
|
||||||
m_traits = nullptr;
|
m_traits = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void simplify(const Polygon_2& pgn)
|
void simplify(const Polygon_2& pgn) {
|
||||||
{
|
|
||||||
Construct_curves_2 ctr_curves =
|
Construct_curves_2 ctr_curves =
|
||||||
reinterpret_cast<const Gt2*>(m_traits)->construct_curves_2_object();
|
reinterpret_cast<const Gt2*>(m_traits)->construct_curves_2_object();
|
||||||
|
|
||||||
|
|
@ -122,14 +114,13 @@ public:
|
||||||
std::pair<Curve_const_iterator, Curve_const_iterator> itr_pair =
|
std::pair<Curve_const_iterator, Curve_const_iterator> itr_pair =
|
||||||
ctr_curves(pgn);
|
ctr_curves(pgn);
|
||||||
|
|
||||||
unsigned int index = 0;
|
std::size_t index = 0;
|
||||||
for (Curve_const_iterator itr = itr_pair.first; itr != itr_pair.second;
|
for (Curve_const_iterator itr = itr_pair.first; itr != itr_pair.second;
|
||||||
++itr, ++index)
|
++itr, ++index) {
|
||||||
{
|
|
||||||
Curve_data cv_data(1, 0, index);
|
Curve_data cv_data(1, 0, index);
|
||||||
curves_list.push_back(Meta_X_monotone_curve_2(*itr, cv_data));
|
curves_list.push_back(Meta_X_monotone_curve_2(*itr, cv_data));
|
||||||
}
|
}
|
||||||
m_traits->set_polygon_size(static_cast<unsigned int>(curves_list.size()));
|
m_traits->set_polygon_size(curves_list.size());
|
||||||
|
|
||||||
m_surface_sweep.sweep(curves_list.begin(), curves_list.end());
|
m_surface_sweep.sweep(curves_list.begin(), curves_list.end());
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,14 +7,13 @@
|
||||||
// $Id$
|
// $Id$
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
//
|
//
|
||||||
//
|
|
||||||
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||||
// Ron Wein <wein@post.tau.ac.il>
|
// Ron Wein <wein@post.tau.ac.il>
|
||||||
// Boris Kozorovitzky <boriskoz@post.tau.ac.il>
|
// Boris Kozorovitzky <boriskoz@post.tau.ac.il>
|
||||||
// Guy Zucker <guyzucke@post.tau.ac.il>
|
// Guy Zucker <guyzucke@post.tau.ac.il>
|
||||||
|
|
||||||
#ifndef CGAL_BSO_2_GPS_POLYGON_VALIDATION_2_H
|
#ifndef CGAL_GPS_POLYGON_VALIDATION_2_H
|
||||||
#define CGAL_BSO_2_GPS_POLYGON_VALIDATION_2_H
|
#define CGAL_GPS_POLYGON_VALIDATION_2_H
|
||||||
|
|
||||||
#include <CGAL/license/Boolean_set_operations_2.h>
|
#include <CGAL/license/Boolean_set_operations_2.h>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@
|
||||||
// $Id$
|
// $Id$
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
//
|
//
|
||||||
//
|
|
||||||
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||||
// Efi Fogel <efifogel@gmail.com>
|
// Efi Fogel <efifogel@gmail.com>
|
||||||
|
|
||||||
|
|
@ -23,97 +22,94 @@ namespace CGAL {
|
||||||
|
|
||||||
class Gps_simplifier_curve_data {
|
class Gps_simplifier_curve_data {
|
||||||
protected:
|
protected:
|
||||||
unsigned int m_bc;
|
std::size_t m_bc;
|
||||||
unsigned int m_twin_bc;
|
std::size_t m_twin_bc;
|
||||||
unsigned int m_index;
|
std::size_t m_index;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Gps_simplifier_curve_data() {}
|
Gps_simplifier_curve_data() {}
|
||||||
|
|
||||||
Gps_simplifier_curve_data(unsigned int bc, unsigned int twin_bc,
|
Gps_simplifier_curve_data(std::size_t bc, std::size_t twin_bc,
|
||||||
unsigned int index):
|
std::size_t index):
|
||||||
m_bc(bc),
|
m_bc(bc),
|
||||||
m_twin_bc(twin_bc),
|
m_twin_bc(twin_bc),
|
||||||
m_index(index)
|
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 {
|
struct Gps_simplifier_point_data {
|
||||||
protected:
|
protected:
|
||||||
unsigned int m_index;
|
std::size_t m_index;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Gps_simplifier_point_data() {}
|
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 <typename Traits_>
|
template <typename Traits_>
|
||||||
class Gps_simplifier_traits :
|
class Gps_simplifier_traits :
|
||||||
public Gps_traits_decorator<Traits_,
|
public Gps_traits_decorator<Traits_,
|
||||||
Gps_simplifier_curve_data,
|
Gps_simplifier_curve_data,
|
||||||
Gps_simplifier_point_data>
|
Gps_simplifier_point_data> {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
typedef Traits_ Traits;
|
using Traits = Traits_;
|
||||||
typedef Gps_traits_decorator<Traits_,
|
using Base = Gps_traits_decorator<Traits_, Gps_simplifier_curve_data, Gps_simplifier_point_data>;
|
||||||
Gps_simplifier_curve_data,
|
using Self = Gps_simplifier_traits<Traits>;
|
||||||
Gps_simplifier_point_data> Base;
|
using Base_x_monotone_curve_2 = typename Traits::X_monotone_curve_2;
|
||||||
typedef Gps_simplifier_traits<Traits> Self;
|
using Base_point_2 = typename Traits::Point_2;
|
||||||
typedef typename Traits::X_monotone_curve_2 Base_x_monotone_curve_2;
|
using Base_Construct_min_vertex_2 = typename Traits::Construct_min_vertex_2;
|
||||||
typedef typename Traits::Point_2 Base_point_2;
|
using Base_Construct_max_vertex_2 = typename Traits::Construct_max_vertex_2;
|
||||||
typedef typename Traits::Construct_min_vertex_2 Base_Construct_min_vertex_2;
|
using Base_Compare_endpoints_xy_2 = typename Traits::Compare_endpoints_xy_2;
|
||||||
typedef typename Traits::Construct_max_vertex_2 Base_Construct_max_vertex_2;
|
using Base_Compare_xy_2 = typename Traits::Compare_xy_2;
|
||||||
typedef typename Traits::Compare_endpoints_xy_2 Base_Compare_endpoints_xy_2;
|
using Base_Compare_y_at_x_right_2 = typename Traits::Compare_y_at_x_right_2;
|
||||||
typedef typename Traits::Compare_xy_2 Base_Compare_xy_2;
|
using Base_Compare_y_at_x_2 = typename Traits::Compare_y_at_x_2;
|
||||||
typedef typename Traits::Compare_y_at_x_right_2 Base_Compare_y_at_x_right_2;
|
using Base_Intersect_2 = typename Traits::Intersect_2;
|
||||||
typedef typename Traits::Compare_y_at_x_2 Base_Compare_y_at_x_2;
|
using Base_Split_2 = typename Traits::Split_2;
|
||||||
typedef typename Traits::Intersect_2 Base_Intersect_2;
|
|
||||||
typedef typename Traits::Split_2 Base_Split_2;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
mutable unsigned int m_pgn_size;
|
mutable std::size_t m_pgn_size;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef typename Base::X_monotone_curve_2 X_monotone_curve_2;
|
using X_monotone_curve_2 = typename Base::X_monotone_curve_2;
|
||||||
typedef typename Base::Point_2 Point_2;
|
using Point_2 = typename Base::Point_2;
|
||||||
typedef typename Base::Multiplicity Multiplicity;
|
using Multiplicity = typename Base::Multiplicity;
|
||||||
|
|
||||||
typedef typename Base::Curve_data Curve_data;
|
using Curve_data = typename Base::Curve_data;
|
||||||
typedef typename Base::Point_data Point_data;
|
using Point_data = typename Base::Point_data;
|
||||||
|
|
||||||
Gps_simplifier_traits() {}
|
Gps_simplifier_traits() {}
|
||||||
|
|
||||||
Gps_simplifier_traits(const Traits& tr) : Base(tr) {}
|
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); }
|
{ 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 {
|
class Intersect_2 {
|
||||||
private:
|
private:
|
||||||
|
|
@ -129,12 +125,9 @@ public:
|
||||||
template <typename OutputIterator>
|
template <typename OutputIterator>
|
||||||
OutputIterator operator()(const X_monotone_curve_2& cv1,
|
OutputIterator operator()(const X_monotone_curve_2& cv1,
|
||||||
const X_monotone_curve_2& cv2,
|
const X_monotone_curve_2& cv2,
|
||||||
OutputIterator oi) const
|
OutputIterator oi) const {
|
||||||
{
|
using Intersection_base_point = const std::pair<Base_point_2, Multiplicity>;
|
||||||
typedef const std::pair<Base_point_2, Multiplicity>
|
using Intersection_base_result = std::variant<Intersection_base_point, Base_x_monotone_curve_2>;
|
||||||
Intersection_base_point;
|
|
||||||
typedef std::variant<Intersection_base_point, Base_x_monotone_curve_2>
|
|
||||||
Intersection_base_result;
|
|
||||||
|
|
||||||
const auto* base_traits = m_traits.m_base_traits;
|
const auto* base_traits = m_traits.m_base_traits;
|
||||||
auto base_cmp_xy = base_traits->compare_xy_2_object();
|
auto base_cmp_xy = base_traits->compare_xy_2_object();
|
||||||
|
|
@ -146,7 +139,7 @@ public:
|
||||||
//if (m_traits.is_valid_index(cv1.data().index()) &&
|
//if (m_traits.is_valid_index(cv1.data().index()) &&
|
||||||
// m_traits.is_valid_index(cv2.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()) ?
|
||||||
// (cv1.data().index() - cv2.data().index()):
|
// (cv1.data().index() - cv2.data().index()):
|
||||||
// (cv2.data().index() - cv1.data().index());
|
// (cv2.data().index() - cv1.data().index());
|
||||||
|
|
@ -180,8 +173,8 @@ public:
|
||||||
std::get_if<Base_x_monotone_curve_2>(&xection);
|
std::get_if<Base_x_monotone_curve_2>(&xection);
|
||||||
|
|
||||||
CGAL_assertion(overlap_cv != nullptr);
|
CGAL_assertion(overlap_cv != nullptr);
|
||||||
unsigned int ov_bc;
|
std::size_t ov_bc;
|
||||||
unsigned int ov_twin_bc;
|
std::size_t ov_twin_bc;
|
||||||
if (base_cmp_endpoints(cv1) == base_cmp_endpoints(cv2)) {
|
if (base_cmp_endpoints(cv1) == base_cmp_endpoints(cv2)) {
|
||||||
// cv1 and cv2 have the same directions
|
// cv1 and cv2 have the same directions
|
||||||
ov_bc = cv1.data().bc() + cv2.data().bc();
|
ov_bc = cv1.data().bc() + cv2.data().bc();
|
||||||
|
|
@ -220,8 +213,7 @@ public:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void operator()(const X_monotone_curve_2& cv, const Point_2 & p,
|
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;
|
const auto* base_traits = m_traits.m_base_traits;
|
||||||
auto base_split = base_traits->split_2_object();
|
auto base_split = base_traits->split_2_object();
|
||||||
base_split(cv.base(), p.base(), c1.base(), c2.base());
|
base_split(cv.base(), p.base(), c1.base(), c2.base());
|
||||||
|
|
@ -250,8 +242,7 @@ public:
|
||||||
* \param cv The curve.
|
* \param cv The curve.
|
||||||
* \return The left endpoint.
|
* \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;
|
const auto* base_traits = m_traits.m_base_traits;
|
||||||
auto base_ctr_min_vertex = base_traits->construct_min_vertex_2_object();
|
auto base_ctr_min_vertex = base_traits->construct_min_vertex_2_object();
|
||||||
|
|
||||||
|
|
@ -290,8 +281,7 @@ public:
|
||||||
* \param cv The curve.
|
* \param cv The curve.
|
||||||
* \return The left endpoint.
|
* \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;
|
const auto* base_traits = m_traits.m_base_traits;
|
||||||
auto base_ctr_max_vertex = base_traits->construct_max_vertex_2_object();
|
auto base_ctr_max_vertex = base_traits->construct_max_vertex_2_object();
|
||||||
if (! m_traits.is_valid_index(cv.data().index()))
|
if (! m_traits.is_valid_index(cv.data().index()))
|
||||||
|
|
@ -329,8 +319,7 @@ public:
|
||||||
* \param cv The curve.
|
* \param cv The curve.
|
||||||
* \return The left endpoint.
|
* \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;
|
const auto* base_traits = m_traits.m_base_traits;
|
||||||
auto base_cmp_xy = base_traits->compare_xy_2_object();
|
auto base_cmp_xy = base_traits->compare_xy_2_object();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,8 @@
|
||||||
// Ron Wein <wein@post.tau.ac.il>
|
// Ron Wein <wein@post.tau.ac.il>
|
||||||
// Efi Fogel <efifogel@gmail.com>
|
// Efi Fogel <efifogel@gmail.com>
|
||||||
|
|
||||||
#ifndef CGAL_BSO_2_INDEXED_VISITOR_H
|
#ifndef CGAL_INDEXED_VISITOR_H
|
||||||
#define CGAL_BSO_2_INDEXED_VISITOR_H
|
#define CGAL_INDEXED_VISITOR_H
|
||||||
|
|
||||||
#include <CGAL/license/Boolean_set_operations_2.h>
|
#include <CGAL/license/Boolean_set_operations_2.h>
|
||||||
|
|
||||||
|
|
@ -32,17 +32,16 @@ class Indexed_event :
|
||||||
Arrangement_,
|
Arrangement_,
|
||||||
Allocator_>,
|
Allocator_>,
|
||||||
Allocator_>,
|
Allocator_>,
|
||||||
Arrangement_>
|
Arrangement_> {
|
||||||
{
|
|
||||||
private:
|
private:
|
||||||
unsigned int m_index;
|
std::size_t m_index;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Indexed_event() : m_index (0) {}
|
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
|
} // namespace CGAL
|
||||||
|
|
|
||||||
|
|
@ -31,9 +31,9 @@ namespace CGAL {
|
||||||
// Utility struct
|
// Utility struct
|
||||||
template <typename Polygon>
|
template <typename Polygon>
|
||||||
struct Gps_polyline_traits {
|
struct Gps_polyline_traits {
|
||||||
typedef typename Gps_default_traits<Polygon>::Arr_traits Segment_traits;
|
using Segment_traits = typename Gps_default_traits<Polygon>::Arr_traits;
|
||||||
typedef Arr_polyline_traits_2<Segment_traits> Polyline_traits;
|
using Polyline_traits = Arr_polyline_traits_2<Segment_traits>;
|
||||||
typedef Gps_traits_2<Polyline_traits> Traits;
|
using Traits = Gps_traits_2<Polyline_traits>;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Helper to map Polygon_2 -> General_polygon_2 / PWH_2 -> General_PWH_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<Polyline_traits>
|
// Convert Polygon_2 to General_polygon_2<Polyline_traits>
|
||||||
template <typename Kernel, typename Container, typename ArrTraits>
|
template <typename Kernel, typename Container, typename ArrTraits>
|
||||||
General_polygon_2<ArrTraits>
|
General_polygon_2<ArrTraits>
|
||||||
convert_polygon(const Polygon_2<Kernel, Container>& polygon,
|
convert_polygon(const Polygon_2<Kernel, Container>& polygon, const ArrTraits& traits) {
|
||||||
const ArrTraits& traits)
|
|
||||||
{
|
|
||||||
auto ctr = traits.construct_curve_2_object();
|
auto ctr = traits.construct_curve_2_object();
|
||||||
if (polygon.is_empty()) return General_polygon_2<ArrTraits>();
|
if (polygon.is_empty()) return General_polygon_2<ArrTraits>();
|
||||||
using Point = typename ArrTraits::Point_2;
|
using Point = typename ArrTraits::Point_2;
|
||||||
|
|
@ -99,8 +97,7 @@ convert_polygon(const Polygon_2<Kernel, Container>& polygon,
|
||||||
General_polygon_2<ArrTraits> gpgn;
|
General_polygon_2<ArrTraits> gpgn;
|
||||||
auto make_x_mtn = traits.make_x_monotone_2_object();
|
auto make_x_mtn = traits.make_x_monotone_2_object();
|
||||||
make_x_mtn(cv,
|
make_x_mtn(cv,
|
||||||
boost::make_function_output_iterator
|
boost::make_function_output_iterator([&](const Make_x_monotone_result& obj)
|
||||||
([&](const Make_x_monotone_result& obj)
|
|
||||||
{ gpgn.push_back(*(std::get_if<X_monotone_curve>(&obj))); }));
|
{ gpgn.push_back(*(std::get_if<X_monotone_curve>(&obj))); }));
|
||||||
return gpgn;
|
return gpgn;
|
||||||
}
|
}
|
||||||
|
|
@ -110,11 +107,10 @@ convert_polygon(const Polygon_2<Kernel, Container>& polygon,
|
||||||
General_polygon_with_holes_2<General_polygon_2<ArrTraits>>
|
General_polygon_with_holes_2<General_polygon_2<ArrTraits>>
|
||||||
convert_polygon(const Polygon_with_holes_2<Kernel, Container>& pwh,
|
convert_polygon(const Polygon_with_holes_2<Kernel, Container>& pwh,
|
||||||
const ArrTraits& traits) {
|
const ArrTraits& traits) {
|
||||||
typedef General_polygon_2<ArrTraits> General_pgn;
|
using General_pgn = General_polygon_2<ArrTraits>;
|
||||||
typedef Polygon_2<Kernel, Container> Pgn;
|
using Pgn = Polygon_2<Kernel, Container>;
|
||||||
auto converter = [&](const Pgn& pgn)->General_pgn {
|
auto converter = [&](const Pgn& pgn)->General_pgn
|
||||||
return convert_polygon(pgn, traits);
|
{ return convert_polygon(pgn, traits); };
|
||||||
};
|
|
||||||
return General_polygon_with_holes_2<General_polygon_2<ArrTraits>>
|
return General_polygon_with_holes_2<General_polygon_2<ArrTraits>>
|
||||||
(convert_polygon(pwh.outer_boundary(), traits),
|
(convert_polygon(pwh.outer_boundary(), traits),
|
||||||
boost::make_transform_iterator(pwh.holes().begin(), converter),
|
boost::make_transform_iterator(pwh.holes().begin(), converter),
|
||||||
|
|
@ -137,14 +133,11 @@ convert_polygon_back(const General_polygon_2<ArrTraits>& gpgn) {
|
||||||
// Convert General_polygon_with_holes_2<Polyline_traits> to Polygon_with_holes_2
|
// Convert General_polygon_with_holes_2<Polyline_traits> to Polygon_with_holes_2
|
||||||
template <typename Kernel, typename Container, typename ArrTraits>
|
template <typename Kernel, typename Container, typename ArrTraits>
|
||||||
Polygon_with_holes_2<Kernel, Container>
|
Polygon_with_holes_2<Kernel, Container>
|
||||||
convert_polygon_back(const General_polygon_with_holes_2
|
convert_polygon_back(const General_polygon_with_holes_2<General_polygon_2<ArrTraits>>& gpwh) {
|
||||||
<General_polygon_2<ArrTraits> >& gpwh)
|
|
||||||
{
|
|
||||||
using Pgn = Polygon_2<Kernel, Container>;
|
using Pgn = Polygon_2<Kernel, Container>;
|
||||||
using General_pgn = General_polygon_2<ArrTraits>;
|
using General_pgn = General_polygon_2<ArrTraits>;
|
||||||
auto converter = [](const General_pgn& gpgn)->Pgn {
|
auto converter = [](const General_pgn& gpgn)->Pgn
|
||||||
return convert_polygon_back<Kernel, Container>(gpgn);
|
{ return convert_polygon_back<Kernel, Container>(gpgn); };
|
||||||
};
|
|
||||||
return Polygon_with_holes_2<Kernel, Container>
|
return Polygon_with_holes_2<Kernel, Container>
|
||||||
(convert_polygon_back<Kernel, Container>(gpwh.outer_boundary()),
|
(convert_polygon_back<Kernel, Container>(gpwh.outer_boundary()),
|
||||||
boost::make_transform_iterator(gpwh.holes().begin(), converter),
|
boost::make_transform_iterator(gpwh.holes().begin(), converter),
|
||||||
|
|
@ -155,20 +148,16 @@ convert_polygon_back(const General_polygon_with_holes_2
|
||||||
// Polygon_2 to General_polygon_2<Polyline_traits>, or
|
// Polygon_2 to General_polygon_2<Polyline_traits>, or
|
||||||
// Polygon_with_holes_2 to General_polygon_with_holes_2<Polyline_traits>
|
// Polygon_with_holes_2 to General_polygon_with_holes_2<Polyline_traits>
|
||||||
template <typename InputIterator, typename Traits>
|
template <typename InputIterator, typename Traits>
|
||||||
boost::transform_iterator
|
boost::transform_iterator<std::function<
|
||||||
<std::function
|
typename General_polygon_of_polygon<typename std::iterator_traits<
|
||||||
<typename General_polygon_of_polygon<typename std::iterator_traits
|
InputIterator>::value_type>::type
|
||||||
<InputIterator>::value_type>::type
|
(typename std::iterator_traits<InputIterator>::reference)>, InputIterator>
|
||||||
(typename std::iterator_traits<InputIterator>::reference)>,
|
convert_polygon_iterator(InputIterator it, const Traits& traits) {
|
||||||
InputIterator>
|
|
||||||
convert_polygon_iterator(InputIterator it, const Traits& traits)
|
|
||||||
{
|
|
||||||
using Input_type = typename std::iterator_traits<InputIterator>::value_type;
|
using Input_type = typename std::iterator_traits<InputIterator>::value_type;
|
||||||
using Return_type = typename General_polygon_of_polygon<Input_type>::type;
|
using Return_type = typename General_polygon_of_polygon<Input_type>::type;
|
||||||
using Function_type = std::function<Return_type(Input_type)>;
|
using Function_type = std::function<Return_type(Input_type)>;
|
||||||
|
|
||||||
Function_type func =
|
Function_type func = [&traits](const Input_type& p)->Return_type
|
||||||
[&traits](const Input_type& p)->Return_type
|
|
||||||
{ return convert_polygon(p, traits); };
|
{ return convert_polygon(p, traits); };
|
||||||
|
|
||||||
return boost::transform_iterator<Function_type, InputIterator>(it, func);
|
return boost::transform_iterator<Function_type, InputIterator>(it, func);
|
||||||
|
|
@ -186,8 +175,7 @@ struct Polygon_converter {
|
||||||
|
|
||||||
// Convert and export to output iterator.
|
// Convert and export to output iterator.
|
||||||
template <typename ArrTraits>
|
template <typename ArrTraits>
|
||||||
void operator()(const General_polygon_with_holes_2
|
void operator()(const General_polygon_with_holes_2<General_polygon_2<ArrTraits>>& gpwh) const
|
||||||
<General_polygon_2<ArrTraits> >& gpwh) const
|
|
||||||
{ *m_output++ = convert_polygon_back<Kernel, Container>(gpwh); }
|
{ *m_output++ = convert_polygon_back<Kernel, Container>(gpwh); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -195,9 +183,7 @@ struct Polygon_converter {
|
||||||
// OutputIterator
|
// OutputIterator
|
||||||
template <typename Kernel, typename Container, typename OutputIterator>
|
template <typename Kernel, typename Container, typename OutputIterator>
|
||||||
struct Polygon_converter_output_iterator :
|
struct Polygon_converter_output_iterator :
|
||||||
boost::function_output_iterator<Polygon_converter
|
boost::function_output_iterator<Polygon_converter<Kernel, Container, OutputIterator>> {
|
||||||
<Kernel, Container, OutputIterator> >
|
|
||||||
{
|
|
||||||
using Converter = Polygon_converter<Kernel, Container, OutputIterator>;
|
using Converter = Polygon_converter<Kernel, Container, OutputIterator>;
|
||||||
using Base = boost::function_output_iterator<Converter>;
|
using Base = boost::function_output_iterator<Converter>;
|
||||||
|
|
||||||
|
|
@ -214,11 +200,8 @@ struct Polygon_converter_output_iterator :
|
||||||
// (indirection with Polygon_2)
|
// (indirection with Polygon_2)
|
||||||
template <typename OutputIterator, typename Kernel, typename Container>
|
template <typename OutputIterator, typename Kernel, typename Container>
|
||||||
Polygon_converter_output_iterator<Kernel, Container, OutputIterator>
|
Polygon_converter_output_iterator<Kernel, Container, OutputIterator>
|
||||||
convert_polygon_back(OutputIterator& output,
|
convert_polygon_back(OutputIterator& output, const Polygon_2<Kernel, Container>&) {
|
||||||
const Polygon_2<Kernel, Container>&)
|
return Polygon_converter_output_iterator<Kernel, Container, OutputIterator>(output);
|
||||||
{
|
|
||||||
return Polygon_converter_output_iterator
|
|
||||||
<Kernel, Container, OutputIterator>(output);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Converts General_polygon_with_holes_2<Polyline_traits> to Polygon_with_holes_2
|
// Converts General_polygon_with_holes_2<Polyline_traits> to Polygon_with_holes_2
|
||||||
|
|
@ -226,10 +209,8 @@ convert_polygon_back(OutputIterator& output,
|
||||||
template <typename OutputIterator, typename Kernel, typename Container>
|
template <typename OutputIterator, typename Kernel, typename Container>
|
||||||
Polygon_converter_output_iterator<Kernel, Container, OutputIterator>
|
Polygon_converter_output_iterator<Kernel, Container, OutputIterator>
|
||||||
convert_polygon_back(OutputIterator& output,
|
convert_polygon_back(OutputIterator& output,
|
||||||
const Polygon_with_holes_2<Kernel, Container>&)
|
const Polygon_with_holes_2<Kernel, Container>&) {
|
||||||
{
|
return Polygon_converter_output_iterator<Kernel, Container, OutputIterator>(output);
|
||||||
return Polygon_converter_output_iterator
|
|
||||||
<Kernel, Container, OutputIterator>(output);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename InputIterator>
|
template <typename InputIterator>
|
||||||
|
|
@ -238,7 +219,6 @@ struct Iterator_to_gps_traits {
|
||||||
typedef typename Gps_default_traits<InputPolygon>::Traits Traits;
|
typedef typename Gps_default_traits<InputPolygon>::Traits Traits;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // CGAL_BSO_POLYGON_CONVERSIONS_H
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -33,12 +33,18 @@
|
||||||
#include <CGAL/Boolean_set_operations_2/Polygon_conversions.h>
|
#include <CGAL/Boolean_set_operations_2/Polygon_conversions.h>
|
||||||
#include <CGAL/type_traits/is_iterator.h>
|
#include <CGAL/type_traits/is_iterator.h>
|
||||||
|
|
||||||
namespace CGAL
|
namespace CGAL {
|
||||||
{
|
|
||||||
|
|
||||||
/// \name do_intersect() functions.
|
/// \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 ========================================================
|
// Polygon_2, Polygon_2 ========================================================
|
||||||
// With Traits
|
// With Traits
|
||||||
template <typename Kernel, typename Container, typename Traits>
|
template <typename Kernel, typename Container, typename Traits>
|
||||||
|
|
@ -47,24 +53,24 @@ inline bool do_intersect(const Polygon_2<Kernel, Container>& pgn1,
|
||||||
Traits& traits)
|
Traits& traits)
|
||||||
{ return s_do_intersect(pgn1, pgn2, traits); }
|
{ return s_do_intersect(pgn1, pgn2, traits); }
|
||||||
|
|
||||||
// With Tag_true
|
// without traits
|
||||||
template <typename Kernel, typename Container>
|
template <typename Kernel, typename Container>
|
||||||
inline bool do_intersect(const Polygon_2<Kernel, Container>& pgn1,
|
inline bool do_intersect(const Polygon_2<Kernel, Container>& pgn1,
|
||||||
const Polygon_2<Kernel, Container>& pgn2,
|
const Polygon_2<Kernel, Container>& pgn2) {
|
||||||
Tag_true = Tag_true())
|
using Polygon = Polygon_2<Kernel, Container>;
|
||||||
{ return s_do_intersect(pgn1, pgn2); }
|
|
||||||
|
|
||||||
// With Tag_false
|
|
||||||
template <typename Kernel, typename Container>
|
|
||||||
inline bool do_intersect(const Polygon_2<Kernel, Container>& pgn1,
|
|
||||||
const Polygon_2<Kernel, Container>& pgn2,
|
|
||||||
Tag_false)
|
|
||||||
{
|
|
||||||
typedef Polygon_2<Kernel, Container> Polygon;
|
|
||||||
typename Gps_default_traits<Polygon>::Traits traits;
|
typename Gps_default_traits<Polygon>::Traits traits;
|
||||||
return s_do_intersect(pgn1, pgn2, traits);
|
return s_do_intersect(pgn1, pgn2, traits);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef CGAL_NO_DEPRECATED_CODE
|
||||||
|
template <typename Kernel, typename Container, bool b>
|
||||||
|
inline bool do_intersect(const Polygon_2<Kernel, Container>& pgn1,
|
||||||
|
const Polygon_2<Kernel, Container>& pgn2,
|
||||||
|
std::bool_constant<b>) {
|
||||||
|
return do_intersect(pgn1, pgn2);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Polygon_2, Polygon_with_hole_2 ==============================================
|
// Polygon_2, Polygon_with_hole_2 ==============================================
|
||||||
// With Traits
|
// With Traits
|
||||||
template <typename Kernel, typename Container, typename Traits>
|
template <typename Kernel, typename Container, typename Traits>
|
||||||
|
|
@ -73,25 +79,25 @@ inline bool do_intersect(const Polygon_2<Kernel, Container>& pgn1,
|
||||||
Traits& traits)
|
Traits& traits)
|
||||||
{ return s_do_intersect(pgn1, pgn2, traits); }
|
{ return s_do_intersect(pgn1, pgn2, traits); }
|
||||||
|
|
||||||
// With Tag_true
|
// Without traits
|
||||||
template <typename Kernel, typename Container>
|
template <typename Kernel, typename Container>
|
||||||
inline bool do_intersect(const Polygon_2<Kernel, Container>& pgn1,
|
inline bool do_intersect(const Polygon_2<Kernel, Container>& pgn1,
|
||||||
const Polygon_with_holes_2<Kernel, Container>& pgn2,
|
const Polygon_with_holes_2<Kernel, Container>& pgn2) {
|
||||||
Tag_true = Tag_true())
|
|
||||||
{ return s_do_intersect(pgn1, pgn2); }
|
|
||||||
|
|
||||||
// With Tag_false
|
|
||||||
template <typename Kernel, typename Container>
|
|
||||||
inline bool do_intersect(const Polygon_2<Kernel, Container>& pgn1,
|
|
||||||
const Polygon_with_holes_2<Kernel, Container>& pgn2,
|
|
||||||
Tag_false)
|
|
||||||
{
|
|
||||||
// Use the first polygon to determine the (default) traits
|
// Use the first polygon to determine the (default) traits
|
||||||
typedef Polygon_2<Kernel, Container> Polygon;
|
using Polygon = Polygon_2<Kernel, Container>;
|
||||||
typename Gps_default_traits<Polygon>::Traits traits;
|
typename Gps_default_traits<Polygon>::Traits traits;
|
||||||
return s_do_intersect(pgn1, pgn2, traits);
|
return s_do_intersect(pgn1, pgn2, traits);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef CGAL_NO_DEPRECATED_CODE
|
||||||
|
template <typename Kernel, typename Container, bool b>
|
||||||
|
inline bool do_intersect(const Polygon_2<Kernel, Container>& pgn1,
|
||||||
|
const Polygon_with_holes_2<Kernel, Container>& pgn2,
|
||||||
|
std::bool_constant<b>) {
|
||||||
|
return do_intersect(pgn1, pgn2);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Polygon_with_hole_2, Polygon_2 ==============================================
|
// Polygon_with_hole_2, Polygon_2 ==============================================
|
||||||
// With Traits
|
// With Traits
|
||||||
template <typename Kernel, typename Container, typename Traits>
|
template <typename Kernel, typename Container, typename Traits>
|
||||||
|
|
@ -100,25 +106,25 @@ inline bool do_intersect(const Polygon_with_holes_2<Kernel, Container>& pgn1,
|
||||||
Traits& traits)
|
Traits& traits)
|
||||||
{ return s_do_intersect(pgn1, pgn2, traits); }
|
{ return s_do_intersect(pgn1, pgn2, traits); }
|
||||||
|
|
||||||
// With Tag_true
|
// Without traits
|
||||||
template <typename Kernel, typename Container>
|
template <typename Kernel, typename Container>
|
||||||
inline bool do_intersect(const Polygon_with_holes_2<Kernel, Container>& pgn1,
|
inline bool do_intersect(const Polygon_with_holes_2<Kernel, Container>& pgn1,
|
||||||
const Polygon_2<Kernel, Container>& pgn2,
|
const Polygon_2<Kernel, Container>& pgn2) {
|
||||||
Tag_true = Tag_true())
|
|
||||||
{ return s_do_intersect(pgn1, pgn2); }
|
|
||||||
|
|
||||||
// With Tag_false
|
|
||||||
template <typename Kernel, typename Container>
|
|
||||||
inline bool do_intersect(const Polygon_with_holes_2<Kernel, Container>& pgn1,
|
|
||||||
const Polygon_2<Kernel, Container>& pgn2,
|
|
||||||
Tag_false)
|
|
||||||
{
|
|
||||||
// Use the first polygon to determine the (default) traits
|
// Use the first polygon to determine the (default) traits
|
||||||
typedef Polygon_with_holes_2<Kernel, Container> Polygon_with_holes;
|
using Polygon_with_holes = Polygon_with_holes_2<Kernel, Container>;
|
||||||
typename Gps_default_traits<Polygon_with_holes>::Traits traits;
|
typename Gps_default_traits<Polygon_with_holes>::Traits traits;
|
||||||
return s_do_intersect(pgn1, pgn2, traits);
|
return s_do_intersect(pgn1, pgn2, traits);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef CGAL_NO_DEPRECATED_CODE
|
||||||
|
template <typename Kernel, typename Container, bool b>
|
||||||
|
inline bool do_intersect(const Polygon_with_holes_2<Kernel, Container>& pgn1,
|
||||||
|
const Polygon_2<Kernel, Container>& pgn2,
|
||||||
|
std::bool_constant<b>) {
|
||||||
|
return do_intersect(pgn1, pgn2);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Polygon_with_hole_2, Polygon_with_hole_2 ====================================
|
// Polygon_with_hole_2, Polygon_with_hole_2 ====================================
|
||||||
// With Traits
|
// With Traits
|
||||||
template <typename Kernel, typename Container, typename Traits>
|
template <typename Kernel, typename Container, typename Traits>
|
||||||
|
|
@ -127,25 +133,25 @@ inline bool do_intersect(const Polygon_with_holes_2<Kernel, Container>& pgn1,
|
||||||
Traits& traits)
|
Traits& traits)
|
||||||
{ return s_do_intersect(pgn1, pgn2, traits); }
|
{ return s_do_intersect(pgn1, pgn2, traits); }
|
||||||
|
|
||||||
// With Tag_true
|
// Without traits
|
||||||
template <typename Kernel, typename Container>
|
template <typename Kernel, typename Container>
|
||||||
inline bool do_intersect(const Polygon_with_holes_2<Kernel, Container>& pgn1,
|
inline bool do_intersect(const Polygon_with_holes_2<Kernel, Container>& pgn1,
|
||||||
const Polygon_with_holes_2<Kernel, Container>& pgn2,
|
const Polygon_with_holes_2<Kernel, Container>& pgn2) {
|
||||||
Tag_true = Tag_true())
|
|
||||||
{ return s_do_intersect(pgn1, pgn2); }
|
|
||||||
|
|
||||||
// With Tag_false
|
|
||||||
template <typename Kernel, typename Container>
|
|
||||||
inline bool do_intersect(const Polygon_with_holes_2<Kernel, Container>& pgn1,
|
|
||||||
const Polygon_with_holes_2<Kernel, Container>& pgn2,
|
|
||||||
Tag_false)
|
|
||||||
{
|
|
||||||
// Use the first polygon to determine the (default) traits
|
// Use the first polygon to determine the (default) traits
|
||||||
typedef Polygon_with_holes_2<Kernel, Container> Polygon_with_holes;
|
using Polygon_with_holes = Polygon_with_holes_2<Kernel, Container>;
|
||||||
typename Gps_default_traits<Polygon_with_holes>::Traits traits;
|
typename Gps_default_traits<Polygon_with_holes>::Traits traits;
|
||||||
return s_do_intersect(pgn1, pgn2, traits);
|
return s_do_intersect(pgn1, pgn2, traits);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef CGAL_NO_DEPRECATED_CODE
|
||||||
|
template <typename Kernel, typename Container, bool b>
|
||||||
|
inline bool do_intersect(const Polygon_with_holes_2<Kernel, Container>& pgn1,
|
||||||
|
const Polygon_with_holes_2<Kernel, Container>& pgn2,
|
||||||
|
std::bool_constant<b>) {
|
||||||
|
return do_intersect(pgn1, pgn2);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// General_polygon_2, General_polygon_2 ========================================
|
// General_polygon_2, General_polygon_2 ========================================
|
||||||
// With Traits
|
// With Traits
|
||||||
template <typename ArrTraits, typename GpsTraits>
|
template <typename ArrTraits, typename GpsTraits>
|
||||||
|
|
@ -157,14 +163,22 @@ inline bool do_intersect(const General_polygon_2<ArrTraits>& pgn1,
|
||||||
// Without Traits
|
// Without Traits
|
||||||
template <typename ArrTraits>
|
template <typename ArrTraits>
|
||||||
inline bool do_intersect(const General_polygon_2<ArrTraits>& pgn1,
|
inline bool do_intersect(const General_polygon_2<ArrTraits>& pgn1,
|
||||||
const General_polygon_2<ArrTraits>& pgn2)
|
const General_polygon_2<ArrTraits>& pgn2) {
|
||||||
{
|
|
||||||
// Use the first polygon to determine the (default) traits
|
// Use the first polygon to determine the (default) traits
|
||||||
typedef General_polygon_2<ArrTraits> Polygon;
|
using Polygon = General_polygon_2<ArrTraits>;
|
||||||
typename Gps_default_traits<Polygon>::Traits traits;
|
typename Gps_default_traits<Polygon>::Traits traits;
|
||||||
return s_do_intersect(pgn1, pgn2, traits);
|
return s_do_intersect(pgn1, pgn2, traits);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef CGAL_NO_DEPRECATED_CODE
|
||||||
|
template <typename ArrTraits, bool b>
|
||||||
|
inline bool do_intersect(const General_polygon_2<ArrTraits>& pgn1,
|
||||||
|
const General_polygon_2<ArrTraits>& pgn2,
|
||||||
|
std::bool_constant<b>) {
|
||||||
|
return do_intersect(pgn1, pgn2);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// General_polygon_2, General_polygon_with_holes_2 =============================
|
// General_polygon_2, General_polygon_with_holes_2 =============================
|
||||||
// With Traits
|
// With Traits
|
||||||
template <typename ArrTraits, typename GpsTraits>
|
template <typename ArrTraits, typename GpsTraits>
|
||||||
|
|
@ -178,14 +192,23 @@ inline bool do_intersect(const General_polygon_2<ArrTraits>& pgn1,
|
||||||
template <typename ArrTraits>
|
template <typename ArrTraits>
|
||||||
inline bool do_intersect(const General_polygon_2<ArrTraits>& pgn1,
|
inline bool do_intersect(const General_polygon_2<ArrTraits>& pgn1,
|
||||||
const General_polygon_with_holes_2
|
const General_polygon_with_holes_2
|
||||||
<General_polygon_2<ArrTraits> >& pgn2)
|
<General_polygon_2<ArrTraits> >& pgn2) {
|
||||||
{
|
|
||||||
// Use the first polygon to determine the (default) traits
|
// Use the first polygon to determine the (default) traits
|
||||||
typedef General_polygon_2<ArrTraits> Polygon;
|
using Polygon = General_polygon_2<ArrTraits>;
|
||||||
typename Gps_default_traits<Polygon>::Traits traits;
|
typename Gps_default_traits<Polygon>::Traits traits;
|
||||||
return s_do_intersect(pgn1, pgn2, traits);
|
return s_do_intersect(pgn1, pgn2, traits);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef CGAL_NO_DEPRECATED_CODE
|
||||||
|
template <typename ArrTraits, bool b>
|
||||||
|
inline bool do_intersect(const General_polygon_2<ArrTraits>& pgn1,
|
||||||
|
const General_polygon_with_holes_2
|
||||||
|
<General_polygon_2<ArrTraits> >& pgn2,
|
||||||
|
std::bool_constant<b>) {
|
||||||
|
return do_intersect(pgn1, pgn2);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// General_polygon_with_holes_2, General_polygon_2 =============================
|
// General_polygon_with_holes_2, General_polygon_2 =============================
|
||||||
// With Traits
|
// With Traits
|
||||||
template <typename ArrTraits, typename GpsTraits>
|
template <typename ArrTraits, typename GpsTraits>
|
||||||
|
|
@ -199,15 +222,25 @@ inline bool do_intersect(const General_polygon_with_holes_2
|
||||||
template <typename ArrTraits>
|
template <typename ArrTraits>
|
||||||
inline bool do_intersect(const General_polygon_with_holes_2
|
inline bool do_intersect(const General_polygon_with_holes_2
|
||||||
<General_polygon_2<ArrTraits> >& pgn1,
|
<General_polygon_2<ArrTraits> >& pgn1,
|
||||||
const General_polygon_2<ArrTraits>& pgn2)
|
const General_polygon_2<ArrTraits>& pgn2) {
|
||||||
{
|
|
||||||
// Use the first polygon to determine the (default) traits
|
// Use the first polygon to determine the (default) traits
|
||||||
typedef General_polygon_2<ArrTraits> Polygon;
|
using Polygon = General_polygon_2<ArrTraits>;
|
||||||
typedef General_polygon_with_holes_2<Polygon> Polygon_with_holes;
|
using Polygon_with_holes = General_polygon_with_holes_2<Polygon>;
|
||||||
typename Gps_default_traits<Polygon_with_holes>::Traits traits;
|
typename Gps_default_traits<Polygon_with_holes>::Traits traits;
|
||||||
return s_do_intersect(pgn1, pgn2, traits);
|
return s_do_intersect(pgn1, pgn2, traits);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef CGAL_NO_DEPRECATED_CODE
|
||||||
|
template <typename ArrTraits, bool b>
|
||||||
|
inline bool do_intersect(const General_polygon_with_holes_2
|
||||||
|
<General_polygon_2<ArrTraits> >& pgn1,
|
||||||
|
const General_polygon_2<ArrTraits>& pgn2,
|
||||||
|
std::bool_constant<b>) {
|
||||||
|
return do_intersect(pgn1, pgn2);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// General_polygon_with_holes_2, General_polygon_with_holes_2 ==================
|
// General_polygon_with_holes_2, General_polygon_with_holes_2 ==================
|
||||||
// With Traits
|
// With Traits
|
||||||
template <typename Polygon_, typename Traits>
|
template <typename Polygon_, typename Traits>
|
||||||
|
|
@ -219,14 +252,22 @@ inline bool do_intersect(const General_polygon_with_holes_2<Polygon_>& pgn1,
|
||||||
// Without Traits
|
// Without Traits
|
||||||
template <typename Polygon_>
|
template <typename Polygon_>
|
||||||
inline bool do_intersect(const General_polygon_with_holes_2<Polygon_>& pgn1,
|
inline bool do_intersect(const General_polygon_with_holes_2<Polygon_>& pgn1,
|
||||||
const General_polygon_with_holes_2<Polygon_>& pgn2)
|
const General_polygon_with_holes_2<Polygon_>& pgn2) {
|
||||||
{
|
|
||||||
// Use the first polygon to determine the (default) traits
|
// Use the first polygon to determine the (default) traits
|
||||||
typedef General_polygon_with_holes_2<Polygon_> Polygon_with_holes;
|
using Polygon_with_holes = General_polygon_with_holes_2<Polygon_>;
|
||||||
typename Gps_default_traits<Polygon_with_holes>::Traits traits;
|
typename Gps_default_traits<Polygon_with_holes>::Traits traits;
|
||||||
return s_do_intersect(pgn1, pgn2, traits);
|
return s_do_intersect(pgn1, pgn2, traits);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef CGAL_NO_DEPRECATED_CODE
|
||||||
|
template <typename Polygon_, bool b>
|
||||||
|
inline bool do_intersect(const General_polygon_with_holes_2<Polygon_>& pgn1,
|
||||||
|
const General_polygon_with_holes_2<Polygon_>& pgn2,
|
||||||
|
std::bool_constant<b>) {
|
||||||
|
return do_intersect(pgn1, pgn2);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
/// \name Aggregated do_intersect() functions.
|
/// \name Aggregated do_intersect() functions.
|
||||||
|
|
@ -235,26 +276,15 @@ inline bool do_intersect(const General_polygon_with_holes_2<Polygon_>& pgn1,
|
||||||
// With Traits
|
// With Traits
|
||||||
template <typename InputIterator, typename Traits>
|
template <typename InputIterator, typename Traits>
|
||||||
inline bool do_intersect(InputIterator begin, InputIterator end, Traits& traits,
|
inline bool do_intersect(InputIterator begin, InputIterator end, Traits& traits,
|
||||||
unsigned int k=5,
|
std::size_t k = 5,
|
||||||
std::enable_if_t<CGAL::is_iterator<InputIterator>::value>* = 0)
|
std::enable_if_t<CGAL::is_iterator<InputIterator>::value>* = 0)
|
||||||
{ return r_do_intersect(begin, end, traits, k); }
|
{ return r_do_intersect(begin, end, traits, k); }
|
||||||
|
|
||||||
// Without Traits
|
// Without Traits
|
||||||
// Tag_true => convert to polylines
|
|
||||||
template <typename InputIterator>
|
template <typename InputIterator>
|
||||||
inline bool do_intersect(InputIterator begin, InputIterator end,
|
inline bool do_intersect(InputIterator begin, InputIterator end, std::size_t k = 5,
|
||||||
Tag_true = Tag_true(), unsigned int k=5,
|
|
||||||
std::enable_if_t<CGAL::is_iterator<InputIterator>::value>* = 0,
|
std::enable_if_t<CGAL::is_iterator<InputIterator>::value>* = 0,
|
||||||
Enable_if_Polygon_2_iterator<InputIterator>* = 0)
|
Enable_if_Polygon_2_iterator<InputIterator>* = 0) {
|
||||||
{ return r_do_intersect(begin, end, k); }
|
|
||||||
|
|
||||||
// Tag_false => do not convert to polylines
|
|
||||||
template <typename InputIterator>
|
|
||||||
inline bool do_intersect(InputIterator begin, InputIterator end,
|
|
||||||
Tag_false, unsigned int k=5,
|
|
||||||
std::enable_if_t<CGAL::is_iterator<InputIterator>::value>* = 0,
|
|
||||||
Enable_if_Polygon_2_iterator<InputIterator>* = 0)
|
|
||||||
{
|
|
||||||
typename Iterator_to_gps_traits<InputIterator>::Traits traits;
|
typename Iterator_to_gps_traits<InputIterator>::Traits traits;
|
||||||
return r_do_intersect(begin, end, traits, k);
|
return r_do_intersect(begin, end, traits, k);
|
||||||
}
|
}
|
||||||
|
|
@ -262,35 +292,33 @@ inline bool do_intersect(InputIterator begin, InputIterator end,
|
||||||
// General polygons or polygons with holes
|
// General polygons or polygons with holes
|
||||||
template <typename InputIterator>
|
template <typename InputIterator>
|
||||||
inline bool do_intersect(InputIterator begin, InputIterator end,
|
inline bool do_intersect(InputIterator begin, InputIterator end,
|
||||||
unsigned int k=5,
|
std::size_t k = 5,
|
||||||
std::enable_if_t<CGAL::is_iterator<InputIterator>::value>* = 0,
|
std::enable_if_t<CGAL::is_iterator<InputIterator>::value>* = 0,
|
||||||
Disable_if_Polygon_2_iterator<InputIterator>* = 0)
|
Disable_if_Polygon_2_iterator<InputIterator>* = 0) {
|
||||||
{
|
|
||||||
typename Iterator_to_gps_traits<InputIterator>::Traits traits;
|
typename Iterator_to_gps_traits<InputIterator>::Traits traits;
|
||||||
return do_intersect(begin, end, traits, k);
|
return do_intersect(begin, end, traits, k);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef CGAL_NO_DEPRECATED_CODE
|
||||||
|
template <typename InputIterator, bool b>
|
||||||
|
inline bool do_intersect(InputIterator begin, InputIterator end, std::bool_constant<b>,
|
||||||
|
std::enable_if_t<CGAL::is_iterator<InputIterator>::value>* = 0) {
|
||||||
|
return do_intersect(begin, end);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// With Traits
|
// With Traits
|
||||||
template <typename InputIterator1, typename InputIterator2, typename Traits>
|
template <typename InputIterator1, typename InputIterator2, typename Traits>
|
||||||
inline bool do_intersect(InputIterator1 begin1, InputIterator1 end1,
|
inline bool do_intersect(InputIterator1 begin1, InputIterator1 end1,
|
||||||
InputIterator2 begin2, InputIterator2 end2,
|
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); }
|
{ return r_do_intersect(begin1, end1, begin2, end2, traits, k); }
|
||||||
|
|
||||||
// Without Traits
|
// Without Traits
|
||||||
// Tag_true => convert to polylines
|
|
||||||
template <typename InputIterator1, typename InputIterator2>
|
template <typename InputIterator1, typename InputIterator2>
|
||||||
inline bool do_intersect(InputIterator1 begin1, InputIterator1 end1,
|
inline bool do_intersect(InputIterator1 begin1, InputIterator1 end1,
|
||||||
InputIterator2 begin2, InputIterator2 end2,
|
InputIterator2 begin2, InputIterator2 end2,
|
||||||
Tag_true = Tag_true(), unsigned int k=5,
|
std::size_t k = 5,
|
||||||
Enable_if_Polygon_2_iterator<InputIterator1>* = 0)
|
|
||||||
{ return r_do_intersect(begin1, end1, begin2, end2, k); }
|
|
||||||
|
|
||||||
// Tag_false => do not convert to polylines
|
|
||||||
template <typename InputIterator1, typename InputIterator2>
|
|
||||||
inline bool do_intersect (InputIterator1 begin1, InputIterator1 end1,
|
|
||||||
InputIterator2 begin2, InputIterator2 end2,
|
|
||||||
Tag_false, unsigned int k=5,
|
|
||||||
Enable_if_Polygon_2_iterator<InputIterator1>* = 0)
|
Enable_if_Polygon_2_iterator<InputIterator1>* = 0)
|
||||||
{ return r_do_intersect(begin1, end1, begin2, end2, k); }
|
{ return r_do_intersect(begin1, end1, begin2, end2, k); }
|
||||||
|
|
||||||
|
|
@ -298,13 +326,23 @@ inline bool do_intersect (InputIterator1 begin1, InputIterator1 end1,
|
||||||
template <typename InputIterator1, typename InputIterator2>
|
template <typename InputIterator1, typename InputIterator2>
|
||||||
inline bool do_intersect(InputIterator1 begin1, InputIterator1 end1,
|
inline bool do_intersect(InputIterator1 begin1, InputIterator1 end1,
|
||||||
InputIterator2 begin2, InputIterator2 end2,
|
InputIterator2 begin2, InputIterator2 end2,
|
||||||
unsigned int k=5,
|
std::size_t k = 5,
|
||||||
Disable_if_Polygon_2_iterator<InputIterator1>* = 0)
|
Disable_if_Polygon_2_iterator<InputIterator1>* = 0) {
|
||||||
{
|
|
||||||
typename Iterator_to_gps_traits<InputIterator1>::Traits traits;
|
typename Iterator_to_gps_traits<InputIterator1>::Traits traits;
|
||||||
return r_do_intersect(begin1, end1, begin2, end2, traits, k);
|
return r_do_intersect(begin1, end1, begin2, end2, traits, k);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef CGAL_NO_DEPRECATED_CODE
|
||||||
|
template <typename InputIterator1, typename InputIterator2, bool b>
|
||||||
|
inline bool do_intersect(InputIterator1 begin1, InputIterator1 end1,
|
||||||
|
InputIterator2 begin2, InputIterator2 end2,
|
||||||
|
std::bool_constant<b>,
|
||||||
|
std::enable_if_t<CGAL::is_iterator<InputIterator1>::value &&
|
||||||
|
CGAL::is_iterator<InputIterator2>::value >* = 0) {
|
||||||
|
return do_intersect(begin1, end1, begin2, end2);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
} //namespace CGAL
|
} //namespace CGAL
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@
|
||||||
// $Id$
|
// $Id$
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
//
|
//
|
||||||
//
|
|
||||||
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||||
// Ron Wein <wein@post.tau.ac.il>
|
// Ron Wein <wein@post.tau.ac.il>
|
||||||
// Efi Fogel <efif@post.tau.ac.il>
|
// Efi Fogel <efif@post.tau.ac.il>
|
||||||
|
|
@ -33,8 +32,7 @@
|
||||||
#include <CGAL/Boolean_set_operations_2/Polygon_conversions.h>
|
#include <CGAL/Boolean_set_operations_2/Polygon_conversions.h>
|
||||||
#include <CGAL/type_traits/is_iterator.h>
|
#include <CGAL/type_traits/is_iterator.h>
|
||||||
|
|
||||||
namespace CGAL
|
namespace CGAL {
|
||||||
{
|
|
||||||
|
|
||||||
/// \name intersection() functions.
|
/// \name intersection() functions.
|
||||||
//@{
|
//@{
|
||||||
|
|
@ -59,10 +57,9 @@ inline OutputIterator intersection(const Polygon_2<Kernel, Container>& pgn1,
|
||||||
template <typename Kernel, typename Container, typename OutputIterator>
|
template <typename Kernel, typename Container, typename OutputIterator>
|
||||||
inline OutputIterator intersection(const Polygon_2<Kernel, Container>& pgn1,
|
inline OutputIterator intersection(const Polygon_2<Kernel, Container>& pgn1,
|
||||||
const Polygon_2<Kernel, Container>& pgn2,
|
const Polygon_2<Kernel, Container>& pgn2,
|
||||||
OutputIterator out, Tag_false)
|
OutputIterator out, Tag_false) {
|
||||||
{
|
|
||||||
// Use the first polygon to determine the (default) traits
|
// Use the first polygon to determine the (default) traits
|
||||||
typedef Polygon_2<Kernel, Container> Polygon;
|
using Polygon = Polygon_2<Kernel, Container>;
|
||||||
typename Gps_default_traits<Polygon>::Traits traits;
|
typename Gps_default_traits<Polygon>::Traits traits;
|
||||||
return s_intersection(pgn1, pgn2, out, traits);
|
return s_intersection(pgn1, pgn2, out, traits);
|
||||||
}
|
}
|
||||||
|
|
@ -90,10 +87,9 @@ template <typename Kernel, typename Container, typename OutputIterator>
|
||||||
inline OutputIterator
|
inline OutputIterator
|
||||||
intersection(const Polygon_2<Kernel, Container>& pgn1,
|
intersection(const Polygon_2<Kernel, Container>& pgn1,
|
||||||
const Polygon_with_holes_2<Kernel, Container>& pgn2,
|
const Polygon_with_holes_2<Kernel, Container>& pgn2,
|
||||||
OutputIterator out, Tag_false)
|
OutputIterator out, Tag_false) {
|
||||||
{
|
|
||||||
// Use the first polygon to determine the (default) traits
|
// Use the first polygon to determine the (default) traits
|
||||||
typedef Polygon_2<Kernel, Container> Polygon;
|
using Polygon = Polygon_2<Kernel, Container>;
|
||||||
typename Gps_default_traits<Polygon>::Traits traits;
|
typename Gps_default_traits<Polygon>::Traits traits;
|
||||||
return s_intersection(pgn1, pgn2, out, traits);
|
return s_intersection(pgn1, pgn2, out, traits);
|
||||||
}
|
}
|
||||||
|
|
@ -121,10 +117,9 @@ template <typename Kernel, typename Container, typename OutputIterator>
|
||||||
inline OutputIterator
|
inline OutputIterator
|
||||||
intersection(const Polygon_with_holes_2<Kernel, Container>& pgn1,
|
intersection(const Polygon_with_holes_2<Kernel, Container>& pgn1,
|
||||||
const Polygon_2<Kernel, Container>& pgn2,
|
const Polygon_2<Kernel, Container>& pgn2,
|
||||||
OutputIterator out, Tag_false)
|
OutputIterator out, Tag_false) {
|
||||||
{
|
|
||||||
// Use the first polygon to determine the (default) traits
|
// Use the first polygon to determine the (default) traits
|
||||||
typedef Polygon_with_holes_2<Kernel, Container> Polygon_with_holes;
|
using Polygon_with_holes = Polygon_with_holes_2<Kernel, Container>;
|
||||||
typename Gps_default_traits<Polygon_with_holes>::Traits traits;
|
typename Gps_default_traits<Polygon_with_holes>::Traits traits;
|
||||||
return s_intersection(pgn1, pgn2, out, traits);
|
return s_intersection(pgn1, pgn2, out, traits);
|
||||||
}
|
}
|
||||||
|
|
@ -152,10 +147,9 @@ template <typename Kernel, typename Container, typename OutputIterator>
|
||||||
inline OutputIterator
|
inline OutputIterator
|
||||||
intersection(const Polygon_with_holes_2<Kernel, Container>& pgn1,
|
intersection(const Polygon_with_holes_2<Kernel, Container>& pgn1,
|
||||||
const Polygon_with_holes_2<Kernel, Container>& pgn2,
|
const Polygon_with_holes_2<Kernel, Container>& pgn2,
|
||||||
OutputIterator out, Tag_false)
|
OutputIterator out, Tag_false) {
|
||||||
{
|
|
||||||
// Use the first polygon to determine the (default) traits
|
// Use the first polygon to determine the (default) traits
|
||||||
typedef Polygon_with_holes_2<Kernel, Container> Polygon_with_holes;
|
using Polygon_with_holes = Polygon_with_holes_2<Kernel, Container>;
|
||||||
typename Gps_default_traits<Polygon_with_holes>::Traits traits;
|
typename Gps_default_traits<Polygon_with_holes>::Traits traits;
|
||||||
return s_intersection(pgn1, pgn2, out, traits);
|
return s_intersection(pgn1, pgn2, out, traits);
|
||||||
}
|
}
|
||||||
|
|
@ -172,10 +166,9 @@ inline OutputIterator intersection(const General_polygon_2<ArrTraits>& pgn1,
|
||||||
template <typename ArrTraits, typename OutputIterator>
|
template <typename ArrTraits, typename OutputIterator>
|
||||||
inline OutputIterator intersection(const General_polygon_2<ArrTraits>& pgn1,
|
inline OutputIterator intersection(const General_polygon_2<ArrTraits>& pgn1,
|
||||||
const General_polygon_2<ArrTraits>& pgn2,
|
const General_polygon_2<ArrTraits>& pgn2,
|
||||||
OutputIterator out)
|
OutputIterator out) {
|
||||||
{
|
|
||||||
// Use the first polygon to determine the (default) traits
|
// Use the first polygon to determine the (default) traits
|
||||||
typedef General_polygon_2<ArrTraits> Polygon;
|
using Polygon = General_polygon_2<ArrTraits>;
|
||||||
typename Gps_default_traits<Polygon>::Traits traits;
|
typename Gps_default_traits<Polygon>::Traits traits;
|
||||||
return s_intersection(pgn1, pgn2, out, traits);
|
return s_intersection(pgn1, pgn2, out, traits);
|
||||||
}
|
}
|
||||||
|
|
@ -194,10 +187,9 @@ template <typename ArrTraits, typename OutputIterator>
|
||||||
inline OutputIterator intersection(const General_polygon_2<ArrTraits>& pgn1,
|
inline OutputIterator intersection(const General_polygon_2<ArrTraits>& pgn1,
|
||||||
const General_polygon_with_holes_2
|
const General_polygon_with_holes_2
|
||||||
<General_polygon_2<ArrTraits> >& pgn2,
|
<General_polygon_2<ArrTraits> >& pgn2,
|
||||||
OutputIterator out)
|
OutputIterator out) {
|
||||||
{
|
|
||||||
// Use the first polygon to determine the (default) traits
|
// Use the first polygon to determine the (default) traits
|
||||||
typedef General_polygon_2<ArrTraits> Polygon;
|
using Polygon = General_polygon_2<ArrTraits>;
|
||||||
typename Gps_default_traits<Polygon>::Traits traits;
|
typename Gps_default_traits<Polygon>::Traits traits;
|
||||||
return s_intersection(pgn1, pgn2, out, traits);
|
return s_intersection(pgn1, pgn2, out, traits);
|
||||||
}
|
}
|
||||||
|
|
@ -216,11 +208,10 @@ template <typename ArrTraits, typename OutputIterator>
|
||||||
inline OutputIterator intersection(const General_polygon_with_holes_2
|
inline OutputIterator intersection(const General_polygon_with_holes_2
|
||||||
<General_polygon_2<ArrTraits> >& pgn1,
|
<General_polygon_2<ArrTraits> >& pgn1,
|
||||||
const General_polygon_2<ArrTraits>& pgn2,
|
const General_polygon_2<ArrTraits>& pgn2,
|
||||||
OutputIterator out)
|
OutputIterator out) {
|
||||||
{
|
|
||||||
// Use the first polygon to determine the (default) traits
|
// Use the first polygon to determine the (default) traits
|
||||||
typedef General_polygon_2<ArrTraits> Polygon;
|
using Polygon = General_polygon_2<ArrTraits>;
|
||||||
typedef General_polygon_with_holes_2<Polygon> Polygon_with_holes;
|
using Polygon_with_holes = General_polygon_with_holes_2<Polygon>;
|
||||||
typename Gps_default_traits<Polygon_with_holes>::Traits traits;
|
typename Gps_default_traits<Polygon_with_holes>::Traits traits;
|
||||||
return s_intersection(pgn1, pgn2, out, traits);
|
return s_intersection(pgn1, pgn2, out, traits);
|
||||||
}
|
}
|
||||||
|
|
@ -239,10 +230,9 @@ template <typename Polygon_, typename OutputIterator>
|
||||||
inline OutputIterator
|
inline OutputIterator
|
||||||
intersection(const General_polygon_with_holes_2<Polygon_>& pgn1,
|
intersection(const General_polygon_with_holes_2<Polygon_>& pgn1,
|
||||||
const General_polygon_with_holes_2<Polygon_>& pgn2,
|
const General_polygon_with_holes_2<Polygon_>& pgn2,
|
||||||
OutputIterator out)
|
OutputIterator out) {
|
||||||
{
|
|
||||||
// Use the first polygon to determine the (default) traits
|
// Use the first polygon to determine the (default) traits
|
||||||
typedef General_polygon_with_holes_2<Polygon_> Polygon_with_holes;
|
using Polygon_with_holes = General_polygon_with_holes_2<Polygon_>;
|
||||||
typename Gps_default_traits<Polygon_with_holes>::Traits traits;
|
typename Gps_default_traits<Polygon_with_holes>::Traits traits;
|
||||||
return s_intersection(pgn1, pgn2, out, traits);
|
return s_intersection(pgn1, pgn2, out, traits);
|
||||||
}
|
}
|
||||||
|
|
@ -256,7 +246,7 @@ intersection(const General_polygon_with_holes_2<Polygon_>& pgn1,
|
||||||
template <typename InputIterator, typename OutputIterator, typename Traits>
|
template <typename InputIterator, typename OutputIterator, typename Traits>
|
||||||
inline OutputIterator intersection(InputIterator begin, InputIterator end,
|
inline OutputIterator intersection(InputIterator begin, InputIterator end,
|
||||||
OutputIterator oi, Traits& traits,
|
OutputIterator oi, Traits& traits,
|
||||||
unsigned int k=5)
|
std::size_t k = 5)
|
||||||
{ return r_intersection(begin, end, oi, traits, k); }
|
{ return r_intersection(begin, end, oi, traits, k); }
|
||||||
|
|
||||||
// Without Traits
|
// Without Traits
|
||||||
|
|
@ -265,7 +255,7 @@ template <typename InputIterator, typename OutputIterator>
|
||||||
inline OutputIterator
|
inline OutputIterator
|
||||||
intersection(InputIterator begin, InputIterator end,
|
intersection(InputIterator begin, InputIterator end,
|
||||||
OutputIterator oi, Tag_true = Tag_true(),
|
OutputIterator oi, Tag_true = Tag_true(),
|
||||||
unsigned int k=5,
|
std::size_t k = 5,
|
||||||
Enable_if_Polygon_2_iterator<InputIterator>* = 0)
|
Enable_if_Polygon_2_iterator<InputIterator>* = 0)
|
||||||
{ return r_intersection(begin, end, oi, k); }
|
{ return r_intersection(begin, end, oi, k); }
|
||||||
|
|
||||||
|
|
@ -273,9 +263,8 @@ intersection(InputIterator begin, InputIterator end,
|
||||||
template <typename InputIterator, typename OutputIterator>
|
template <typename InputIterator, typename OutputIterator>
|
||||||
inline OutputIterator
|
inline OutputIterator
|
||||||
intersection(InputIterator begin, InputIterator end,
|
intersection(InputIterator begin, InputIterator end,
|
||||||
OutputIterator oi, Tag_false, unsigned int k=5,
|
OutputIterator oi, Tag_false, std::size_t k = 5,
|
||||||
Enable_if_Polygon_2_iterator<InputIterator>* = 0)
|
Enable_if_Polygon_2_iterator<InputIterator>* = 0) {
|
||||||
{
|
|
||||||
typename Iterator_to_gps_traits<InputIterator>::Traits traits;
|
typename Iterator_to_gps_traits<InputIterator>::Traits traits;
|
||||||
return r_intersection(begin, end, oi, traits, k);
|
return r_intersection(begin, end, oi, traits, k);
|
||||||
}
|
}
|
||||||
|
|
@ -284,11 +273,10 @@ intersection(InputIterator begin, InputIterator end,
|
||||||
template <typename InputIterator, typename OutputIterator>
|
template <typename InputIterator, typename OutputIterator>
|
||||||
inline OutputIterator
|
inline OutputIterator
|
||||||
intersection(InputIterator begin, InputIterator end,
|
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
|
// workaround to avoid ambiguous calls with kernel functions
|
||||||
std::enable_if_t<CGAL::is_iterator<InputIterator>::value>* = 0,
|
std::enable_if_t<CGAL::is_iterator<InputIterator>::value>* = 0,
|
||||||
Disable_if_Polygon_2_iterator<InputIterator>* = 0)
|
Disable_if_Polygon_2_iterator<InputIterator>* = 0) {
|
||||||
{
|
|
||||||
typename Iterator_to_gps_traits<InputIterator>::Traits traits;
|
typename Iterator_to_gps_traits<InputIterator>::Traits traits;
|
||||||
return r_intersection(begin, end, oi, traits, k);
|
return r_intersection(begin, end, oi, traits, k);
|
||||||
}
|
}
|
||||||
|
|
@ -300,7 +288,7 @@ template <typename InputIterator1, typename InputIterator2,
|
||||||
inline OutputIterator intersection(InputIterator1 begin1, InputIterator1 end1,
|
inline OutputIterator intersection(InputIterator1 begin1, InputIterator1 end1,
|
||||||
InputIterator2 begin2, InputIterator2 end2,
|
InputIterator2 begin2, InputIterator2 end2,
|
||||||
OutputIterator oi, Traits& traits,
|
OutputIterator oi, Traits& traits,
|
||||||
unsigned int k=5)
|
std::size_t k = 5)
|
||||||
{ return r_intersection(begin1, end1, begin2, end2, oi, traits, k); }
|
{ return r_intersection(begin1, end1, begin2, end2, oi, traits, k); }
|
||||||
|
|
||||||
// Without Traits
|
// Without Traits
|
||||||
|
|
@ -310,7 +298,7 @@ template <typename InputIterator1, typename InputIterator2,
|
||||||
inline OutputIterator
|
inline OutputIterator
|
||||||
intersection(InputIterator1 begin1, InputIterator1 end1,
|
intersection(InputIterator1 begin1, InputIterator1 end1,
|
||||||
InputIterator2 begin2, InputIterator2 end2,
|
InputIterator2 begin2, InputIterator2 end2,
|
||||||
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<InputIterator1>* = 0)
|
Enable_if_Polygon_2_iterator<InputIterator1>* = 0)
|
||||||
{ return r_intersection(begin1, end1, begin2, end2, oi, k); }
|
{ return r_intersection(begin1, end1, begin2, end2, oi, k); }
|
||||||
|
|
||||||
|
|
@ -320,9 +308,8 @@ template <typename InputIterator1, typename InputIterator2,
|
||||||
inline OutputIterator
|
inline OutputIterator
|
||||||
intersection(InputIterator1 begin1, InputIterator1 end1,
|
intersection(InputIterator1 begin1, InputIterator1 end1,
|
||||||
InputIterator2 begin2, InputIterator2 end2,
|
InputIterator2 begin2, InputIterator2 end2,
|
||||||
OutputIterator oi, Tag_false, unsigned int k=5,
|
OutputIterator oi, Tag_false, std::size_t k = 5,
|
||||||
Enable_if_Polygon_2_iterator<InputIterator1>* = 0)
|
Enable_if_Polygon_2_iterator<InputIterator1>* = 0) {
|
||||||
{
|
|
||||||
typename Iterator_to_gps_traits<InputIterator1>::Traits traits;
|
typename Iterator_to_gps_traits<InputIterator1>::Traits traits;
|
||||||
return r_intersection(begin1, end1, begin2, end2, oi, traits, k);
|
return r_intersection(begin1, end1, begin2, end2, oi, traits, k);
|
||||||
}
|
}
|
||||||
|
|
@ -333,9 +320,8 @@ template <typename InputIterator1, typename InputIterator2,
|
||||||
inline OutputIterator
|
inline OutputIterator
|
||||||
intersection(InputIterator1 begin1, InputIterator1 end1,
|
intersection(InputIterator1 begin1, InputIterator1 end1,
|
||||||
InputIterator2 begin2, InputIterator2 end2,
|
InputIterator2 begin2, InputIterator2 end2,
|
||||||
OutputIterator oi, unsigned int k=5,
|
OutputIterator oi, std::size_t k = 5,
|
||||||
Disable_if_Polygon_2_iterator<InputIterator1>* = 0)
|
Disable_if_Polygon_2_iterator<InputIterator1>* = 0) {
|
||||||
{
|
|
||||||
typename Iterator_to_gps_traits<InputIterator1>::Traits traits;
|
typename Iterator_to_gps_traits<InputIterator1>::Traits traits;
|
||||||
return r_intersection(begin1, end1, begin2, end2, oi, traits, k);
|
return r_intersection(begin1, end1, begin2, end2, oi, traits, k);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@
|
||||||
// $Id$
|
// $Id$
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
//
|
//
|
||||||
//
|
|
||||||
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||||
// Ron Wein <wein@post.tau.ac.il>
|
// Ron Wein <wein@post.tau.ac.il>
|
||||||
// Efi Fogel <efif@post.tau.ac.il>
|
// Efi Fogel <efif@post.tau.ac.il>
|
||||||
|
|
@ -33,8 +32,7 @@
|
||||||
#include <CGAL/Boolean_set_operations_2/Polygon_conversions.h>
|
#include <CGAL/Boolean_set_operations_2/Polygon_conversions.h>
|
||||||
#include <CGAL/type_traits/is_iterator.h>
|
#include <CGAL/type_traits/is_iterator.h>
|
||||||
|
|
||||||
namespace CGAL
|
namespace CGAL {
|
||||||
{
|
|
||||||
|
|
||||||
/// \name join() functions.
|
/// \name join() functions.
|
||||||
//@{
|
//@{
|
||||||
|
|
@ -60,10 +58,9 @@ template <typename Kernel, typename Container>
|
||||||
inline bool join(const Polygon_2<Kernel, Container>& pgn1,
|
inline bool join(const Polygon_2<Kernel, Container>& pgn1,
|
||||||
const Polygon_2<Kernel, Container>& pgn2,
|
const Polygon_2<Kernel, Container>& pgn2,
|
||||||
Polygon_with_holes_2<Kernel, Container>& res,
|
Polygon_with_holes_2<Kernel, Container>& res,
|
||||||
Tag_false)
|
Tag_false) {
|
||||||
{
|
|
||||||
// Use the first polygon to determine the (default) traits
|
// Use the first polygon to determine the (default) traits
|
||||||
typedef Polygon_2<Kernel, Container> Polygon;
|
using Polygon = Polygon_2<Kernel, Container>;
|
||||||
typename Gps_default_traits<Polygon>::Traits traits;
|
typename Gps_default_traits<Polygon>::Traits traits;
|
||||||
return s_join(pgn1, pgn2, res, traits);
|
return s_join(pgn1, pgn2, res, traits);
|
||||||
}
|
}
|
||||||
|
|
@ -89,10 +86,9 @@ template <typename Kernel, typename Container>
|
||||||
inline bool join(const Polygon_2<Kernel, Container>& pgn1,
|
inline bool join(const Polygon_2<Kernel, Container>& pgn1,
|
||||||
const Polygon_with_holes_2<Kernel, Container>& pgn2,
|
const Polygon_with_holes_2<Kernel, Container>& pgn2,
|
||||||
Polygon_with_holes_2<Kernel, Container>& res,
|
Polygon_with_holes_2<Kernel, Container>& res,
|
||||||
Tag_false)
|
Tag_false) {
|
||||||
{
|
|
||||||
// Use the first polygon to determine the (default) traits
|
// Use the first polygon to determine the (default) traits
|
||||||
typedef Polygon_2<Kernel, Container> Polygon;
|
using Polygon = Polygon_2<Kernel, Container>;
|
||||||
typename Gps_default_traits<Polygon>::Traits traits;
|
typename Gps_default_traits<Polygon>::Traits traits;
|
||||||
return s_join(pgn1, pgn2, res, traits);
|
return s_join(pgn1, pgn2, res, traits);
|
||||||
}
|
}
|
||||||
|
|
@ -118,10 +114,9 @@ template <typename Kernel, typename Container>
|
||||||
inline bool join(const Polygon_with_holes_2<Kernel, Container>& pgn1,
|
inline bool join(const Polygon_with_holes_2<Kernel, Container>& pgn1,
|
||||||
const Polygon_2<Kernel, Container>& pgn2,
|
const Polygon_2<Kernel, Container>& pgn2,
|
||||||
Polygon_with_holes_2<Kernel, Container>& res,
|
Polygon_with_holes_2<Kernel, Container>& res,
|
||||||
Tag_false)
|
Tag_false) {
|
||||||
{
|
|
||||||
// Use the first polygon to determine the (default) traits
|
// Use the first polygon to determine the (default) traits
|
||||||
typedef Polygon_with_holes_2<Kernel, Container> Polygon_with_holes;
|
using Polygon_with_holes = Polygon_with_holes_2<Kernel, Container>;
|
||||||
typename Gps_default_traits<Polygon_with_holes>::Traits traits;
|
typename Gps_default_traits<Polygon_with_holes>::Traits traits;
|
||||||
return s_join(pgn1, pgn2, res, traits);
|
return s_join(pgn1, pgn2, res, traits);
|
||||||
}
|
}
|
||||||
|
|
@ -147,10 +142,9 @@ template <typename Kernel, typename Container>
|
||||||
inline bool join(const Polygon_with_holes_2<Kernel, Container>& pgn1,
|
inline bool join(const Polygon_with_holes_2<Kernel, Container>& pgn1,
|
||||||
const Polygon_with_holes_2<Kernel, Container>& pgn2,
|
const Polygon_with_holes_2<Kernel, Container>& pgn2,
|
||||||
Polygon_with_holes_2<Kernel, Container>& res,
|
Polygon_with_holes_2<Kernel, Container>& res,
|
||||||
Tag_false)
|
Tag_false) {
|
||||||
{
|
|
||||||
// Use the first polygon to determine the (default) traits
|
// Use the first polygon to determine the (default) traits
|
||||||
typedef Polygon_with_holes_2<Kernel, Container> Polygon_with_holes;
|
using Polygon_with_holes = Polygon_with_holes_2<Kernel, Container>;
|
||||||
typename Gps_default_traits<Polygon_with_holes>::Traits traits;
|
typename Gps_default_traits<Polygon_with_holes>::Traits traits;
|
||||||
return s_join(pgn1, pgn2, res, traits);
|
return s_join(pgn1, pgn2, res, traits);
|
||||||
}
|
}
|
||||||
|
|
@ -170,10 +164,9 @@ template <typename ArrTraits>
|
||||||
inline bool
|
inline bool
|
||||||
join(const General_polygon_2<ArrTraits>& pgn1,
|
join(const General_polygon_2<ArrTraits>& pgn1,
|
||||||
const General_polygon_2<ArrTraits>& pgn2,
|
const General_polygon_2<ArrTraits>& pgn2,
|
||||||
General_polygon_with_holes_2<General_polygon_2<ArrTraits> >& res)
|
General_polygon_with_holes_2<General_polygon_2<ArrTraits> >& res) {
|
||||||
{
|
|
||||||
// Use the first polygon to determine the (default) traits
|
// Use the first polygon to determine the (default) traits
|
||||||
typedef General_polygon_2<ArrTraits> Polygon;
|
using Polygon = General_polygon_2<ArrTraits>;
|
||||||
typename Gps_default_traits<Polygon>::Traits traits;
|
typename Gps_default_traits<Polygon>::Traits traits;
|
||||||
return s_join(pgn1, pgn2, res, traits);
|
return s_join(pgn1, pgn2, res, traits);
|
||||||
}
|
}
|
||||||
|
|
@ -193,10 +186,9 @@ template <typename ArrTraits>
|
||||||
inline bool
|
inline bool
|
||||||
join(const General_polygon_2<ArrTraits>& pgn1,
|
join(const General_polygon_2<ArrTraits>& pgn1,
|
||||||
const General_polygon_with_holes_2<General_polygon_2<ArrTraits> >& pgn2,
|
const General_polygon_with_holes_2<General_polygon_2<ArrTraits> >& pgn2,
|
||||||
General_polygon_with_holes_2<General_polygon_2<ArrTraits> >& res)
|
General_polygon_with_holes_2<General_polygon_2<ArrTraits> >& res) {
|
||||||
{
|
|
||||||
// Use the first polygon to determine the (default) traits
|
// Use the first polygon to determine the (default) traits
|
||||||
typedef General_polygon_2<ArrTraits> Polygon;
|
using Polygon = General_polygon_2<ArrTraits>;
|
||||||
typename Gps_default_traits<Polygon>::Traits traits;
|
typename Gps_default_traits<Polygon>::Traits traits;
|
||||||
return s_join(pgn1, pgn2, res, traits);
|
return s_join(pgn1, pgn2, res, traits);
|
||||||
}
|
}
|
||||||
|
|
@ -216,11 +208,10 @@ template <typename ArrTraits>
|
||||||
inline bool
|
inline bool
|
||||||
join(const General_polygon_with_holes_2<General_polygon_2<ArrTraits> >& pgn1,
|
join(const General_polygon_with_holes_2<General_polygon_2<ArrTraits> >& pgn1,
|
||||||
const General_polygon_2<ArrTraits>& pgn2,
|
const General_polygon_2<ArrTraits>& pgn2,
|
||||||
General_polygon_with_holes_2<General_polygon_2<ArrTraits> >& res)
|
General_polygon_with_holes_2<General_polygon_2<ArrTraits> >& res) {
|
||||||
{
|
|
||||||
// Use the first polygon to determine the (default) traits
|
// Use the first polygon to determine the (default) traits
|
||||||
typedef General_polygon_2<ArrTraits> Polygon;
|
using Polygon = General_polygon_2<ArrTraits>;
|
||||||
typedef General_polygon_with_holes_2<Polygon> Polygon_with_holes;
|
using Polygon_with_holes = General_polygon_with_holes_2<Polygon>;
|
||||||
typename Gps_default_traits<Polygon_with_holes>::Traits traits;
|
typename Gps_default_traits<Polygon_with_holes>::Traits traits;
|
||||||
return s_join(pgn1, pgn2, res, traits);
|
return s_join(pgn1, pgn2, res, traits);
|
||||||
}
|
}
|
||||||
|
|
@ -237,10 +228,9 @@ inline bool join(const General_polygon_with_holes_2<Polygon_>& pgn1,
|
||||||
template <typename Polygon_>
|
template <typename Polygon_>
|
||||||
inline bool join(const General_polygon_with_holes_2<Polygon_>& pgn1,
|
inline bool join(const General_polygon_with_holes_2<Polygon_>& pgn1,
|
||||||
const General_polygon_with_holes_2<Polygon_>& pgn2,
|
const General_polygon_with_holes_2<Polygon_>& pgn2,
|
||||||
General_polygon_with_holes_2<Polygon_>& res)
|
General_polygon_with_holes_2<Polygon_>& res) {
|
||||||
{
|
|
||||||
// Use the first polygon to determine the (default) traits
|
// Use the first polygon to determine the (default) traits
|
||||||
typedef General_polygon_with_holes_2<Polygon_> Polygon_with_holes;
|
using Polygon_with_holes = General_polygon_with_holes_2<Polygon_>;
|
||||||
typename Gps_default_traits<Polygon_with_holes>::Traits traits;
|
typename Gps_default_traits<Polygon_with_holes>::Traits traits;
|
||||||
return s_join(pgn1, pgn2, res, traits);
|
return s_join(pgn1, pgn2, res, traits);
|
||||||
}
|
}
|
||||||
|
|
@ -253,7 +243,7 @@ inline bool join(const General_polygon_with_holes_2<Polygon_>& pgn1,
|
||||||
// With Traits
|
// With Traits
|
||||||
template <typename InputIterator, typename OutputIterator, typename Traits>
|
template <typename InputIterator, typename OutputIterator, typename Traits>
|
||||||
inline OutputIterator join(InputIterator begin, InputIterator end,
|
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); }
|
{ return r_join(begin, end, oi, traits, k); }
|
||||||
|
|
||||||
// Without Traits
|
// Without Traits
|
||||||
|
|
@ -261,16 +251,15 @@ inline OutputIterator join(InputIterator begin, InputIterator end,
|
||||||
template <typename InputIterator, typename OutputIterator>
|
template <typename InputIterator, typename OutputIterator>
|
||||||
inline OutputIterator join(InputIterator begin, InputIterator end,
|
inline OutputIterator join(InputIterator begin, InputIterator end,
|
||||||
OutputIterator oi, Tag_true = Tag_true(),
|
OutputIterator oi, Tag_true = Tag_true(),
|
||||||
unsigned int k=5,
|
std::size_t k = 5,
|
||||||
Enable_if_Polygon_2_iterator<InputIterator>* = 0)
|
Enable_if_Polygon_2_iterator<InputIterator>* = 0)
|
||||||
{ return r_join(begin, end, oi, k); }
|
{ return r_join(begin, end, oi, k); }
|
||||||
|
|
||||||
// Tag_false => do not convert to polylines
|
// Tag_false => do not convert to polylines
|
||||||
template <typename InputIterator, typename OutputIterator>
|
template <typename InputIterator, typename OutputIterator>
|
||||||
inline OutputIterator join(InputIterator begin, InputIterator end,
|
inline OutputIterator join(InputIterator begin, InputIterator end,
|
||||||
OutputIterator oi, Tag_false, unsigned int k=5,
|
OutputIterator oi, Tag_false, std::size_t k = 5,
|
||||||
Enable_if_Polygon_2_iterator<InputIterator>* = 0)
|
Enable_if_Polygon_2_iterator<InputIterator>* = 0) {
|
||||||
{
|
|
||||||
typename Iterator_to_gps_traits<InputIterator>::Traits traits;
|
typename Iterator_to_gps_traits<InputIterator>::Traits traits;
|
||||||
return r_join(begin, end, oi, traits, k);
|
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
|
// General polygons or polygons with holes
|
||||||
template <typename InputIterator, typename OutputIterator>
|
template <typename InputIterator, typename OutputIterator>
|
||||||
inline OutputIterator join(InputIterator begin, InputIterator end,
|
inline OutputIterator join(InputIterator begin, InputIterator end,
|
||||||
OutputIterator oi, unsigned int k=5,
|
OutputIterator oi, std::size_t k = 5,
|
||||||
Disable_if_Polygon_2_iterator<InputIterator>* = 0)
|
Disable_if_Polygon_2_iterator<InputIterator>* = 0) {
|
||||||
{
|
|
||||||
typename Iterator_to_gps_traits<InputIterator>::Traits traits;
|
typename Iterator_to_gps_traits<InputIterator>::Traits traits;
|
||||||
return r_join(begin, end, oi, traits, k);
|
return r_join(begin, end, oi, traits, k);
|
||||||
}
|
}
|
||||||
|
|
@ -291,7 +279,7 @@ template <typename InputIterator1, typename InputIterator2,
|
||||||
typename OutputIterator, typename Traits>
|
typename OutputIterator, typename Traits>
|
||||||
inline OutputIterator join(InputIterator1 begin1, InputIterator1 end1,
|
inline OutputIterator join(InputIterator1 begin1, InputIterator1 end1,
|
||||||
InputIterator2 begin2, InputIterator2 end2,
|
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); }
|
{ return r_join(begin1, end1, begin2, end2, oi, traits, k); }
|
||||||
|
|
||||||
// Without Traits
|
// Without Traits
|
||||||
|
|
@ -301,7 +289,7 @@ template <typename InputIterator1, typename InputIterator2,
|
||||||
inline OutputIterator join(InputIterator1 begin1, InputIterator1 end1,
|
inline OutputIterator join(InputIterator1 begin1, InputIterator1 end1,
|
||||||
InputIterator2 begin2, InputIterator2 end2,
|
InputIterator2 begin2, InputIterator2 end2,
|
||||||
OutputIterator oi, Tag_true = Tag_true(),
|
OutputIterator oi, Tag_true = Tag_true(),
|
||||||
unsigned int k=5,
|
std::size_t k = 5,
|
||||||
Enable_if_Polygon_2_iterator<InputIterator1>* = 0)
|
Enable_if_Polygon_2_iterator<InputIterator1>* = 0)
|
||||||
{ return r_join(begin1, end1, begin2, end2, oi, k); }
|
{ return r_join(begin1, end1, begin2, end2, oi, k); }
|
||||||
|
|
||||||
|
|
@ -310,9 +298,8 @@ template <typename InputIterator1, typename InputIterator2,
|
||||||
typename OutputIterator>
|
typename OutputIterator>
|
||||||
inline OutputIterator join(InputIterator1 begin1, InputIterator1 end1,
|
inline OutputIterator join(InputIterator1 begin1, InputIterator1 end1,
|
||||||
InputIterator2 begin2, InputIterator2 end2,
|
InputIterator2 begin2, InputIterator2 end2,
|
||||||
OutputIterator oi, Tag_false, unsigned int k=5,
|
OutputIterator oi, Tag_false, std::size_t k = 5,
|
||||||
Enable_if_Polygon_2_iterator<InputIterator1>* = 0)
|
Enable_if_Polygon_2_iterator<InputIterator1>* = 0) {
|
||||||
{
|
|
||||||
typename Iterator_to_gps_traits<InputIterator1>::Traits traits;
|
typename Iterator_to_gps_traits<InputIterator1>::Traits traits;
|
||||||
return r_join(begin1, end1, begin2, end2, oi, traits, k);
|
return r_join(begin1, end1, begin2, end2, oi, traits, k);
|
||||||
}
|
}
|
||||||
|
|
@ -322,9 +309,8 @@ template <typename InputIterator1, typename InputIterator2,
|
||||||
typename OutputIterator>
|
typename OutputIterator>
|
||||||
inline OutputIterator join(InputIterator1 begin1, InputIterator1 end1,
|
inline OutputIterator join(InputIterator1 begin1, InputIterator1 end1,
|
||||||
InputIterator2 begin2, InputIterator2 end2,
|
InputIterator2 begin2, InputIterator2 end2,
|
||||||
OutputIterator oi, unsigned int k=5,
|
OutputIterator oi, std::size_t k = 5,
|
||||||
Disable_if_Polygon_2_iterator<InputIterator1>* = 0)
|
Disable_if_Polygon_2_iterator<InputIterator1>* = 0) {
|
||||||
{
|
|
||||||
typename Iterator_to_gps_traits<InputIterator1>::Traits traits;
|
typename Iterator_to_gps_traits<InputIterator1>::Traits traits;
|
||||||
return r_join(begin1, end1, begin2, end2, oi, traits, k);
|
return r_join(begin1, end1, begin2, end2, oi, traits, k);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@
|
||||||
// $Id$
|
// $Id$
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
//
|
//
|
||||||
//
|
|
||||||
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||||
// Ron Wein <wein@post.tau.ac.il>
|
// Ron Wein <wein@post.tau.ac.il>
|
||||||
// Efi Fogel <efif@post.tau.ac.il>
|
// Efi Fogel <efif@post.tau.ac.il>
|
||||||
|
|
@ -33,8 +32,7 @@
|
||||||
#include <CGAL/Boolean_set_operations_2/Polygon_conversions.h>
|
#include <CGAL/Boolean_set_operations_2/Polygon_conversions.h>
|
||||||
#include <CGAL/type_traits/is_iterator.h>
|
#include <CGAL/type_traits/is_iterator.h>
|
||||||
|
|
||||||
namespace CGAL
|
namespace CGAL {
|
||||||
{
|
|
||||||
|
|
||||||
/// \name symmetric_difference() functions.
|
/// \name symmetric_difference() functions.
|
||||||
//@{
|
//@{
|
||||||
|
|
@ -62,10 +60,9 @@ template <typename Kernel, typename Container, typename OutputIterator>
|
||||||
inline OutputIterator
|
inline OutputIterator
|
||||||
symmetric_difference(const Polygon_2<Kernel, Container>& pgn1,
|
symmetric_difference(const Polygon_2<Kernel, Container>& pgn1,
|
||||||
const Polygon_2<Kernel, Container>& pgn2,
|
const Polygon_2<Kernel, Container>& pgn2,
|
||||||
OutputIterator oi, Tag_false)
|
OutputIterator oi, Tag_false) {
|
||||||
{
|
|
||||||
// Use the first polygon to determine the (default) traits
|
// Use the first polygon to determine the (default) traits
|
||||||
typedef Polygon_2<Kernel, Container> Polygon;
|
using Polygon = Polygon_2<Kernel, Container>;
|
||||||
typename Gps_default_traits<Polygon>::Traits traits;
|
typename Gps_default_traits<Polygon>::Traits traits;
|
||||||
return s_symmetric_difference(pgn1, pgn2, oi, traits);
|
return s_symmetric_difference(pgn1, pgn2, oi, traits);
|
||||||
}
|
}
|
||||||
|
|
@ -93,10 +90,9 @@ template <typename Kernel, typename Container, typename OutputIterator>
|
||||||
inline OutputIterator
|
inline OutputIterator
|
||||||
symmetric_difference(const Polygon_2<Kernel, Container>& pgn1,
|
symmetric_difference(const Polygon_2<Kernel, Container>& pgn1,
|
||||||
const Polygon_with_holes_2<Kernel, Container>& pgn2,
|
const Polygon_with_holes_2<Kernel, Container>& pgn2,
|
||||||
OutputIterator oi, Tag_false)
|
OutputIterator oi, Tag_false) {
|
||||||
{
|
|
||||||
// Use the first polygon to determine the (default) traits
|
// Use the first polygon to determine the (default) traits
|
||||||
typedef Polygon_2<Kernel, Container> Polygon;
|
using Polygon = Polygon_2<Kernel, Container>;
|
||||||
typename Gps_default_traits<Polygon>::Traits traits;
|
typename Gps_default_traits<Polygon>::Traits traits;
|
||||||
return s_symmetric_difference(pgn1, pgn2, oi, traits);
|
return s_symmetric_difference(pgn1, pgn2, oi, traits);
|
||||||
}
|
}
|
||||||
|
|
@ -124,10 +120,9 @@ template <typename Kernel, typename Container, typename OutputIterator>
|
||||||
inline OutputIterator
|
inline OutputIterator
|
||||||
symmetric_difference(const Polygon_with_holes_2<Kernel, Container>& pgn1,
|
symmetric_difference(const Polygon_with_holes_2<Kernel, Container>& pgn1,
|
||||||
const Polygon_2<Kernel, Container>& pgn2,
|
const Polygon_2<Kernel, Container>& pgn2,
|
||||||
OutputIterator oi, Tag_false)
|
OutputIterator oi, Tag_false) {
|
||||||
{
|
|
||||||
// Use the first polygon to determine the (default) traits
|
// Use the first polygon to determine the (default) traits
|
||||||
typedef Polygon_with_holes_2<Kernel, Container> Polygon_with_holes;
|
using Polygon_with_holes = Polygon_with_holes_2<Kernel, Container>;
|
||||||
typename Gps_default_traits<Polygon_with_holes>::Traits traits;
|
typename Gps_default_traits<Polygon_with_holes>::Traits traits;
|
||||||
return s_symmetric_difference(pgn1, pgn2, oi, traits);
|
return s_symmetric_difference(pgn1, pgn2, oi, traits);
|
||||||
}
|
}
|
||||||
|
|
@ -155,10 +150,9 @@ template <typename Kernel, typename Container, typename OutputIterator>
|
||||||
inline OutputIterator
|
inline OutputIterator
|
||||||
symmetric_difference(const Polygon_with_holes_2<Kernel, Container>& pgn1,
|
symmetric_difference(const Polygon_with_holes_2<Kernel, Container>& pgn1,
|
||||||
const Polygon_with_holes_2<Kernel, Container>& pgn2,
|
const Polygon_with_holes_2<Kernel, Container>& pgn2,
|
||||||
OutputIterator oi, Tag_false)
|
OutputIterator oi, Tag_false) {
|
||||||
{
|
|
||||||
// Use the first polygon to determine the (default) traits
|
// Use the first polygon to determine the (default) traits
|
||||||
typedef Polygon_with_holes_2<Kernel, Container> Polygon_with_holes;
|
using Polygon_with_holes = Polygon_with_holes_2<Kernel, Container>;
|
||||||
typename Gps_default_traits<Polygon_with_holes>::Traits traits;
|
typename Gps_default_traits<Polygon_with_holes>::Traits traits;
|
||||||
return s_symmetric_difference(pgn1, pgn2, oi, traits);
|
return s_symmetric_difference(pgn1, pgn2, oi, traits);
|
||||||
}
|
}
|
||||||
|
|
@ -176,10 +170,9 @@ template <typename ArrTraits, typename OutputIterator>
|
||||||
inline OutputIterator
|
inline OutputIterator
|
||||||
symmetric_difference(const General_polygon_2<ArrTraits>& pgn1,
|
symmetric_difference(const General_polygon_2<ArrTraits>& pgn1,
|
||||||
const General_polygon_2<ArrTraits>& pgn2,
|
const General_polygon_2<ArrTraits>& pgn2,
|
||||||
OutputIterator oi)
|
OutputIterator oi) {
|
||||||
{
|
|
||||||
// Use the first polygon to determine the (default) traits
|
// Use the first polygon to determine the (default) traits
|
||||||
typedef General_polygon_2<ArrTraits> Polygon;
|
using Polygon = General_polygon_2<ArrTraits>;
|
||||||
typename Gps_default_traits<Polygon>::Traits traits;
|
typename Gps_default_traits<Polygon>::Traits traits;
|
||||||
return s_symmetric_difference(pgn1, pgn2, oi, traits);
|
return s_symmetric_difference(pgn1, pgn2, oi, traits);
|
||||||
}
|
}
|
||||||
|
|
@ -200,10 +193,9 @@ inline OutputIterator
|
||||||
symmetric_difference(const General_polygon_2<ArrTraits>& pgn1,
|
symmetric_difference(const General_polygon_2<ArrTraits>& pgn1,
|
||||||
const General_polygon_with_holes_2
|
const General_polygon_with_holes_2
|
||||||
<General_polygon_2<ArrTraits> >& pgn2,
|
<General_polygon_2<ArrTraits> >& pgn2,
|
||||||
OutputIterator oi)
|
OutputIterator oi) {
|
||||||
{
|
|
||||||
// Use the first polygon to determine the (default) traits
|
// Use the first polygon to determine the (default) traits
|
||||||
typedef General_polygon_2<ArrTraits> Polygon;
|
using Polygon = General_polygon_2<ArrTraits>;
|
||||||
typename Gps_default_traits<Polygon>::Traits traits;
|
typename Gps_default_traits<Polygon>::Traits traits;
|
||||||
return s_symmetric_difference(pgn1, pgn2, oi, traits);
|
return s_symmetric_difference(pgn1, pgn2, oi, traits);
|
||||||
}
|
}
|
||||||
|
|
@ -224,11 +216,10 @@ inline OutputIterator
|
||||||
symmetric_difference(const General_polygon_with_holes_2
|
symmetric_difference(const General_polygon_with_holes_2
|
||||||
<General_polygon_2<ArrTraits> >& pgn1,
|
<General_polygon_2<ArrTraits> >& pgn1,
|
||||||
const General_polygon_2<ArrTraits>& pgn2,
|
const General_polygon_2<ArrTraits>& pgn2,
|
||||||
OutputIterator oi)
|
OutputIterator oi) {
|
||||||
{
|
|
||||||
// Use the first polygon to determine the (default) traits
|
// Use the first polygon to determine the (default) traits
|
||||||
typedef General_polygon_2<ArrTraits> Polygon;
|
using Polygon = General_polygon_2<ArrTraits>;
|
||||||
typedef General_polygon_with_holes_2<Polygon> Polygon_with_holes;
|
using Polygon_with_holes = General_polygon_with_holes_2<Polygon>;
|
||||||
typename Gps_default_traits<Polygon_with_holes>::Traits traits;
|
typename Gps_default_traits<Polygon_with_holes>::Traits traits;
|
||||||
return s_symmetric_difference(pgn1, pgn2, oi, traits);
|
return s_symmetric_difference(pgn1, pgn2, oi, traits);
|
||||||
}
|
}
|
||||||
|
|
@ -247,9 +238,8 @@ template <typename Polygon_, typename OutputIterator>
|
||||||
inline OutputIterator
|
inline OutputIterator
|
||||||
symmetric_difference(const General_polygon_with_holes_2<Polygon_>& pgn1,
|
symmetric_difference(const General_polygon_with_holes_2<Polygon_>& pgn1,
|
||||||
const General_polygon_with_holes_2<Polygon_>& pgn2,
|
const General_polygon_with_holes_2<Polygon_>& pgn2,
|
||||||
OutputIterator oi)
|
OutputIterator oi) {
|
||||||
{
|
using Polygon_with_holes = General_polygon_with_holes_2<Polygon_>;
|
||||||
typedef General_polygon_with_holes_2<Polygon_> Polygon_with_holes;
|
|
||||||
typename Gps_default_traits<Polygon_with_holes>::Traits traits;
|
typename Gps_default_traits<Polygon_with_holes>::Traits traits;
|
||||||
return s_symmetric_difference(pgn1, pgn2, oi, traits);
|
return s_symmetric_difference(pgn1, pgn2, oi, traits);
|
||||||
}
|
}
|
||||||
|
|
@ -264,7 +254,7 @@ template <typename InputIterator, typename OutputIterator, typename Traits>
|
||||||
inline
|
inline
|
||||||
OutputIterator symmetric_difference(InputIterator begin, InputIterator end,
|
OutputIterator symmetric_difference(InputIterator begin, InputIterator end,
|
||||||
OutputIterator oi, Traits& traits,
|
OutputIterator oi, Traits& traits,
|
||||||
unsigned int k=5)
|
std::size_t k = 5)
|
||||||
{ return r_symmetric_difference(begin, end, oi, traits, k); }
|
{ return r_symmetric_difference(begin, end, oi, traits, k); }
|
||||||
|
|
||||||
// Without Traits
|
// Without Traits
|
||||||
|
|
@ -272,7 +262,7 @@ OutputIterator symmetric_difference(InputIterator begin, InputIterator end,
|
||||||
template <typename InputIterator, typename OutputIterator>
|
template <typename InputIterator, typename OutputIterator>
|
||||||
inline OutputIterator
|
inline OutputIterator
|
||||||
symmetric_difference(InputIterator begin, InputIterator end,
|
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<InputIterator>* = 0)
|
Enable_if_Polygon_2_iterator<InputIterator>* = 0)
|
||||||
{ return r_symmetric_difference(begin, end, oi, k); }
|
{ return r_symmetric_difference(begin, end, oi, k); }
|
||||||
|
|
||||||
|
|
@ -280,9 +270,8 @@ symmetric_difference(InputIterator begin, InputIterator end,
|
||||||
template <typename InputIterator, typename OutputIterator>
|
template <typename InputIterator, typename OutputIterator>
|
||||||
inline OutputIterator
|
inline OutputIterator
|
||||||
symmetric_difference(InputIterator begin, InputIterator end,
|
symmetric_difference(InputIterator begin, InputIterator end,
|
||||||
OutputIterator oi, Tag_false, unsigned int k=5,
|
OutputIterator oi, Tag_false, std::size_t k = 5,
|
||||||
Enable_if_Polygon_2_iterator<InputIterator>* = 0)
|
Enable_if_Polygon_2_iterator<InputIterator>* = 0) {
|
||||||
{
|
|
||||||
typename Iterator_to_gps_traits<InputIterator>::Traits traits;
|
typename Iterator_to_gps_traits<InputIterator>::Traits traits;
|
||||||
return r_symmetric_difference(begin, end, oi, traits, k);
|
return r_symmetric_difference(begin, end, oi, traits, k);
|
||||||
}
|
}
|
||||||
|
|
@ -291,9 +280,8 @@ symmetric_difference(InputIterator begin, InputIterator end,
|
||||||
template <typename InputIterator, typename OutputIterator>
|
template <typename InputIterator, typename OutputIterator>
|
||||||
inline OutputIterator
|
inline OutputIterator
|
||||||
symmetric_difference(InputIterator begin, InputIterator end,
|
symmetric_difference(InputIterator begin, InputIterator end,
|
||||||
OutputIterator oi, unsigned int k=5,
|
OutputIterator oi, std::size_t k = 5,
|
||||||
Disable_if_Polygon_2_iterator<InputIterator>* = 0)
|
Disable_if_Polygon_2_iterator<InputIterator>* = 0) {
|
||||||
{
|
|
||||||
typename Iterator_to_gps_traits<InputIterator>::Traits traits;
|
typename Iterator_to_gps_traits<InputIterator>::Traits traits;
|
||||||
return r_symmetric_difference(begin, end, oi, traits, k);
|
return r_symmetric_difference(begin, end, oi, traits, k);
|
||||||
}
|
}
|
||||||
|
|
@ -306,7 +294,7 @@ inline
|
||||||
OutputIterator symmetric_difference(InputIterator1 begin1, InputIterator1 end1,
|
OutputIterator symmetric_difference(InputIterator1 begin1, InputIterator1 end1,
|
||||||
InputIterator2 begin2, InputIterator2 end2,
|
InputIterator2 begin2, InputIterator2 end2,
|
||||||
OutputIterator oi, Traits& traits,
|
OutputIterator oi, Traits& traits,
|
||||||
unsigned int k=5)
|
std::size_t k = 5)
|
||||||
{ return r_symmetric_difference(begin1, end1, begin2, end2, oi, traits, k); }
|
{ return r_symmetric_difference(begin1, end1, begin2, end2, oi, traits, k); }
|
||||||
|
|
||||||
// Without Traits
|
// Without Traits
|
||||||
|
|
@ -316,7 +304,7 @@ template <typename InputIterator1, typename InputIterator2,
|
||||||
inline OutputIterator
|
inline OutputIterator
|
||||||
symmetric_difference(InputIterator1 begin1, InputIterator1 end1,
|
symmetric_difference(InputIterator1 begin1, InputIterator1 end1,
|
||||||
InputIterator2 begin2, InputIterator2 end2,
|
InputIterator2 begin2, InputIterator2 end2,
|
||||||
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<InputIterator1>* = 0)
|
Enable_if_Polygon_2_iterator<InputIterator1>* = 0)
|
||||||
{ return r_symmetric_difference(begin1, end1, begin2, end2, oi, k); }
|
{ return r_symmetric_difference(begin1, end1, begin2, end2, oi, k); }
|
||||||
|
|
||||||
|
|
@ -326,9 +314,8 @@ template <typename InputIterator1, typename InputIterator2,
|
||||||
inline OutputIterator
|
inline OutputIterator
|
||||||
symmetric_difference(InputIterator1 begin1, InputIterator1 end1,
|
symmetric_difference(InputIterator1 begin1, InputIterator1 end1,
|
||||||
InputIterator2 begin2, InputIterator2 end2,
|
InputIterator2 begin2, InputIterator2 end2,
|
||||||
OutputIterator oi, Tag_false, unsigned int k=5,
|
OutputIterator oi, Tag_false, std::size_t k = 5,
|
||||||
Enable_if_Polygon_2_iterator<InputIterator1>* = 0)
|
Enable_if_Polygon_2_iterator<InputIterator1>* = 0) {
|
||||||
{
|
|
||||||
typename Iterator_to_gps_traits<InputIterator1>::Traits traits;
|
typename Iterator_to_gps_traits<InputIterator1>::Traits traits;
|
||||||
return r_symmetric_difference(begin1, end1, begin2, end2, oi, traits, k);
|
return r_symmetric_difference(begin1, end1, begin2, end2, oi, traits, k);
|
||||||
}
|
}
|
||||||
|
|
@ -339,9 +326,8 @@ template <typename InputIterator1, typename InputIterator2,
|
||||||
inline OutputIterator
|
inline OutputIterator
|
||||||
symmetric_difference(InputIterator1 begin1, InputIterator1 end1,
|
symmetric_difference(InputIterator1 begin1, InputIterator1 end1,
|
||||||
InputIterator2 begin2, InputIterator2 end2,
|
InputIterator2 begin2, InputIterator2 end2,
|
||||||
OutputIterator oi, unsigned int k=5,
|
OutputIterator oi, std::size_t k = 5,
|
||||||
Disable_if_Polygon_2_iterator<InputIterator1>* = 0)
|
Disable_if_Polygon_2_iterator<InputIterator1>* = 0) {
|
||||||
{
|
|
||||||
typename Iterator_to_gps_traits<InputIterator1>::Traits traits;
|
typename Iterator_to_gps_traits<InputIterator1>::Traits traits;
|
||||||
return r_symmetric_difference(begin1, end1, begin2, end2, oi, traits, k);
|
return r_symmetric_difference(begin1, end1, begin2, end2, oi, traits, k);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,25 +27,20 @@
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
|
|
||||||
// General_polygon_set_2
|
// General_polygon_set_2
|
||||||
template <class Traits_, class Dcel_ = Gps_default_dcel<Traits_> >
|
template <typename Traits_, typename Dcel_ = Gps_default_dcel<Traits_>>
|
||||||
class General_polygon_set_2 : public General_polygon_set_on_surface_2
|
class General_polygon_set_2 :
|
||||||
<Traits_, typename Default_planar_topology<Traits_, Dcel_>::Traits>
|
public General_polygon_set_on_surface_2<
|
||||||
{
|
Traits_, typename Default_planar_topology<Traits_, Dcel_>::Traits> {
|
||||||
protected:
|
|
||||||
typedef General_polygon_set_2<Traits_, Dcel_> Self;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef Traits_ Traits_2;
|
using Traits_2 = Traits_;
|
||||||
typedef Dcel_ Dcel;
|
using Dcel = Dcel_;
|
||||||
|
using Self = General_polygon_set_2<Traits_2, Dcel>;
|
||||||
typedef General_polygon_set_on_surface_2 <Traits_2,
|
using Topology_traits = typename Default_planar_topology<Traits_2, Dcel>::Traits;
|
||||||
typename Default_planar_topology<Traits_2, Dcel >::Traits>
|
using Base = General_polygon_set_on_surface_2<Traits_2, Topology_traits>;
|
||||||
Base;
|
using Arrangement_2 = CGAL::Arrangement_2<Traits_2, Dcel>;
|
||||||
|
using Polygon_2 = typename Base::Polygon_2;
|
||||||
typedef CGAL::Arrangement_2<Traits_2, Dcel> Arrangement_2;
|
using Polygon_with_holes_2 = typename Base::Polygon_with_holes_2;
|
||||||
|
|
||||||
typedef typename Base::Polygon_2 Polygon_2;
|
|
||||||
typedef typename Base::Polygon_with_holes_2 Polygon_with_holes_2;
|
|
||||||
|
|
||||||
// default constructor
|
// default constructor
|
||||||
General_polygon_set_2() : Base() {}
|
General_polygon_set_2() : Base() {}
|
||||||
|
|
@ -80,19 +75,16 @@ public:
|
||||||
using Base::join;
|
using Base::join;
|
||||||
using Base::symmetric_difference;
|
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<const Base&>(ps1),
|
Base::intersection(static_cast<const Base&>(ps1),
|
||||||
static_cast<const Base&>(ps2));
|
static_cast<const Base&>(ps2));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void join(const Self& ps1, const Self& ps2)
|
inline void join(const Self& ps1, const Self& ps2) {
|
||||||
{
|
|
||||||
Base::join(static_cast<const Base&>(ps1), static_cast<const Base&>(ps2));
|
Base::join(static_cast<const Base&>(ps1), static_cast<const Base&>(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<const Base&>(ps1),
|
Base::symmetric_difference(static_cast<const Base&>(ps1),
|
||||||
static_cast<const Base&>(ps2));
|
static_cast<const Base&>(ps2));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,54 +23,48 @@
|
||||||
|
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
|
|
||||||
namespace Boolean_set_operation_2_internal
|
namespace Boolean_set_operation_2_internal {
|
||||||
{
|
|
||||||
struct PreconditionValidationPolicy
|
struct PreconditionValidationPolicy {
|
||||||
{
|
/*! Checks if a Traits::Polygon_2 or Traits::Polygon_with_holes_2 are valid.
|
||||||
/*! is_valid - Checks if a Traits::Polygon_2 OR
|
* This validation policy checks that polygons are valid in a
|
||||||
Traits::Polygon_with_holes_2 are valid.
|
* CGAL_precondition macro. We inherit from Gps_on_surface_base_2 and use
|
||||||
This validation policy checks that polygons are valid in a
|
* preconditions to validate the input polygons.
|
||||||
CGAL_precondition macro. We inherit from Gps_on_surface_base_2
|
|
||||||
and use preconditions to validate the input polygons.
|
|
||||||
*/
|
*/
|
||||||
template <class Polygon, class Traits>
|
template <typename Polygon, typename Traits>
|
||||||
inline static void is_valid(const Polygon& p, const Traits& t)
|
inline static void is_valid(const Polygon& p, const Traits& t) {
|
||||||
{
|
|
||||||
CGAL_precondition(is_valid_unknown_polygon(p, t));
|
CGAL_precondition(is_valid_unknown_polygon(p, t));
|
||||||
CGAL_USE(p); CGAL_USE(t);
|
CGAL_USE(p); CGAL_USE(t);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// General_polygon_set_on_surface_2
|
/* `General_polygon_set_on_surface_2` class is derived from
|
||||||
/*
|
* `Gps_on_surface_base_2`. It enforces the validation conditions for general
|
||||||
This class is derived from Gps_on_surface_base_2.
|
* polygons, and is therefore the basic implementation that should be used by
|
||||||
It enforces the validation conditions for general polygons, and is therefore
|
* the user
|
||||||
the basic implementation that should be used by the user
|
|
||||||
*/
|
*/
|
||||||
template <class Traits_, class TopTraits_>
|
template <typename Traits_, typename TopTraits_>
|
||||||
class General_polygon_set_on_surface_2 :
|
class General_polygon_set_on_surface_2 :
|
||||||
public Gps_on_surface_base_2<Traits_, TopTraits_,
|
public Gps_on_surface_base_2<
|
||||||
Boolean_set_operation_2_internal::PreconditionValidationPolicy>
|
Traits_, TopTraits_,
|
||||||
{
|
Boolean_set_operation_2_internal::PreconditionValidationPolicy> {
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
typedef Traits_ Traits_2;
|
using Traits_2 = Traits_;
|
||||||
typedef General_polygon_set_on_surface_2<Traits_2, TopTraits_> Self;
|
using Self = General_polygon_set_on_surface_2<Traits_2, TopTraits_>;
|
||||||
typedef Gps_on_surface_base_2<Traits_2, TopTraits_,
|
using Base = Gps_on_surface_base_2<Traits_2, TopTraits_,
|
||||||
Boolean_set_operation_2_internal::PreconditionValidationPolicy> Base;
|
Boolean_set_operation_2_internal::PreconditionValidationPolicy>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef typename Base::Polygon_2 Polygon_2;
|
using Polygon_2 = typename Base::Polygon_2;
|
||||||
typedef typename Base::Polygon_with_holes_2
|
using Polygon_with_holes_2 = typename Base::Polygon_with_holes_2;
|
||||||
Polygon_with_holes_2;
|
using Arrangement_on_surface_2 = typename Base::Arrangement_on_surface_2;
|
||||||
typedef typename Base::Arrangement_on_surface_2
|
|
||||||
Arrangement_on_surface_2;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// default constructor
|
// default constructor
|
||||||
General_polygon_set_on_surface_2() : Base()
|
General_polygon_set_on_surface_2() : Base() {}
|
||||||
{}
|
|
||||||
|
|
||||||
// constructor from a traits object
|
// constructor from a traits object
|
||||||
General_polygon_set_on_surface_2(const Traits_2& traits) : Base(traits) {}
|
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) {}
|
General_polygon_set_on_surface_2(const Self& ps) : Base(ps) {}
|
||||||
|
|
||||||
// assignment operator
|
// 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);
|
Base::operator=(ps);
|
||||||
return (*this);
|
return (*this);
|
||||||
}
|
}
|
||||||
|
|
@ -90,19 +83,15 @@ public:
|
||||||
|
|
||||||
// constructor from a polygon with holes
|
// constructor from a polygon with holes
|
||||||
explicit
|
explicit
|
||||||
General_polygon_set_on_surface_2(const Polygon_with_holes_2& pwh) :
|
General_polygon_set_on_surface_2(const Polygon_with_holes_2& pwh) : Base(pwh) {}
|
||||||
Base(pwh)
|
|
||||||
{}
|
|
||||||
|
|
||||||
// constructor from a polygon and a traits object
|
// constructor from a polygon and a traits object
|
||||||
explicit General_polygon_set_on_surface_2(const Polygon_2& pgn,
|
explicit General_polygon_set_on_surface_2(const Polygon_2& pgn, const Traits_2& traits) :
|
||||||
const Traits_2& traits) :
|
|
||||||
Base(pgn, traits) {}
|
Base(pgn, traits) {}
|
||||||
|
|
||||||
// constructor from a polygon with holes and a traits object
|
// constructor from a polygon with holes and a traits object
|
||||||
explicit
|
explicit
|
||||||
General_polygon_set_on_surface_2(const Polygon_with_holes_2& pwh,
|
General_polygon_set_on_surface_2(const Polygon_with_holes_2& pwh, const Traits_2& traits) :
|
||||||
const Traits_2& traits) :
|
|
||||||
Base(pwh, traits)
|
Base(pwh, traits)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
@ -142,4 +131,4 @@ private:
|
||||||
|
|
||||||
#include <CGAL/enable_warnings.h>
|
#include <CGAL/enable_warnings.h>
|
||||||
|
|
||||||
#endif // CGAL_GENERAL_POLYGON_SET_ON_SURFACE_2_H
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -1,48 +0,0 @@
|
||||||
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
|
||||||
#include <CGAL/Boolean_set_operations_2.h>
|
|
||||||
#include <CGAL/Polygon_set_2.h>
|
|
||||||
#include <list>
|
|
||||||
|
|
||||||
typedef CGAL::Exact_predicates_exact_constructions_kernel K;
|
|
||||||
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
CGAL::Polygon_2<K> ob;
|
|
||||||
ob.push_back(CGAL::Point_2<K>(1, 1));
|
|
||||||
ob.push_back(CGAL::Point_2<K>(1, 0));
|
|
||||||
ob.push_back(CGAL::Point_2<K>(6, 0));
|
|
||||||
ob.push_back(CGAL::Point_2<K>(6, 7));
|
|
||||||
ob.push_back(CGAL::Point_2<K>(0, 7));
|
|
||||||
ob.push_back(CGAL::Point_2<K>(0, 1));
|
|
||||||
|
|
||||||
CGAL::Polygon_2<K> h;
|
|
||||||
h.push_back(CGAL::Point_2<K>(2, 1));
|
|
||||||
h.push_back(CGAL::Point_2<K>(2, 2));
|
|
||||||
h.push_back(CGAL::Point_2<K>(3, 2));
|
|
||||||
h.push_back(CGAL::Point_2<K>(3, 3));
|
|
||||||
h.push_back(CGAL::Point_2<K>(2, 3));
|
|
||||||
h.push_back(CGAL::Point_2<K>(2, 4));
|
|
||||||
h.push_back(CGAL::Point_2<K>(3, 4));
|
|
||||||
h.push_back(CGAL::Point_2<K>(3, 5));
|
|
||||||
h.push_back(CGAL::Point_2<K>(4, 5));
|
|
||||||
h.push_back(CGAL::Point_2<K>(4, 1));
|
|
||||||
|
|
||||||
CGAL::Polygon_with_holes_2<K> ob_with_holes(ob);
|
|
||||||
ob_with_holes.add_hole(h);
|
|
||||||
CGAL::Polygon_set_2<K> inter(ob_with_holes);
|
|
||||||
|
|
||||||
CGAL::Polygon_2<K> new_poly;
|
|
||||||
new_poly.push_back(CGAL::Point_2<K>(1, 1));
|
|
||||||
new_poly.push_back(CGAL::Point_2<K>(2, 1));
|
|
||||||
new_poly.push_back(CGAL::Point_2<K>(2, 2));
|
|
||||||
new_poly.push_back(CGAL::Point_2<K>(2, 3));
|
|
||||||
new_poly.push_back(CGAL::Point_2<K>(2, 4));
|
|
||||||
new_poly.push_back(CGAL::Point_2<K>(2, 5));
|
|
||||||
new_poly.push_back(CGAL::Point_2<K>(3, 5));
|
|
||||||
new_poly.push_back(CGAL::Point_2<K>(4, 5));
|
|
||||||
new_poly.push_back(CGAL::Point_2<K>(4, 6));
|
|
||||||
new_poly.push_back(CGAL::Point_2<K>(1, 6));
|
|
||||||
|
|
||||||
inter.difference(new_poly);
|
|
||||||
}
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <CGAL/Simple_cartesian.h>
|
#include <CGAL/Simple_cartesian.h>
|
||||||
|
|
@ -13,30 +12,27 @@
|
||||||
#include <CGAL/Polygon_set_2.h>
|
#include <CGAL/Polygon_set_2.h>
|
||||||
|
|
||||||
//typedef CGAL::Quotient<CGAL::MP_Float> Number_type;
|
//typedef CGAL::Quotient<CGAL::MP_Float> Number_type;
|
||||||
typedef int Number_type;
|
using Number_type = int;
|
||||||
|
|
||||||
typedef CGAL::Simple_cartesian<Number_type> Kernel;
|
using Kernel = CGAL::Simple_cartesian<Number_type>;
|
||||||
|
|
||||||
typedef CGAL::Gps_segment_traits_2<Kernel> Traits;
|
using Traits = CGAL::Gps_segment_traits_2<Kernel>;
|
||||||
typedef CGAL::Polygon_set_2<Kernel> Ps;
|
using Ps = CGAL::Polygon_set_2<Kernel>;
|
||||||
|
|
||||||
typedef CGAL::Arr_segment_traits_2<Kernel> Arr_traits;
|
using Arr_traits = CGAL::Arr_segment_traits_2<Kernel>;
|
||||||
typedef CGAL::Gps_traits_2<Arr_traits> General_traits;
|
using General_traits = CGAL::Gps_traits_2<Arr_traits>;
|
||||||
typedef CGAL::General_polygon_set_2<General_traits> Gps;
|
using Gps = CGAL::General_polygon_set_2<General_traits>;
|
||||||
|
|
||||||
typedef CGAL::Arr_non_caching_segment_traits_2<Kernel> Nc_traits;
|
using Nc_traits = CGAL::Arr_non_caching_segment_traits_2<Kernel>;
|
||||||
typedef CGAL::Gps_segment_traits_2<Kernel,
|
using Traits_non_caching = CGAL::Gps_segment_traits_2<Kernel, std::vector<Kernel::Point_2>, Nc_traits>;
|
||||||
std::vector<Kernel::Point_2>,
|
using Gps_non_caching = CGAL::General_polygon_set_2<Traits_non_caching>;
|
||||||
Nc_traits> Traits_non_caching;
|
|
||||||
typedef CGAL::General_polygon_set_2<Traits_non_caching> Gps_non_caching;
|
|
||||||
|
|
||||||
template <class GPS>
|
template <typename GPS>
|
||||||
void test()
|
void test() {
|
||||||
{
|
using Traits = typename GPS::Traits_2;
|
||||||
typedef typename GPS::Traits_2 Traits;
|
using Point_2 = typename Traits::Point_2;
|
||||||
typedef typename Traits::Point_2 Point_2;
|
using Polygon_2 = typename Traits::Polygon_2;
|
||||||
typedef typename Traits::Polygon_2 Polygon_2;
|
using Polygon_with_holes_2 = typename Traits::Polygon_with_holes_2;
|
||||||
typedef typename Traits::Polygon_with_holes_2 Polygon_with_holes_2;
|
|
||||||
|
|
||||||
Polygon_2 pgn1, pgn2;
|
Polygon_2 pgn1, pgn2;
|
||||||
Polygon_with_holes_2 pgn_with_holes1, pgn_with_holes2;
|
Polygon_with_holes_2 pgn_with_holes1, pgn_with_holes2;
|
||||||
|
|
@ -242,8 +238,7 @@ void test()
|
||||||
GPS new_gps2 = gps;
|
GPS new_gps2 = gps;
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_CGAL_Polygon_variants()
|
void test_CGAL_Polygon_variants() {
|
||||||
{
|
|
||||||
typedef CGAL::Polygon_2<Kernel> Polygon_2;
|
typedef CGAL::Polygon_2<Kernel> Polygon_2;
|
||||||
typedef CGAL::Polygon_with_holes_2<Kernel> Polygon_with_holes_2;
|
typedef CGAL::Polygon_with_holes_2<Kernel> Polygon_with_holes_2;
|
||||||
typedef CGAL::Gps_default_traits<Polygon_2>::Traits Traits;
|
typedef CGAL::Gps_default_traits<Polygon_2>::Traits Traits;
|
||||||
|
|
@ -257,45 +252,25 @@ void test_CGAL_Polygon_variants()
|
||||||
Traits tr;
|
Traits tr;
|
||||||
|
|
||||||
CGAL::do_intersect(pgn1, pgn2);
|
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, pgn2, tr);
|
||||||
|
|
||||||
CGAL::do_intersect(pgn1, pgn_with_holes2);
|
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(pgn1, pgn_with_holes2, tr);
|
||||||
|
|
||||||
CGAL::do_intersect(pgn_with_holes1, pgn2);
|
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, pgn2, tr);
|
||||||
|
|
||||||
CGAL::do_intersect(pgn_with_holes1, pgn_with_holes2);
|
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(pgn_with_holes1, pgn_with_holes2, tr);
|
||||||
|
|
||||||
CGAL::do_intersect(polygons.begin(), polygons.end());
|
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.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::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_with_holes.begin(), polygons_with_holes.end(), tr);
|
||||||
|
|
||||||
CGAL::do_intersect(polygons.begin(), polygons.end(),
|
CGAL::do_intersect(polygons.begin(), polygons.end(),
|
||||||
polygons_with_holes.begin(), polygons_with_holes.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(),
|
CGAL::do_intersect(polygons.begin(), polygons.end(),
|
||||||
polygons_with_holes.begin(), polygons_with_holes.end(), tr);
|
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);
|
CGAL::complement(pgn_with_holes1, std::back_inserter(result), tr);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main()
|
int main() {
|
||||||
{
|
|
||||||
test<Gps>();
|
test<Gps>();
|
||||||
test<Ps>();
|
test<Ps>();
|
||||||
test<Gps_non_caching>();
|
test<Gps_non_caching>();
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,94 @@
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
||||||
|
#include <CGAL/Boolean_set_operations_2.h>
|
||||||
|
#include <CGAL/Arr_circle_segment_traits_2.h>
|
||||||
|
#include <CGAL/General_polygon_2.h>
|
||||||
|
#include <CGAL/Boolean_set_operations_2.h>
|
||||||
|
// #include <CGAL/draw_arrangement_2.h>
|
||||||
|
|
||||||
|
using Kernel = CGAL::Exact_predicates_exact_constructions_kernel;
|
||||||
|
using Point_2 = Kernel::Point_2;
|
||||||
|
using Polygon_2 = CGAL::Polygon_2<Kernel>;
|
||||||
|
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<Kernel>;
|
||||||
|
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<Circle_segment_arr_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<Circle_segment_polygon> 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<Circle_segment_polygon> 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_traits_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;
|
||||||
|
}
|
||||||
|
|
@ -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.
|
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.
|
- **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)
|
## [Release 6.1](https://github.com/CGAL/cgal/releases/tag/v6.1)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -50,28 +50,27 @@ template <typename GeometryTraits_2, typename Event_, typename Subcurve_,
|
||||||
typename Allocator_, typename Visitor_>
|
typename Allocator_, typename Visitor_>
|
||||||
class Default_visitor_base {
|
class Default_visitor_base {
|
||||||
public:
|
public:
|
||||||
typedef GeometryTraits_2 Geometry_traits_2;
|
using Geometry_traits_2 = GeometryTraits_2;
|
||||||
typedef Event_ Event;
|
using Event = Event_;
|
||||||
typedef Subcurve_ Subcurve;
|
using Subcurve = Subcurve_;
|
||||||
typedef Allocator_ Allocator;
|
using Allocator = Allocator_;
|
||||||
typedef Visitor_ Visitor;
|
using Visitor = Visitor_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef Geometry_traits_2 Gt2;
|
using Gt2 = Geometry_traits_2;
|
||||||
typedef Default_visitor_base<Gt2, Event, Subcurve, Allocator, Visitor>
|
using Self = Default_visitor_base<Gt2, Event, Subcurve, Allocator, Visitor>;
|
||||||
Self;
|
|
||||||
|
|
||||||
public:
|
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;
|
using X_monotone_curve_2 = typename Gt2::X_monotone_curve_2;
|
||||||
typedef typename Gt2::Point_2 Point_2;
|
using Point_2 = typename Gt2::Point_2;
|
||||||
|
using Multiplicity = typename Gt2::Multiplicity;
|
||||||
|
|
||||||
typedef typename Event::Subcurve_iterator Event_subcurve_iterator;
|
using Event_subcurve_iterator = typename Event::Subcurve_iterator;
|
||||||
typedef typename Event::Subcurve_reverse_iterator
|
using Event_subcurve_reverse_iterator = typename Event::Subcurve_reverse_iterator;
|
||||||
Event_subcurve_reverse_iterator;
|
|
||||||
|
|
||||||
typedef No_intersection_surface_sweep_2<Visitor> Surface_sweep_2;
|
using Surface_sweep_2 = No_intersection_surface_sweep_2<Visitor>;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Data members:
|
// Data members:
|
||||||
|
|
@ -134,7 +133,8 @@ public:
|
||||||
void update_event(Event* /* e */,
|
void update_event(Event* /* e */,
|
||||||
Subcurve* /* sc1 */,
|
Subcurve* /* sc1 */,
|
||||||
Subcurve* /* sc2 */,
|
Subcurve* /* sc2 */,
|
||||||
bool /* is_new */)
|
bool /* is_new */,
|
||||||
|
Multiplicity /* multiplicity */)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/*! Update the event. */
|
/*! Update the event. */
|
||||||
|
|
|
||||||
|
|
@ -39,27 +39,27 @@ template <typename GeometryTraits_2,
|
||||||
class Do_interior_intersect_visitor :
|
class Do_interior_intersect_visitor :
|
||||||
public Default_visitor<Do_interior_intersect_visitor<GeometryTraits_2,
|
public Default_visitor<Do_interior_intersect_visitor<GeometryTraits_2,
|
||||||
Allocator_>,
|
Allocator_>,
|
||||||
GeometryTraits_2, Allocator_>
|
GeometryTraits_2, Allocator_> {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
typedef GeometryTraits_2 Geometry_traits_2;
|
using Geometry_traits_2 = GeometryTraits_2;
|
||||||
typedef Allocator_ Allocator;
|
using Allocator = Allocator_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef Geometry_traits_2 Gt2;
|
using Gt2 = Geometry_traits_2;
|
||||||
typedef Do_interior_intersect_visitor<Gt2, Allocator> Self;
|
using Self = Do_interior_intersect_visitor<Gt2, Allocator>;
|
||||||
typedef Default_visitor<Self, Gt2, Allocator> Base;
|
using Base = Default_visitor<Self, Gt2, Allocator>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef typename Base::Event Event;
|
using Event = typename Base::Event;
|
||||||
typedef typename Base::Subcurve Subcurve;
|
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;
|
using X_monotone_curve_2 = typename Gt2::X_monotone_curve_2;
|
||||||
typedef typename Gt2::Point_2 Point_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:
|
protected:
|
||||||
// Data members:
|
// Data members:
|
||||||
|
|
@ -69,8 +69,7 @@ public:
|
||||||
Do_interior_intersect_visitor() : m_found_x(false) {}
|
Do_interior_intersect_visitor() : m_found_x(false) {}
|
||||||
|
|
||||||
template <typename CurveIterator>
|
template <typename CurveIterator>
|
||||||
void sweep(CurveIterator begin, CurveIterator end)
|
void sweep(CurveIterator begin, CurveIterator end) {
|
||||||
{
|
|
||||||
std::vector<X_monotone_curve_2> curves_vec;
|
std::vector<X_monotone_curve_2> curves_vec;
|
||||||
std::vector<Point_2> points_vec;
|
std::vector<Point_2> points_vec;
|
||||||
|
|
||||||
|
|
@ -89,7 +88,8 @@ public:
|
||||||
void update_event(Event* /* e */,
|
void update_event(Event* /* e */,
|
||||||
Subcurve* /* sc1 */,
|
Subcurve* /* sc1 */,
|
||||||
Subcurve* /* sc2 */,
|
Subcurve* /* sc2 */,
|
||||||
bool /* is_new */)
|
bool /* is_new */,
|
||||||
|
Multiplicity /* multiplicity */)
|
||||||
{ m_found_x = true; }
|
{ m_found_x = true; }
|
||||||
|
|
||||||
void update_event(Event* /* e */,
|
void update_event(Event* /* e */,
|
||||||
|
|
@ -115,8 +115,7 @@ public:
|
||||||
{}
|
{}
|
||||||
|
|
||||||
template <typename XCurveIterator>
|
template <typename XCurveIterator>
|
||||||
void sweep_xcurves(XCurveIterator begin, XCurveIterator end)
|
void sweep_xcurves(XCurveIterator begin, XCurveIterator end) {
|
||||||
{
|
|
||||||
// Perform the sweep.
|
// Perform the sweep.
|
||||||
Surface_sweep_2* sl = this->surface_sweep();
|
Surface_sweep_2* sl = this->surface_sweep();
|
||||||
sl->sweep(begin, end);
|
sl->sweep(begin, end);
|
||||||
|
|
@ -129,8 +128,7 @@ public:
|
||||||
|
|
||||||
bool after_handle_event(Event* /* event */,
|
bool after_handle_event(Event* /* event */,
|
||||||
Status_line_iterator /* iter */,
|
Status_line_iterator /* iter */,
|
||||||
bool /* flag */)
|
bool /* flag */) {
|
||||||
{
|
|
||||||
if (m_found_x) {
|
if (m_found_x) {
|
||||||
Surface_sweep_2* sl = this->surface_sweep();
|
Surface_sweep_2* sl = this->surface_sweep();
|
||||||
sl->stop_sweep();
|
sl->stop_sweep();
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
//
|
//
|
||||||
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||||
// Efi Fogel <efif@post.tau.ac.il>
|
// Efi Fogel <efif@post.tau.ac.il>
|
||||||
// (based on old version by Tali Zvi)
|
// (based on a previous version developed by Tali Zvi)
|
||||||
|
|
||||||
#ifndef CGAL_SURFACE_SWEEP_2_IMPL_H
|
#ifndef CGAL_SURFACE_SWEEP_2_IMPL_H
|
||||||
#define 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.
|
// Initialize the data structures for the sweep-line algorithm.
|
||||||
//
|
//
|
||||||
template <typename Vis>
|
template <typename Vis>
|
||||||
void Surface_sweep_2<Vis>::_init_structures()
|
void Surface_sweep_2<Vis>::_init_structures() {
|
||||||
{
|
|
||||||
// Initialize the structures maintained by the base sweep-line class.
|
// Initialize the structures maintained by the base sweep-line class.
|
||||||
Base::_init_structures();
|
Base::_init_structures();
|
||||||
}
|
}
|
||||||
|
|
@ -43,8 +42,7 @@ void Surface_sweep_2<Vis>::_init_structures()
|
||||||
// Complete the sweep (complete the data structures).
|
// Complete the sweep (complete the data structures).
|
||||||
//
|
//
|
||||||
template <typename Vis>
|
template <typename Vis>
|
||||||
void Surface_sweep_2<Vis>::_complete_sweep()
|
void Surface_sweep_2<Vis>::_complete_sweep() {
|
||||||
{
|
|
||||||
CGAL_SS_PRINT_START_EOL("completing the sweep");
|
CGAL_SS_PRINT_START_EOL("completing the sweep");
|
||||||
|
|
||||||
// Complete the sweep process using base sweep-line class.
|
// Complete the sweep process using base sweep-line class.
|
||||||
|
|
@ -68,8 +66,7 @@ void Surface_sweep_2<Vis>::_complete_sweep()
|
||||||
// Handle the subcurves to the left of the current event point.
|
// Handle the subcurves to the left of the current event point.
|
||||||
//
|
//
|
||||||
template <typename Vis>
|
template <typename Vis>
|
||||||
void Surface_sweep_2<Vis>::_handle_left_curves()
|
void Surface_sweep_2<Vis>::_handle_left_curves() {
|
||||||
{
|
|
||||||
CGAL_SS_PRINT_START("handling left curves at (");
|
CGAL_SS_PRINT_START("handling left curves at (");
|
||||||
CGAL_SS_DEBUG(this->PrintEvent(this->m_currentEvent));
|
CGAL_SS_DEBUG(this->PrintEvent(this->m_currentEvent));
|
||||||
CGAL_SS_PRINT_TEXT(")");
|
CGAL_SS_PRINT_TEXT(")");
|
||||||
|
|
@ -189,14 +186,12 @@ void Surface_sweep_2<Vis>::_handle_left_curves()
|
||||||
// and with a left end not being the current event
|
// and with a left end not being the current event
|
||||||
//
|
//
|
||||||
template <typename Vis>
|
template <typename Vis>
|
||||||
void Surface_sweep_2<Vis>::_clip_non_active_curve_at_current_event(Subcurve* subcurve)
|
void Surface_sweep_2<Vis>::_clip_non_active_curve_at_current_event(Subcurve* subcurve) {
|
||||||
{
|
|
||||||
// ignore active curve (will be split at intersection point)
|
// ignore active curve (will be split at intersection point)
|
||||||
if (subcurve->hint() != this->m_statusLine.end() &&
|
if (subcurve->hint() != this->m_statusLine.end() &&
|
||||||
subcurve->hint() != Status_line_iterator() ) return;
|
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_TEXT("Splitting ");
|
||||||
CGAL_SS_PRINT_CURVE(subcurve);
|
CGAL_SS_PRINT_CURVE(subcurve);
|
||||||
CGAL_SS_PRINT_EOL();
|
CGAL_SS_PRINT_EOL();
|
||||||
|
|
@ -215,13 +210,11 @@ void Surface_sweep_2<Vis>::_clip_non_active_curve_at_current_event(Subcurve* sub
|
||||||
// Handle the overlaps between subcurves to the right of the current event point.
|
// Handle the overlaps between subcurves to the right of the current event point.
|
||||||
//
|
//
|
||||||
template <typename Vis>
|
template <typename Vis>
|
||||||
void Surface_sweep_2<Vis>::_handle_overlaps_in_right_curves()
|
void Surface_sweep_2<Vis>::_handle_overlaps_in_right_curves() {
|
||||||
{
|
const std::vector< std::pair<Subcurve*, Subcurve*> >& subcurve_pairs =
|
||||||
const std::vector< std::pair<Subcurve*, Subcurve*> >& subcurve_pairs
|
this->m_currentEvent->overlaps_on_right;
|
||||||
= this->m_currentEvent->overlaps_on_right;
|
|
||||||
|
|
||||||
if (!subcurve_pairs.empty())
|
if (!subcurve_pairs.empty()) {
|
||||||
{
|
|
||||||
// handling overlaps on the right of the current event.
|
// handling overlaps on the right of the current event.
|
||||||
// Only one curve from the overlapping curve is currently
|
// Only one curve from the overlapping curve is currently
|
||||||
// in the right curves of the event. Other curve overlapping
|
// in the right curves of the event. Other curve overlapping
|
||||||
|
|
@ -243,8 +236,7 @@ void Surface_sweep_2<Vis>::_handle_overlaps_in_right_curves()
|
||||||
typedef std::map<Subcurve*, std::vector<Subcurve*>> Subcurve_map;
|
typedef std::map<Subcurve*, std::vector<Subcurve*>> Subcurve_map;
|
||||||
Subcurve_map tests_per_subcurve_on_right;
|
Subcurve_map tests_per_subcurve_on_right;
|
||||||
|
|
||||||
for (std::size_t i=0; i<nb_p; ++i)
|
for (std::size_t i = 0; i < nb_p; ++i) {
|
||||||
{
|
|
||||||
CGAL_SS_PRINT_TEXT("(");
|
CGAL_SS_PRINT_TEXT("(");
|
||||||
CGAL_SS_PRINT(subcurve_pairs[i].first);
|
CGAL_SS_PRINT(subcurve_pairs[i].first);
|
||||||
CGAL_SS_PRINT_TEXT(",");
|
CGAL_SS_PRINT_TEXT(",");
|
||||||
|
|
@ -254,13 +246,10 @@ void Surface_sweep_2<Vis>::_handle_overlaps_in_right_curves()
|
||||||
tests_per_subcurve_on_right[subcurve_pairs[i].first].push_back(subcurve_pairs[i].second);
|
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(),
|
for (auto it = tests_per_subcurve_on_right.begin(), end = tests_per_subcurve_on_right.end(); it != end; ++it) {
|
||||||
end = tests_per_subcurve_on_right.end(); it!=end; ++it)
|
|
||||||
{
|
|
||||||
std::size_t nbc = it->second.size();
|
std::size_t nbc = it->second.size();
|
||||||
// remove possible duplicates
|
// remove possible duplicates
|
||||||
if (nbc>1)
|
if (nbc > 1) {
|
||||||
{
|
|
||||||
std::sort(it->second.begin(), it->second.end());
|
std::sort(it->second.begin(), it->second.end());
|
||||||
typename std::vector<Subcurve*>::iterator last =
|
typename std::vector<Subcurve*>::iterator last =
|
||||||
std::unique(it->second.begin(), it->second.end());
|
std::unique(it->second.begin(), it->second.end());
|
||||||
|
|
@ -277,8 +266,7 @@ void Surface_sweep_2<Vis>::_handle_overlaps_in_right_curves()
|
||||||
else{
|
else{
|
||||||
// get the curve just after the key in the sorted set of curves on the right as it might be replaced
|
// 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);
|
Subcurve_iterator next_after = this->m_currentEvent->get_curve_after_on_right(it->first);
|
||||||
for (std::size_t i=0; i<nbc; ++i)
|
for (std::size_t i = 0; i < nbc; ++i) {
|
||||||
{
|
|
||||||
_intersect(it->second[i], *std::prev(next_after), this->m_currentEvent);
|
_intersect(it->second[i], *std::prev(next_after), this->m_currentEvent);
|
||||||
CGAL_assertion(it->second.size()==nbc); // make sure the container was not updated
|
CGAL_assertion(it->second.size()==nbc); // make sure the container was not updated
|
||||||
}
|
}
|
||||||
|
|
@ -289,27 +277,19 @@ void Surface_sweep_2<Vis>::_handle_overlaps_in_right_curves()
|
||||||
}
|
}
|
||||||
|
|
||||||
// split curves not already split. TODO: this should be done above?
|
// split curves not already split. TODO: this should be done above?
|
||||||
for (Event_subcurve_iterator subcurve_it = this->m_currentEvent->right_curves_begin();
|
for (auto subcurve_it = this->m_currentEvent->right_curves_begin();
|
||||||
subcurve_it != this->m_currentEvent->right_curves_end();
|
subcurve_it != this->m_currentEvent->right_curves_end(); ++subcurve_it)
|
||||||
++subcurve_it)
|
|
||||||
{
|
|
||||||
_clip_non_active_curve_at_current_event(*subcurve_it);
|
_clip_non_active_curve_at_current_event(*subcurve_it);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Handle the subcurves to the right of the current event point.
|
// Handle the subcurves to the right of the current event point.
|
||||||
//
|
//
|
||||||
template <typename Vis>
|
template <typename Vis>
|
||||||
void Surface_sweep_2<Vis>::_handle_right_curves()
|
void Surface_sweep_2<Vis>::_handle_right_curves() {
|
||||||
{
|
for (auto sc_it = this->m_currentEvent->right_curves_begin(), sc_it_end = this->m_currentEvent->right_curves_end();
|
||||||
|
|
||||||
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)
|
sc_it != sc_it_end; ++sc_it)
|
||||||
{
|
|
||||||
(*sc_it)->reset_left_event();
|
(*sc_it)->reset_left_event();
|
||||||
}
|
|
||||||
|
|
||||||
CGAL_SS_PRINT_START("handling right curves at (");
|
CGAL_SS_PRINT_START("handling right curves at (");
|
||||||
CGAL_SS_DEBUG(this->PrintEvent(this->m_currentEvent));
|
CGAL_SS_DEBUG(this->PrintEvent(this->m_currentEvent));
|
||||||
|
|
@ -329,15 +309,11 @@ void Surface_sweep_2<Vis>::_handle_right_curves()
|
||||||
// - We also check to see if the two intersect again to the right of the
|
// - We also check to see if the two intersect again to the right of the
|
||||||
// point.
|
// point.
|
||||||
|
|
||||||
Event_subcurve_iterator currentOne =
|
Event_subcurve_iterator currentOne = this->m_currentEvent->right_curves_begin();
|
||||||
this->m_currentEvent->right_curves_begin();
|
Event_subcurve_iterator rightCurveEnd = this->m_currentEvent->right_curves_end();
|
||||||
Event_subcurve_iterator rightCurveEnd =
|
|
||||||
this->m_currentEvent->right_curves_end();
|
|
||||||
|
|
||||||
CGAL_SS_PRINT_INSERT(*currentOne);
|
CGAL_SS_PRINT_INSERT(*currentOne);
|
||||||
Status_line_iterator slIter =
|
Status_line_iterator slIter = this->m_statusLine.insert_before(this->m_status_line_insert_hint, *currentOne);
|
||||||
this->m_statusLine.insert_before(this->m_status_line_insert_hint,
|
|
||||||
*currentOne);
|
|
||||||
Subcurve* sc = *currentOne;
|
Subcurve* sc = *currentOne;
|
||||||
sc->set_hint(slIter);
|
sc->set_hint(slIter);
|
||||||
|
|
||||||
|
|
@ -352,8 +328,7 @@ void Surface_sweep_2<Vis>::_handle_right_curves()
|
||||||
++currentOne;
|
++currentOne;
|
||||||
while (currentOne != rightCurveEnd) {
|
while (currentOne != rightCurveEnd) {
|
||||||
CGAL_SS_PRINT_INSERT(*currentOne);
|
CGAL_SS_PRINT_INSERT(*currentOne);
|
||||||
slIter = this->m_statusLine.insert_before(this->m_status_line_insert_hint,
|
slIter = this->m_statusLine.insert_before(this->m_status_line_insert_hint, *currentOne);
|
||||||
*currentOne);
|
|
||||||
|
|
||||||
Subcurve* sc = *currentOne;
|
Subcurve* sc = *currentOne;
|
||||||
sc->set_hint(slIter);
|
sc->set_hint(slIter);
|
||||||
|
|
@ -390,12 +365,8 @@ bool Surface_sweep_2<Vis>::_add_curve_to_right(Event* event, Subcurve* curve)
|
||||||
CGAL_SS_PRINT_CURVE(curve);
|
CGAL_SS_PRINT_CURVE(curve);
|
||||||
CGAL_SS_PRINT_EOL();
|
CGAL_SS_PRINT_EOL();
|
||||||
|
|
||||||
Event_subcurve_iterator iter;
|
for (auto iter = event->right_curves_begin(); iter != event->right_curves_end(); ++iter) {
|
||||||
for (iter = event->right_curves_begin(); iter != event->right_curves_end();
|
if (*iter == curve) {
|
||||||
++iter)
|
|
||||||
{
|
|
||||||
if (*iter == curve)
|
|
||||||
{
|
|
||||||
CGAL_SS_PRINT_END_EOL("adding a Curve to the right (curve exists)");
|
CGAL_SS_PRINT_END_EOL("adding a Curve to the right (curve exists)");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -405,8 +376,7 @@ bool Surface_sweep_2<Vis>::_add_curve_to_right(Event* event, Subcurve* curve)
|
||||||
if ((*iter)->are_all_leaves_contained(curve)) {
|
if ((*iter)->are_all_leaves_contained(curve)) {
|
||||||
CGAL_SS_PRINT_END_EOL("adding a Curve to the right (containing curve exists)");
|
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
|
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
|
_add_curve_to_right( (*iter)->right_event(), curve); // WARNING recursive
|
||||||
}
|
}
|
||||||
|
|
@ -417,8 +387,7 @@ bool Surface_sweep_2<Vis>::_add_curve_to_right(Event* event, Subcurve* curve)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (curve->are_all_leaves_contained(*iter)) {
|
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
|
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
|
_add_curve_to_right( curve->right_event(), *iter); // WARNING recursive
|
||||||
}
|
}
|
||||||
|
|
@ -426,8 +395,7 @@ bool Surface_sweep_2<Vis>::_add_curve_to_right(Event* event, Subcurve* curve)
|
||||||
(*iter)->right_event()->remove_curve_from_left(*iter);
|
(*iter)->right_event()->remove_curve_from_left(*iter);
|
||||||
|
|
||||||
*iter = curve; // replace the current curve with the new one.
|
*iter = curve; // replace the current curve with the new one.
|
||||||
CGAL_SS_PRINT_END_EOL
|
CGAL_SS_PRINT_END_EOL("replacing a Curve to the right (curve partially overlaps)");
|
||||||
("replacing a Curve to the right (curve partially overlaps)");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -446,8 +414,7 @@ bool Surface_sweep_2<Vis>::_add_curve_to_right(Event* event, Subcurve* curve)
|
||||||
if (event != this->m_currentEvent)
|
if (event != this->m_currentEvent)
|
||||||
event->overlaps_on_right.push_back(
|
event->overlaps_on_right.push_back(
|
||||||
std::make_pair(static_cast<Subcurve*>(*(pair_res.second)),
|
std::make_pair(static_cast<Subcurve*>(*(pair_res.second)),
|
||||||
static_cast<Subcurve*>(curve))
|
static_cast<Subcurve*>(curve)));
|
||||||
);
|
|
||||||
else
|
else
|
||||||
_intersect(static_cast<Subcurve*>(curve),
|
_intersect(static_cast<Subcurve*>(curve),
|
||||||
static_cast<Subcurve*>(*(pair_res.second)),
|
static_cast<Subcurve*>(*(pair_res.second)),
|
||||||
|
|
@ -467,8 +434,7 @@ bool Surface_sweep_2<Vis>::_add_curve_to_right(Event* event, Subcurve* curve)
|
||||||
//
|
//
|
||||||
template <typename Vis>
|
template <typename Vis>
|
||||||
void Surface_sweep_2<Vis>::_remove_curve_from_status_line(Subcurve* leftCurve,
|
void Surface_sweep_2<Vis>::_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_START("removing a curve from the status line, ");
|
||||||
CGAL_SS_PRINT_CURVE(leftCurve);
|
CGAL_SS_PRINT_CURVE(leftCurve);
|
||||||
CGAL_SS_PRINT_EOL();
|
CGAL_SS_PRINT_EOL();
|
||||||
|
|
@ -513,8 +479,7 @@ void Surface_sweep_2<Vis>::_remove_curve_from_status_line(Subcurve* leftCurve,
|
||||||
//
|
//
|
||||||
template <typename Vis>
|
template <typename Vis>
|
||||||
void Surface_sweep_2<Vis>::_intersect(Subcurve* c1, Subcurve* c2,
|
void Surface_sweep_2<Vis>::_intersect(Subcurve* c1, Subcurve* c2,
|
||||||
Event* event_for_overlap)
|
Event* event_for_overlap) {
|
||||||
{
|
|
||||||
CGAL_SS_PRINT_START("computing intersection of ");
|
CGAL_SS_PRINT_START("computing intersection of ");
|
||||||
CGAL_SS_PRINT_CURVE(c1);
|
CGAL_SS_PRINT_CURVE(c1);
|
||||||
CGAL_SS_PRINT_TEXT(" and ");
|
CGAL_SS_PRINT_TEXT(" and ");
|
||||||
|
|
@ -538,8 +503,7 @@ void Surface_sweep_2<Vis>::_intersect(Subcurve* c1, Subcurve* c2,
|
||||||
Subcurve_vector all_leaves_diff;
|
Subcurve_vector all_leaves_diff;
|
||||||
Subcurve* first_parent = nullptr;
|
Subcurve* first_parent = nullptr;
|
||||||
if ((c1->originating_subcurve1() != 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
|
// 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
|
// set the subcurves leaves that are not in the other one. If empty, it
|
||||||
// means that a subcurves is completely contained in another one.
|
// means that a subcurves is completely contained in another one.
|
||||||
|
|
@ -628,9 +592,7 @@ void Surface_sweep_2<Vis>::_intersect(Subcurve* c1, Subcurve* c2,
|
||||||
CGAL_SS_PRINT_CURVE(first_parent);
|
CGAL_SS_PRINT_CURVE(first_parent);
|
||||||
CGAL_SS_PRINT_EOL();
|
CGAL_SS_PRINT_EOL();
|
||||||
X_monotone_curve_2 xc = first_parent->last_curve();
|
X_monotone_curve_2 xc = first_parent->last_curve();
|
||||||
for (auto sc_it = all_leaves_diff.begin();
|
for (auto sc_it = all_leaves_diff.begin(); sc_it != all_leaves_diff.end(); ++sc_it) {
|
||||||
sc_it != all_leaves_diff.end(); ++sc_it)
|
|
||||||
{
|
|
||||||
CGAL_SS_PRINT_TEXT("Inter with curve: ");
|
CGAL_SS_PRINT_TEXT("Inter with curve: ");
|
||||||
CGAL_SS_PRINT_CURVE((*sc_it));
|
CGAL_SS_PRINT_CURVE((*sc_it));
|
||||||
CGAL_SS_PRINT_EOL();
|
CGAL_SS_PRINT_EOL();
|
||||||
|
|
@ -681,12 +643,10 @@ void Surface_sweep_2<Vis>::_intersect(Subcurve* c1, Subcurve* c2,
|
||||||
if ((ps_x1 == ps_x2) && (ps_y1 == ps_y2) &&
|
if ((ps_x1 == ps_x2) && (ps_y1 == ps_y2) &&
|
||||||
((ps_x1 != ARR_INTERIOR) || (ps_y1 != ARR_INTERIOR)) &&
|
((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()(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<Intersection_point>(&(*vi)) != nullptr) &&
|
if ((std::get_if<Intersection_point>(&(*vi)) != nullptr) &&
|
||||||
this->m_traits->equal_2_object()(ctr_min(c1->last_curve()),
|
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_TEXT("Skipping common left endpoint on boundary ...");
|
||||||
CGAL_SS_PRINT_EOL();
|
CGAL_SS_PRINT_EOL();
|
||||||
++vi;
|
++vi;
|
||||||
|
|
@ -719,12 +679,10 @@ void Surface_sweep_2<Vis>::_intersect(Subcurve* c1, Subcurve* c2,
|
||||||
if ((ps_x1 == ps_x2) && (ps_y1 == ps_y2) &&
|
if ((ps_x1 == ps_x2) && (ps_y1 == ps_y2) &&
|
||||||
((ps_x1 != ARR_INTERIOR) || (ps_y2 != ARR_INTERIOR)) &&
|
((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()(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()
|
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()(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;
|
vector_inserter vi_last = vi_end;
|
||||||
|
|
||||||
--vi_last;
|
--vi_last;
|
||||||
|
|
@ -791,8 +749,7 @@ template <typename Vis>
|
||||||
void Surface_sweep_2<Vis>::_create_intersection_point(const Point_2& xp,
|
void Surface_sweep_2<Vis>::_create_intersection_point(const Point_2& xp,
|
||||||
Multiplicity multiplicity,
|
Multiplicity multiplicity,
|
||||||
Subcurve*& c1,
|
Subcurve*& c1,
|
||||||
Subcurve*& c2)
|
Subcurve*& c2) {
|
||||||
{
|
|
||||||
CGAL_SS_PRINT_START_EOL("creating an intersection point between");
|
CGAL_SS_PRINT_START_EOL("creating an intersection point between");
|
||||||
CGAL_SS_PRINT_CURVE(c1);
|
CGAL_SS_PRINT_CURVE(c1);
|
||||||
CGAL_SS_PRINT_EOL();
|
CGAL_SS_PRINT_EOL();
|
||||||
|
|
@ -814,7 +771,7 @@ void Surface_sweep_2<Vis>::_create_intersection_point(const Point_2& xp,
|
||||||
|
|
||||||
e->set_intersection();
|
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(c1);
|
||||||
e->push_back_curve_to_left(c2);
|
e->push_back_curve_to_left(c2);
|
||||||
|
|
||||||
|
|
@ -858,7 +815,7 @@ void Surface_sweep_2<Vis>::_create_intersection_point(const Point_2& xp,
|
||||||
_add_curve_to_right(e, c1);
|
_add_curve_to_right(e, c1);
|
||||||
_add_curve_to_right(e, c2);
|
_add_curve_to_right(e, c2);
|
||||||
e->set_intersection();
|
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 (multiplicity == 0) {
|
||||||
if (e->is_right_curve_bigger(c1, c2, this->m_traits)) std::swap(c1, c2);
|
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,
|
Subcurve*& c1 , Subcurve*& c2,
|
||||||
const Subcurve_vector& all_leaves_diff,
|
const Subcurve_vector& all_leaves_diff,
|
||||||
Subcurve* first_parent,
|
Subcurve* first_parent,
|
||||||
Event* event_on_overlap)
|
Event* event_on_overlap) {
|
||||||
{
|
|
||||||
// An overlap occurs:
|
// An overlap occurs:
|
||||||
CGAL_SS_PRINT_START_EOL("creating an overlapping curve");
|
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)) {
|
if ((ps_x_r != ARR_INTERIOR) || (ps_y_r != ARR_INTERIOR)) {
|
||||||
// CGAL_assertion(c1->right_event() == c2->right_event());
|
// CGAL_assertion(c1->right_event() == c2->right_event());
|
||||||
// right_event = c1->right_event();
|
// right_event = c1->right_event();
|
||||||
right_event = this->_push_event(overlap_cv, ARR_MAX_END, Event::DEFAULT,
|
right_event = this->_push_event(overlap_cv, ARR_MAX_END, Event::DEFAULT, ps_x_r, ps_y_r).first;
|
||||||
ps_x_r, ps_y_r).first;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
auto max_vertex = this->m_traits->construct_max_vertex_2_object();
|
auto max_vertex = this->m_traits->construct_max_vertex_2_object();
|
||||||
auto right_end = max_vertex(overlap_cv);
|
auto right_end = max_vertex(overlap_cv);
|
||||||
right_event = this->_push_event(right_end, Event::DEFAULT, ARR_INTERIOR,
|
right_event = this->_push_event(right_end, Event::DEFAULT, ARR_INTERIOR, ARR_INTERIOR).first;
|
||||||
ARR_INTERIOR).first;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!c1->is_start_point(left_event)) {
|
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
|
// Allocate the new Subcurve for the overlap
|
||||||
Subcurve* overlap_sc=nullptr;
|
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
|
// first check that an equivalent curve is not already in left_event
|
||||||
for (Subcurve_iterator iter = left_event->right_curves_begin();
|
for (auto iter = left_event->right_curves_begin(); iter != left_event->right_curves_end(); ++iter) {
|
||||||
iter != left_event->right_curves_end(); ++iter)
|
|
||||||
{
|
|
||||||
if ((*iter)->has_same_leaves(c1, c2)) {
|
if ((*iter)->has_same_leaves(c1, c2)) {
|
||||||
CGAL_SS_PRINT_TEXT("Reuse overlapping curve ");
|
CGAL_SS_PRINT_TEXT("Reuse overlapping curve ");
|
||||||
CGAL_SS_PRINT_CURVE(*iter);
|
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_TEXT("Allocate a new subcurve for the overlap (no common subcurves)");
|
||||||
CGAL_SS_PRINT_EOL();
|
CGAL_SS_PRINT_EOL();
|
||||||
// no duplicate only one curve is needed
|
// 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();
|
CGAL_SS_PRINT_EOL();
|
||||||
|
|
||||||
// create an overlapping curve per subcurve in second_parent that is not in first_parent
|
// create an overlapping curve per subcurve in second_parent that is not in first_parent
|
||||||
for (typename std::vector<Subcurve*>::const_iterator sc_it = all_leaves_diff.begin();
|
for (auto sc_it = all_leaves_diff.begin(); sc_it != all_leaves_diff.end(); ++sc_it) {
|
||||||
sc_it != all_leaves_diff.end();
|
|
||||||
++sc_it)
|
|
||||||
{
|
|
||||||
overlap_sc = this->m_subCurveAlloc.allocate(1);
|
overlap_sc = this->m_subCurveAlloc.allocate(1);
|
||||||
std::allocator_traits<Subcurve_alloc>::construct(this->m_subCurveAlloc,overlap_sc, this->m_masterSubcurve);
|
std::allocator_traits<Subcurve_alloc>::construct(this->m_subCurveAlloc,overlap_sc, this->m_masterSubcurve);
|
||||||
overlap_sc->set_hint(this->m_statusLine.end());
|
overlap_sc->set_hint(this->m_statusLine.end());
|
||||||
|
|
@ -1063,8 +1010,7 @@ _create_overlapping_curve(const X_monotone_curve_2& overlap_cv,
|
||||||
// or updated.
|
// or updated.
|
||||||
//
|
//
|
||||||
template <typename Vis>
|
template <typename Vis>
|
||||||
void Surface_sweep_2<Vis>::_add_curve(Event* e, Subcurve* sc, Attribute type)
|
void Surface_sweep_2<Vis>::_add_curve(Event* e, Subcurve* sc, Attribute type) {
|
||||||
{
|
|
||||||
if (sc == nullptr) return;
|
if (sc == nullptr) return;
|
||||||
|
|
||||||
if (type == Event::LEFT_END) {
|
if (type == Event::LEFT_END) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue