mirror of https://github.com/CGAL/cgal
Compare commits
268 Commits
cb604e35e5
...
0e59f3220b
| Author | SHA1 | Date |
|---|---|---|
|
|
0e59f3220b | |
|
|
a14621b595 | |
|
|
5d1f3306a6 | |
|
|
ff9223ab21 | |
|
|
25e41104d1 | |
|
|
52740b5b6d | |
|
|
6df6b69d7b | |
|
|
26a5fc70e4 | |
|
|
39dd7c5028 | |
|
|
def6c38d76 | |
|
|
f503ce9359 | |
|
|
be305f320f | |
|
|
b8db056348 | |
|
|
18ee149f2e | |
|
|
15d96571a1 | |
|
|
06996f077f | |
|
|
5f8a8fe359 | |
|
|
543d424f58 | |
|
|
fdbbdb4cdc | |
|
|
284d228b96 | |
|
|
2d56c7bfe6 | |
|
|
7aa81c4505 | |
|
|
93c4a44b90 | |
|
|
8e3a59a27b | |
|
|
40ac746be7 | |
|
|
9d28892e5f | |
|
|
8c6dd11492 | |
|
|
dbcace69e6 | |
|
|
88fea191ec | |
|
|
bac686d05b | |
|
|
30f63794c3 | |
|
|
92a896abb9 | |
|
|
2d1da34beb | |
|
|
4f30141af0 | |
|
|
77f3df5934 | |
|
|
1b3556184a | |
|
|
d14619c335 | |
|
|
f76137d10e | |
|
|
50a187db38 | |
|
|
95a315335f | |
|
|
ff5166fbee | |
|
|
3195009f59 | |
|
|
15e431c48c | |
|
|
9f2fcb5e28 | |
|
|
85ef57ffa1 | |
|
|
aefbc23955 | |
|
|
fdf06fe969 | |
|
|
c8099415d4 | |
|
|
da0f634cb2 | |
|
|
7bf5687d5d | |
|
|
a0c32277d0 | |
|
|
1069678f36 | |
|
|
cda931ec46 | |
|
|
884e9fc4ee | |
|
|
cee9effe09 | |
|
|
eb14bf2a17 | |
|
|
970f16913b | |
|
|
583a8364c9 | |
|
|
3ebe9203a7 | |
|
|
bf25dd27b8 | |
|
|
8ee288ee22 | |
|
|
e9fb73cadf | |
|
|
f98d968ed0 | |
|
|
9bd1705bf8 | |
|
|
0fc710e95d | |
|
|
dee5ed8cc2 | |
|
|
737bcb264e | |
|
|
2f9854b422 | |
|
|
e12a760f03 | |
|
|
eb992b38ca | |
|
|
3ccdc134fe | |
|
|
1602be1348 | |
|
|
ba17e0bdde | |
|
|
12445cc6e1 | |
|
|
e7205b985d | |
|
|
12a0f67674 | |
|
|
5812c1d6b5 | |
|
|
07347da411 | |
|
|
1dc39039e9 | |
|
|
1673cd0f9e | |
|
|
dfc5fb5065 | |
|
|
48262b8068 | |
|
|
24d3cd4bec | |
|
|
d226e504c4 | |
|
|
097fc2c5ab | |
|
|
77bac5866b | |
|
|
066159f792 | |
|
|
333a15584f | |
|
|
cd787c84d1 | |
|
|
0ac856dd41 | |
|
|
31734df2ef | |
|
|
3ef43324bb | |
|
|
3c7d507530 | |
|
|
76552ccca1 | |
|
|
546d0b2871 | |
|
|
af94906903 | |
|
|
3b0d95e0e5 | |
|
|
ffda347171 | |
|
|
a9b369650a | |
|
|
faae741666 | |
|
|
9e36c6744b | |
|
|
828d57a419 | |
|
|
6f2c3d819e | |
|
|
459fcf3c3f | |
|
|
1c1245d5c0 | |
|
|
d1c66eaa0f | |
|
|
175b7b9241 | |
|
|
e74cd68cfb | |
|
|
05bf3c4ffc | |
|
|
7e1f685ea3 | |
|
|
f92b41ae0a | |
|
|
e4469c043e | |
|
|
25005a97d8 | |
|
|
25844edf50 | |
|
|
6bd5ec4f8b | |
|
|
eaa25c500b | |
|
|
64e33bd6cb | |
|
|
3fe83c7ce0 | |
|
|
f28e643ed0 | |
|
|
2d39ab4dd8 | |
|
|
2fb9a2d832 | |
|
|
7c3b2302b5 | |
|
|
8b4e81ab5c | |
|
|
44306e981a | |
|
|
25060734a0 | |
|
|
e70e2109f4 | |
|
|
fb748f6442 | |
|
|
622b652652 | |
|
|
5050b54bfe | |
|
|
35613b984f | |
|
|
00f5ae061d | |
|
|
6e2caa7e28 | |
|
|
27edd158c1 | |
|
|
73b8e65b5a | |
|
|
7c4a3c1dad | |
|
|
eaea32ee9f | |
|
|
f766834601 | |
|
|
5e26465b2c | |
|
|
67220b911b | |
|
|
37b6a7214d | |
|
|
592b8824ec | |
|
|
7c9b9d1592 | |
|
|
6d011a62ae | |
|
|
8623f28bb0 | |
|
|
4c27d08372 | |
|
|
4acccc210b | |
|
|
5d82eed3ea | |
|
|
d9ba43a9ba | |
|
|
98a3051235 | |
|
|
da011b2abe | |
|
|
3706528a0c | |
|
|
878ba3fc53 | |
|
|
62a9c9e04f | |
|
|
67349ccbe1 | |
|
|
8215abd980 | |
|
|
358a588eae | |
|
|
c43058de26 | |
|
|
f6425d7773 | |
|
|
2ca338068b | |
|
|
e1ec2fd1d2 | |
|
|
ce1c890cb0 | |
|
|
8c84316796 | |
|
|
ed6eb76670 | |
|
|
66bb36e336 | |
|
|
cd248c2638 | |
|
|
1a03f8c6e1 | |
|
|
0ffa81d3c4 | |
|
|
865c1d2ed7 | |
|
|
24024424ef | |
|
|
39531baac8 | |
|
|
18f1f65bbf | |
|
|
9a99df4a9d | |
|
|
737079e530 | |
|
|
0a743e6a1a | |
|
|
36b66946b8 | |
|
|
89ba13f977 | |
|
|
33bd58bbef | |
|
|
e652a7976a | |
|
|
3be4ffce37 | |
|
|
3567ba1456 | |
|
|
806e65f259 | |
|
|
a9a60b5a00 | |
|
|
92dc53c58a | |
|
|
b97c4b78c3 | |
|
|
5103fb4eb7 | |
|
|
fad48f7305 | |
|
|
bdee2836df | |
|
|
39fe8b3a6d | |
|
|
61cf55efee | |
|
|
0cf9d434b6 | |
|
|
93d3356dd9 | |
|
|
561ec37dc6 | |
|
|
5c058a8c9b | |
|
|
b668fb4b5a | |
|
|
d7cfaccfa1 | |
|
|
316c455034 | |
|
|
7d4852a60f | |
|
|
6c4aeabb9d | |
|
|
9b3132a2cd | |
|
|
967aee62e9 | |
|
|
05dd65609d | |
|
|
2e087bc108 | |
|
|
bd6a4ca392 | |
|
|
3988fe2009 | |
|
|
0f2aa39b62 | |
|
|
ba19fbd67d | |
|
|
65c797ab44 | |
|
|
a9e0eeec8f | |
|
|
dc422a7531 | |
|
|
e73cf18c12 | |
|
|
bc29da5ee3 | |
|
|
4d615a31b6 | |
|
|
5a3dbda022 | |
|
|
876db072d8 | |
|
|
8ebeb13896 | |
|
|
f25a684c95 | |
|
|
3382ac0d18 | |
|
|
707375e780 | |
|
|
1d62c37822 | |
|
|
4a6d766d8c | |
|
|
f8c9340c1c | |
|
|
5b6df813f5 | |
|
|
f41b5b60f7 | |
|
|
b871b81d57 | |
|
|
29715e44a4 | |
|
|
f4a02aeaef | |
|
|
f69ad03ef8 | |
|
|
a366725c85 | |
|
|
1c45ed834c | |
|
|
375681748d | |
|
|
81bb832333 | |
|
|
a74945062c | |
|
|
e5049d4b03 | |
|
|
1bd923b393 | |
|
|
c677355de2 | |
|
|
0f528545c7 | |
|
|
35721db0b9 | |
|
|
d41efe0330 | |
|
|
bf1bc2fc85 | |
|
|
cc19bd4a80 | |
|
|
464c591b5a | |
|
|
e0634c4ab1 | |
|
|
c37745641a | |
|
|
09365799e9 | |
|
|
e187dc03cb | |
|
|
ad20fa497a | |
|
|
4cfd48ba76 | |
|
|
b66c3743ec | |
|
|
5b2887240c | |
|
|
5171477b26 | |
|
|
05014378d6 | |
|
|
0e27e7632c | |
|
|
7ab9468594 | |
|
|
a316b67548 | |
|
|
ba87b5c2e5 | |
|
|
a08388c4e3 | |
|
|
969062e3df | |
|
|
cfcc90d649 | |
|
|
c5a688590a | |
|
|
710666a51b | |
|
|
c58286d716 | |
|
|
6cba601ff3 | |
|
|
fe86a79bdc | |
|
|
7a984104fa | |
|
|
d876fbab69 | |
|
|
5eb93449c5 | |
|
|
40dee7d2a0 | |
|
|
2d72f21107 |
|
|
@ -30,7 +30,7 @@
|
|||
|
||||
#include <CGAL/tags.h>
|
||||
#include <CGAL/Arr_tags.h>
|
||||
#include <CGAL/Cartesian.h>
|
||||
#include <CGAL/Simple_cartesian.h>
|
||||
#include <CGAL/Arr_geometry_traits/Circle_segment_2.h>
|
||||
|
||||
namespace CGAL {
|
||||
|
|
@ -41,31 +41,31 @@ namespace CGAL {
|
|||
template <typename Kernel_, bool Filter = true>
|
||||
class Arr_circle_segment_traits_2 {
|
||||
public:
|
||||
typedef Kernel_ Kernel;
|
||||
typedef typename Kernel::FT NT;
|
||||
typedef typename Kernel::Point_2 Rational_point_2;
|
||||
typedef typename Kernel::Segment_2 Rational_segment_2;
|
||||
typedef typename Kernel::Circle_2 Rational_circle_2;
|
||||
typedef _One_root_point_2<NT, Filter> Point_2;
|
||||
typedef typename Point_2::CoordNT CoordNT;
|
||||
typedef _Circle_segment_2<Kernel, Filter> Curve_2;
|
||||
typedef _X_monotone_circle_segment_2<Kernel, Filter> X_monotone_curve_2;
|
||||
typedef unsigned int Multiplicity;
|
||||
typedef Arr_circle_segment_traits_2<Kernel, Filter> Self;
|
||||
using Kernel = Kernel_;
|
||||
using NT = typename Kernel::FT;
|
||||
using Rational_point_2 = typename Kernel::Point_2;
|
||||
using Rational_segment_2 = typename Kernel::Segment_2;
|
||||
using Rational_circle_2 = typename Kernel::Circle_2;
|
||||
using Point_2 = _One_root_point_2<NT, Filter>;
|
||||
using CoordNT = typename Point_2::CoordNT;
|
||||
using Curve_2 = _Circle_segment_2<Kernel, Filter>;
|
||||
using X_monotone_curve_2 = _X_monotone_circle_segment_2<Kernel, Filter>;
|
||||
using Multiplicity = std::size_t;
|
||||
using Self = Arr_circle_segment_traits_2<Kernel, Filter>;
|
||||
|
||||
// Category tags:
|
||||
typedef Tag_true Has_left_category;
|
||||
typedef Tag_true Has_merge_category;
|
||||
typedef Tag_false Has_do_intersect_category;
|
||||
using Has_left_category = Tag_true;
|
||||
using Has_merge_category = Tag_true;
|
||||
using Has_do_intersect_category = Tag_false;
|
||||
|
||||
typedef Arr_oblivious_side_tag Left_side_category;
|
||||
typedef Arr_oblivious_side_tag Bottom_side_category;
|
||||
typedef Arr_oblivious_side_tag Top_side_category;
|
||||
typedef Arr_oblivious_side_tag Right_side_category;
|
||||
using Left_side_category = Arr_oblivious_side_tag;
|
||||
using Bottom_side_category = Arr_oblivious_side_tag;
|
||||
using Top_side_category = Arr_oblivious_side_tag;
|
||||
using Right_side_category = Arr_oblivious_side_tag;
|
||||
|
||||
protected:
|
||||
// Type definition for the intersection points mapping.
|
||||
typedef typename X_monotone_curve_2::Intersection_map Intersection_map;
|
||||
using Intersection_map = typename X_monotone_curve_2::Intersection_map;
|
||||
|
||||
mutable Intersection_map inter_map; // Mapping pairs of curve IDs to their
|
||||
// intersection points.
|
||||
|
|
@ -78,8 +78,7 @@ public:
|
|||
{}
|
||||
|
||||
/*! obtains the next curve index. */
|
||||
static unsigned int get_index ()
|
||||
{
|
||||
static unsigned int get_index() {
|
||||
#ifdef CGAL_NO_ATOMIC
|
||||
static unsigned int index;
|
||||
#else
|
||||
|
|
@ -91,8 +90,7 @@ public:
|
|||
/// \name Basic functor definitions.
|
||||
//@{
|
||||
|
||||
class Compare_x_2
|
||||
{
|
||||
class Compare_x_2 {
|
||||
public:
|
||||
/*! compares the \f$x\f$-coordinates of two points.
|
||||
* \param p1 The first point.
|
||||
|
|
@ -101,23 +99,17 @@ public:
|
|||
* SMALLER if x(p1) < x(p2);
|
||||
* EQUAL if x(p1) = x(p2).
|
||||
*/
|
||||
Comparison_result operator() (const Point_2& p1, const Point_2& p2) const
|
||||
{
|
||||
if (p1.identical (p2))
|
||||
return (EQUAL);
|
||||
Comparison_result operator() (const Point_2& p1, const Point_2& p2) const {
|
||||
if (p1.identical (p2)) return (EQUAL);
|
||||
|
||||
return (CGAL::compare (p1.x(), p2.x()));
|
||||
}
|
||||
};
|
||||
|
||||
/*! obtains a `Compare_x_2` functor object. */
|
||||
Compare_x_2 compare_x_2_object () const
|
||||
{
|
||||
return Compare_x_2();
|
||||
}
|
||||
Compare_x_2 compare_x_2_object () const { return Compare_x_2(); }
|
||||
|
||||
class Compare_xy_2
|
||||
{
|
||||
class Compare_xy_2 {
|
||||
public:
|
||||
/*! compares two points lexigoraphically: by x, then by y.
|
||||
* \param p1 The first point.
|
||||
|
|
@ -126,15 +118,11 @@ public:
|
|||
* SMALLER if x(p1) < x(p2), or if x(p1) = x(p2) and y(p1) < y(p2);
|
||||
* EQUAL if the two points are equal.
|
||||
*/
|
||||
Comparison_result operator() (const Point_2& p1, const Point_2& p2) const
|
||||
{
|
||||
if (p1.identical (p2))
|
||||
return (EQUAL);
|
||||
Comparison_result operator() (const Point_2& p1, const Point_2& p2) const {
|
||||
if (p1.identical (p2)) return (EQUAL);
|
||||
|
||||
Comparison_result res = CGAL::compare (p1.x(), p2.x());
|
||||
|
||||
if (res != EQUAL)
|
||||
return (res);
|
||||
Comparison_result res = CGAL::compare(p1.x(), p2.x());
|
||||
if (res != EQUAL) return (res);
|
||||
|
||||
return (CGAL::compare (p1.y(), p2.y()));
|
||||
}
|
||||
|
|
@ -142,69 +130,51 @@ public:
|
|||
|
||||
/*! obtains a Compare_xy_2 functor object. */
|
||||
Compare_xy_2 compare_xy_2_object () const
|
||||
{
|
||||
return Compare_xy_2();
|
||||
}
|
||||
{ return Compare_xy_2(); }
|
||||
|
||||
class Construct_min_vertex_2
|
||||
{
|
||||
class Construct_min_vertex_2 {
|
||||
public:
|
||||
/*! obtains the left endpoint of the \f$x\f$-monotone curve (segment).
|
||||
* \param cv The curve.
|
||||
* \return The left endpoint.
|
||||
*/
|
||||
const Point_2& operator() (const X_monotone_curve_2 & cv) const
|
||||
{
|
||||
return (cv.left());
|
||||
}
|
||||
{ return (cv.left()); }
|
||||
};
|
||||
|
||||
/*! obtains a `Construct_min_vertex_2` functor object. */
|
||||
Construct_min_vertex_2 construct_min_vertex_2_object () const
|
||||
{
|
||||
return Construct_min_vertex_2();
|
||||
}
|
||||
{ return Construct_min_vertex_2(); }
|
||||
|
||||
class Construct_max_vertex_2
|
||||
{
|
||||
class Construct_max_vertex_2 {
|
||||
public:
|
||||
/*! obtains the right endpoint of the \f$x\f$-monotone curve (segment).
|
||||
* \param cv The curve.
|
||||
* \return The right endpoint.
|
||||
*/
|
||||
const Point_2& operator() (const X_monotone_curve_2 & cv) const
|
||||
{
|
||||
return (cv.right());
|
||||
}
|
||||
{ return (cv.right()); }
|
||||
};
|
||||
|
||||
/*! obtains a Construct_max_vertex_2 functor object. */
|
||||
Construct_max_vertex_2 construct_max_vertex_2_object () const
|
||||
{
|
||||
return Construct_max_vertex_2();
|
||||
}
|
||||
{ return Construct_max_vertex_2(); }
|
||||
|
||||
class Is_vertical_2
|
||||
{
|
||||
class Is_vertical_2 {
|
||||
public:
|
||||
/*! checks whether the given \f$x\f$-monotone curve is a vertical segment.
|
||||
* \param cv The curve.
|
||||
* \return (true) if the curve is a vertical segment; (false) otherwise.
|
||||
*/
|
||||
bool operator() (const X_monotone_curve_2& cv) const
|
||||
{
|
||||
return (cv.is_vertical());
|
||||
}
|
||||
{ return (cv.is_vertical()); }
|
||||
};
|
||||
|
||||
/*! obtains an `Is_vertical_2` functor object. */
|
||||
Is_vertical_2 is_vertical_2_object () const
|
||||
{
|
||||
return Is_vertical_2();
|
||||
}
|
||||
{ return Is_vertical_2(); }
|
||||
|
||||
class Compare_y_at_x_2
|
||||
{
|
||||
class Compare_y_at_x_2 {
|
||||
public:
|
||||
/*! returns the location of the given point with respect to the input curve.
|
||||
* \param cv The curve.
|
||||
|
|
@ -214,23 +184,19 @@ public:
|
|||
* LARGER if y(p) > cv(x(p)), i.e. the point is above the curve;
|
||||
* EQUAL if p lies on the curve.
|
||||
*/
|
||||
Comparison_result operator() (const Point_2& p,
|
||||
const X_monotone_curve_2& cv) const
|
||||
{
|
||||
CGAL_precondition (cv.is_in_x_range (p));
|
||||
Comparison_result operator()(const Point_2& p,
|
||||
const X_monotone_curve_2& cv) const {
|
||||
CGAL_precondition (cv.is_in_x_range(p));
|
||||
|
||||
return (cv.point_position (p));
|
||||
return (cv.point_position(p));
|
||||
}
|
||||
};
|
||||
|
||||
/*! obtains a `Compare_y_at_x_2` functor object. */
|
||||
Compare_y_at_x_2 compare_y_at_x_2_object () const
|
||||
{
|
||||
return Compare_y_at_x_2();
|
||||
}
|
||||
{ return Compare_y_at_x_2(); }
|
||||
|
||||
class Compare_y_at_x_right_2
|
||||
{
|
||||
class Compare_y_at_x_right_2 {
|
||||
public:
|
||||
/*! compares the y value of two \f$x\f$-monotone curves immediately to the
|
||||
* right of their intersection point.
|
||||
|
|
@ -244,30 +210,29 @@ public:
|
|||
*/
|
||||
Comparison_result operator() (const X_monotone_curve_2& cv1,
|
||||
const X_monotone_curve_2& cv2,
|
||||
const Point_2& p) const
|
||||
{
|
||||
const Point_2& p) const {
|
||||
// Make sure that p lies on both curves, and that both are defined to its
|
||||
// right (so their right endpoint is lexicographically larger than p).
|
||||
CGAL_precondition (cv1.point_position (p) == EQUAL &&
|
||||
cv2.point_position (p) == EQUAL);
|
||||
|
||||
if ((CGAL::compare (cv1.left().x(),cv1.right().x()) == EQUAL) &&
|
||||
(CGAL::compare (cv2.left().x(),cv2.right().x()) == EQUAL))
|
||||
{ //both cv1 and cv2 are vertical
|
||||
(CGAL::compare (cv2.left().x(),cv2.right().x()) == EQUAL)) {
|
||||
//both cv1 and cv2 are vertical
|
||||
CGAL_precondition (!(cv1.right()).equals(p) && !(cv2.right()).equals(p));
|
||||
}
|
||||
else if ((CGAL::compare (cv1.left().x(),cv1.right().x()) != EQUAL) &&
|
||||
(CGAL::compare (cv2.left().x(),cv2.right().x()) == EQUAL))
|
||||
{ //only cv1 is vertical
|
||||
(CGAL::compare (cv2.left().x(),cv2.right().x()) == EQUAL)) {
|
||||
//only cv1 is vertical
|
||||
CGAL_precondition (!(cv1.right()).equals(p));
|
||||
}
|
||||
else if ((CGAL::compare (cv1.left().x(),cv1.right().x()) == EQUAL) &&
|
||||
(CGAL::compare (cv2.left().x(),cv2.right().x()) != EQUAL))
|
||||
{ //only cv2 is vertical
|
||||
(CGAL::compare (cv2.left().x(),cv2.right().x()) != EQUAL)) {
|
||||
//only cv2 is vertical
|
||||
CGAL_precondition (!(cv2.right()).equals(p));
|
||||
}
|
||||
else
|
||||
{ //both cv1 and cv2 are non vertical
|
||||
else {
|
||||
//both cv1 and cv2 are non vertical
|
||||
CGAL_precondition (CGAL::compare (cv1.right().x(),p.x()) == LARGER &&
|
||||
CGAL::compare (cv2.right().x(),p.x()) == LARGER);
|
||||
}
|
||||
|
|
@ -278,12 +243,9 @@ public:
|
|||
|
||||
/*! obtains a `Compare_y_at_x_right_2` functor object. */
|
||||
Compare_y_at_x_right_2 compare_y_at_x_right_2_object () const
|
||||
{
|
||||
return Compare_y_at_x_right_2();
|
||||
}
|
||||
{ return Compare_y_at_x_right_2(); }
|
||||
|
||||
class Compare_y_at_x_left_2
|
||||
{
|
||||
class Compare_y_at_x_left_2 {
|
||||
public:
|
||||
/*! compares the \f$y\f$-value of two \f$x\f$-monotone curves immediately to
|
||||
* the left of their intersection point.
|
||||
|
|
@ -297,8 +259,7 @@ public:
|
|||
*/
|
||||
Comparison_result operator() (const X_monotone_curve_2& cv1,
|
||||
const X_monotone_curve_2& cv2,
|
||||
const Point_2& p) const
|
||||
{
|
||||
const Point_2& p) const {
|
||||
// Make sure that p lies on both curves, and that both are defined to its
|
||||
// left (so their left endpoint is lexicographically smaller than p).
|
||||
|
||||
|
|
@ -306,25 +267,25 @@ public:
|
|||
cv2.point_position (p) == EQUAL);
|
||||
|
||||
if ((CGAL::compare (cv1.left().x(),cv1.right().x()) == EQUAL) &&
|
||||
(CGAL::compare (cv2.left().x(),cv2.right().x()) == EQUAL))
|
||||
{ //both cv1 and cv2 are vertical
|
||||
CGAL_precondition (!(cv1.left()).equals(p) && !(cv2.left()).equals(p));
|
||||
}
|
||||
else if ((CGAL::compare (cv1.left().x(),cv1.right().x()) != EQUAL) &&
|
||||
(CGAL::compare (cv2.left().x(),cv2.right().x()) == EQUAL))
|
||||
{ //only cv1 is vertical
|
||||
CGAL_precondition (!(cv1.left()).equals(p));
|
||||
}
|
||||
else if ((CGAL::compare (cv1.left().x(),cv1.right().x()) == EQUAL) &&
|
||||
(CGAL::compare (cv2.left().x(),cv2.right().x()) != EQUAL))
|
||||
{ //only cv2 is vertical
|
||||
CGAL_precondition (!(cv2.left()).equals(p));
|
||||
}
|
||||
else
|
||||
{ //both cv1 and cv2 are non vertical
|
||||
(CGAL::compare (cv2.left().x(),cv2.right().x()) == EQUAL)) {
|
||||
//both cv1 and cv2 are vertical
|
||||
CGAL_precondition (!(cv1.left()).equals(p) && !(cv2.left()).equals(p));
|
||||
}
|
||||
else if ((CGAL::compare (cv1.left().x(),cv1.right().x()) != EQUAL) &&
|
||||
(CGAL::compare (cv2.left().x(),cv2.right().x()) == EQUAL)) {
|
||||
//only cv1 is vertical
|
||||
CGAL_precondition (!(cv1.left()).equals(p));
|
||||
}
|
||||
else if ((CGAL::compare (cv1.left().x(),cv1.right().x()) == EQUAL) &&
|
||||
(CGAL::compare (cv2.left().x(),cv2.right().x()) != EQUAL)) {
|
||||
//only cv2 is vertical
|
||||
CGAL_precondition (!(cv2.left()).equals(p));
|
||||
}
|
||||
else {
|
||||
//both cv1 and cv2 are non vertical
|
||||
CGAL_precondition (CGAL::compare (cv1.left().x(),p.x()) == SMALLER &&
|
||||
CGAL::compare (cv2.left().x(),p.x()) == SMALLER);
|
||||
}
|
||||
}
|
||||
// Compare the two curves immediately to the left of p:
|
||||
return (cv1.compare_to_left (cv2, p));
|
||||
}
|
||||
|
|
@ -332,12 +293,9 @@ public:
|
|||
|
||||
/*! obtains a `Compare_y_at_x_left_2` functor object. */
|
||||
Compare_y_at_x_left_2 compare_y_at_x_left_2_object () const
|
||||
{
|
||||
return Compare_y_at_x_left_2();
|
||||
}
|
||||
{ return Compare_y_at_x_left_2(); }
|
||||
|
||||
class Equal_2
|
||||
{
|
||||
class Equal_2 {
|
||||
public:
|
||||
/*! checks if the two \f$x\f$-monotone curves are the same (have the same
|
||||
* graph).
|
||||
|
|
@ -346,10 +304,8 @@ public:
|
|||
* \return (true) if the two curves are the same; (false) otherwise.
|
||||
*/
|
||||
bool operator() (const X_monotone_curve_2& cv1,
|
||||
const X_monotone_curve_2& cv2) const
|
||||
{
|
||||
if (&cv1 == &cv2)
|
||||
return (true);
|
||||
const X_monotone_curve_2& cv2) const {
|
||||
if (&cv1 == &cv2) return (true);
|
||||
|
||||
return (cv1.equals (cv2));
|
||||
}
|
||||
|
|
@ -360,24 +316,20 @@ public:
|
|||
* \return (true) if the two point are the same; (false) otherwise.
|
||||
*/
|
||||
bool operator() (const Point_2& p1, const Point_2& p2) const
|
||||
{
|
||||
return (p1.equals (p2));
|
||||
}
|
||||
{ return (p1.equals (p2)); }
|
||||
};
|
||||
|
||||
/*! obtains an `Equal_2` functor object. */
|
||||
Equal_2 equal_2_object () const
|
||||
{
|
||||
return Equal_2();
|
||||
}
|
||||
{ return Equal_2(); }
|
||||
//@}
|
||||
|
||||
/// \name Functor definitions for approximations. Used by the landmarks
|
||||
// point-location strategy and the drawing procedure.
|
||||
//@{
|
||||
typedef double Approximate_number_type;
|
||||
typedef CGAL::Cartesian<Approximate_number_type> Approximate_kernel;
|
||||
typedef Approximate_kernel::Point_2 Approximate_point_2;
|
||||
using Approximate_number_type = double;
|
||||
using Approximate_kernel = CGAL::Simple_cartesian<Approximate_number_type>;
|
||||
using Approximate_point_2 = Approximate_kernel::Point_2;
|
||||
|
||||
class Approximate_2 {
|
||||
protected:
|
||||
|
|
@ -557,7 +509,7 @@ public:
|
|||
*/
|
||||
class Make_x_monotone_2 {
|
||||
private:
|
||||
typedef Arr_circle_segment_traits_2<Kernel_, Filter> Self;
|
||||
using Self = Arr_circle_segment_traits_2<Kernel_, Filter>;
|
||||
|
||||
bool m_use_cache;
|
||||
|
||||
|
|
@ -573,8 +525,7 @@ public:
|
|||
* \return the past-the-end iterator.
|
||||
*/
|
||||
template <typename OutputIterator>
|
||||
OutputIterator operator()(const Curve_2& cv, OutputIterator oi) const
|
||||
{
|
||||
OutputIterator operator()(const Curve_2& cv, OutputIterator oi) const {
|
||||
// Increment the serial number of the curve cv, which will serve as its
|
||||
// unique identifier.
|
||||
unsigned int index = 0;
|
||||
|
|
@ -591,7 +542,7 @@ public:
|
|||
|
||||
// Check the case of a degenerate circle (a point).
|
||||
const typename Kernel::Circle_2& circ = cv.supporting_circle();
|
||||
CGAL::Sign sign_rad = CGAL::sign (circ.squared_radius());
|
||||
CGAL::Sign sign_rad = CGAL::sign (circ.squared_radius());
|
||||
CGAL_precondition (sign_rad != NEGATIVE);
|
||||
|
||||
if (sign_rad == ZERO) {
|
||||
|
|
@ -603,8 +554,8 @@ public:
|
|||
|
||||
// The curve is circular: compute the to vertical tangency points
|
||||
// of the supporting circle.
|
||||
Point_2 vpts[2];
|
||||
unsigned int n_vpts = cv.vertical_tangency_points (vpts);
|
||||
Point_2 vpts[2];
|
||||
unsigned int n_vpts = cv.vertical_tangency_points (vpts);
|
||||
|
||||
if (cv.is_full()) {
|
||||
CGAL_assertion (n_vpts == 2);
|
||||
|
|
@ -674,8 +625,7 @@ public:
|
|||
Make_x_monotone_2 make_x_monotone_2_object() const
|
||||
{ return Make_x_monotone_2(m_use_cache); }
|
||||
|
||||
class Split_2
|
||||
{
|
||||
class Split_2 {
|
||||
public:
|
||||
|
||||
/*! splits a given \f$x\f$-monotone curve at a given point into two
|
||||
|
|
@ -687,8 +637,7 @@ public:
|
|||
* \pre `p` lies on cv but is not one of its end-points.
|
||||
*/
|
||||
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 {
|
||||
CGAL_precondition (cv.point_position(p)==EQUAL &&
|
||||
! p.equals (cv.source()) &&
|
||||
! p.equals (cv.target()));
|
||||
|
|
@ -699,10 +648,7 @@ public:
|
|||
};
|
||||
|
||||
/*! obtains a `Split_2` functor object. */
|
||||
Split_2 split_2_object () const
|
||||
{
|
||||
return Split_2();
|
||||
}
|
||||
Split_2 split_2_object () const { return Split_2(); }
|
||||
|
||||
class Intersect_2 {
|
||||
private:
|
||||
|
|
@ -730,8 +676,7 @@ public:
|
|||
/*! obtains an `Intersect_2` functor object. */
|
||||
Intersect_2 intersect_2_object() const { return (Intersect_2(inter_map)); }
|
||||
|
||||
class Are_mergeable_2
|
||||
{
|
||||
class Are_mergeable_2 {
|
||||
public:
|
||||
/*! checks whether it is possible to merge two given \f$x\f$-monotone curves.
|
||||
* \param cv1 The first curve.
|
||||
|
|
@ -742,24 +687,19 @@ public:
|
|||
*/
|
||||
bool operator() (const X_monotone_curve_2& cv1,
|
||||
const X_monotone_curve_2& cv2) const
|
||||
{
|
||||
return (cv1.can_merge_with (cv2));
|
||||
}
|
||||
{ return (cv1.can_merge_with (cv2)); }
|
||||
};
|
||||
|
||||
/*! obtains an `Are_mergeable_2` functor object. */
|
||||
Are_mergeable_2 are_mergeable_2_object () const
|
||||
{
|
||||
return Are_mergeable_2();
|
||||
}
|
||||
{ return Are_mergeable_2(); }
|
||||
|
||||
/*! \class Merge_2
|
||||
* A functor that merges two \f$x\f$-monotone arcs into one.
|
||||
*/
|
||||
class Merge_2
|
||||
{
|
||||
class Merge_2 {
|
||||
protected:
|
||||
typedef Arr_circle_segment_traits_2<Kernel, Filter> Traits;
|
||||
using Traits = Arr_circle_segment_traits_2<Kernel, Filter>;
|
||||
|
||||
/*! The traits (in case it has state) */
|
||||
const Traits* m_traits;
|
||||
|
|
@ -780,8 +720,7 @@ public:
|
|||
*/
|
||||
void operator() (const X_monotone_curve_2& cv1,
|
||||
const X_monotone_curve_2& cv2,
|
||||
X_monotone_curve_2& c) const
|
||||
{
|
||||
X_monotone_curve_2& c) const {
|
||||
CGAL_precondition(m_traits->are_mergeable_2_object()(cv2, cv1));
|
||||
|
||||
c = cv1;
|
||||
|
|
@ -790,20 +729,15 @@ public:
|
|||
};
|
||||
|
||||
/*! obtains a `Merge_2` functor object. */
|
||||
Merge_2 merge_2_object () const
|
||||
{
|
||||
return Merge_2(this);
|
||||
}
|
||||
Merge_2 merge_2_object () const { return Merge_2(this); }
|
||||
|
||||
class Compare_endpoints_xy_2
|
||||
{
|
||||
class Compare_endpoints_xy_2 {
|
||||
public:
|
||||
/*! compares lexicogrphic the endpoints of a \f$x\f$-monotone curve.
|
||||
* \param cv the curve
|
||||
* \return `SMALLER` if the curve is directed right, else return `LARGER`.
|
||||
*/
|
||||
Comparison_result operator()(const X_monotone_curve_2& cv) const
|
||||
{
|
||||
Comparison_result operator()(const X_monotone_curve_2& cv) const {
|
||||
if(cv.is_directed_right())
|
||||
return(SMALLER);
|
||||
return (LARGER);
|
||||
|
|
@ -812,32 +746,25 @@ public:
|
|||
|
||||
/*! obtains a `Compare_endpoints_xy_2` functor object. */
|
||||
Compare_endpoints_xy_2 compare_endpoints_xy_2_object() const
|
||||
{
|
||||
return Compare_endpoints_xy_2();
|
||||
}
|
||||
{ return Compare_endpoints_xy_2(); }
|
||||
|
||||
class Construct_opposite_2
|
||||
{
|
||||
class Construct_opposite_2 {
|
||||
public:
|
||||
/*! constructs an opposite \f$x\f$-monotone curve.
|
||||
* \param cv the curve
|
||||
* \return an opposite \f$x\f$-monotone curve.
|
||||
*/
|
||||
X_monotone_curve_2 operator()(const X_monotone_curve_2& cv) const
|
||||
{
|
||||
return cv.construct_opposite();
|
||||
}
|
||||
{ return cv.construct_opposite(); }
|
||||
};
|
||||
|
||||
/*! obtains a `Construct_opposite_2` functor object. */
|
||||
Construct_opposite_2 construct_opposite_2_object() const
|
||||
{
|
||||
return Construct_opposite_2();
|
||||
}
|
||||
{ return Construct_opposite_2(); }
|
||||
|
||||
class Trim_2 {
|
||||
protected:
|
||||
typedef Arr_circle_segment_traits_2<Kernel, Filter> Traits;
|
||||
using Traits = Arr_circle_segment_traits_2<Kernel, Filter>;
|
||||
|
||||
/*! The traits (in case it has state) */
|
||||
const Traits& m_traits;
|
||||
|
|
@ -860,8 +787,7 @@ public:
|
|||
*/
|
||||
X_monotone_curve_2 operator()(const X_monotone_curve_2& xcv,
|
||||
const Point_2& src,
|
||||
const Point_2& tgt)const
|
||||
{
|
||||
const Point_2& tgt)const {
|
||||
// make functor objects
|
||||
CGAL_precondition_code(Compare_y_at_x_2 compare_y_at_x_2 =
|
||||
m_traits.compare_y_at_x_2_object());
|
||||
|
|
@ -885,7 +811,6 @@ public:
|
|||
Trim_2 trim_2_object() const { return Trim_2(*this); }
|
||||
|
||||
// @}
|
||||
|
||||
};
|
||||
|
||||
} // namespace CGAL
|
||||
|
|
|
|||
|
|
@ -40,55 +40,54 @@
|
|||
namespace CGAL {
|
||||
|
||||
namespace internal{
|
||||
template <class CircularKernel>
|
||||
class Non_x_monotonic_Circular_arc_2
|
||||
: public CircularKernel::Circular_arc_2
|
||||
{
|
||||
typedef typename CircularKernel::FT FT;
|
||||
typedef typename CircularKernel::Point_2 Point_2;
|
||||
typedef typename CircularKernel::Line_2 Line_2;
|
||||
typedef typename CircularKernel::Circle_2 Circle_2;
|
||||
typedef typename CircularKernel::Circular_arc_point_2
|
||||
Circular_arc_point_2;
|
||||
|
||||
typedef typename CircularKernel::Circular_arc_2 Base;
|
||||
template <typename CircularKernel>
|
||||
class Non_x_monotonic_Circular_arc_2 :
|
||||
public CircularKernel::Circular_arc_2 {
|
||||
using FT = typename CircularKernel::FT;
|
||||
using Point_2 = typename CircularKernel::Point_2;
|
||||
using Line_2 = typename CircularKernel::Line_2;
|
||||
using Circle_2 = typename CircularKernel::Circle_2;
|
||||
using Circular_arc_point_2 = typename CircularKernel::Circular_arc_point_2;
|
||||
|
||||
using Base = typename CircularKernel::Circular_arc_2;
|
||||
|
||||
public:
|
||||
Non_x_monotonic_Circular_arc_2(): Base(){}
|
||||
|
||||
Non_x_monotonic_Circular_arc_2(const Circle_2 &c): Base(c){}
|
||||
Non_x_monotonic_Circular_arc_2(const Circle_2& c): Base(c){}
|
||||
// Not Documented
|
||||
Non_x_monotonic_Circular_arc_2(const Circle_2 &support,
|
||||
const Line_2 &l1, const bool b_l1,
|
||||
const Line_2 &l2, const bool b_l2)
|
||||
: Base(support,l1,b_l1,l2,b_l2){}
|
||||
Non_x_monotonic_Circular_arc_2(const Circle_2& support,
|
||||
const Line_2& l1, const bool b_l1,
|
||||
const Line_2& l2, const bool b_l2) :
|
||||
Base(support,l1,b_l1,l2,b_l2){}
|
||||
|
||||
// Not Documented
|
||||
Non_x_monotonic_Circular_arc_2(const Circle_2 &c,
|
||||
const Circle_2 &c1, const bool b_1,
|
||||
const Circle_2 &c2, const bool b_2)
|
||||
: Base(c,c1,b_1,c2,b_2)
|
||||
Non_x_monotonic_Circular_arc_2(const Circle_2& c,
|
||||
const Circle_2& c1, const bool b_1,
|
||||
const Circle_2& c2, const bool b_2) :
|
||||
Base(c,c1,b_1,c2,b_2)
|
||||
{}
|
||||
|
||||
Non_x_monotonic_Circular_arc_2(const Point_2 &start,
|
||||
const Point_2 &middle,
|
||||
const Point_2 &end)
|
||||
: Base(start,middle,end)
|
||||
Non_x_monotonic_Circular_arc_2(const Point_2& start,
|
||||
const Point_2& middle,
|
||||
const Point_2& end) :
|
||||
Base(start,middle,end)
|
||||
{}
|
||||
|
||||
Non_x_monotonic_Circular_arc_2(const Circle_2 &support,
|
||||
const Circular_arc_point_2 &begin,
|
||||
const Circular_arc_point_2 &end)
|
||||
: Base(support,begin,end)
|
||||
Non_x_monotonic_Circular_arc_2(const Circle_2& support,
|
||||
const Circular_arc_point_2& begin,
|
||||
const Circular_arc_point_2& end) :
|
||||
Base(support,begin,end)
|
||||
{}
|
||||
|
||||
Non_x_monotonic_Circular_arc_2(const Point_2 &start,
|
||||
const Point_2 &end,
|
||||
const FT &bulge)
|
||||
: Base(start,end,bulge)
|
||||
Non_x_monotonic_Circular_arc_2(const Point_2& start,
|
||||
const Point_2& end,
|
||||
const FT& bulge) :
|
||||
Base(start,end,bulge)
|
||||
{}
|
||||
|
||||
Non_x_monotonic_Circular_arc_2(const Base& a) : Base(a) {}
|
||||
Non_x_monotonic_Circular_arc_2(const Base& a) : Base(a) {}
|
||||
};
|
||||
|
||||
} //namespace internal
|
||||
|
|
@ -98,45 +97,40 @@ public:
|
|||
|
||||
template < typename CircularKernel >
|
||||
class Arr_circular_arc_traits_2 {
|
||||
|
||||
CircularKernel ck;
|
||||
|
||||
public:
|
||||
using Kernel = CircularKernel;
|
||||
using Curve_2 = internal::Non_x_monotonic_Circular_arc_2<CircularKernel>;
|
||||
using X_monotone_curve_2 = typename CircularKernel::Circular_arc_2;
|
||||
|
||||
typedef CircularKernel Kernel;
|
||||
typedef internal::Non_x_monotonic_Circular_arc_2<CircularKernel> Curve_2;
|
||||
typedef typename CircularKernel::Circular_arc_2 X_monotone_curve_2;
|
||||
using Point = typename CircularKernel::Circular_arc_point_2;
|
||||
using Point_2 = typename CircularKernel::Circular_arc_point_2;
|
||||
|
||||
typedef typename CircularKernel::Circular_arc_point_2 Point;
|
||||
typedef typename CircularKernel::Circular_arc_point_2 Point_2;
|
||||
using Multiplicity = std::size_t;
|
||||
|
||||
typedef unsigned int Multiplicity;
|
||||
using Has_left_category = CGAL::Tag_false;
|
||||
using Has_merge_category = CGAL::Tag_false;
|
||||
using Has_do_intersect_category = CGAL::Tag_false;
|
||||
|
||||
typedef CGAL::Tag_false Has_left_category;
|
||||
typedef CGAL::Tag_false Has_merge_category;
|
||||
typedef CGAL::Tag_false Has_do_intersect_category;
|
||||
using Left_side_category = Arr_oblivious_side_tag;
|
||||
using Bottom_side_category = Arr_oblivious_side_tag;
|
||||
using Top_side_category = Arr_oblivious_side_tag;
|
||||
using Right_side_category = Arr_oblivious_side_tag;
|
||||
|
||||
typedef Arr_oblivious_side_tag Left_side_category;
|
||||
typedef Arr_oblivious_side_tag Bottom_side_category;
|
||||
typedef Arr_oblivious_side_tag Top_side_category;
|
||||
typedef Arr_oblivious_side_tag Right_side_category;
|
||||
Arr_circular_arc_traits_2(const CircularKernel& k = CircularKernel()) : ck(k) {}
|
||||
|
||||
Arr_circular_arc_traits_2(const CircularKernel &k = CircularKernel())
|
||||
: ck(k) {}
|
||||
|
||||
typedef typename CircularKernel::Compare_x_2 Compare_x_2;
|
||||
typedef typename CircularKernel::Compare_xy_2 Compare_xy_2;
|
||||
typedef typename CircularKernel::Compare_y_at_x_2 Compare_y_at_x_2;
|
||||
typedef typename CircularKernel::Compare_y_to_right_2 Compare_y_at_x_right_2;
|
||||
typedef typename CircularKernel::Construct_circular_max_vertex_2
|
||||
Construct_max_vertex_2;
|
||||
typedef typename CircularKernel::Construct_circular_min_vertex_2
|
||||
Construct_min_vertex_2;
|
||||
typedef typename CircularKernel::Equal_2 Equal_2;
|
||||
using Compare_x_2 = typename CircularKernel::Compare_x_2;
|
||||
using Compare_xy_2 = typename CircularKernel::Compare_xy_2;
|
||||
using Compare_y_at_x_2 = typename CircularKernel::Compare_y_at_x_2;
|
||||
using Compare_y_at_x_right_2 = typename CircularKernel::Compare_y_to_right_2;
|
||||
using Construct_max_vertex_2 = typename CircularKernel::Construct_circular_max_vertex_2;
|
||||
using Construct_min_vertex_2 = typename CircularKernel::Construct_circular_min_vertex_2;
|
||||
using Equal_2 = typename CircularKernel::Equal_2;
|
||||
// typedef typename CircularKernel::Make_x_monotone_2 Make_x_monotone_2;
|
||||
typedef typename CircularKernel::Split_2 Split_2;
|
||||
typedef typename CircularKernel::Intersect_2 Intersect_2;
|
||||
typedef typename CircularKernel::Is_vertical_2 Is_vertical_2;
|
||||
using Split_2 = typename CircularKernel::Split_2;
|
||||
using Intersect_2 = typename CircularKernel::Intersect_2;
|
||||
using Is_vertical_2 = typename CircularKernel::Is_vertical_2;
|
||||
|
||||
Compare_x_2 compare_x_2_object() const
|
||||
{ return ck.compare_x_2_object(); }
|
||||
|
|
@ -160,26 +154,23 @@ public:
|
|||
{ return ck.split_2_object(); }
|
||||
|
||||
Intersect_2 intersect_2_object() const
|
||||
{ return ck.intersect_2_object(); }
|
||||
{ return ck.intersect_2_object(); }
|
||||
|
||||
Construct_max_vertex_2 construct_max_vertex_2_object() const
|
||||
{ return ck.construct_circular_max_vertex_2_object(); }
|
||||
{ return ck.construct_circular_max_vertex_2_object(); }
|
||||
|
||||
Construct_min_vertex_2 construct_min_vertex_2_object() const
|
||||
{ return ck.construct_circular_min_vertex_2_object(); }
|
||||
{ return ck.construct_circular_min_vertex_2_object(); }
|
||||
|
||||
Is_vertical_2 is_vertical_2_object() const
|
||||
{ return ck.is_vertical_2_object(); }
|
||||
|
||||
{ return ck.is_vertical_2_object(); }
|
||||
|
||||
//! A functor for subdividing curves into x-monotone curves.
|
||||
class Make_x_monotone_2 {
|
||||
public:
|
||||
template <typename OutputIterator>
|
||||
OutputIterator operator()(const Curve_2& arc, OutputIterator oi) const
|
||||
{
|
||||
typedef std::variant<Point_2, X_monotone_curve_2>
|
||||
Make_x_monotone_result;
|
||||
OutputIterator operator()(const Curve_2& arc, OutputIterator oi) const {
|
||||
using Make_x_monotone_result = std::variant<Point_2, X_monotone_curve_2>;
|
||||
|
||||
std::vector<Make_x_monotone_result> objs;
|
||||
CircularKernel().make_x_monotone_2_object()(arc, std::back_inserter(objs));
|
||||
|
|
|
|||
|
|
@ -41,515 +41,395 @@
|
|||
#include <CGAL/Arr_tags.h>
|
||||
|
||||
namespace CGAL {
|
||||
namespace VariantFunctors{
|
||||
|
||||
// Takes an iterator range of Object(Line/Circular_arc/Point),
|
||||
// returns a variant of Line, Circular_arc, and Point_2.
|
||||
template <class CK, class Arc1, class Arc2, class OutputIterator>
|
||||
OutputIterator
|
||||
object_to_object_variant(const std::vector<CGAL::Object>& res1,
|
||||
OutputIterator res2)
|
||||
{
|
||||
typedef typename CK::Circular_arc_point_2 Point_2;
|
||||
typedef std::variant<Arc1, Arc2> X_monotone_curve_2;
|
||||
typedef std::variant<Point_2, X_monotone_curve_2>
|
||||
Make_x_monotone_result;
|
||||
namespace VariantFunctors {
|
||||
|
||||
for (auto it = res1.begin(); it != res1.end(); ++it) {
|
||||
if (const Arc1* arc = CGAL::object_cast<Arc1>(&*it)) {
|
||||
std::variant<Arc1, Arc2> v = *arc;
|
||||
*res2++ = Make_x_monotone_result(v);
|
||||
}
|
||||
else if (const Arc2* line = CGAL::object_cast<Arc2>(&*it)) {
|
||||
std::variant<Arc1, Arc2> v = *line;
|
||||
*res2++ = Make_x_monotone_result(v);
|
||||
}
|
||||
else if (const Point_2* p = CGAL::object_cast<Point_2>(&*it)) {
|
||||
*res2++ = Make_x_monotone_result(*p);
|
||||
}
|
||||
else CGAL_error();
|
||||
// Takes an iterator range of Object(Line/Circular_arc/Point),
|
||||
// returns a variant of Line, Circular_arc, and Point_2.
|
||||
template <typename CK, typename Arc1, typename Arc2, typename OutputIterator>
|
||||
OutputIterator object_to_object_variant(const std::vector<CGAL::Object>& res1,
|
||||
OutputIterator res2) {
|
||||
using Point_2 = typename CK::Circular_arc_point_2;
|
||||
using X_monotone_curve_2 = std::variant<Arc1, Arc2>;
|
||||
using Make_x_monotone_result = std::variant<Point_2, X_monotone_curve_2>;
|
||||
|
||||
for (auto it = res1.begin(); it != res1.end(); ++it) {
|
||||
if (const Arc1* arc = CGAL::object_cast<Arc1>(&*it)) {
|
||||
std::variant<Arc1, Arc2> v = *arc;
|
||||
*res2++ = Make_x_monotone_result(v);
|
||||
}
|
||||
else if (const Arc2* line = CGAL::object_cast<Arc2>(&*it)) {
|
||||
std::variant<Arc1, Arc2> v = *line;
|
||||
*res2++ = Make_x_monotone_result(v);
|
||||
}
|
||||
else if (const Point_2* p = CGAL::object_cast<Point_2>(&*it)) {
|
||||
*res2++ = Make_x_monotone_result(*p);
|
||||
}
|
||||
else CGAL_error();
|
||||
}
|
||||
return res2;
|
||||
}
|
||||
|
||||
template <typename CircularKernel, typename Arc1, typename Arc2>
|
||||
class Compare_y_to_right_2 {
|
||||
public:
|
||||
using result_type = CGAL::Comparison_result;
|
||||
using Circular_arc_point_2 = typename CircularKernel::Circular_arc_point_2;
|
||||
|
||||
result_type operator()(const std::variant<Arc1, Arc2>& a1,
|
||||
const std::variant<Arc1, Arc2>& a2,
|
||||
const Circular_arc_point_2& p) const {
|
||||
if (const Arc1* arc1 = std::get_if<Arc1>(&a1)) {
|
||||
if (const Arc1* arc2 = std::get_if<Arc1>(&a2)) {
|
||||
return CircularKernel().compare_y_to_right_2_object()(*arc1, *arc2, p);
|
||||
}
|
||||
return res2;
|
||||
else {
|
||||
const Arc2* arc2e = std::get_if<Arc2>(&a2);
|
||||
return CircularKernel().compare_y_to_right_2_object()(*arc1, *arc2e, p);
|
||||
}
|
||||
}
|
||||
const Arc2* arc1 = std::get_if<Arc2>(&a1);
|
||||
if (const Arc1* arc2 = std::get_if<Arc1>(&a2)) {
|
||||
return CircularKernel().compare_y_to_right_2_object()(*arc1, *arc2, p);
|
||||
}
|
||||
const Arc2* arc2e = std::get_if<Arc2>(&a2);
|
||||
return CircularKernel().compare_y_to_right_2_object()(*arc1, *arc2e, p);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename CircularKernel>
|
||||
class Variant_Equal_2 {
|
||||
public:
|
||||
template <typename T>
|
||||
bool operator()(const T& a0, const T& a1) const
|
||||
{ return CircularKernel().equal_2_object()(a0,a1); }
|
||||
|
||||
template <typename T1, typename T2>
|
||||
bool operator()(const T1& , const T2&) const
|
||||
{ return false; }
|
||||
};
|
||||
|
||||
template <typename CircularKernel, class Arc1, class Arc2>
|
||||
class Equal_2 : public CircularKernel::Equal_2 {
|
||||
public:
|
||||
using Curve_2 = std::variant< Arc1, Arc2>;
|
||||
using result_type = bool;
|
||||
using CircularKernel::Equal_2::operator();
|
||||
using Circular_arc_point_2 = typename CircularKernel::Circular_arc_point_2;
|
||||
using Line_arc_2 = typename CircularKernel::Line_arc_2;
|
||||
using Circular_arc_2 = typename CircularKernel::Circular_arc_2;
|
||||
using CK_Equal_2 = typename CircularKernel::Equal_2;
|
||||
|
||||
result_type operator()(const Circular_arc_point_2& p0,
|
||||
const Circular_arc_point_2& p1) const
|
||||
{ return CK_Equal_2()(p0, p1); }
|
||||
|
||||
result_type operator()(const Circular_arc_2& a0, const Circular_arc_2& a1) const
|
||||
{ return CK_Equal_2()(a0, a1); }
|
||||
|
||||
result_type operator()(const Line_arc_2& a0, const Line_arc_2& a1) const
|
||||
{ return CK_Equal_2()(a0, a1); }
|
||||
|
||||
result_type operator()(const Line_arc_2& /*a0*/, const Circular_arc_2& /*a1*/) const
|
||||
{ return false; }
|
||||
|
||||
result_type operator()(const Circular_arc_2& /*a0*/, const Line_arc_2& /*a1*/) const
|
||||
{ return false; }
|
||||
|
||||
result_type operator()(const Curve_2& a0, const Curve_2& a1) const
|
||||
{ return std::visit(Variant_Equal_2<CircularKernel>(), a0, a1); }
|
||||
};
|
||||
|
||||
template <typename CircularKernel, typename Arc1, typename Arc2>
|
||||
class Compare_y_at_x_2 {
|
||||
public:
|
||||
using Circular_arc_point_2 = typename CircularKernel::Circular_arc_point_2;
|
||||
using result_type = CGAL::Comparison_result;
|
||||
|
||||
result_type operator()(const Circular_arc_point_2& p,
|
||||
const std::variant< Arc1, Arc2>& A1) const {
|
||||
if (const Arc1* arc1 = std::get_if<Arc1>(&A1)){
|
||||
return CircularKernel().compare_y_at_x_2_object()(p, *arc1);
|
||||
}
|
||||
else {
|
||||
const Arc2* arc2 = std::get_if<Arc2>(&A1);
|
||||
return CircularKernel().compare_y_at_x_2_object()(p, *arc2);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename CircularKernel>
|
||||
class Variant_Do_overlap_2 {
|
||||
public:
|
||||
template <typename T>
|
||||
bool operator()(const T& a0, const T& a1) const
|
||||
{ return CircularKernel().do_overlap_2_object()(a0, a1); }
|
||||
|
||||
template <typename T1, typename T2>
|
||||
bool operator()(const T1&, const T2&) const
|
||||
{ return false; }
|
||||
};
|
||||
|
||||
template <typename CircularKernel, typename Arc1, typename Arc2>
|
||||
class Do_overlap_2 {
|
||||
public:
|
||||
using Circular_arc_point_2 = typename CircularKernel::Circular_arc_point_2;
|
||||
using result_type = bool;
|
||||
|
||||
result_type operator()(const std::variant< Arc1, Arc2>& A0,
|
||||
const std::variant< Arc1, Arc2>& A1) const
|
||||
{ return std::visit(Variant_Do_overlap_2<CircularKernel>(), A0, A1); }
|
||||
};
|
||||
|
||||
//! A functor for subdividing curves into x-monotone curves.
|
||||
template <typename CircularKernel, typename Arc1, typename Arc2>
|
||||
class Make_x_monotone_2 {
|
||||
public:
|
||||
using Circular_arc_point_2 = typename CircularKernel::Circular_arc_point_2;
|
||||
|
||||
template <typename OutputIterator, typename Not_X_Monotone>
|
||||
OutputIterator operator()(const std::variant<Arc1, Arc2, Not_X_Monotone>& A,
|
||||
OutputIterator res) const {
|
||||
if ( const Arc1* arc1 = std::get_if<Arc1>(&A)) {
|
||||
return CircularKernel().make_x_monotone_2_object()(*arc1, res);
|
||||
}
|
||||
else {
|
||||
const Arc2* arc2 = std::get_if<Arc2>(&A);
|
||||
return CircularKernel().make_x_monotone_2_object()(*arc2, res);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename CircularKernel, typename Arc1, typename Arc2>
|
||||
class Intersect_2 {
|
||||
public:
|
||||
using Circular_arc_point_2 = typename CircularKernel::Circular_arc_point_2;
|
||||
|
||||
template <typename OutputIterator>
|
||||
OutputIterator operator()(const std::variant< Arc1, Arc2>& c1,
|
||||
const std::variant< Arc1, Arc2>& c2,
|
||||
OutputIterator oi) const {
|
||||
if (const Arc1* arc1 = std::get_if<Arc1>(&c1)) {
|
||||
if ( const Arc1* arc2 = std::get_if<Arc1>(&c2)) {
|
||||
return CircularKernel().intersect_2_object()(*arc1, *arc2, oi);
|
||||
}
|
||||
const Arc2* arc2 = std::get_if<Arc2>(&c2);
|
||||
return CircularKernel().intersect_2_object()(*arc1, *arc2, oi);
|
||||
}
|
||||
|
||||
template <class CircularKernel, class Arc1, class Arc2>
|
||||
class Compare_y_to_right_2
|
||||
{
|
||||
public:
|
||||
typedef CGAL::Comparison_result result_type;
|
||||
typedef typename CircularKernel::Circular_arc_point_2
|
||||
Circular_arc_point_2;
|
||||
|
||||
result_type
|
||||
operator()(const std::variant< Arc1, Arc2 > &a1,
|
||||
const std::variant< Arc1, Arc2 > &a2,
|
||||
const Circular_arc_point_2 &p) const
|
||||
{
|
||||
if ( const Arc1* arc1 = std::get_if<Arc1>( &a1 ) ){
|
||||
if ( const Arc1* arc2 = std::get_if<Arc1>( &a2 ) ){
|
||||
return CircularKernel()
|
||||
.compare_y_to_right_2_object()(*arc1, *arc2, p);
|
||||
}
|
||||
else {
|
||||
const Arc2* arc2e = std::get_if<Arc2>( &a2 );
|
||||
return CircularKernel()
|
||||
.compare_y_to_right_2_object()(*arc1, *arc2e, p);
|
||||
}
|
||||
}
|
||||
const Arc2* arc1 = std::get_if<Arc2>( &a1 );
|
||||
if ( const Arc1* arc2 = std::get_if<Arc1>( &a2 ) ){
|
||||
return CircularKernel()
|
||||
.compare_y_to_right_2_object()(*arc1, *arc2, p);
|
||||
}
|
||||
const Arc2* arc2e = std::get_if<Arc2>( &a2 );
|
||||
return CircularKernel()
|
||||
.compare_y_to_right_2_object()(*arc1, *arc2e, p);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <class CircularKernel>
|
||||
class Variant_Equal_2
|
||||
{
|
||||
public :
|
||||
|
||||
template < typename T >
|
||||
bool
|
||||
operator()(const T &a0, const T &a1) const
|
||||
{
|
||||
return CircularKernel().equal_2_object()(a0,a1);
|
||||
}
|
||||
|
||||
template < typename T1, typename T2 >
|
||||
bool
|
||||
operator()(const T1 &, const T2 &) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
template <class CircularKernel, class Arc1, class Arc2>
|
||||
class Equal_2
|
||||
: public CircularKernel::Equal_2
|
||||
{
|
||||
public:
|
||||
typedef std::variant< Arc1, Arc2 > Curve_2;
|
||||
typedef bool result_type;
|
||||
using CircularKernel::Equal_2::operator();
|
||||
typedef typename CircularKernel::Circular_arc_point_2
|
||||
Circular_arc_point_2;
|
||||
typedef typename CircularKernel::Line_arc_2 Line_arc_2;
|
||||
typedef typename CircularKernel::Circular_arc_2 Circular_arc_2;
|
||||
typedef typename CircularKernel::Equal_2 CK_Equal_2;
|
||||
|
||||
result_type
|
||||
operator() (const Circular_arc_point_2 &p0,
|
||||
const Circular_arc_point_2 &p1) const
|
||||
{ return CK_Equal_2()(p0, p1); }
|
||||
|
||||
result_type
|
||||
operator() (const Circular_arc_2 &a0, const Circular_arc_2 &a1) const
|
||||
{ return CK_Equal_2()(a0, a1); }
|
||||
|
||||
result_type
|
||||
operator() (const Line_arc_2 &a0, const Line_arc_2 &a1) const
|
||||
{ return CK_Equal_2()(a0, a1); }
|
||||
|
||||
result_type
|
||||
operator() ( const Line_arc_2 &/*a0*/, const Circular_arc_2 &/*a1*/) const
|
||||
{ return false; }
|
||||
|
||||
result_type
|
||||
operator() ( const Circular_arc_2 &/*a0*/, const Line_arc_2 &/*a1*/) const
|
||||
{ return false; }
|
||||
|
||||
result_type
|
||||
operator()(const Curve_2 &a0, const Curve_2 &a1) const
|
||||
{
|
||||
return std::visit
|
||||
( Variant_Equal_2<CircularKernel>(), a0, a1 );
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
template <class CircularKernel, class Arc1, class Arc2>
|
||||
class Compare_y_at_x_2
|
||||
{
|
||||
public:
|
||||
typedef typename CircularKernel::Circular_arc_point_2
|
||||
Circular_arc_point_2;
|
||||
typedef CGAL::Comparison_result result_type;
|
||||
|
||||
result_type
|
||||
operator() (const Circular_arc_point_2 &p,
|
||||
const std::variant< Arc1, Arc2 > &A1) const
|
||||
{
|
||||
if ( const Arc1* arc1 = std::get_if<Arc1>( &A1 ) ){
|
||||
return CircularKernel().compare_y_at_x_2_object()(p, *arc1);
|
||||
}
|
||||
else {
|
||||
const Arc2* arc2 = std::get_if<Arc2>( &A1 );
|
||||
return CircularKernel().compare_y_at_x_2_object()(p, *arc2);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <class CircularKernel>
|
||||
class Variant_Do_overlap_2
|
||||
{
|
||||
public:
|
||||
template < typename T >
|
||||
bool
|
||||
operator()(const T &a0, const T &a1) const
|
||||
{
|
||||
return CircularKernel().do_overlap_2_object()(a0, a1);
|
||||
}
|
||||
|
||||
template < typename T1, typename T2 >
|
||||
bool
|
||||
operator()(const T1 &, const T2 &) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <class CircularKernel, class Arc1, class Arc2>
|
||||
class Do_overlap_2
|
||||
{
|
||||
public:
|
||||
typedef typename CircularKernel::Circular_arc_point_2
|
||||
Circular_arc_point_2;
|
||||
typedef bool result_type;
|
||||
|
||||
result_type
|
||||
operator()(const std::variant< Arc1, Arc2 > &A0,
|
||||
const std::variant< Arc1, Arc2 > &A1) const
|
||||
{
|
||||
return std::visit
|
||||
( Variant_Do_overlap_2<CircularKernel>(), A0, A1 );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//! A functor for subdividing curves into x-monotone curves.
|
||||
template <class CircularKernel, class Arc1, class Arc2>
|
||||
class Make_x_monotone_2
|
||||
{
|
||||
public:
|
||||
typedef typename CircularKernel::Circular_arc_point_2
|
||||
Circular_arc_point_2;
|
||||
|
||||
template < class OutputIterator,class Not_X_Monotone >
|
||||
OutputIterator
|
||||
operator()(const std::variant<Arc1, Arc2, Not_X_Monotone> &A,
|
||||
OutputIterator res) const
|
||||
{
|
||||
if ( const Arc1* arc1 = std::get_if<Arc1>( &A ) ) {
|
||||
return CircularKernel().
|
||||
make_x_monotone_2_object()(*arc1, res);
|
||||
}
|
||||
else {
|
||||
const Arc2* arc2 = std::get_if<Arc2>( &A );
|
||||
return CircularKernel().
|
||||
make_x_monotone_2_object()(*arc2, res);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <class CircularKernel, class Arc1, class Arc2>
|
||||
class Intersect_2
|
||||
{
|
||||
public:
|
||||
typedef typename CircularKernel::Circular_arc_point_2
|
||||
Circular_arc_point_2;
|
||||
|
||||
template < class OutputIterator >
|
||||
OutputIterator
|
||||
operator()(const std::variant< Arc1, Arc2 > &c1,
|
||||
const std::variant< Arc1, Arc2 > &c2,
|
||||
OutputIterator oi) const
|
||||
{
|
||||
if ( const Arc1* arc1 = std::get_if<Arc1>( &c1 ) ){
|
||||
if ( const Arc1* arc2 = std::get_if<Arc1>( &c2 ) ){
|
||||
return CircularKernel().intersect_2_object()(*arc1, *arc2, oi);
|
||||
}
|
||||
const Arc2* arc2 = std::get_if<Arc2>( &c2 );
|
||||
return CircularKernel().intersect_2_object()(*arc1, *arc2, oi);
|
||||
}
|
||||
|
||||
const Arc2* arc1e = std::get_if<Arc2>( &c1 );
|
||||
if ( const Arc1* arc2 = std::get_if<Arc1>( &c2 ) ){
|
||||
return CircularKernel().intersect_2_object()(*arc1e, *arc2, oi);
|
||||
}
|
||||
const Arc2* arc2 = std::get_if<Arc2>( &c2 );
|
||||
return CircularKernel().intersect_2_object()(*arc1e, *arc2, oi);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <class CircularKernel, class Arc1, class Arc2>
|
||||
class Split_2
|
||||
{
|
||||
|
||||
public:
|
||||
typedef typename CircularKernel::Circular_arc_point_2
|
||||
Circular_arc_point_2;
|
||||
typedef void result_type;
|
||||
result_type
|
||||
operator()(const std::variant< Arc1, Arc2 > &A,
|
||||
const Circular_arc_point_2 &p,
|
||||
std::variant< Arc1, Arc2 > &ca1,
|
||||
std::variant< Arc1, Arc2 > &ca2) const
|
||||
{
|
||||
// TODO : optimize by extracting the references from the variants ?
|
||||
if ( const Arc1* arc1 = std::get_if<Arc1>( &A ) ){
|
||||
Arc1 carc1;
|
||||
Arc1 carc2;
|
||||
CircularKernel().split_2_object()(*arc1, p, carc1, carc2);
|
||||
ca1 = carc1;
|
||||
ca2 = carc2;
|
||||
return ;
|
||||
|
||||
}
|
||||
else{
|
||||
const Arc2* arc2 = std::get_if<Arc2>( &A );
|
||||
Arc2 cline1;
|
||||
Arc2 cline2;
|
||||
CircularKernel().split_2_object()(*arc2, p, cline1, cline2);
|
||||
ca1 = cline1;
|
||||
ca2 = cline2;
|
||||
return ;
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <class CircularKernel>
|
||||
class Variant_Construct_min_vertex_2
|
||||
{
|
||||
typedef typename CircularKernel::Circular_arc_point_2
|
||||
Circular_arc_point_2;
|
||||
|
||||
public :
|
||||
|
||||
typedef Circular_arc_point_2 result_type;
|
||||
//typedef const result_type& qualified_result_type;
|
||||
|
||||
template < typename T >
|
||||
//std::remove_reference_t<qualified_result_type>
|
||||
Circular_arc_point_2
|
||||
operator()(const T &a) const
|
||||
{
|
||||
//CGAL_kernel_precondition(CircularKernel().compare_xy_2_object()(a.left(), a.right())==CGAL::SMALLER);
|
||||
return CircularKernel().construct_circular_min_vertex_2_object()(a);
|
||||
}
|
||||
};
|
||||
|
||||
template <class CircularKernel, class Arc1, class Arc2>
|
||||
class Construct_min_vertex_2//: public Has_qrt
|
||||
{
|
||||
typedef typename CircularKernel::Circular_arc_point_2 Point_2;
|
||||
public:
|
||||
|
||||
typedef Point_2 result_type;
|
||||
//typedef const result_type& qualified_result_type;
|
||||
|
||||
//std::remove_reference_t<qualified_result_type>
|
||||
result_type
|
||||
operator() (const std::variant< Arc1, Arc2 > & cv) const
|
||||
{
|
||||
return std::visit
|
||||
( Variant_Construct_min_vertex_2<CircularKernel>(), cv );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
template <class CircularKernel>
|
||||
class Variant_Construct_max_vertex_2
|
||||
{
|
||||
typedef typename CircularKernel::Circular_arc_point_2
|
||||
Circular_arc_point_2;
|
||||
|
||||
public:
|
||||
typedef Circular_arc_point_2 result_type;
|
||||
//typedef const result_type& qualified_result_type;
|
||||
|
||||
template < typename T >
|
||||
//std::remove_reference_t<qualified_result_type>
|
||||
Circular_arc_point_2
|
||||
operator()(const T &a) const
|
||||
{
|
||||
//CGAL_kernel_precondition(CircularKernel().compare_xy_2_object()(a.left(), a.right())==CGAL::SMALLER);
|
||||
return (CircularKernel().construct_circular_max_vertex_2_object()(a));
|
||||
}
|
||||
};
|
||||
|
||||
template <class CircularKernel, class Arc1, class Arc2>
|
||||
class Construct_max_vertex_2//: public Has_qrt
|
||||
{
|
||||
typedef typename CircularKernel::Circular_arc_point_2 Point_2;
|
||||
|
||||
public:
|
||||
/*! obtains the right endpoint of the x-monotone curve (segment).
|
||||
* \param cv The curve.
|
||||
* \return The right endpoint.
|
||||
*/
|
||||
typedef Point_2 result_type;
|
||||
//typedef const result_type& qualified_result_type;
|
||||
|
||||
//std::remove_reference<qualified_result_type>
|
||||
result_type
|
||||
operator() (const std::variant< Arc1, Arc2 > & cv) const
|
||||
{
|
||||
return std::visit
|
||||
( Variant_Construct_max_vertex_2<CircularKernel>(), cv );
|
||||
}
|
||||
};
|
||||
|
||||
template <class CircularKernel>
|
||||
class Variant_Is_vertical_2
|
||||
{
|
||||
public:
|
||||
|
||||
template < typename T >
|
||||
bool
|
||||
operator()(const T &a) const
|
||||
{
|
||||
return CircularKernel().is_vertical_2_object()(a);
|
||||
}
|
||||
};
|
||||
|
||||
template <class CircularKernel, class Arc1, class Arc2>
|
||||
class Is_vertical_2
|
||||
{
|
||||
public:
|
||||
typedef bool result_type;
|
||||
|
||||
bool operator() (const std::variant< Arc1, Arc2 >& cv) const
|
||||
{
|
||||
return std::visit
|
||||
( Variant_Is_vertical_2<CircularKernel>(), cv );
|
||||
}
|
||||
};
|
||||
|
||||
const Arc2* arc1e = std::get_if<Arc2>(&c1);
|
||||
if ( const Arc1* arc2 = std::get_if<Arc1>(&c2)) {
|
||||
return CircularKernel().intersect_2_object()(*arc1e, *arc2, oi);
|
||||
}
|
||||
const Arc2* arc2 = std::get_if<Arc2>(&c2);
|
||||
return CircularKernel().intersect_2_object()(*arc1e, *arc2, oi);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename CircularKernel, typename Arc1, typename Arc2>
|
||||
class Split_2 {
|
||||
public:
|
||||
using Circular_arc_point_2 = typename CircularKernel::Circular_arc_point_2;
|
||||
using result_type = void;
|
||||
|
||||
// an empty class used to have different types between Curve_2 and X_monotone_curve_2
|
||||
// in Arr_circular_line_arc_traits_2.
|
||||
namespace internal_Argt_traits {
|
||||
struct Not_X_Monotone{};
|
||||
inline std::ostream& operator << (std::ostream& os, const Not_X_Monotone&)
|
||||
{return os;}
|
||||
result_type operator()(const std::variant< Arc1, Arc2>& A,
|
||||
const Circular_arc_point_2& p,
|
||||
std::variant< Arc1, Arc2>& ca1,
|
||||
std::variant< Arc1, Arc2>& ca2) const {
|
||||
// TODO : optimize by extracting the references from the variants ?
|
||||
if (const Arc1* arc1 = std::get_if<Arc1>(&A)) {
|
||||
Arc1 carc1;
|
||||
Arc1 carc2;
|
||||
CircularKernel().split_2_object()(*arc1, p, carc1, carc2);
|
||||
ca1 = carc1;
|
||||
ca2 = carc2;
|
||||
return ;
|
||||
}
|
||||
else {
|
||||
const Arc2* arc2 = std::get_if<Arc2>(&A);
|
||||
Arc2 cline1;
|
||||
Arc2 cline2;
|
||||
CircularKernel().split_2_object()(*arc2, p, cline1, cline2);
|
||||
ca1 = cline1;
|
||||
ca2 = cline2;
|
||||
return ;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/// Traits class for CGAL::Arrangement_2 (and similar) based on a CircularKernel.
|
||||
template <typename CircularKernel>
|
||||
class Variant_Construct_min_vertex_2 {
|
||||
using Circular_arc_point_2 = typename CircularKernel::Circular_arc_point_2;
|
||||
public:
|
||||
using result_type = Circular_arc_point_2;
|
||||
// using qualified_result_type = const result_type& ;
|
||||
|
||||
template < typename CircularKernel>
|
||||
class Arr_circular_line_arc_traits_2 {
|
||||
template <typename T>
|
||||
//std::remove_reference_t<qualified_result_type>
|
||||
Circular_arc_point_2 operator()(const T& a) const {
|
||||
//CGAL_kernel_precondition(CircularKernel().compare_xy_2_object()(a.left(), a.right())==CGAL::SMALLER);
|
||||
return CircularKernel().construct_circular_min_vertex_2_object()(a);
|
||||
}
|
||||
};
|
||||
|
||||
typedef Arr_circular_line_arc_traits_2< CircularKernel > Self;
|
||||
template <typename CircularKernel, typename Arc1, typename Arc2>
|
||||
class Construct_min_vertex_2 {
|
||||
//: public Has_qrt
|
||||
using Point_2 = typename CircularKernel::Circular_arc_point_2;
|
||||
|
||||
typedef typename CircularKernel::Line_arc_2 Arc1;
|
||||
typedef typename CircularKernel::Circular_arc_2 Arc2;
|
||||
public:
|
||||
using result_type = Point_2;
|
||||
// using qualified_result_type = const result_type&;
|
||||
|
||||
public:
|
||||
//std::remove_reference_t<qualified_result_type>
|
||||
result_type operator() (const std::variant< Arc1, Arc2>& cv) const
|
||||
{ return std::visit(Variant_Construct_min_vertex_2<CircularKernel>(), cv); }
|
||||
};
|
||||
|
||||
typedef CircularKernel Kernel;
|
||||
typedef typename CircularKernel::Circular_arc_point_2
|
||||
Circular_arc_point_2;
|
||||
template <typename CircularKernel>
|
||||
class Variant_Construct_max_vertex_2 {
|
||||
using Circular_arc_point_2 = typename CircularKernel::Circular_arc_point_2;
|
||||
public:
|
||||
using result_type = Circular_arc_point_2;
|
||||
// using qualified_result_type = const result_type&;
|
||||
|
||||
typedef typename CircularKernel::Circular_arc_point_2 Point;
|
||||
typedef typename CircularKernel::Circular_arc_point_2 Point_2;
|
||||
template <typename T>
|
||||
//std::remove_reference_t<qualified_result_type>
|
||||
Circular_arc_point_2 operator()(const T& a) const {
|
||||
//CGAL_kernel_precondition(CircularKernel().compare_xy_2_object()(a.left(), a.right())==CGAL::SMALLER);
|
||||
return (CircularKernel().construct_circular_max_vertex_2_object()(a));
|
||||
}
|
||||
};
|
||||
|
||||
typedef unsigned int Multiplicity;
|
||||
template <typename CircularKernel, typename Arc1, typename Arc2>
|
||||
class Construct_max_vertex_2 {
|
||||
//: public Has_qrt
|
||||
using Point_2 = typename CircularKernel::Circular_arc_point_2;
|
||||
|
||||
typedef CGAL::Tag_false Has_left_category;
|
||||
typedef CGAL::Tag_false Has_merge_category;
|
||||
typedef CGAL::Tag_false Has_do_intersect_category;
|
||||
public:
|
||||
/*! obtains the right endpoint of the x-monotone curve (segment).
|
||||
* \param cv The curve.
|
||||
* \return The right endpoint.
|
||||
*/
|
||||
using result_type = Point_2;
|
||||
// using qualified_result_type = const result_type&;
|
||||
|
||||
typedef Arr_oblivious_side_tag Left_side_category;
|
||||
typedef Arr_oblivious_side_tag Bottom_side_category;
|
||||
typedef Arr_oblivious_side_tag Top_side_category;
|
||||
typedef Arr_oblivious_side_tag Right_side_category;
|
||||
//std::remove_reference<qualified_result_type>
|
||||
result_type operator() (const std::variant<Arc1, Arc2>& cv) const
|
||||
{ return std::visit(Variant_Construct_max_vertex_2<CircularKernel>(), cv); }
|
||||
};
|
||||
|
||||
typedef internal_Argt_traits::Not_X_Monotone Not_X_Monotone;
|
||||
template <typename CircularKernel>
|
||||
class Variant_Is_vertical_2 {
|
||||
public:
|
||||
template <typename T>
|
||||
bool operator()(const T& a) const
|
||||
{ return CircularKernel().is_vertical_2_object()(a); }
|
||||
};
|
||||
|
||||
typedef std::variant< Arc1, Arc2, Not_X_Monotone > Curve_2;
|
||||
typedef std::variant< Arc1, Arc2 > X_monotone_curve_2;
|
||||
template <typename CircularKernel, typename Arc1, typename Arc2>
|
||||
class Is_vertical_2 {
|
||||
public:
|
||||
using result_type = bool;
|
||||
|
||||
private:
|
||||
CircularKernel ck;
|
||||
public:
|
||||
bool operator() (const std::variant<Arc1, Arc2>& cv) const
|
||||
{ return std::visit(Variant_Is_vertical_2<CircularKernel>(), cv); }
|
||||
};
|
||||
|
||||
Arr_circular_line_arc_traits_2(const CircularKernel &k = CircularKernel())
|
||||
: ck(k) {}
|
||||
}
|
||||
|
||||
typedef typename CircularKernel::Compare_x_2 Compare_x_2;
|
||||
typedef typename CircularKernel::Compare_xy_2 Compare_xy_2;
|
||||
typedef typename
|
||||
VariantFunctors::Construct_min_vertex_2<CircularKernel, Arc1, Arc2>
|
||||
Construct_min_vertex_2;
|
||||
typedef
|
||||
VariantFunctors::Construct_max_vertex_2<CircularKernel, Arc1, Arc2>
|
||||
Construct_max_vertex_2;
|
||||
typedef VariantFunctors::Is_vertical_2<CircularKernel, Arc1, Arc2>
|
||||
Is_vertical_2;
|
||||
typedef VariantFunctors::Compare_y_at_x_2<CircularKernel, Arc1, Arc2>
|
||||
Compare_y_at_x_2;
|
||||
typedef VariantFunctors::Compare_y_to_right_2<CircularKernel, Arc1, Arc2>
|
||||
Compare_y_at_x_right_2;
|
||||
typedef VariantFunctors::Equal_2<CircularKernel, Arc1, Arc2>
|
||||
Equal_2;
|
||||
typedef VariantFunctors::Make_x_monotone_2<CircularKernel, Arc1, Arc2>
|
||||
Make_x_monotone_2;
|
||||
typedef VariantFunctors::Split_2<CircularKernel, Arc1, Arc2>
|
||||
Split_2;
|
||||
typedef VariantFunctors::Intersect_2<CircularKernel, Arc1, Arc2>
|
||||
Intersect_2;
|
||||
// an empty class used to have different types between Curve_2 and X_monotone_curve_2
|
||||
// in Arr_circular_line_arc_traits_2.
|
||||
namespace internal_Argt_traits {
|
||||
|
||||
Compare_x_2 compare_x_2_object() const
|
||||
{ return ck.compare_x_2_object(); }
|
||||
struct Not_X_Monotone{};
|
||||
|
||||
Compare_xy_2 compare_xy_2_object() const
|
||||
{ return ck.compare_xy_2_object(); }
|
||||
inline std::ostream& operator << (std::ostream& os, const Not_X_Monotone&) { return os; }
|
||||
|
||||
Compare_y_at_x_2 compare_y_at_x_2_object() const
|
||||
{ return Compare_y_at_x_2(); }
|
||||
}
|
||||
|
||||
Compare_y_at_x_right_2 compare_y_at_x_right_2_object() const
|
||||
{ return Compare_y_at_x_right_2(); }
|
||||
/// Traits class for CGAL::Arrangement_2 (and similar) based on a CircularKernel.
|
||||
|
||||
Equal_2 equal_2_object() const
|
||||
{ return Equal_2(); }
|
||||
template <typename CircularKernel>
|
||||
class Arr_circular_line_arc_traits_2 {
|
||||
using Self = Arr_circular_line_arc_traits_2<CircularKernel>;
|
||||
|
||||
Make_x_monotone_2 make_x_monotone_2_object() const
|
||||
{ return Make_x_monotone_2(); }
|
||||
using Arc1 = typename CircularKernel::Line_arc_2;
|
||||
using Arc2 = typename CircularKernel::Circular_arc_2;
|
||||
|
||||
Split_2 split_2_object() const
|
||||
{ return Split_2(); }
|
||||
public:
|
||||
using Kernel = CircularKernel;
|
||||
using Circular_arc_point_2 = typename CircularKernel::Circular_arc_point_2;
|
||||
|
||||
Intersect_2 intersect_2_object() const
|
||||
{ return Intersect_2(); }
|
||||
using Point = typename CircularKernel::Circular_arc_point_2;
|
||||
using Point_2 = typename CircularKernel::Circular_arc_point_2;
|
||||
|
||||
Construct_min_vertex_2 construct_min_vertex_2_object() const
|
||||
{ return Construct_min_vertex_2(); }
|
||||
using Multiplicity = std::size_t;
|
||||
|
||||
Construct_max_vertex_2 construct_max_vertex_2_object() const
|
||||
{ return Construct_max_vertex_2(); }
|
||||
using Has_left_category = CGAL::Tag_false;
|
||||
using Has_merge_category = CGAL::Tag_false;
|
||||
using Has_do_intersect_category = CGAL::Tag_false;
|
||||
|
||||
Is_vertical_2 is_vertical_2_object() const
|
||||
{ return Is_vertical_2();}
|
||||
using Left_side_category = Arr_oblivious_side_tag;
|
||||
using Bottom_side_category = Arr_oblivious_side_tag;
|
||||
using Top_side_category = Arr_oblivious_side_tag;
|
||||
using Right_side_category = Arr_oblivious_side_tag;
|
||||
|
||||
using Not_X_Monotone = internal_Argt_traits::Not_X_Monotone;
|
||||
|
||||
using Curve_2 = std::variant<Arc1, Arc2, Not_X_Monotone>;
|
||||
using X_monotone_curve_2 = std::variant<Arc1, Arc2>;
|
||||
|
||||
private:
|
||||
CircularKernel ck;
|
||||
|
||||
public:
|
||||
Arr_circular_line_arc_traits_2(const CircularKernel& k = CircularKernel()) : ck(k) {}
|
||||
|
||||
using Compare_x_2 = typename CircularKernel::Compare_x_2;
|
||||
using Compare_xy_2 = typename CircularKernel::Compare_xy_2;
|
||||
using Construct_min_vertex_2 = typename VariantFunctors::Construct_min_vertex_2<CircularKernel, Arc1, Arc2>;
|
||||
using Construct_max_vertex_2 = VariantFunctors::Construct_max_vertex_2<CircularKernel, Arc1, Arc2>;
|
||||
using Is_vertical_2 = VariantFunctors::Is_vertical_2<CircularKernel, Arc1, Arc2>;
|
||||
using Compare_y_at_x_2 = VariantFunctors::Compare_y_at_x_2<CircularKernel, Arc1, Arc2>;
|
||||
using Compare_y_at_x_right_2 = VariantFunctors::Compare_y_to_right_2<CircularKernel, Arc1, Arc2>;
|
||||
using Equal_2 = VariantFunctors::Equal_2<CircularKernel, Arc1, Arc2>;
|
||||
using Make_x_monotone_2 = VariantFunctors::Make_x_monotone_2<CircularKernel, Arc1, Arc2>;
|
||||
using Split_2 = VariantFunctors::Split_2<CircularKernel, Arc1, Arc2>;
|
||||
using Intersect_2 = VariantFunctors::Intersect_2<CircularKernel, Arc1, Arc2>;
|
||||
|
||||
Compare_x_2 compare_x_2_object() const
|
||||
{ return ck.compare_x_2_object(); }
|
||||
|
||||
Compare_xy_2 compare_xy_2_object() const
|
||||
{ return ck.compare_xy_2_object(); }
|
||||
|
||||
Compare_y_at_x_2 compare_y_at_x_2_object() const
|
||||
{ return Compare_y_at_x_2(); }
|
||||
|
||||
Compare_y_at_x_right_2 compare_y_at_x_right_2_object() const
|
||||
{ return Compare_y_at_x_right_2(); }
|
||||
|
||||
Equal_2 equal_2_object() const
|
||||
{ return Equal_2(); }
|
||||
|
||||
Make_x_monotone_2 make_x_monotone_2_object() const
|
||||
{ return Make_x_monotone_2(); }
|
||||
|
||||
Split_2 split_2_object() const
|
||||
{ return Split_2(); }
|
||||
|
||||
Intersect_2 intersect_2_object() const
|
||||
{ return Intersect_2(); }
|
||||
|
||||
Construct_min_vertex_2 construct_min_vertex_2_object() const
|
||||
{ return Construct_min_vertex_2(); }
|
||||
|
||||
Construct_max_vertex_2 construct_max_vertex_2_object() const
|
||||
{ return Construct_max_vertex_2(); }
|
||||
|
||||
Is_vertical_2 is_vertical_2_object() const
|
||||
{ return Is_vertical_2();}
|
||||
};
|
||||
|
||||
} // namespace CGAL
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
#include <boost/math/constants/constants.hpp>
|
||||
|
||||
#include <CGAL/Cartesian.h>
|
||||
#include <CGAL/Simple_cartesian.h>
|
||||
#include <CGAL/tags.h>
|
||||
#include <CGAL/Arr_tags.h>
|
||||
#include <CGAL/Arr_enums.h>
|
||||
|
|
@ -59,37 +59,37 @@ namespace CGAL {
|
|||
template <typename RatKernel, typename AlgKernel, typename NtTraits>
|
||||
class Arr_conic_traits_2 {
|
||||
public:
|
||||
typedef RatKernel Rat_kernel;
|
||||
typedef AlgKernel Alg_kernel;
|
||||
typedef NtTraits Nt_traits;
|
||||
using Rat_kernel = RatKernel;
|
||||
using Alg_kernel = AlgKernel;
|
||||
using Nt_traits = NtTraits;
|
||||
|
||||
typedef typename Rat_kernel::FT Rational;
|
||||
typedef typename Rat_kernel::Point_2 Rat_point_2;
|
||||
typedef typename Rat_kernel::Segment_2 Rat_segment_2;
|
||||
typedef typename Rat_kernel::Line_2 Rat_line_2;
|
||||
typedef typename Rat_kernel::Circle_2 Rat_circle_2;
|
||||
using Rational = typename Rat_kernel::FT;
|
||||
using Rat_point_2 = typename Rat_kernel::Point_2;
|
||||
using Rat_segment_2 = typename Rat_kernel::Segment_2;
|
||||
using Rat_line_2 = typename Rat_kernel::Line_2;
|
||||
using Rat_circle_2 = typename Rat_kernel::Circle_2;
|
||||
|
||||
typedef typename Alg_kernel::FT Algebraic;
|
||||
typedef typename Alg_kernel::Point_2 Alg_point_2;
|
||||
using Algebraic = typename Alg_kernel::FT;
|
||||
using Alg_point_2 = typename Alg_kernel::Point_2;
|
||||
|
||||
typedef typename Nt_traits::Integer Integer;
|
||||
using Integer = typename Nt_traits::Integer;
|
||||
|
||||
// Category tags:
|
||||
typedef Tag_true Has_left_category;
|
||||
typedef Tag_true Has_merge_category;
|
||||
typedef Tag_false Has_do_intersect_category;
|
||||
using Has_left_category = Tag_true;
|
||||
using Has_merge_category = Tag_true;
|
||||
using Has_do_intersect_category = Tag_false;
|
||||
//typedef std::true_type Has_line_segment_constructor;
|
||||
|
||||
typedef Arr_oblivious_side_tag Left_side_category;
|
||||
typedef Arr_oblivious_side_tag Bottom_side_category;
|
||||
typedef Arr_oblivious_side_tag Top_side_category;
|
||||
typedef Arr_oblivious_side_tag Right_side_category;
|
||||
using Left_side_category = Arr_oblivious_side_tag;
|
||||
using Bottom_side_category = Arr_oblivious_side_tag;
|
||||
using Top_side_category = Arr_oblivious_side_tag;
|
||||
using Right_side_category = Arr_oblivious_side_tag;
|
||||
|
||||
// Traits objects:
|
||||
typedef Conic_arc_2<Rat_kernel, Alg_kernel, Nt_traits> Curve_2;
|
||||
typedef Conic_x_monotone_arc_2<Curve_2> X_monotone_curve_2;
|
||||
typedef Conic_point_2<Alg_kernel> Point_2;
|
||||
typedef size_t Multiplicity;
|
||||
using Curve_2 = Conic_arc_2<Rat_kernel, Alg_kernel, Nt_traits>;
|
||||
using X_monotone_curve_2 = Conic_x_monotone_arc_2<Curve_2>;
|
||||
using Point_2 = Conic_point_2<Alg_kernel>;
|
||||
using Multiplicity = std::size_t;
|
||||
|
||||
private:
|
||||
// Type definition for the intersection points mapping.
|
||||
|
|
@ -106,16 +106,14 @@ private:
|
|||
}
|
||||
};
|
||||
|
||||
typedef std::pair<Point_2, Multiplicity> Intersection_point;
|
||||
typedef std::list<Intersection_point> Intersection_list;
|
||||
typedef std::map<Conic_pair, Intersection_list, Less_conic_pair>
|
||||
Intersection_map;
|
||||
typedef typename Intersection_map::iterator Intersection_map_iterator;
|
||||
using Intersection_point = std::pair<Point_2, Multiplicity>;
|
||||
using Intersection_list = std::list<Intersection_point>;
|
||||
using Intersection_map = std::map<Conic_pair, Intersection_list, Less_conic_pair>;
|
||||
using Intersection_map_iterator = typename Intersection_map::iterator;
|
||||
|
||||
|
||||
typedef std::shared_ptr<Rat_kernel> Shared_rat_kernel;
|
||||
typedef std::shared_ptr<Alg_kernel> Shared_alg_kernel;
|
||||
typedef std::shared_ptr<Nt_traits> Shared_nt_traits;
|
||||
using Shared_rat_kernel = std::shared_ptr<Rat_kernel>;
|
||||
using Shared_alg_kernel = std::shared_ptr<Alg_kernel>;
|
||||
using Shared_nt_traits = std::shared_ptr<Nt_traits>;
|
||||
|
||||
const Shared_rat_kernel m_rat_kernel;
|
||||
const Shared_alg_kernel m_alg_kernel;
|
||||
|
|
@ -127,10 +125,10 @@ private:
|
|||
public:
|
||||
/*! constructs default.
|
||||
*/
|
||||
Arr_conic_traits_2()
|
||||
: m_rat_kernel(std::make_shared<Rat_kernel>()),
|
||||
m_alg_kernel(std::make_shared<Alg_kernel>()),
|
||||
m_nt_traits(std::make_shared<Nt_traits>())
|
||||
Arr_conic_traits_2() :
|
||||
m_rat_kernel(std::make_shared<Rat_kernel>()),
|
||||
m_alg_kernel(std::make_shared<Alg_kernel>()),
|
||||
m_nt_traits(std::make_shared<Nt_traits>())
|
||||
{}
|
||||
|
||||
/*! constructs from resources.
|
||||
|
|
@ -360,8 +358,7 @@ public:
|
|||
*/
|
||||
Comparison_result operator()(const X_monotone_curve_2& xcv1,
|
||||
const X_monotone_curve_2& xcv2,
|
||||
const Point_2& p) const
|
||||
{
|
||||
const Point_2& p) const {
|
||||
// Make sure that p lies on both curves, and that both are defined to its
|
||||
// left (so their left endpoint is lexicographically smaller than p).
|
||||
CGAL_precondition(m_traits.contains_point(xcv1, p) &&
|
||||
|
|
@ -538,8 +535,7 @@ public:
|
|||
*/
|
||||
Comparison_result operator()(const X_monotone_curve_2& xcv1,
|
||||
const X_monotone_curve_2& xcv2,
|
||||
const Point_2& p) const
|
||||
{
|
||||
const Point_2& p) const {
|
||||
// Make sure that p lies on both curves, and that both are defined to its
|
||||
// left (so their left endpoint is lexicographically smaller than p).
|
||||
CGAL_precondition(m_traits.contains_point(xcv1, p) &&
|
||||
|
|
@ -703,8 +699,7 @@ public:
|
|||
* \return `true` if the two curves are the same; `false` otherwise.
|
||||
*/
|
||||
bool operator()(const X_monotone_curve_2& xcv1,
|
||||
const X_monotone_curve_2& xcv2) const
|
||||
{
|
||||
const X_monotone_curve_2& xcv2) const {
|
||||
if (&xcv1 == &xcv2) return true;
|
||||
return equals(xcv1, xcv2);
|
||||
}
|
||||
|
|
@ -924,8 +919,7 @@ public:
|
|||
|
||||
if (((cv.orientation() == COUNTERCLOCKWISE) &&
|
||||
(start_pos == order_vpts)) ||
|
||||
((cv.orientation() == CLOCKWISE) && (start_pos != order_vpts)))
|
||||
{
|
||||
((cv.orientation() == CLOCKWISE) && (start_pos != order_vpts))) {
|
||||
ind_first = 1;
|
||||
ind_second = 0;
|
||||
}
|
||||
|
|
@ -1101,8 +1095,7 @@ public:
|
|||
else if (m_traits.is_between_endpoints(xcv2, xcv1.source()) &&
|
||||
m_traits.is_between_endpoints(xcv2, xcv1.target()) &&
|
||||
(m_traits.is_strictly_between_endpoints(xcv2, xcv1.source()) ||
|
||||
m_traits.is_strictly_between_endpoints(xcv2, xcv1.target())))
|
||||
{
|
||||
m_traits.is_strictly_between_endpoints(xcv2, xcv1.target()))) {
|
||||
// Case 4 - *this: +----------->
|
||||
// arc: +================>
|
||||
overlap = xcv1;
|
||||
|
|
@ -1285,8 +1278,7 @@ public:
|
|||
for (i = 0; i < n_xs; ++i) {
|
||||
for (j = 0; j < n_ys; ++j) {
|
||||
if (xcv1.is_on_supporting_conic(xs[i], ys[j]) &&
|
||||
xcv2.is_on_supporting_conic(xs[i], ys[j]))
|
||||
{
|
||||
xcv2.is_on_supporting_conic(xs[i], ys[j])) {
|
||||
// Create the intersection point and set its generating conics.
|
||||
Point_2 ip(xs[i], ys[j]);
|
||||
|
||||
|
|
@ -1314,8 +1306,7 @@ public:
|
|||
OutputIterator intersect(const X_monotone_curve_2& xcv1,
|
||||
const X_monotone_curve_2& xcv2,
|
||||
Intersection_map& inter_map,
|
||||
OutputIterator oi) const
|
||||
{
|
||||
OutputIterator oi) const {
|
||||
if (m_traits.has_same_supporting_conic(xcv1, xcv2)) {
|
||||
// Check for overlaps between the two arcs.
|
||||
X_monotone_curve_2 overlap;
|
||||
|
|
@ -1392,8 +1383,7 @@ public:
|
|||
// both \f$x\f$-monotone arcs.
|
||||
for (auto iter = inter_list.begin(); iter != inter_list.end(); ++iter) {
|
||||
if (m_traits.is_between_endpoints(xcv1, (*iter).first) &&
|
||||
m_traits.is_between_endpoints(xcv2, (*iter).first))
|
||||
{
|
||||
m_traits.is_between_endpoints(xcv2, (*iter).first)) {
|
||||
*oi++ = *iter;
|
||||
}
|
||||
}
|
||||
|
|
@ -1481,8 +1471,7 @@ public:
|
|||
*/
|
||||
void operator()(const X_monotone_curve_2& xcv1,
|
||||
const X_monotone_curve_2& xcv2,
|
||||
X_monotone_curve_2& xcv) const
|
||||
{
|
||||
X_monotone_curve_2& xcv) const {
|
||||
CGAL_precondition(m_traits.are_mergeable_2_object()(xcv2, xcv1));
|
||||
xcv = xcv1;
|
||||
merge(xcv, xcv2);
|
||||
|
|
@ -1523,11 +1512,11 @@ public:
|
|||
* point-location strategy and the drawing function.
|
||||
*/
|
||||
//@{
|
||||
typedef double Approximate_number_type;
|
||||
typedef CGAL::Cartesian<Approximate_number_type> Approximate_kernel;
|
||||
typedef Approximate_kernel::Point_2 Approximate_point_2;
|
||||
using Approximate_number_type = double;
|
||||
using Approximate_kernel = CGAL::Simple_cartesian<Approximate_number_type>;
|
||||
using Approximate_point_2 = Approximate_kernel::Point_2;
|
||||
|
||||
class Approximate_curve_length_2 {
|
||||
class Approximate_length_2 {
|
||||
protected:
|
||||
using Traits = Arr_conic_traits_2<Rat_kernel, Alg_kernel, Nt_traits>;
|
||||
|
||||
|
|
@ -1537,7 +1526,7 @@ public:
|
|||
/*! constructs
|
||||
* \param traits the traits.
|
||||
*/
|
||||
Approximate_curve_length_2(const Traits& traits) : m_traits(traits) {}
|
||||
Approximate_length_2(const Traits& traits) : m_traits(traits) {}
|
||||
|
||||
friend class Arr_conic_traits_2<Rat_kernel, Alg_kernel, Nt_traits>;
|
||||
|
||||
|
|
@ -1557,7 +1546,7 @@ public:
|
|||
private:
|
||||
/*! obtains the segment length.
|
||||
*/
|
||||
double segment_length(const X_monotone_curve_2& xcv) {
|
||||
double segment_length(const X_monotone_curve_2& xcv) const {
|
||||
auto min_vertex = m_traits.construct_min_vertex_2_object();
|
||||
auto max_vertex = m_traits.construct_max_vertex_2_object();
|
||||
const auto& minv = min_vertex(xcv);
|
||||
|
|
@ -1597,7 +1586,7 @@ public:
|
|||
|
||||
/*! obtains the parabolic arc length.
|
||||
*/
|
||||
double parabola_length(const X_monotone_curve_2& xcv) {
|
||||
double parabola_length(const X_monotone_curve_2& xcv) const {
|
||||
double r_m, t_m, s_m, u_m, v_m, w_m;
|
||||
double cost, sint;
|
||||
double xs_t, ys_t, xt_t, yt_t;
|
||||
|
|
@ -1617,7 +1606,7 @@ public:
|
|||
return d;
|
||||
}
|
||||
|
||||
double ellipse_length(const X_monotone_curve_2& xcv) {
|
||||
double ellipse_length(const X_monotone_curve_2& xcv) const {
|
||||
double r_m, t_m, s_m, u_m, v_m, w_m;
|
||||
double cost, sint;
|
||||
double xs_t, ys_t, xt_t, yt_t;
|
||||
|
|
@ -1638,7 +1627,7 @@ public:
|
|||
return d;
|
||||
}
|
||||
|
||||
double hyperbola_length(const X_monotone_curve_2& /* xcv */) {
|
||||
double hyperbola_length(const X_monotone_curve_2& /* xcv */) const {
|
||||
CGAL_error_msg("Not implemented yet!");
|
||||
double l(0.0);
|
||||
return l;
|
||||
|
|
@ -1901,8 +1890,7 @@ public:
|
|||
template <typename OutputIterator>
|
||||
OutputIterator approximate_parabola(const X_monotone_curve_2& xcv,
|
||||
double error, OutputIterator oi,
|
||||
bool l2r = true)
|
||||
const {
|
||||
bool l2r = true) const {
|
||||
// std::cout << "PARABOLA\n";
|
||||
auto min_vertex = m_traits.construct_min_vertex_2_object();
|
||||
auto max_vertex = m_traits.construct_max_vertex_2_object();
|
||||
|
|
@ -2104,8 +2092,7 @@ public:
|
|||
*/
|
||||
X_monotone_curve_2 operator()(const Curve_2& cv,
|
||||
const Point_2& source, const Point_2& target,
|
||||
const Conic_id& id) const
|
||||
{
|
||||
const Conic_id& id) const {
|
||||
// Set the two endpoints.
|
||||
X_monotone_curve_2 xcv(cv, id);
|
||||
xcv.set_source(source);
|
||||
|
|
@ -2122,8 +2109,7 @@ public:
|
|||
* \return A segment connecting `source` and `target`.
|
||||
*/
|
||||
X_monotone_curve_2 operator()(const Point_2& source, const Point_2& target)
|
||||
const
|
||||
{
|
||||
const {
|
||||
X_monotone_curve_2 xcv;
|
||||
|
||||
// Set the basic properties.
|
||||
|
|
@ -2157,8 +2143,7 @@ public:
|
|||
X_monotone_curve_2 operator()(const Algebraic& a, const Algebraic& b,
|
||||
const Algebraic& c,
|
||||
const Point_2& source, const Point_2& target)
|
||||
const
|
||||
{
|
||||
const {
|
||||
auto cmp_xy = m_traits.m_alg_kernel->compare_xy_2_object();
|
||||
Comparison_result res = cmp_xy(source, target);
|
||||
CGAL_precondition(res != EQUAL);
|
||||
|
|
@ -2238,8 +2223,7 @@ public:
|
|||
*/
|
||||
Curve_2 operator()(const Rational& r, const Rational& s, const Rational& t,
|
||||
const Rational& u, const Rational& v, const Rational& w)
|
||||
const
|
||||
{
|
||||
const {
|
||||
// Ensure that the given curve is an ellipse (4rs - t^2 is positive).
|
||||
CGAL_precondition(CGAL::sign(4*r*s - t*t) == POSITIVE);
|
||||
|
||||
|
|
@ -2445,8 +2429,7 @@ public:
|
|||
|
||||
if (! m_traits.is_strictly_between_endpoints(arc, mp2) ||
|
||||
! m_traits.is_strictly_between_endpoints(arc, mp3) ||
|
||||
! m_traits.is_strictly_between_endpoints(arc, mp4))
|
||||
{
|
||||
! m_traits.is_strictly_between_endpoints(arc, mp4)) {
|
||||
arc.reset_flags(); // invalid arc
|
||||
return arc;
|
||||
}
|
||||
|
|
@ -2853,8 +2836,7 @@ public:
|
|||
* \pre both points must be interior and must lie on \c cv
|
||||
*/
|
||||
X_monotone_curve_2 operator()(const X_monotone_curve_2& xcv,
|
||||
const Point_2& src, const Point_2& tgt) const
|
||||
{
|
||||
const Point_2& src, const Point_2& tgt) const {
|
||||
// make functor objects
|
||||
CGAL_precondition_code(Compare_y_at_x_2 compare_y_at_x_2 =
|
||||
m_traits.compare_y_at_x_2_object());
|
||||
|
|
@ -3084,16 +3066,14 @@ public:
|
|||
const auto& target = cv.target();
|
||||
// Make sure both endpoint lie on the supporting conic.
|
||||
if (! is_on_supporting_conic(cv, source) ||
|
||||
! is_on_supporting_conic(cv, target))
|
||||
{
|
||||
! is_on_supporting_conic(cv, target)) {
|
||||
cv.reset_flags(); // invalid arc
|
||||
return;
|
||||
}
|
||||
|
||||
// Check whether we have a degree 2 curve.
|
||||
if ((CGAL::sign(r) != ZERO) || (CGAL::sign(s) != ZERO) ||
|
||||
(CGAL::sign(t) != ZERO))
|
||||
{
|
||||
(CGAL::sign(t) != ZERO)) {
|
||||
if (cv.orientation() == COLLINEAR) {
|
||||
// Make sure the midpoint is on the line pair (thus making sure that
|
||||
// the two points are not taken from different lines).
|
||||
|
|
@ -3105,8 +3085,7 @@ public:
|
|||
m_nt_traits->convert(u)) * p_mid.x() +
|
||||
(m_nt_traits->convert(s)*p_mid.y() +
|
||||
m_nt_traits->convert(v)) * p_mid.y() +
|
||||
m_nt_traits->convert(w)) != ZERO)
|
||||
{
|
||||
m_nt_traits->convert(w)) != ZERO) {
|
||||
cv.reset_flags(); // invalid arc
|
||||
return;
|
||||
}
|
||||
|
|
@ -3645,8 +3624,7 @@ public:
|
|||
// Compute the degree of the underlying conic.
|
||||
if ((CGAL::sign(xcv.r()) != ZERO) ||
|
||||
(CGAL::sign(xcv.s()) != ZERO) ||
|
||||
(CGAL::sign(xcv.t()) != ZERO))
|
||||
{
|
||||
(CGAL::sign(xcv.t()) != ZERO)) {
|
||||
xcv.set_flag(X_monotone_curve_2::DEGREE_2);
|
||||
xcv.set_flag(X_monotone_curve_2::IS_SPECIAL_SEGMENT);
|
||||
}
|
||||
|
|
@ -3856,8 +3834,7 @@ public:
|
|||
for (int j = 0; j < n_ys; ++j) {
|
||||
if (CGAL::compare(m_nt_traits->convert(Integer(two*s)) * ys[j],
|
||||
-(m_nt_traits->convert(t) * xs[i] +
|
||||
m_nt_traits->convert(v))) == EQUAL)
|
||||
{
|
||||
m_nt_traits->convert(v))) == EQUAL) {
|
||||
ps[n++] = Point_2(xs[i], ys[j]);
|
||||
break;
|
||||
}
|
||||
|
|
@ -4128,8 +4105,7 @@ public:
|
|||
double& xs_t, double& ys_t, double& ts,
|
||||
double& xt_t, double& yt_t, double& tt,
|
||||
double& a, double& b, double& cx, double& cy,
|
||||
bool l2r = true)
|
||||
const {
|
||||
bool l2r = true) const {
|
||||
auto min_vertex = construct_min_vertex_2_object();
|
||||
auto max_vertex = construct_max_vertex_2_object();
|
||||
const auto& src = (l2r) ? min_vertex(xcv) : max_vertex(xcv);
|
||||
|
|
@ -4206,8 +4182,7 @@ public:
|
|||
double& xs_t, double& ys_t, double& ts,
|
||||
double& xt_t, double& yt_t, double& tt,
|
||||
double& a, double& b, double& cx, double& cy,
|
||||
bool l2r = true)
|
||||
const {
|
||||
bool l2r = true) const {
|
||||
auto min_vertex = construct_min_vertex_2_object();
|
||||
auto max_vertex = construct_max_vertex_2_object();
|
||||
const auto& src = (l2r) ? min_vertex(xcv) : max_vertex(xcv);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -28,7 +28,7 @@
|
|||
#include <variant>
|
||||
|
||||
#include <CGAL/config.h>
|
||||
#include <CGAL/Cartesian.h>
|
||||
#include <CGAL/Simple_cartesian.h>
|
||||
#include <CGAL/tags.h>
|
||||
#include <CGAL/tss.h>
|
||||
#include <CGAL/intersections.h>
|
||||
|
|
@ -2856,7 +2856,7 @@ public:
|
|||
/// \name Functor definitions for the landmarks point-location strategy.
|
||||
//@{
|
||||
using Approximate_number_type = double;
|
||||
using Approximate_kernel = CGAL::Cartesian<Approximate_number_type>;
|
||||
using Approximate_kernel = CGAL::Simple_cartesian<Approximate_number_type>;
|
||||
using Approximate_point_2 = Arr_extended_direction_3<Approximate_kernel>;
|
||||
using Approximate_kernel_vector_3 = Approximate_kernel::Vector_3;
|
||||
using Approximate_kernel_direction_3 = Approximate_kernel::Direction_3;
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@
|
|||
* Definition of the Bezier_bounding_rational_traits<Kernel> class.
|
||||
*/
|
||||
|
||||
#include <CGAL/Cartesian.h>
|
||||
#include <CGAL/Polygon_2_algorithms.h>
|
||||
#include <CGAL/Arr_geometry_traits/de_Casteljau_2.h>
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -41,9 +41,9 @@ class _One_root_point_2_rep {
|
|||
friend class _One_root_point_2<NumberType_, Filter_>;
|
||||
|
||||
public:
|
||||
typedef NumberType_ NT;
|
||||
typedef _One_root_point_2_rep<NT, Filter_> Self;
|
||||
typedef Sqrt_extension<NT, NT, Tag_true,Boolean_tag<Filter_> > CoordNT;
|
||||
using NT = NumberType_;
|
||||
using Self = _One_root_point_2_rep<NT, Filter_>;
|
||||
using CoordNT = Sqrt_extension<NT, NT, Tag_true,Boolean_tag<Filter_> >;
|
||||
|
||||
private:
|
||||
CoordNT _x; // The coordinates.
|
||||
|
|
@ -70,18 +70,17 @@ public:
|
|||
*/
|
||||
template <typename NumberType_, bool Filter_>
|
||||
class _One_root_point_2 :
|
||||
public Handle_for<_One_root_point_2_rep<NumberType_, Filter_> >
|
||||
{
|
||||
public Handle_for<_One_root_point_2_rep<NumberType_, Filter_>> {
|
||||
public:
|
||||
typedef NumberType_ NT;
|
||||
typedef _One_root_point_2<NT, Filter_> Self;
|
||||
using NT = NumberType_;
|
||||
using Self = _One_root_point_2<NT, Filter_>;
|
||||
|
||||
private:
|
||||
typedef _One_root_point_2_rep<NT, Filter_> Point_rep;
|
||||
typedef Handle_for<Point_rep> Point_handle;
|
||||
using Point_rep = _One_root_point_2_rep<NT, Filter_>;
|
||||
using Point_handle = Handle_for<Point_rep>;
|
||||
|
||||
public:
|
||||
typedef typename Point_rep::CoordNT CoordNT;
|
||||
using CoordNT = typename Point_rep::CoordNT;
|
||||
|
||||
/*! constructs default. */
|
||||
_One_root_point_2() : Point_handle(Point_rep()) {}
|
||||
|
|
@ -106,8 +105,7 @@ public:
|
|||
const CoordNT& y() const { return (this->ptr()->_y); }
|
||||
|
||||
/*! checks for equality. */
|
||||
bool equals(const Self& p) const
|
||||
{
|
||||
bool equals(const Self& p) const {
|
||||
if (this->identical(p)) return (true);
|
||||
|
||||
return (CGAL::compare(this->ptr()->_x, p.ptr()->_x) == EQUAL &&
|
||||
|
|
@ -119,8 +117,7 @@ public:
|
|||
bool operator == (const Self& p) const { return equals(p); }
|
||||
|
||||
/*! sets the point coordinates. */
|
||||
void set(const NT& x, const NT& y)
|
||||
{
|
||||
void set(const NT& x, const NT& y) {
|
||||
this->copy_on_write();
|
||||
this->ptr()->_x = CoordNT(x);
|
||||
this->ptr()->_y = CoordNT(y);
|
||||
|
|
@ -128,8 +125,7 @@ public:
|
|||
}
|
||||
|
||||
/*! sets the point coordinates. */
|
||||
void set(const CoordNT& x, const CoordNT& y)
|
||||
{
|
||||
void set(const CoordNT& x, const CoordNT& y) {
|
||||
this->copy_on_write();
|
||||
this->ptr()->_x = x;
|
||||
this->ptr()->_y = y;
|
||||
|
|
@ -141,8 +137,7 @@ public:
|
|||
*/
|
||||
template <typename NT, bool Filter>
|
||||
std::ostream& operator<<(std::ostream& os,
|
||||
const _One_root_point_2<NT, Filter>& p)
|
||||
{
|
||||
const _One_root_point_2<NT, Filter>& p) {
|
||||
os << CGAL::to_double(p.x()) << ' ' << CGAL::to_double(p.y());
|
||||
return (os);
|
||||
}
|
||||
|
|
@ -165,15 +160,15 @@ std::istream & operator >> (std::istream & is,
|
|||
template <typename Kernel_, bool Filter_>
|
||||
class _Circle_segment_2 {
|
||||
public:
|
||||
typedef Kernel_ Kernel;
|
||||
typedef typename Kernel::FT NT;
|
||||
typedef _One_root_point_2<NT, Filter_> Point_2;
|
||||
typedef typename Kernel::Circle_2 Circle_2;
|
||||
typedef typename Kernel::Segment_2 Segment_2;
|
||||
typedef typename Kernel::Line_2 Line_2;
|
||||
using Kernel = Kernel_;
|
||||
using NT = typename Kernel::FT;
|
||||
using Point_2 = _One_root_point_2<NT, Filter_>;
|
||||
using Circle_2 = typename Kernel::Circle_2;
|
||||
using Segment_2 = typename Kernel::Segment_2;
|
||||
using Line_2 = typename Kernel::Line_2;
|
||||
|
||||
protected:
|
||||
typedef typename Point_2::CoordNT CoordNT;
|
||||
using CoordNT = typename Point_2::CoordNT;
|
||||
|
||||
// Data members:
|
||||
Line_2 m_line; // The supporting line (for line segments).
|
||||
|
|
@ -234,8 +229,7 @@ public:
|
|||
m_has_radius(false),
|
||||
m_source(source),
|
||||
m_target(target),
|
||||
m_orient(COLLINEAR)
|
||||
{
|
||||
m_orient(COLLINEAR) {
|
||||
CGAL_precondition(CGAL::compare(source.x() * line.a() + line.c(),
|
||||
-source.y() * line.b()) == EQUAL);
|
||||
|
||||
|
|
@ -282,8 +276,7 @@ public:
|
|||
m_has_radius(false),
|
||||
m_source(source),
|
||||
m_target(target),
|
||||
m_orient(circ.orientation())
|
||||
{
|
||||
m_orient(circ.orientation()) {
|
||||
CGAL_assertion(m_orient != COLLINEAR);
|
||||
|
||||
CGAL_precondition
|
||||
|
|
@ -315,8 +308,7 @@ public:
|
|||
m_radius(r),
|
||||
m_source(source),
|
||||
m_target(target),
|
||||
m_orient(orient)
|
||||
{
|
||||
m_orient(orient) {
|
||||
CGAL_assertion(orient != COLLINEAR);
|
||||
|
||||
CGAL_precondition
|
||||
|
|
@ -343,8 +335,7 @@ public:
|
|||
m_is_full(false),
|
||||
m_has_radius(false),
|
||||
m_source(p1.x(), p1.y()),
|
||||
m_target(p3.x(), p3.y())
|
||||
{
|
||||
m_target(p3.x(), p3.y()) {
|
||||
// Set the source and target.
|
||||
NT x1 = p1.x();
|
||||
NT y1 = p1.y();
|
||||
|
|
@ -359,7 +350,7 @@ public:
|
|||
// Compute the lines: A1*x + B1*y + C1 = 0,
|
||||
// and: A2*x + B2*y + C2 = 0,
|
||||
// where:
|
||||
const NT _two = 2;
|
||||
const NT _two = 2;
|
||||
|
||||
const NT A1 = _two*(x1 - x2);
|
||||
const NT B1 = _two*(y1 - y2);
|
||||
|
|
@ -423,8 +414,7 @@ public:
|
|||
/*! obtains the supporting line.
|
||||
* \pre The curve orientation is COLLINEAR.
|
||||
*/
|
||||
const Line_2& supporting_line() const
|
||||
{
|
||||
const Line_2& supporting_line() const {
|
||||
CGAL_precondition(m_orient == COLLINEAR);
|
||||
return m_line;
|
||||
}
|
||||
|
|
@ -432,8 +422,7 @@ public:
|
|||
/*! obtains the supporting circle.
|
||||
* \pre The curve orientation is not COLLINEAR.
|
||||
*/
|
||||
const Circle_2& supporting_circle() const
|
||||
{
|
||||
const Circle_2& supporting_circle() const {
|
||||
CGAL_precondition(m_orient != COLLINEAR);
|
||||
return m_circ;
|
||||
}
|
||||
|
|
@ -444,8 +433,7 @@ public:
|
|||
/*! obtains the source point.
|
||||
* \pre The curve is not a full circle.
|
||||
*/
|
||||
const Point_2& source() const
|
||||
{
|
||||
const Point_2& source() const {
|
||||
CGAL_precondition(! m_is_full);
|
||||
return (m_source);
|
||||
}
|
||||
|
|
@ -453,8 +441,7 @@ public:
|
|||
/*! obtains the target point.
|
||||
* \pre The curve is not a full circle.
|
||||
*/
|
||||
const Point_2& target() const
|
||||
{
|
||||
const Point_2& target() const {
|
||||
CGAL_precondition(! m_is_full);
|
||||
return (m_target);
|
||||
}
|
||||
|
|
@ -464,8 +451,7 @@ public:
|
|||
* \pre The curve is circular.
|
||||
* \return The number of points (0, 1, or 2).
|
||||
*/
|
||||
unsigned int vertical_tangency_points(Point_2* vpts) const
|
||||
{
|
||||
unsigned int vertical_tangency_points(Point_2* vpts) const {
|
||||
CGAL_precondition(m_orient != COLLINEAR);
|
||||
unsigned int n_vpts = 0;
|
||||
|
||||
|
|
@ -519,8 +505,7 @@ private:
|
|||
*/
|
||||
unsigned int _ccw_vertical_tangency_points(const Point_2& src,
|
||||
const Point_2& trg,
|
||||
Point_2* vpts) const
|
||||
{
|
||||
Point_2* vpts) const {
|
||||
unsigned int n_vpts = 0;
|
||||
const NT& x0 = m_circ.center().x();
|
||||
const NT& y0 = m_circ.center().y();
|
||||
|
|
@ -547,8 +532,7 @@ private:
|
|||
if ((qs % 4) == 1) {
|
||||
// We collect the left tangency point when going from Q[1] to Q[2]:
|
||||
if (CGAL::compare(x0, trg.x()) != LARGER ||
|
||||
CGAL::compare(y0, trg.y()) != EQUAL)
|
||||
{
|
||||
CGAL::compare(y0, trg.y()) != EQUAL) {
|
||||
if (m_has_radius)
|
||||
vpts[n_vpts] = Point_2(CoordNT(x0 - m_radius), y0);
|
||||
else
|
||||
|
|
@ -561,8 +545,7 @@ private:
|
|||
else if ((qs % 4) == 3) {
|
||||
// We collect the right tangency point when going from Q[3] to Q[0]:
|
||||
if (CGAL::compare(x0, trg.x()) != SMALLER ||
|
||||
CGAL::compare(y0, trg.y()) != EQUAL)
|
||||
{
|
||||
CGAL::compare(y0, trg.y()) != EQUAL) {
|
||||
if (m_has_radius)
|
||||
vpts[n_vpts] = Point_2(CoordNT(x0 + m_radius), y0);
|
||||
else
|
||||
|
|
@ -581,8 +564,7 @@ private:
|
|||
/*! obtains the index of the quarter-plane containing the given point,
|
||||
* where the circle center is considered to be the origin.
|
||||
*/
|
||||
int _quart_index(const Point_2& p) const
|
||||
{
|
||||
int _quart_index(const Point_2& p) const {
|
||||
// The plane looks like:
|
||||
//
|
||||
// Q[1] : | Q[0]:
|
||||
|
|
@ -608,8 +590,7 @@ private:
|
|||
*/
|
||||
template <typename Kernel, bool Filter>
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, const _Circle_segment_2<Kernel, Filter>& c)
|
||||
{
|
||||
operator<<(std::ostream& os, const _Circle_segment_2<Kernel, Filter>& c) {
|
||||
if (c.orientation() == COLLINEAR) {
|
||||
os<< "segment: " << c.source() << " -> " << c.target();
|
||||
}
|
||||
|
|
@ -632,35 +613,33 @@ operator<<(std::ostream& os, const _Circle_segment_2<Kernel, Filter>& c)
|
|||
template <typename Kernel_, bool Filter_>
|
||||
class _X_monotone_circle_segment_2 {
|
||||
public:
|
||||
typedef Kernel_ Kernel;
|
||||
typedef _X_monotone_circle_segment_2<Kernel, Filter_> Self;
|
||||
typedef typename Kernel::FT NT;
|
||||
typedef _One_root_point_2<NT, Filter_> Point_2;
|
||||
typedef typename Kernel::Circle_2 Circle_2;
|
||||
typedef typename Kernel::Line_2 Line_2;
|
||||
typedef typename Point_2::CoordNT CoordNT;
|
||||
using Kernel = Kernel_;
|
||||
using Self = _X_monotone_circle_segment_2<Kernel, Filter_>;
|
||||
using NT = typename Kernel::FT;
|
||||
using Point_2 = _One_root_point_2<NT, Filter_>;
|
||||
using Circle_2 = typename Kernel::Circle_2;
|
||||
using Line_2 = typename Kernel::Line_2;
|
||||
using CoordNT = typename Point_2::CoordNT;
|
||||
|
||||
// Type definition for the intersection points mapping.
|
||||
typedef std::pair<unsigned int, unsigned int> Curve_id_pair;
|
||||
typedef unsigned int Multiplicity;
|
||||
typedef std::pair<Point_2, Multiplicity> Intersection_point;
|
||||
typedef std::list<Intersection_point> Intersection_list;
|
||||
using Curve_id_pair = std::pair<unsigned int, unsigned int>;
|
||||
using Multiplicity = std::size_t;
|
||||
using Intersection_point = std::pair<Point_2, Multiplicity>;
|
||||
using Intersection_list = std::list<Intersection_point>;
|
||||
|
||||
/*! \struct Less functor for Curve_id_pair.
|
||||
*/
|
||||
struct Less_id_pair {
|
||||
bool operator()(const Curve_id_pair& ip1, const Curve_id_pair& ip2) const
|
||||
{
|
||||
bool operator()(const Curve_id_pair& ip1, const Curve_id_pair& ip2) const {
|
||||
// Compare the pairs of IDs lexicographically.
|
||||
return (ip1.first < ip2.first ||
|
||||
(ip1.first == ip2.first && ip1.second < ip2.second));
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::map<Curve_id_pair, Intersection_list, Less_id_pair>
|
||||
Intersection_map;
|
||||
typedef typename Intersection_map::value_type Intersection_map_entry;
|
||||
typedef typename Intersection_map::iterator Intersection_map_iterator;
|
||||
using Intersection_map = std::map<Curve_id_pair, Intersection_list, Less_id_pair>;
|
||||
using Intersection_map_entry = typename Intersection_map::value_type;
|
||||
using Intersection_map_iterator = typename Intersection_map::iterator;
|
||||
|
||||
protected:
|
||||
NT m_first; // The x-coordinate of the circle center.
|
||||
|
|
@ -713,8 +692,7 @@ public:
|
|||
m_third(line.c()),
|
||||
m_source(source),
|
||||
m_target(target),
|
||||
m_info(index << INDEX_SHIFT_BITS)
|
||||
{
|
||||
m_info(index << INDEX_SHIFT_BITS) {
|
||||
// Check if the segment is directed left or right:
|
||||
Comparison_result res = CGAL::compare(source.x(), target.x());
|
||||
|
||||
|
|
@ -740,8 +718,7 @@ public:
|
|||
const typename Kernel::Point_2& target) :
|
||||
m_source(source.x(), source.y()),
|
||||
m_target(target.x(), target.y()),
|
||||
m_info(0)
|
||||
{
|
||||
m_info(0) {
|
||||
Line_2 line(source, target);
|
||||
m_first = line.a();
|
||||
m_second = line.b();
|
||||
|
|
@ -778,8 +755,7 @@ public:
|
|||
m_third(circ.squared_radius()),
|
||||
m_source(source),
|
||||
m_target(target),
|
||||
m_info(index << INDEX_SHIFT_BITS)
|
||||
{
|
||||
m_info(index << INDEX_SHIFT_BITS) {
|
||||
// Check if the segment is directed left or right:
|
||||
Comparison_result res = CGAL::compare (source.x(), target.x());
|
||||
|
||||
|
|
@ -802,8 +778,7 @@ public:
|
|||
/*! obtains the supporting line.
|
||||
* \pre The arc is linear (a line segment).
|
||||
*/
|
||||
Line_2 supporting_line() const
|
||||
{
|
||||
Line_2 supporting_line() const {
|
||||
CGAL_precondition (is_linear());
|
||||
return (Line_2 (a(), b(), c()));
|
||||
}
|
||||
|
|
@ -811,8 +786,7 @@ public:
|
|||
/*! obtains the supporting circle.
|
||||
* \pre The arc is circular.
|
||||
*/
|
||||
Circle_2 supporting_circle() const
|
||||
{
|
||||
Circle_2 supporting_circle() const {
|
||||
CGAL_precondition (is_circular());
|
||||
|
||||
typename Kernel::Point_2 center(x0(), y0());
|
||||
|
|
@ -843,8 +817,7 @@ public:
|
|||
|
||||
/*! checks whether the given point is in the x-range of the arc.
|
||||
*/
|
||||
bool is_in_x_range(const Point_2& p) const
|
||||
{
|
||||
bool is_in_x_range(const Point_2& p) const {
|
||||
Comparison_result res = CGAL::compare (p.x(), left().x());
|
||||
|
||||
if (res == SMALLER) return false;
|
||||
|
|
@ -858,8 +831,7 @@ public:
|
|||
{ return ((m_info & IS_VERTICAL_SEGMENT_MASK) != 0); }
|
||||
|
||||
/*! obtains the orientation of the arc. */
|
||||
inline Orientation orientation() const
|
||||
{
|
||||
inline Orientation orientation() const {
|
||||
unsigned int or_ = (m_info & ORIENTATION_MASK);
|
||||
if (or_ == COUNTERCLOCKWISE_CODE) return (CGAL::COUNTERCLOCKWISE);
|
||||
else if (or_ == CLOCKWISE_CODE) return (CGAL::CLOCKWISE);
|
||||
|
|
@ -870,16 +842,14 @@ public:
|
|||
|
||||
/*! checks the position of a given point with respect to the arc.
|
||||
*/
|
||||
Comparison_result point_position(const Point_2& p) const
|
||||
{
|
||||
Comparison_result point_position(const Point_2& p) const {
|
||||
if (is_linear()) return (_line_point_position(p));
|
||||
else return (_circ_point_position (p));
|
||||
}
|
||||
|
||||
/*! compares the two arcs to the right of their intersection point.
|
||||
*/
|
||||
Comparison_result compare_to_right(const Self& cv, const Point_2& p) const
|
||||
{
|
||||
Comparison_result compare_to_right(const Self& cv, const Point_2& p) const {
|
||||
if (is_linear()) {
|
||||
if (cv.is_linear()) return (_lines_compare_to_right (cv, p));
|
||||
Comparison_result res = cv._circ_line_compare_to_right (*this, p);
|
||||
|
|
@ -894,8 +864,7 @@ public:
|
|||
|
||||
/*! compares the two arcs to the left of their intersection point.
|
||||
*/
|
||||
Comparison_result compare_to_left(const Self& cv, const Point_2& p) const
|
||||
{
|
||||
Comparison_result compare_to_left(const Self& cv, const Point_2& p) const {
|
||||
if (is_linear()) {
|
||||
if (cv.is_linear()) return (_lines_compare_to_left (cv, p));
|
||||
Comparison_result res = cv._circ_line_compare_to_left(*this, p);
|
||||
|
|
@ -910,8 +879,7 @@ public:
|
|||
|
||||
/*! checks whether the two arcs have the same supporting curve.
|
||||
*/
|
||||
bool has_same_supporting_curve(const Self& cv) const
|
||||
{
|
||||
bool has_same_supporting_curve(const Self& cv) const {
|
||||
// Check if the curve indices are the same.
|
||||
if (_index() != 0 && _index() == cv._index()) return true;
|
||||
|
||||
|
|
@ -950,8 +918,7 @@ public:
|
|||
|
||||
/*! checks whether the two curves are equal.
|
||||
*/
|
||||
bool equals(const Self& cv) const
|
||||
{
|
||||
bool equals(const Self& cv) const {
|
||||
if (! this->has_same_supporting_curve(cv)) return false;
|
||||
|
||||
if (is_linear()) {
|
||||
|
|
@ -969,8 +936,7 @@ public:
|
|||
|
||||
/*! splits the curve at a given point into two sub-arcs.
|
||||
*/
|
||||
void split(const Point_2& p, Self& c1, Self& c2) const
|
||||
{
|
||||
void split(const Point_2& p, Self& c1, Self& c2) const {
|
||||
// Copy the properties of this arc to the sub-arcs.
|
||||
c1 = *this;
|
||||
c2 = *this;
|
||||
|
|
@ -990,8 +956,7 @@ public:
|
|||
*/
|
||||
template <typename OutputIterator>
|
||||
OutputIterator intersect(const Self& cv, OutputIterator oi,
|
||||
Intersection_map* inter_map = nullptr) const
|
||||
{
|
||||
Intersection_map* inter_map = nullptr) const {
|
||||
// First check whether the two arcs have the same supporting curve.
|
||||
if (has_same_supporting_curve(cv)) {
|
||||
// Check for overlaps between the two arcs.
|
||||
|
|
@ -1064,8 +1029,7 @@ public:
|
|||
// Report only the intersection points that lie on both arcs.
|
||||
for (auto iter = inter_list.begin(); iter != inter_list.end(); ++iter) {
|
||||
if (this->_is_between_endpoints (iter->first) &&
|
||||
cv._is_between_endpoints (iter->first))
|
||||
{
|
||||
cv._is_between_endpoints (iter->first)) {
|
||||
*oi++ = *iter;
|
||||
}
|
||||
}
|
||||
|
|
@ -1075,8 +1039,7 @@ public:
|
|||
|
||||
/*! checks whether it is possible to merge our arc with the given arc.
|
||||
*/
|
||||
bool can_merge_with(const Self& cv) const
|
||||
{
|
||||
bool can_merge_with(const Self& cv) const {
|
||||
// In order to merge the two arcs, they should have the same supporting
|
||||
// curve.
|
||||
if (! this->has_same_supporting_curve(cv)) return false;
|
||||
|
|
@ -1089,8 +1052,7 @@ public:
|
|||
/*! merges our arc with the given arc.
|
||||
* \pre The two arcs are mergeable.
|
||||
*/
|
||||
void merge(const Self& cv)
|
||||
{
|
||||
void merge(const Self& cv) {
|
||||
CGAL_precondition(this->can_merge_with (cv));
|
||||
|
||||
// Check if we should extend the arc to the left or to the right.
|
||||
|
|
@ -1109,8 +1071,7 @@ public:
|
|||
}
|
||||
|
||||
/*! constructs an opposite arc. */
|
||||
Self construct_opposite() const
|
||||
{
|
||||
Self construct_opposite() const {
|
||||
Self opp_cv;
|
||||
opp_cv.m_first = this->m_first;
|
||||
opp_cv.m_second = this->m_second;
|
||||
|
|
@ -1127,8 +1088,7 @@ public:
|
|||
return (opp_cv);
|
||||
}
|
||||
|
||||
Bbox_2 bbox() const
|
||||
{
|
||||
Bbox_2 bbox() const {
|
||||
double x_min = to_double(left().x());
|
||||
double x_max = to_double(right().x());
|
||||
double y_min = to_double(left().y());
|
||||
|
|
@ -1167,8 +1127,7 @@ protected:
|
|||
|
||||
/*! checks if the circular arc lies on the upper half of the supporting circle.
|
||||
*/
|
||||
inline bool _is_upper() const
|
||||
{
|
||||
inline bool _is_upper() const {
|
||||
Orientation orient = orientation();
|
||||
bool dir_right = ((m_info & IS_DIRECTED_RIGHT_MASK) != 0);
|
||||
|
||||
|
|
@ -1197,8 +1156,7 @@ protected:
|
|||
|
||||
/*! checks the position of a given point with respect to a line segment.
|
||||
*/
|
||||
Comparison_result _line_point_position(const Point_2& p) const
|
||||
{
|
||||
Comparison_result _line_point_position(const Point_2& p) const {
|
||||
// Check if we have a vertical segment.
|
||||
|
||||
CGAL_precondition(is_in_x_range(p));
|
||||
|
|
@ -1229,20 +1187,17 @@ protected:
|
|||
|
||||
/*! checks the position of a given point with respect to a circular arc.
|
||||
*/
|
||||
Comparison_result _circ_point_position(const Point_2& p) const
|
||||
{
|
||||
Comparison_result _circ_point_position(const Point_2& p) const {
|
||||
|
||||
Comparison_result c_res = CGAL::compare (p.y(), y0());
|
||||
|
||||
if (_is_upper()) {
|
||||
// Check if p lies below the "equator" (while the arc lies above it):
|
||||
if (c_res == SMALLER)
|
||||
return (SMALLER);
|
||||
if (c_res == SMALLER) return (SMALLER);
|
||||
}
|
||||
else {
|
||||
// Check if p lies above the "equator" (while the arc lies below it):
|
||||
if (c_res == LARGER)
|
||||
return (LARGER);
|
||||
if (c_res == LARGER) return (LARGER);
|
||||
}
|
||||
|
||||
// Check if p lies inside the supporting circle, namely we have to check
|
||||
|
|
@ -1271,8 +1226,7 @@ protected:
|
|||
/*! compares two line segments to the right of their intersection point.
|
||||
*/
|
||||
Comparison_result _lines_compare_to_right(const Self& cv,
|
||||
const Point_2& /* p */) const
|
||||
{
|
||||
const Point_2& /* p */) const {
|
||||
if (_index() != 0 && _index() == cv._index()) return (EQUAL);
|
||||
|
||||
// Special treatment for vertical segments: a vertical segment is larger
|
||||
|
|
@ -1292,8 +1246,7 @@ protected:
|
|||
* their intersection point.
|
||||
*/
|
||||
Comparison_result _circ_line_compare_to_right(const Self& cv,
|
||||
const Point_2& p) const
|
||||
{
|
||||
const Point_2& p) const {
|
||||
// A vertical segment lies above any other circle to the right of p:
|
||||
if (cv.is_vertical()) return (SMALLER);
|
||||
|
||||
|
|
@ -1334,8 +1287,7 @@ protected:
|
|||
/*! compares two circular arcs to the right of their intersection point.
|
||||
*/
|
||||
Comparison_result _circs_compare_to_right(const Self& cv,
|
||||
const Point_2& p) const
|
||||
{
|
||||
const Point_2& p) const {
|
||||
if (_index() != 0 && _index() == cv._index()) {
|
||||
// Check the case of comparing two circular arcs that originate from the
|
||||
// same supporting circle. Their comparison result is not EQUAL only if
|
||||
|
|
@ -1413,13 +1365,11 @@ protected:
|
|||
// Compare the slopes of the two tangents to the circles.
|
||||
Comparison_result slope_res;
|
||||
|
||||
if (sign_slope1 == ZERO && sign_slope2 == ZERO)
|
||||
{
|
||||
if (sign_slope1 == ZERO && sign_slope2 == ZERO) {
|
||||
// Special case were both circles have a horizontal tangent:
|
||||
slope_res = EQUAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
// Actually compare the slopes.
|
||||
const bool swap_res = (sign_denom1 != sign_denom2);
|
||||
const CoordNT A = NT(cv.y0() - y0())*p.x() + (y0()*cv.x0() - cv.y0()*x0());
|
||||
|
|
@ -1466,8 +1416,7 @@ protected:
|
|||
/*! compares two line segments to the left of their intersection point.
|
||||
*/
|
||||
Comparison_result _lines_compare_to_left(const Self& cv,
|
||||
const Point_2& ) const
|
||||
{
|
||||
const Point_2& ) const {
|
||||
if (_index() != 0 && _index() == cv._index()) return (EQUAL);
|
||||
|
||||
// Special treatment for vertical segments: a vertical segment is smaller
|
||||
|
|
@ -1489,8 +1438,7 @@ protected:
|
|||
* their intersection point.
|
||||
*/
|
||||
Comparison_result _circ_line_compare_to_left(const Self& cv,
|
||||
const Point_2& p) const
|
||||
{
|
||||
const Point_2& p) const {
|
||||
// A vertical segment lies below any other circle to the left of p:
|
||||
if (cv.is_vertical()) return (LARGER);
|
||||
|
||||
|
|
@ -1534,8 +1482,7 @@ protected:
|
|||
/*! compares the two arcs to the left of their intersection point.
|
||||
*/
|
||||
Comparison_result _circs_compare_to_left(const Self& cv,
|
||||
const Point_2& p) const
|
||||
{
|
||||
const Point_2& p) const {
|
||||
if (_index() != 0 && _index() == cv._index()) {
|
||||
// Check the case of comparing two circular arcs that originate from the
|
||||
// same supporting circle. Their comparison result is not EQUAL only if
|
||||
|
|
@ -1614,8 +1561,7 @@ protected:
|
|||
// Compare the slopes of the two tangents to the circles.
|
||||
Comparison_result slope_res;
|
||||
|
||||
if (sign_slope1 == ZERO && sign_slope2 == ZERO)
|
||||
{
|
||||
if (sign_slope1 == ZERO && sign_slope2 == ZERO) {
|
||||
// Special case were both circles have a horizontal tangent:
|
||||
slope_res = EQUAL;
|
||||
}
|
||||
|
|
@ -1668,8 +1614,7 @@ protected:
|
|||
/*! computes the intersections between two line segments.
|
||||
*/
|
||||
void _lines_intersect(const Self& cv,
|
||||
Intersection_list& inter_list) const
|
||||
{
|
||||
Intersection_list& inter_list) const {
|
||||
// The intersection of the lines:
|
||||
// a1*x + b1*y + c1 = 0 and a2*x + b2*y + c2 = 0 ,
|
||||
// is given by:
|
||||
|
|
@ -1695,8 +1640,7 @@ protected:
|
|||
* the supporting line of the segment cv.
|
||||
*/
|
||||
void _circ_line_intersect(const Self& cv,
|
||||
Intersection_list& inter_list) const
|
||||
{
|
||||
Intersection_list& inter_list) const {
|
||||
Point_2 p;
|
||||
unsigned int mult;
|
||||
|
||||
|
|
@ -1818,8 +1762,7 @@ protected:
|
|||
|
||||
/*! computes the intersections between two circles.
|
||||
*/
|
||||
void _circs_intersect(const Self& cv, Intersection_list& inter_list) const
|
||||
{
|
||||
void _circs_intersect(const Self& cv, Intersection_list& inter_list) const {
|
||||
Point_2 p;
|
||||
unsigned int mult;
|
||||
|
||||
|
|
@ -1884,8 +1827,7 @@ protected:
|
|||
/*! checks if the given point lies on the arc.
|
||||
* \pre p lies on the supporting curve.
|
||||
*/
|
||||
bool _is_between_endpoints(const Point_2& p) const
|
||||
{
|
||||
bool _is_between_endpoints(const Point_2& p) const {
|
||||
if (is_linear()) {
|
||||
if (is_vertical()) {
|
||||
// Check if the point is in the y-range of the arc.
|
||||
|
|
@ -1908,8 +1850,7 @@ protected:
|
|||
// Check whether p lies on the upper or on the lower part of the circle.
|
||||
Comparison_result c_res = CGAL::compare(p.y(), y0());
|
||||
|
||||
if ((_is_upper() && c_res == SMALLER) || (! _is_upper() && c_res == LARGER))
|
||||
{
|
||||
if ((_is_upper() && c_res == SMALLER) || (! _is_upper() && c_res == LARGER)) {
|
||||
// The point lies on the other half of the circle:
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1921,8 +1862,7 @@ protected:
|
|||
/*! checks whether the given point lies in the interior of the arc.
|
||||
* \pre p lies on the supporting curve.
|
||||
*/
|
||||
bool _is_strictly_between_endpoints(const Point_2& p) const
|
||||
{
|
||||
bool _is_strictly_between_endpoints(const Point_2& p) const {
|
||||
if (p.equals (m_source) || p.equals (m_target)) return false;
|
||||
return (_is_between_endpoints(p));
|
||||
}
|
||||
|
|
@ -1932,8 +1872,7 @@ protected:
|
|||
* \param overlap Output: The overlapping arc (if any).
|
||||
* \return Whether we found an overlap.
|
||||
*/
|
||||
bool _compute_overlap(const Self& cv, Self& overlap) const
|
||||
{
|
||||
bool _compute_overlap(const Self& cv, Self& overlap) const {
|
||||
// Check if the two arcs are identical.
|
||||
if (is_linear()) {
|
||||
// In case of line segments we can swap the source and target:
|
||||
|
|
@ -1999,10 +1938,9 @@ protected:
|
|||
return false;
|
||||
}
|
||||
|
||||
public:
|
||||
public:
|
||||
template <class OutputIterator>
|
||||
void approximate(OutputIterator oi, unsigned int n) const
|
||||
{
|
||||
void approximate(OutputIterator oi, unsigned int n) const {
|
||||
const double x_left = CGAL::to_double(this->source().x());
|
||||
const double y_left = CGAL::to_double(this->source().y());
|
||||
|
||||
|
|
@ -2045,8 +1983,7 @@ protected:
|
|||
* \pre Both ps and pt lies on the arc and must conform with the current
|
||||
* direction of the arc.
|
||||
*/
|
||||
Self trim(const Point_2& ps, const Point_2& pt) const
|
||||
{
|
||||
Self trim(const Point_2& ps, const Point_2& pt) const {
|
||||
Self arc = *this;
|
||||
|
||||
arc.m_source = ps;
|
||||
|
|
@ -2063,8 +2000,7 @@ protected:
|
|||
template <class Kernel, bool Filter>
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os,
|
||||
const _X_monotone_circle_segment_2<Kernel, Filter> & arc)
|
||||
{
|
||||
const _X_monotone_circle_segment_2<Kernel, Filter>& arc) {
|
||||
if (! arc.is_linear())
|
||||
os << "(" << arc.supporting_circle() << ") ";
|
||||
|
||||
|
|
|
|||
|
|
@ -43,46 +43,41 @@ namespace CGAL {
|
|||
// Traits class for CGAL::Arrangement_2 (and similar) based on a
|
||||
// CircularKernel.
|
||||
|
||||
template < typename CircularKernel >
|
||||
template <typename CircularKernel>
|
||||
class Arr_line_arc_traits_2 {
|
||||
|
||||
CircularKernel ck;
|
||||
|
||||
public:
|
||||
using Kernel = CircularKernel;
|
||||
using Curve_2 = typename CircularKernel::Line_arc_2;
|
||||
using X_monotone_curve_2 = typename CircularKernel::Line_arc_2;
|
||||
using Multiplicity = std::size_t;
|
||||
|
||||
typedef CircularKernel Kernel;
|
||||
typedef typename CircularKernel::Line_arc_2 Curve_2;
|
||||
typedef typename CircularKernel::Line_arc_2 X_monotone_curve_2;
|
||||
typedef unsigned int Multiplicity;
|
||||
using Point = typename CircularKernel::Circular_arc_point_2;
|
||||
using Point_2 = typename CircularKernel::Circular_arc_point_2;
|
||||
|
||||
typedef typename CircularKernel::Circular_arc_point_2 Point;
|
||||
typedef typename CircularKernel::Circular_arc_point_2 Point_2;
|
||||
using Has_left_category = CGAL::Tag_false;
|
||||
using Has_merge_category = CGAL::Tag_false;
|
||||
using Has_do_intersect_category = CGAL::Tag_false;
|
||||
|
||||
typedef CGAL::Tag_false Has_left_category;
|
||||
typedef CGAL::Tag_false Has_merge_category;
|
||||
typedef CGAL::Tag_false Has_do_intersect_category;
|
||||
using Left_side_category = Arr_oblivious_side_tag;
|
||||
using Bottom_side_category = Arr_oblivious_side_tag;
|
||||
using Top_side_category = Arr_oblivious_side_tag;
|
||||
using Right_side_category = Arr_oblivious_side_tag;
|
||||
|
||||
typedef Arr_oblivious_side_tag Left_side_category;
|
||||
typedef Arr_oblivious_side_tag Bottom_side_category;
|
||||
typedef Arr_oblivious_side_tag Top_side_category;
|
||||
typedef Arr_oblivious_side_tag Right_side_category;
|
||||
Arr_line_arc_traits_2(const CircularKernel& k = CircularKernel()) : ck(k) {}
|
||||
|
||||
Arr_line_arc_traits_2(const CircularKernel &k = CircularKernel())
|
||||
: ck(k) {}
|
||||
|
||||
typedef typename CircularKernel::Compare_x_2 Compare_x_2;
|
||||
typedef typename CircularKernel::Compare_xy_2 Compare_xy_2;
|
||||
typedef typename CircularKernel::Compare_y_at_x_2 Compare_y_at_x_2;
|
||||
typedef typename CircularKernel::Compare_y_to_right_2 Compare_y_at_x_right_2;
|
||||
typedef typename CircularKernel::Equal_2 Equal_2;
|
||||
// typedef typename CircularKernel::Make_x_monotone_2 Make_x_monotone_2;
|
||||
typedef typename CircularKernel::Split_2 Split_2;
|
||||
typedef typename CircularKernel::Construct_circular_min_vertex_2
|
||||
Construct_min_vertex_2;
|
||||
typedef typename CircularKernel::Construct_circular_max_vertex_2
|
||||
Construct_max_vertex_2;
|
||||
typedef typename CircularKernel::Is_vertical_2 Is_vertical_2;
|
||||
typedef typename CircularKernel::Intersect_2 Intersect_2;
|
||||
using Compare_x_2 = typename CircularKernel::Compare_x_2;
|
||||
using Compare_xy_2 = typename CircularKernel::Compare_xy_2;
|
||||
using Compare_y_at_x_2 = typename CircularKernel::Compare_y_at_x_2;
|
||||
using Compare_y_at_x_right_2 = typename CircularKernel::Compare_y_to_right_2;
|
||||
using Equal_2 = typename CircularKernel::Equal_2;
|
||||
// using Make_x_monotone_2 = typename CircularKernel::Make_x_monotone_2;
|
||||
using Split_2 = typename CircularKernel::Split_2;
|
||||
using Construct_min_vertex_2 = typename CircularKernel::Construct_circular_min_vertex_2;
|
||||
using Construct_max_vertex_2 = typename CircularKernel::Construct_circular_max_vertex_2;
|
||||
using Is_vertical_2 = typename CircularKernel::Is_vertical_2;
|
||||
using Intersect_2 = typename CircularKernel::Intersect_2;
|
||||
|
||||
Compare_x_2 compare_x_2_object() const
|
||||
{ return ck.compare_x_2_object(); }
|
||||
|
|
@ -106,7 +101,7 @@ public:
|
|||
{ return ck.split_2_object(); }
|
||||
|
||||
Intersect_2 intersect_2_object() const
|
||||
{ return ck.intersect_2_object(); }
|
||||
{ return ck.intersect_2_object(); }
|
||||
|
||||
Construct_min_vertex_2 construct_min_vertex_2_object() const
|
||||
{ return ck.construct_circular_min_vertex_2_object(); }
|
||||
|
|
@ -121,9 +116,8 @@ public:
|
|||
class Make_x_monotone_2 {
|
||||
public:
|
||||
template <typename OutputIterator>
|
||||
OutputIterator operator()(const Curve_2& line, OutputIterator oi) const
|
||||
{
|
||||
typedef std::variant<Point_2, X_monotone_curve_2> Make_x_monotone_result;
|
||||
OutputIterator operator()(const Curve_2& line, OutputIterator oi) const {
|
||||
using Make_x_monotone_result = std::variant<Point_2, X_monotone_curve_2>;
|
||||
*oi++ = Make_x_monotone_result(line);
|
||||
return oi;
|
||||
}
|
||||
|
|
@ -137,4 +131,4 @@ public:
|
|||
|
||||
#include <CGAL/enable_warnings.h>
|
||||
|
||||
#endif // CGAL_CIRCULAR_KERNEL_LINE_ARC_TRAITS_H
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
#include <variant>
|
||||
|
||||
#include <CGAL/Cartesian.h>
|
||||
#include <CGAL/Simple_cartesian.h>
|
||||
#include <CGAL/tags.h>
|
||||
#include <CGAL/intersections.h>
|
||||
#include <CGAL/Arr_tags.h>
|
||||
|
|
@ -49,58 +49,55 @@ class Arr_linear_traits_2 : public Kernel_ {
|
|||
friend class Arr_linear_object_2<Kernel_>;
|
||||
|
||||
public:
|
||||
typedef Kernel_ Kernel;
|
||||
typedef typename Kernel::FT FT;
|
||||
using Kernel = Kernel_;
|
||||
using FT = typename Kernel::FT;
|
||||
|
||||
typedef typename Algebraic_structure_traits<FT>::Is_exact
|
||||
Has_exact_division;
|
||||
using Has_exact_division = typename Algebraic_structure_traits<FT>::Is_exact;
|
||||
|
||||
// Category tags:
|
||||
typedef Tag_true Has_left_category;
|
||||
typedef Tag_true Has_merge_category;
|
||||
typedef Tag_false Has_do_intersect_category;
|
||||
using Has_left_category = Tag_true;
|
||||
using Has_merge_category = Tag_true;
|
||||
using Has_do_intersect_category = Tag_false;
|
||||
|
||||
typedef Arr_open_side_tag Left_side_category;
|
||||
typedef Arr_open_side_tag Bottom_side_category;
|
||||
typedef Arr_open_side_tag Top_side_category;
|
||||
typedef Arr_open_side_tag Right_side_category;
|
||||
using Left_side_category = Arr_open_side_tag;
|
||||
using Bottom_side_category = Arr_open_side_tag;
|
||||
using Top_side_category = Arr_open_side_tag;
|
||||
using Right_side_category = Arr_open_side_tag;
|
||||
|
||||
typedef typename Kernel::Line_2 Line_2;
|
||||
typedef typename Kernel::Ray_2 Ray_2;
|
||||
typedef typename Kernel::Segment_2 Segment_2;
|
||||
using Line_2 = typename Kernel::Line_2;
|
||||
using Ray_2 = typename Kernel::Ray_2;
|
||||
using Segment_2 = typename Kernel::Segment_2;
|
||||
|
||||
typedef CGAL::Segment_assertions<Arr_linear_traits_2<Kernel> >
|
||||
Segment_assertions;
|
||||
using Segment_assertions = CGAL::Segment_assertions<Arr_linear_traits_2<Kernel>>;
|
||||
|
||||
/*! \class Representation of a linear with cached data.
|
||||
*/
|
||||
class _Linear_object_cached_2 {
|
||||
public:
|
||||
typedef typename Kernel::Line_2 Line_2;
|
||||
typedef typename Kernel::Ray_2 Ray_2;
|
||||
typedef typename Kernel::Segment_2 Segment_2;
|
||||
typedef typename Kernel::Point_2 Point_2;
|
||||
using Line_2 = typename Kernel::Line_2;
|
||||
using Ray_2 = typename Kernel::Ray_2;
|
||||
using Segment_2 = typename Kernel::Segment_2;
|
||||
using Point_2 = typename Kernel::Point_2;
|
||||
|
||||
protected:
|
||||
Line_2 l; // The supporting line.
|
||||
Point_2 ps; // The source point (if exists).
|
||||
Point_2 pt; // The target point (if exists).
|
||||
bool has_source; // Is the source point valid
|
||||
Line_2 l; // The supporting line.
|
||||
Point_2 ps; // The source point (if exists).
|
||||
Point_2 pt; // The target point (if exists).
|
||||
bool has_source; // Is the source point valid
|
||||
// (false for a line).
|
||||
bool has_target; // Is the target point valid
|
||||
bool has_target; // Is the target point valid
|
||||
// (false for a line and for a ray).
|
||||
bool is_right; // Is the object directed to the right
|
||||
bool is_right; // Is the object directed to the right
|
||||
// (for segments and rays).
|
||||
bool is_vert; // Is this a vertical object.
|
||||
bool is_horiz; // Is this a horizontal object.
|
||||
bool has_pos_slope; // Does the supporting line has a positive
|
||||
bool is_vert; // Is this a vertical object.
|
||||
bool is_horiz; // Is this a horizontal object.
|
||||
bool has_pos_slope; // Does the supporting line has a positive
|
||||
// slope (if all three flags is_vert, is_horiz
|
||||
// and has_pos_slope are false, then the line
|
||||
// has a negative slope).
|
||||
bool is_degen; // Is the object degenerate (a single point).
|
||||
bool is_degen; // Is the object degenerate (a single point).
|
||||
|
||||
public:
|
||||
|
||||
/*! constructs default.
|
||||
*/
|
||||
_Linear_object_cached_2() :
|
||||
|
|
@ -121,8 +118,7 @@ public:
|
|||
ps(source),
|
||||
pt(target),
|
||||
has_source(true),
|
||||
has_target(true)
|
||||
{
|
||||
has_target(true) {
|
||||
Kernel kernel;
|
||||
|
||||
Comparison_result res = kernel.compare_xy_2_object()(source, target);
|
||||
|
|
@ -144,8 +140,7 @@ public:
|
|||
*/
|
||||
_Linear_object_cached_2(const Segment_2& seg) :
|
||||
has_source(true),
|
||||
has_target(true)
|
||||
{
|
||||
has_target(true) {
|
||||
Kernel kernel;
|
||||
|
||||
CGAL_assertion_msg(! kernel.is_degenerate_2_object()(seg),
|
||||
|
|
@ -172,8 +167,7 @@ public:
|
|||
*/
|
||||
_Linear_object_cached_2(const Ray_2& ray) :
|
||||
has_source(true),
|
||||
has_target(false)
|
||||
{
|
||||
has_target(false) {
|
||||
Kernel kernel;
|
||||
|
||||
CGAL_assertion_msg(! kernel.is_degenerate_2_object()(ray),
|
||||
|
|
@ -201,8 +195,7 @@ public:
|
|||
_Linear_object_cached_2(const Line_2& ln) :
|
||||
l(ln),
|
||||
has_source(false),
|
||||
has_target(false)
|
||||
{
|
||||
has_target(false) {
|
||||
Kernel kernel;
|
||||
|
||||
CGAL_assertion_msg(! kernel.is_degenerate_2_object()(ln),
|
||||
|
|
@ -226,8 +219,7 @@ public:
|
|||
* \return `ARR_LEFT_BOUNDARY` if the left point is near the boundary;
|
||||
* `ARR_INTERIOR` if the \f$x\f$-coordinate is finite.
|
||||
*/
|
||||
Arr_parameter_space left_infinite_in_x() const
|
||||
{
|
||||
Arr_parameter_space left_infinite_in_x() const {
|
||||
if (is_vert || is_degen) return (ARR_INTERIOR);
|
||||
|
||||
return (is_right) ?
|
||||
|
|
@ -240,8 +232,7 @@ public:
|
|||
* `ARR_INTERIOR` if the \f$y\f$-coordinate is finite.
|
||||
* `ARR_TOP_BOUNDARY` if the left point is at \f$y = +\infty\f$;
|
||||
*/
|
||||
Arr_parameter_space left_infinite_in_y() const
|
||||
{
|
||||
Arr_parameter_space left_infinite_in_y() const {
|
||||
if (is_horiz || is_degen) return ARR_INTERIOR;
|
||||
|
||||
if (is_vert) {
|
||||
|
|
@ -263,8 +254,7 @@ public:
|
|||
/*! obtains the (lexicographically) left endpoint.
|
||||
* \pre The left point is finite.
|
||||
*/
|
||||
const Point_2& left() const
|
||||
{
|
||||
const Point_2& left() const {
|
||||
CGAL_precondition(has_left());
|
||||
return (is_right ? ps : pt);
|
||||
}
|
||||
|
|
@ -274,8 +264,7 @@ public:
|
|||
* \pre p lies on the supporting line to the left of the right endpoint.
|
||||
*/
|
||||
void set_left(const Point_2& p,
|
||||
bool CGAL_assertion_code(check_validity) = true)
|
||||
{
|
||||
bool CGAL_assertion_code(check_validity) = true) {
|
||||
CGAL_precondition(! is_degen);
|
||||
|
||||
CGAL_precondition_code(Kernel kernel);
|
||||
|
|
@ -296,8 +285,7 @@ public:
|
|||
|
||||
/*! sets the (lexicographically) left endpoint as infinite.
|
||||
*/
|
||||
void set_left()
|
||||
{
|
||||
void set_left() {
|
||||
CGAL_precondition(! is_degen);
|
||||
|
||||
if (is_right) has_source = false;
|
||||
|
|
@ -308,8 +296,7 @@ public:
|
|||
* \return `ARR_RIGHT_BOUNDARY` if the right point is near the boundary;
|
||||
* `ARR_INTERIOR` if the \f$x\f$-coordinate is finite.
|
||||
*/
|
||||
Arr_parameter_space right_infinite_in_x() const
|
||||
{
|
||||
Arr_parameter_space right_infinite_in_x() const {
|
||||
if (is_vert || is_degen) return ARR_INTERIOR;
|
||||
|
||||
return (is_right) ?
|
||||
|
|
@ -322,8 +309,7 @@ public:
|
|||
* `ARR_INTERIOR` if the \f$y\f$-coordinate is finite.
|
||||
* `ARR_TOP_BOUNDARY` if the right point is at \f$y = +\infty\f$;
|
||||
*/
|
||||
Arr_parameter_space right_infinite_in_y() const
|
||||
{
|
||||
Arr_parameter_space right_infinite_in_y() const {
|
||||
if (is_horiz || is_degen) return ARR_INTERIOR;
|
||||
|
||||
if (is_vert) {
|
||||
|
|
@ -345,8 +331,7 @@ public:
|
|||
/*! obtains the (lexicographically) right endpoint.
|
||||
* \pre The right endpoint is finite.
|
||||
*/
|
||||
const Point_2& right() const
|
||||
{
|
||||
const Point_2& right() const {
|
||||
CGAL_precondition(has_right());
|
||||
return (is_right ? pt : ps);
|
||||
}
|
||||
|
|
@ -356,8 +341,7 @@ public:
|
|||
* \pre p lies on the supporting line to the right of the left endpoint.
|
||||
*/
|
||||
void set_right(const Point_2& p,
|
||||
bool CGAL_assertion_code(check_validity) = true)
|
||||
{
|
||||
bool CGAL_assertion_code(check_validity) = true) {
|
||||
CGAL_precondition(! is_degen);
|
||||
CGAL_precondition_code(Kernel kernel);
|
||||
CGAL_precondition
|
||||
|
|
@ -377,8 +361,7 @@ public:
|
|||
|
||||
/*! sets the (lexicographically) right endpoint as infinite.
|
||||
*/
|
||||
void set_right()
|
||||
{
|
||||
void set_right() {
|
||||
CGAL_precondition(! is_degen);
|
||||
|
||||
if (is_right) has_target = false;
|
||||
|
|
@ -387,16 +370,14 @@ public:
|
|||
|
||||
/*! obtains the supporting line.
|
||||
*/
|
||||
const Line_2& supp_line() const
|
||||
{
|
||||
const Line_2& supp_line() const {
|
||||
CGAL_precondition(! is_degen);
|
||||
return (l);
|
||||
}
|
||||
|
||||
/*! checks whether the curve is vertical.
|
||||
*/
|
||||
bool is_vertical() const
|
||||
{
|
||||
bool is_vertical() const {
|
||||
CGAL_precondition(! is_degen);
|
||||
return (is_vert);
|
||||
}
|
||||
|
|
@ -414,8 +395,7 @@ public:
|
|||
* \return (true) is in the \f$x\f$-range of the segment; (false) if it is
|
||||
* not.
|
||||
*/
|
||||
bool is_in_x_range(const Point_2& p) const
|
||||
{
|
||||
bool is_in_x_range(const Point_2& p) const {
|
||||
Kernel kernel;
|
||||
typename Kernel_::Compare_x_2 compare_x = kernel.compare_x_2_object();
|
||||
Comparison_result res1;
|
||||
|
|
@ -454,8 +434,7 @@ public:
|
|||
* \return (true) is in the \f$y\f$-range of the segment; (false) if it is
|
||||
* not.
|
||||
*/
|
||||
bool is_in_y_range(const Point_2& p) const
|
||||
{
|
||||
bool is_in_y_range(const Point_2& p) const {
|
||||
CGAL_precondition(is_vertical());
|
||||
|
||||
Kernel kernel;
|
||||
|
|
@ -483,8 +462,7 @@ public:
|
|||
private:
|
||||
/*! determines if the supporting line has a positive slope.
|
||||
*/
|
||||
bool _has_positive_slope() const
|
||||
{
|
||||
bool _has_positive_slope() const {
|
||||
if (is_vert) return true;
|
||||
if (is_horiz) return false;
|
||||
|
||||
|
|
@ -498,10 +476,10 @@ public:
|
|||
|
||||
public:
|
||||
// Traits objects
|
||||
typedef typename Kernel::Point_2 Point_2;
|
||||
typedef Arr_linear_object_2<Kernel> X_monotone_curve_2;
|
||||
typedef Arr_linear_object_2<Kernel> Curve_2;
|
||||
typedef unsigned int Multiplicity;
|
||||
using Point_2 = typename Kernel::Point_2;
|
||||
using X_monotone_curve_2 = Arr_linear_object_2<Kernel>;
|
||||
using Curve_2 = Arr_linear_object_2<Kernel>;
|
||||
using Multiplicity = std::size_t;
|
||||
|
||||
public:
|
||||
/*! constructs default.
|
||||
|
|
@ -514,7 +492,7 @@ public:
|
|||
/*! A functor that compares the \f$x\f$-coordinates of two points */
|
||||
class Compare_x_2 {
|
||||
protected:
|
||||
typedef Arr_linear_traits_2<Kernel> Traits;
|
||||
using Traits = Arr_linear_traits_2<Kernel>;
|
||||
|
||||
/*! The traits (in case it has state) */
|
||||
const Traits& m_traits;
|
||||
|
|
@ -538,8 +516,7 @@ public:
|
|||
* SMALLER if x(p1) < x(p2);
|
||||
* EQUAL if x(p1) = x(p2).
|
||||
*/
|
||||
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 Kernel& kernel = m_traits;
|
||||
return (kernel.compare_x_2_object()(p1, p2));
|
||||
}
|
||||
|
|
@ -567,7 +544,7 @@ public:
|
|||
|
||||
class Trim_2 {
|
||||
protected:
|
||||
typedef Arr_linear_traits_2<Kernel> Traits;
|
||||
using Traits = Arr_linear_traits_2<Kernel>;
|
||||
|
||||
/*! The traits (in case it has state) */
|
||||
const Traits& m_traits;
|
||||
|
|
@ -586,10 +563,8 @@ public:
|
|||
public:
|
||||
X_monotone_curve_2 operator()(const X_monotone_curve_2 xcv,
|
||||
const Point_2 src,
|
||||
const Point_2 tgt)
|
||||
{
|
||||
/*
|
||||
* "Line_segment, line, and ray" will become line segments
|
||||
const Point_2 tgt) {
|
||||
/* "Line_segment, line, and ray" will become line segments
|
||||
* when trimmed.
|
||||
*/
|
||||
Equal_2 equal = Equal_2();
|
||||
|
|
@ -619,7 +594,7 @@ public:
|
|||
|
||||
class Construct_opposite_2{
|
||||
protected:
|
||||
typedef Arr_linear_traits_2<Kernel> Traits;
|
||||
using Traits = Arr_linear_traits_2<Kernel>;
|
||||
|
||||
/*! The traits (in case it has state) */
|
||||
const Traits& m_traits;
|
||||
|
|
@ -636,8 +611,7 @@ public:
|
|||
friend class Arr_linear_traits_2<Kernel>;
|
||||
|
||||
public:
|
||||
X_monotone_curve_2 operator()(const X_monotone_curve_2& xcv) const
|
||||
{
|
||||
X_monotone_curve_2 operator()(const X_monotone_curve_2& xcv) const {
|
||||
CGAL_precondition(! xcv.is_degenerate());
|
||||
|
||||
X_monotone_curve_2 opp_xcv;
|
||||
|
|
@ -667,8 +641,7 @@ public:
|
|||
* SMALLER if x(p1) < x(p2), or if x(p1) = x(p2) and y(p1) < y(p2);
|
||||
* EQUAL if the two points are equal.
|
||||
*/
|
||||
Comparison_result operator()(const Point_2& p1, const Point_2& p2) const
|
||||
{
|
||||
Comparison_result operator()(const Point_2& p1, const Point_2& p2) const {
|
||||
Kernel kernel;
|
||||
return (kernel.compare_xy_2_object()(p1, p2));
|
||||
}
|
||||
|
|
@ -685,8 +658,7 @@ public:
|
|||
* \pre The left end of cv is a valid (bounded) point.
|
||||
* \return The left endpoint.
|
||||
*/
|
||||
const Point_2& operator()(const X_monotone_curve_2& cv) const
|
||||
{
|
||||
const Point_2& operator()(const X_monotone_curve_2& cv) const {
|
||||
CGAL_precondition(! cv.is_degenerate());
|
||||
CGAL_precondition(cv.has_left());
|
||||
|
||||
|
|
@ -706,8 +678,7 @@ public:
|
|||
* \pre The right end of cv is a valid (bounded) point.
|
||||
* \return The right endpoint.
|
||||
*/
|
||||
const Point_2& operator()(const X_monotone_curve_2& cv) const
|
||||
{
|
||||
const Point_2& operator()(const X_monotone_curve_2& cv) const {
|
||||
CGAL_precondition(! cv.is_degenerate());
|
||||
CGAL_precondition(cv.has_right());
|
||||
|
||||
|
|
@ -726,8 +697,7 @@ public:
|
|||
* \param cv The curve.
|
||||
* \return (true) if the curve is a vertical segment; (false) otherwise.
|
||||
*/
|
||||
bool operator()(const X_monotone_curve_2& cv) const
|
||||
{
|
||||
bool operator()(const X_monotone_curve_2& cv) const {
|
||||
CGAL_precondition(! cv.is_degenerate());
|
||||
return (cv.is_vertical());
|
||||
}
|
||||
|
|
@ -741,7 +711,7 @@ public:
|
|||
*/
|
||||
class Compare_y_at_x_2 {
|
||||
protected:
|
||||
typedef Arr_linear_traits_2<Kernel> Traits;
|
||||
using Traits = Arr_linear_traits_2<Kernel>;
|
||||
|
||||
/*! The traits (in case it has state) */
|
||||
const Traits& m_traits;
|
||||
|
|
@ -767,8 +737,7 @@ public:
|
|||
* EQUAL if p lies on the curve.
|
||||
*/
|
||||
Comparison_result operator()(const Point_2& p,
|
||||
const X_monotone_curve_2& cv) const
|
||||
{
|
||||
const X_monotone_curve_2& cv) const {
|
||||
CGAL_precondition(! cv.is_degenerate());
|
||||
CGAL_precondition(cv.is_in_x_range(p));
|
||||
|
||||
|
|
@ -809,8 +778,7 @@ public:
|
|||
*/
|
||||
Comparison_result operator()(const X_monotone_curve_2& cv1,
|
||||
const X_monotone_curve_2& cv2,
|
||||
const Point_2& CGAL_precondition_code(p)) const
|
||||
{
|
||||
const Point_2& CGAL_precondition_code(p)) const {
|
||||
CGAL_precondition(! cv1.is_degenerate());
|
||||
CGAL_precondition(! cv2.is_degenerate());
|
||||
|
||||
|
|
@ -861,8 +829,7 @@ public:
|
|||
*/
|
||||
Comparison_result operator()(const X_monotone_curve_2& cv1,
|
||||
const X_monotone_curve_2& cv2,
|
||||
const Point_2& CGAL_precondition_code(p)) const
|
||||
{
|
||||
const Point_2& CGAL_precondition_code(p)) const {
|
||||
CGAL_precondition(! cv1.is_degenerate());
|
||||
CGAL_precondition(! cv2.is_degenerate());
|
||||
|
||||
|
|
@ -906,8 +873,7 @@ public:
|
|||
* \return (true) if the two curves are the same; (false) otherwise.
|
||||
*/
|
||||
bool operator()(const X_monotone_curve_2& cv1,
|
||||
const X_monotone_curve_2& cv2) const
|
||||
{
|
||||
const X_monotone_curve_2& cv2) const {
|
||||
CGAL_precondition(! cv1.is_degenerate());
|
||||
CGAL_precondition(! cv2.is_degenerate());
|
||||
|
||||
|
|
@ -918,17 +884,13 @@ public:
|
|||
if (! equal(cv1.supp_line(), cv2.supp_line()) &&
|
||||
! equal(cv1.supp_line(),
|
||||
kernel.construct_opposite_line_2_object()(cv2.supp_line())))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check that either the two left endpoints are at infinity, or they
|
||||
// are bounded and equal.
|
||||
if ((cv1.has_left() != cv2.has_left()) ||
|
||||
(cv1.has_left() && ! equal(cv1.left(), cv2.left())))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check that either the two right endpoints are at infinity, or they
|
||||
// are bounded and equal.
|
||||
|
|
@ -941,8 +903,7 @@ public:
|
|||
* \param p2 The second point.
|
||||
* \return (true) if the two point are the same; (false) otherwise.
|
||||
*/
|
||||
bool operator()(const Point_2& p1, const Point_2& p2) const
|
||||
{
|
||||
bool operator()(const Point_2& p1, const Point_2& p2) const {
|
||||
Kernel kernel;
|
||||
return (kernel.equal_2_object()(p1, p2));
|
||||
}
|
||||
|
|
@ -973,8 +934,7 @@ public:
|
|||
* the left at the line right end.
|
||||
*/
|
||||
Arr_parameter_space operator()(const X_monotone_curve_2 & xcv,
|
||||
Arr_curve_end ce) const
|
||||
{
|
||||
Arr_curve_end ce) const {
|
||||
CGAL_precondition(! xcv.is_degenerate());
|
||||
return (ce == ARR_MIN_END) ?
|
||||
xcv.left_infinite_in_x() : xcv.right_infinite_in_x();
|
||||
|
|
@ -1015,8 +975,7 @@ public:
|
|||
* right end.
|
||||
*/
|
||||
Arr_parameter_space operator()(const X_monotone_curve_2 & xcv,
|
||||
Arr_curve_end ce) const
|
||||
{
|
||||
Arr_curve_end ce) const {
|
||||
CGAL_precondition(! xcv.is_degenerate());
|
||||
|
||||
return (ce == ARR_MIN_END) ?
|
||||
|
|
@ -1040,7 +999,7 @@ public:
|
|||
*/
|
||||
class Compare_x_on_boundary_2 {
|
||||
protected:
|
||||
typedef Arr_linear_traits_2<Kernel> Traits;
|
||||
using Traits = Arr_linear_traits_2<Kernel>;
|
||||
|
||||
/*! The traits (in case it has state) */
|
||||
const Traits& m_traits;
|
||||
|
|
@ -1074,8 +1033,7 @@ public:
|
|||
*/
|
||||
Comparison_result operator()(const Point_2 & p,
|
||||
const X_monotone_curve_2 & xcv,
|
||||
Arr_curve_end ) const
|
||||
{
|
||||
Arr_curve_end ) const {
|
||||
CGAL_precondition(! xcv.is_degenerate());
|
||||
CGAL_precondition(xcv.is_vertical());
|
||||
|
||||
|
|
@ -1105,8 +1063,7 @@ public:
|
|||
Comparison_result operator()(const X_monotone_curve_2 & xcv1,
|
||||
Arr_curve_end /* ce1 */,
|
||||
const X_monotone_curve_2 & xcv2,
|
||||
Arr_curve_end /* ce2 */) const
|
||||
{
|
||||
Arr_curve_end /* ce2 */) const {
|
||||
CGAL_precondition(! xcv1.is_degenerate());
|
||||
CGAL_precondition(! xcv2.is_degenerate());
|
||||
CGAL_precondition(xcv1.is_vertical());
|
||||
|
|
@ -1152,8 +1109,7 @@ public:
|
|||
Comparison_result
|
||||
operator()(const X_monotone_curve_2& CGAL_precondition_code(xcv1),
|
||||
const X_monotone_curve_2& CGAL_precondition_code(xcv2),
|
||||
Arr_curve_end /* ce2 */) const
|
||||
{
|
||||
Arr_curve_end /* ce2 */) const {
|
||||
CGAL_precondition(! xcv1.is_degenerate());
|
||||
CGAL_precondition(! xcv2.is_degenerate());
|
||||
CGAL_precondition(xcv1.is_vertical());
|
||||
|
|
@ -1171,7 +1127,7 @@ public:
|
|||
*/
|
||||
class Compare_y_near_boundary_2 {
|
||||
protected:
|
||||
typedef Arr_linear_traits_2<Kernel> Traits;
|
||||
using Traits = Arr_linear_traits_2<Kernel>;
|
||||
|
||||
/*! The traits (in case it has state) */
|
||||
const Traits& m_traits;
|
||||
|
|
@ -1199,8 +1155,7 @@ public:
|
|||
*/
|
||||
Comparison_result operator()(const X_monotone_curve_2 & xcv1,
|
||||
const X_monotone_curve_2 & xcv2,
|
||||
Arr_curve_end ce) const
|
||||
{
|
||||
Arr_curve_end ce) const {
|
||||
// Make sure both curves are defined at \f$x = -\infty\f$ (or at
|
||||
// \f$x = +\infty\f$).
|
||||
CGAL_precondition(! xcv1.is_degenerate());
|
||||
|
|
@ -1252,11 +1207,9 @@ public:
|
|||
* \return The past-the-end iterator.
|
||||
*/
|
||||
template <typename OutputIterator>
|
||||
OutputIterator operator()(const Curve_2& cv, OutputIterator oi) const
|
||||
{
|
||||
OutputIterator operator()(const Curve_2& cv, OutputIterator oi) const {
|
||||
// Wrap the segment with a variant.
|
||||
typedef std::variant<Point_2, X_monotone_curve_2>
|
||||
Make_x_monotone_result;
|
||||
using Make_x_monotone_result = std::variant<Point_2, X_monotone_curve_2>;
|
||||
*oi++ = Make_x_monotone_result(cv);
|
||||
return oi;
|
||||
}
|
||||
|
|
@ -1277,8 +1230,7 @@ public:
|
|||
* \pre `p` lies on `cv` but is not one of its end-points.
|
||||
*/
|
||||
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 {
|
||||
CGAL_precondition(! cv.is_degenerate());
|
||||
|
||||
// Make sure that p lies on the interior of the curve.
|
||||
|
|
@ -1306,7 +1258,7 @@ public:
|
|||
|
||||
class Intersect_2 {
|
||||
protected:
|
||||
typedef Arr_linear_traits_2<Kernel> Traits;
|
||||
using Traits = Arr_linear_traits_2<Kernel>;
|
||||
|
||||
/*! The traits (in case it has state) */
|
||||
const Traits& m_traits;
|
||||
|
|
@ -1330,9 +1282,8 @@ public:
|
|||
template <typename OutputIterator>
|
||||
OutputIterator operator()(const X_monotone_curve_2& cv1,
|
||||
const X_monotone_curve_2& cv2,
|
||||
OutputIterator oi) const
|
||||
{
|
||||
typedef std::pair<Point_2, Multiplicity> Intersection_point;
|
||||
OutputIterator oi) const {
|
||||
using Intersection_point = std::pair<Point_2, Multiplicity>;
|
||||
|
||||
CGAL_precondition(! cv1.is_degenerate());
|
||||
CGAL_precondition(! cv2.is_degenerate());
|
||||
|
|
@ -1429,8 +1380,7 @@ public:
|
|||
* by the same line and share a common endpoint; (false) otherwise.
|
||||
*/
|
||||
bool operator()(const X_monotone_curve_2& cv1,
|
||||
const X_monotone_curve_2& cv2) const
|
||||
{
|
||||
const X_monotone_curve_2& cv2) const {
|
||||
CGAL_precondition(! cv1.is_degenerate());
|
||||
CGAL_precondition(! cv2.is_degenerate());
|
||||
|
||||
|
|
@ -1460,7 +1410,7 @@ public:
|
|||
*/
|
||||
class Merge_2 {
|
||||
protected:
|
||||
typedef Arr_linear_traits_2<Kernel> Traits;
|
||||
using Traits = Arr_linear_traits_2<Kernel>;
|
||||
|
||||
/*! The traits (in case it has state) */
|
||||
const Traits& m_traits;
|
||||
|
|
@ -1481,8 +1431,7 @@ public:
|
|||
*/
|
||||
void operator()(const X_monotone_curve_2& cv1,
|
||||
const X_monotone_curve_2& cv2,
|
||||
X_monotone_curve_2& c) const
|
||||
{
|
||||
X_monotone_curve_2& c) const {
|
||||
CGAL_precondition(m_traits.are_mergeable_2_object()(cv2, cv1));
|
||||
|
||||
CGAL_precondition(!cv1.is_degenerate());
|
||||
|
|
@ -1492,8 +1441,7 @@ public:
|
|||
|
||||
// Check which curve extends to the right of the other.
|
||||
if (cv1.has_right() && cv2.has_left() &&
|
||||
equal(cv1.right(), cv2.left()))
|
||||
{
|
||||
equal(cv1.right(), cv2.left())) {
|
||||
// cv2 extends cv1 to the right.
|
||||
c = cv1;
|
||||
|
||||
|
|
@ -1519,9 +1467,9 @@ public:
|
|||
|
||||
/// \name Functor definitions for the landmarks point-location strategy.
|
||||
//@{
|
||||
typedef double Approximate_number_type;
|
||||
typedef CGAL::Cartesian<Approximate_number_type> Approximate_kernel;
|
||||
typedef Approximate_kernel::Point_2 Approximate_point_2;
|
||||
using Approximate_number_type = double;
|
||||
using Approximate_kernel = CGAL::Simple_cartesian<Approximate_number_type>;
|
||||
using Approximate_point_2 = Approximate_kernel::Point_2;
|
||||
|
||||
class Approximate_2 {
|
||||
protected:
|
||||
|
|
@ -1545,8 +1493,7 @@ public:
|
|||
* \return An approximation of `p`'s \f$x\f$-coordinate (if `i` == 0), or an
|
||||
* approximation of `p`'s \f$y\f$-coordinate (if `i` == 1).
|
||||
*/
|
||||
Approximate_number_type operator()(const Point_2& p, int i) const
|
||||
{
|
||||
Approximate_number_type operator()(const Point_2& p, int i) const {
|
||||
CGAL_precondition((i == 0) || (i == 1));
|
||||
return (i == 0) ? CGAL::to_double(p.x()) : CGAL::to_double(p.y());
|
||||
}
|
||||
|
|
@ -1566,12 +1513,8 @@ public:
|
|||
auto max_vertex = m_traits.construct_max_vertex_2_object();
|
||||
const auto& src = (l2r) ? min_vertex(xcv) : max_vertex(xcv);
|
||||
const auto& trg = (l2r) ? max_vertex(xcv) : min_vertex(xcv);
|
||||
auto xs = CGAL::to_double(src.x());
|
||||
auto ys = CGAL::to_double(src.y());
|
||||
auto xt = CGAL::to_double(trg.x());
|
||||
auto yt = CGAL::to_double(trg.y());
|
||||
*oi++ = Approximate_point_2(xs, ys);
|
||||
*oi++ = Approximate_point_2(xt, yt);
|
||||
*oi++ = operator()(src);
|
||||
*oi++ = operator()(trg);
|
||||
return oi;
|
||||
}
|
||||
|
||||
|
|
@ -1580,8 +1523,7 @@ public:
|
|||
template <typename OutputIterator>
|
||||
OutputIterator operator()(const X_monotone_curve_2& xcv, double /* error */,
|
||||
OutputIterator oi, const Bbox_2& bbox,
|
||||
bool l2r = true) const
|
||||
{
|
||||
bool l2r = true) const {
|
||||
using Approx_pnt = Approximate_point_2;
|
||||
using Approx_seg = Approximate_kernel::Segment_2;
|
||||
using Approx_ray = Approximate_kernel::Ray_2;
|
||||
|
|
@ -1657,8 +1599,7 @@ public:
|
|||
* \pre p and q must not be the same.
|
||||
* \return A segment connecting `p` and `q`.
|
||||
*/
|
||||
X_monotone_curve_2 operator()(const Point_2& p, const Point_2& q) const
|
||||
{
|
||||
X_monotone_curve_2 operator()(const Point_2& p, const Point_2& q) const {
|
||||
Kernel kernel;
|
||||
Segment_2 seg = kernel.construct_segment_2_object()(p, q);
|
||||
|
||||
|
|
@ -1675,7 +1616,7 @@ public:
|
|||
//@{
|
||||
|
||||
//! Functor
|
||||
typedef Construct_x_monotone_curve_2 Construct_curve_2;
|
||||
using Construct_curve_2 = Construct_x_monotone_curve_2;
|
||||
|
||||
/*! obtains a `Construct_curve_2` functor object. */
|
||||
Construct_curve_2 construct_curve_2_object() const
|
||||
|
|
@ -1688,18 +1629,16 @@ public:
|
|||
*/
|
||||
template <typename Kernel_>
|
||||
class Arr_linear_object_2 :
|
||||
public Arr_linear_traits_2<Kernel_>::_Linear_object_cached_2
|
||||
{
|
||||
typedef typename Arr_linear_traits_2<Kernel_>::_Linear_object_cached_2
|
||||
Base;
|
||||
public Arr_linear_traits_2<Kernel_>::_Linear_object_cached_2 {
|
||||
using Base = typename Arr_linear_traits_2<Kernel_>::_Linear_object_cached_2;
|
||||
|
||||
public:
|
||||
typedef Kernel_ Kernel;
|
||||
using Kernel = Kernel_;
|
||||
|
||||
typedef typename Kernel::Point_2 Point_2;
|
||||
typedef typename Kernel::Segment_2 Segment_2;
|
||||
typedef typename Kernel::Ray_2 Ray_2;
|
||||
typedef typename Kernel::Line_2 Line_2;
|
||||
using Point_2 = typename Kernel::Point_2;
|
||||
using Segment_2 = typename Kernel::Segment_2;
|
||||
using Ray_2 = typename Kernel::Ray_2;
|
||||
using Line_2 = typename Kernel::Line_2;
|
||||
|
||||
public:
|
||||
/*! constructs default.
|
||||
|
|
@ -1739,8 +1678,7 @@ public:
|
|||
/*! casts to a segment.
|
||||
* \pre The linear object is really a segment.
|
||||
*/
|
||||
Segment_2 segment() const
|
||||
{
|
||||
Segment_2 segment() const {
|
||||
CGAL_precondition(is_segment());
|
||||
|
||||
Kernel kernel;
|
||||
|
|
@ -1756,8 +1694,7 @@ public:
|
|||
/*! casts to a ray.
|
||||
* \pre The linear object is really a ray.
|
||||
*/
|
||||
Ray_2 ray() const
|
||||
{
|
||||
Ray_2 ray() const {
|
||||
CGAL_precondition(is_ray());
|
||||
|
||||
Kernel kernel;
|
||||
|
|
@ -1776,8 +1713,7 @@ public:
|
|||
/*! casts to a line.
|
||||
* \pre The linear object is really a line.
|
||||
*/
|
||||
Line_2 line() const
|
||||
{
|
||||
Line_2 line() const {
|
||||
CGAL_precondition(is_line());
|
||||
return (this->l);
|
||||
}
|
||||
|
|
@ -1785,8 +1721,7 @@ public:
|
|||
/*! obtains the supporting line.
|
||||
* \pre The object is not a point.
|
||||
*/
|
||||
const Line_2& supporting_line() const
|
||||
{
|
||||
const Line_2& supporting_line() const {
|
||||
CGAL_precondition(! this->is_degen);
|
||||
return (this->l);
|
||||
}
|
||||
|
|
@ -1794,8 +1729,7 @@ public:
|
|||
/*! obtains the source point.
|
||||
* \pre The object is a point, a segment or a ray.
|
||||
*/
|
||||
const Point_2& source() const
|
||||
{
|
||||
const Point_2& source() const {
|
||||
CGAL_precondition(! is_line());
|
||||
|
||||
if (this->is_degen) return (this->ps); // For a point.
|
||||
|
|
@ -1806,16 +1740,14 @@ public:
|
|||
/*! obtains the target point.
|
||||
* \pre The object is a point or a segment.
|
||||
*/
|
||||
const Point_2& target() const
|
||||
{
|
||||
const Point_2& target() const {
|
||||
CGAL_precondition(! is_line() && ! is_ray());
|
||||
return (this->pt);
|
||||
}
|
||||
|
||||
/*! creates a bounding box for the linear object.
|
||||
*/
|
||||
Bbox_2 bbox() const
|
||||
{
|
||||
Bbox_2 bbox() const {
|
||||
CGAL_precondition(this->is_segment());
|
||||
Kernel kernel;
|
||||
Segment_2 seg = kernel.construct_segment_2_object()(this->ps, this->pt);
|
||||
|
|
@ -1834,8 +1766,7 @@ public:
|
|||
*/
|
||||
template <typename Kernel, typename OutputStream>
|
||||
OutputStream& operator<<(OutputStream& os,
|
||||
const Arr_linear_object_2<Kernel>& lobj)
|
||||
{
|
||||
const Arr_linear_object_2<Kernel>& lobj) {
|
||||
// Print a letter identifying the object type, then the object itself.
|
||||
if (lobj.is_segment()) os << " S " << lobj.segment();
|
||||
else if (lobj.is_ray()) os << " R " << lobj.ray();
|
||||
|
|
@ -1846,8 +1777,7 @@ OutputStream& operator<<(OutputStream& os,
|
|||
/*! Importer for the segment class used by the traits-class.
|
||||
*/
|
||||
template <typename Kernel, typename InputStream>
|
||||
InputStream& operator>>(InputStream& is, Arr_linear_object_2<Kernel>& lobj)
|
||||
{
|
||||
InputStream& operator>>(InputStream& is, Arr_linear_object_2<Kernel>& lobj) {
|
||||
// Read the object type.
|
||||
char c;
|
||||
do {
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
* functors required by the concept it models.
|
||||
*/
|
||||
|
||||
#include <CGAL/Cartesian.h>
|
||||
#include <CGAL/Simple_cartesian.h>
|
||||
#include <CGAL/Algebraic_structure_traits.h>
|
||||
#include <CGAL/number_utils.h>
|
||||
#include <CGAL/tags.h>
|
||||
|
|
@ -44,34 +44,28 @@ namespace CGAL {
|
|||
* A model of the AosBasicTraits_2 concept that handles \f$x\f$-monotone
|
||||
* non-intersecting line segments.
|
||||
*/
|
||||
template <class T_Kernel>
|
||||
class Arr_non_caching_segment_basic_traits_2 : public T_Kernel
|
||||
{
|
||||
template <typename T_Kernel>
|
||||
class Arr_non_caching_segment_basic_traits_2 : public T_Kernel {
|
||||
public:
|
||||
|
||||
typedef T_Kernel Kernel;
|
||||
|
||||
typedef typename Kernel::FT FT;
|
||||
using Kernel = T_Kernel;
|
||||
using FT = typename Kernel::FT;
|
||||
|
||||
private:
|
||||
typedef Algebraic_structure_traits<FT> AST;
|
||||
typedef typename AST::Is_exact FT_is_exact;
|
||||
using AST = Algebraic_structure_traits<FT>;
|
||||
using FT_is_exact = typename AST::Is_exact;
|
||||
|
||||
public:
|
||||
|
||||
typedef Boolean_tag<FT_is_exact::value> Has_exact_division;
|
||||
|
||||
typedef
|
||||
CGAL::Segment_assertions<Arr_non_caching_segment_basic_traits_2<Kernel> >
|
||||
Segment_assertions;
|
||||
using Has_exact_division = Boolean_tag<FT_is_exact::value>;
|
||||
using Segment_assertions = CGAL::Segment_assertions<Arr_non_caching_segment_basic_traits_2<Kernel>>;
|
||||
|
||||
// Categories:
|
||||
typedef Tag_true Has_left_category;
|
||||
typedef Tag_false Has_do_intersect_category;
|
||||
using Has_left_category = Tag_true;
|
||||
using Has_do_intersect_category = Tag_false;
|
||||
|
||||
typedef Arr_oblivious_side_tag Left_side_category;
|
||||
typedef Arr_oblivious_side_tag Bottom_side_category;
|
||||
typedef Arr_oblivious_side_tag Top_side_category;
|
||||
typedef Arr_oblivious_side_tag Right_side_category;
|
||||
using Left_side_category = Arr_oblivious_side_tag;
|
||||
using Bottom_side_category = Arr_oblivious_side_tag;
|
||||
using Top_side_category = Arr_oblivious_side_tag;
|
||||
using Right_side_category = Arr_oblivious_side_tag;
|
||||
|
||||
/*! constructs default */
|
||||
Arr_non_caching_segment_basic_traits_2() {}
|
||||
|
|
@ -80,30 +74,30 @@ public:
|
|||
//@{
|
||||
|
||||
// Traits types:
|
||||
typedef typename Kernel::Point_2 Point_2;
|
||||
typedef typename Kernel::Segment_2 X_monotone_curve_2;
|
||||
typedef unsigned int Multiplicity;
|
||||
using Point_2 = typename Kernel::Point_2;
|
||||
using X_monotone_curve_2 = typename Kernel::Segment_2;
|
||||
using Multiplicity = std::size_t;
|
||||
|
||||
/*! Compare the \f$x\f$-coordinates of two points. */
|
||||
typedef typename Kernel::Compare_x_2 Compare_x_2;
|
||||
/*! compares the \f$x\f$-coordinates of two points. */
|
||||
using Compare_x_2 = typename Kernel::Compare_x_2;
|
||||
|
||||
/*! Compare two points lexigoraphically; by \f$x\f$, then by \f$y\f$. */
|
||||
typedef typename Kernel::Compare_xy_2 Compare_xy_2;
|
||||
/*! compares two points lexigoraphically; by \f$x\f$, then by \f$y\f$. */
|
||||
using Compare_xy_2 = typename Kernel::Compare_xy_2;
|
||||
|
||||
/*! Obtain the left endpoint of a given segment. */
|
||||
typedef typename Kernel::Construct_min_vertex_2 Construct_min_vertex_2;
|
||||
/*! obtains the left endpoint of a given segment. */
|
||||
using Construct_min_vertex_2 = typename Kernel::Construct_min_vertex_2;
|
||||
|
||||
/*! Obtain the right endpoint of a given segment. */
|
||||
typedef typename Kernel::Construct_max_vertex_2 Construct_max_vertex_2;
|
||||
/*! obtains the right endpoint of a given segment. */
|
||||
using Construct_max_vertex_2 = typename Kernel::Construct_max_vertex_2;
|
||||
|
||||
/*! Check whether a given segment is vertical. */
|
||||
typedef typename Kernel::Is_vertical_2 Is_vertical_2;
|
||||
/*! checks whether a given segment is vertical. */
|
||||
using Is_vertical_2 = typename Kernel::Is_vertical_2;
|
||||
|
||||
/*! Return the location of a given point with respect to an input segment. */
|
||||
typedef typename Kernel::Compare_y_at_x_2 Compare_y_at_x_2;
|
||||
/*! returns the location of a given point with respect to an input segment. */
|
||||
using Compare_y_at_x_2 = typename Kernel::Compare_y_at_x_2;
|
||||
|
||||
/*! Check if two segments or if two points are identical. */
|
||||
typedef typename Kernel::Equal_2 Equal_2;
|
||||
/*! checks if two segments or if two points are identical. */
|
||||
using Equal_2 = typename Kernel::Equal_2;
|
||||
|
||||
//@}
|
||||
|
||||
|
|
@ -127,8 +121,7 @@ public:
|
|||
*/
|
||||
Comparison_result operator()(const X_monotone_curve_2& cv1,
|
||||
const X_monotone_curve_2& cv2,
|
||||
const Point_2& CGAL_precondition_code(p)) const
|
||||
{
|
||||
const Point_2& CGAL_precondition_code(p)) const {
|
||||
Kernel kernel;
|
||||
|
||||
// The two segments must be defined at q and also to its left.
|
||||
|
|
@ -140,13 +133,13 @@ public:
|
|||
Compare_xy_2 compare_xy = kernel.compare_xy_2_object();
|
||||
typename Kernel::Construct_vertex_2 construct_vertex =
|
||||
kernel.construct_vertex_2_object();
|
||||
const Point_2 & source1 = construct_vertex(cv1, 0);
|
||||
const Point_2 & target1 = construct_vertex(cv1, 1);
|
||||
const Point_2 & left1 =
|
||||
const Point_2& source1 = construct_vertex(cv1, 0);
|
||||
const Point_2& target1 = construct_vertex(cv1, 1);
|
||||
const Point_2& left1 =
|
||||
(kernel.less_xy_2_object()(source1, target1)) ? source1 : target1;
|
||||
const Point_2 & source2 = construct_vertex(cv2, 0);
|
||||
const Point_2 & target2 = construct_vertex(cv2, 1);
|
||||
const Point_2 & left2 =
|
||||
const Point_2& source2 = construct_vertex(cv2, 0);
|
||||
const Point_2& target2 = construct_vertex(cv2, 1);
|
||||
const Point_2& left2 =
|
||||
(kernel.less_xy_2_object()(source2, target2)) ? source2 : target2;
|
||||
);
|
||||
|
||||
|
|
@ -181,10 +174,9 @@ public:
|
|||
* to the right of `p`: `SMALLER`, `LARGER`, or `EQUAL`.
|
||||
*/
|
||||
|
||||
Comparison_result operator()(const X_monotone_curve_2 & cv1,
|
||||
const X_monotone_curve_2 & cv2,
|
||||
const Point_2 & CGAL_precondition_code(p)) const
|
||||
{
|
||||
Comparison_result operator()(const X_monotone_curve_2& cv1,
|
||||
const X_monotone_curve_2& cv2,
|
||||
const Point_2& CGAL_precondition_code(p)) const {
|
||||
Kernel kernel;
|
||||
|
||||
// The two segments must be defined at q and also to its right.
|
||||
|
|
@ -196,13 +188,13 @@ public:
|
|||
Compare_xy_2 compare_xy = kernel.compare_xy_2_object();
|
||||
typename Kernel::Construct_vertex_2 construct_vertex =
|
||||
kernel.construct_vertex_2_object();
|
||||
const Point_2 & source1 = construct_vertex(cv1, 0);
|
||||
const Point_2 & target1 = construct_vertex(cv1, 1);
|
||||
const Point_2 & right1 =
|
||||
const Point_2& source1 = construct_vertex(cv1, 0);
|
||||
const Point_2& target1 = construct_vertex(cv1, 1);
|
||||
const Point_2& right1 =
|
||||
(kernel.less_xy_2_object()(source1, target1)) ? target1 : source1;
|
||||
const Point_2 & source2 = construct_vertex(cv2, 0);
|
||||
const Point_2 & target2 = construct_vertex(cv2, 1);
|
||||
const Point_2 & right2 =
|
||||
const Point_2& source2 = construct_vertex(cv2, 0);
|
||||
const Point_2& target2 = construct_vertex(cv2, 1);
|
||||
const Point_2& right2 =
|
||||
(kernel.less_xy_2_object()(source2, target2)) ? target2 : source2;
|
||||
);
|
||||
|
||||
|
|
@ -222,9 +214,9 @@ public:
|
|||
|
||||
/// \name Functor definitions for the landmarks point-location strategy.
|
||||
//@{
|
||||
typedef double Approximate_number_type;
|
||||
typedef CGAL::Cartesian<Approximate_number_type> Approximate_kernel;
|
||||
typedef Approximate_kernel::Point_2 Approximate_point_2;
|
||||
using Approximate_number_type = double;
|
||||
using Approximate_kernel = CGAL::Simple_cartesian<Approximate_number_type>;
|
||||
using Approximate_point_2 = Approximate_kernel::Point_2;
|
||||
|
||||
class Approximate_2 {
|
||||
protected:
|
||||
|
|
@ -267,12 +259,8 @@ public:
|
|||
auto max_vertex = m_traits.construct_max_vertex_2_object();
|
||||
const auto& src = (l2r) ? min_vertex(xcv) : max_vertex(xcv);
|
||||
const auto& trg = (l2r) ? max_vertex(xcv) : min_vertex(xcv);
|
||||
auto xs = CGAL::to_double(src.x());
|
||||
auto ys = CGAL::to_double(src.y());
|
||||
auto xt = CGAL::to_double(trg.x());
|
||||
auto yt = CGAL::to_double(trg.y());
|
||||
*oi++ = Approximate_point_2(xs, ys);
|
||||
*oi++ = Approximate_point_2(xt, yt);
|
||||
*oi++ = operator()(src);
|
||||
*oi++ = operator()(trg);
|
||||
return oi;
|
||||
}
|
||||
};
|
||||
|
|
@ -280,7 +268,7 @@ public:
|
|||
/*! obtains an Approximate_2 functor object. */
|
||||
Approximate_2 approximate_2_object () const { return Approximate_2(*this); }
|
||||
|
||||
typedef typename Kernel::Construct_segment_2 Construct_x_monotone_curve_2;
|
||||
using Construct_x_monotone_curve_2 = typename Kernel::Construct_segment_2;
|
||||
|
||||
/*! obtains a `Construct_x_monotone_curve_2` functor object. */
|
||||
Construct_x_monotone_curve_2 construct_x_monotone_curve_2_object () const
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
||||
//
|
||||
//
|
||||
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||
// Efi Fogel <efifogel@gmail.com>
|
||||
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||
// Efi Fogel <efifogel@gmail.com>
|
||||
|
||||
#ifndef CGAL_ARR_OVERLAY_2_H
|
||||
#define CGAL_ARR_OVERLAY_2_H
|
||||
|
|
@ -40,24 +40,18 @@
|
|||
namespace CGAL {
|
||||
|
||||
template <typename Arr1, typename Arr2, typename Curve>
|
||||
class Indexed_sweep_accessor
|
||||
{
|
||||
const Arr1& arr1;
|
||||
const Arr2& arr2;
|
||||
mutable std::vector<void*> backup_inc;
|
||||
class Indexed_sweep_accessor {
|
||||
private:
|
||||
const Arr1& m_arr1;
|
||||
const Arr2& m_arr2;
|
||||
mutable std::vector<void*> m_backup_inc;
|
||||
|
||||
public:
|
||||
Indexed_sweep_accessor(const Arr1& arr1, const Arr2& arr2) : m_arr1(arr1), m_arr2(arr2) {}
|
||||
|
||||
Indexed_sweep_accessor (const Arr1& arr1, const Arr2& arr2)
|
||||
: arr1(arr1), arr2(arr2) { }
|
||||
std::size_t nb_vertices() const { return m_arr1.number_of_vertices() + m_arr2.number_of_vertices(); }
|
||||
|
||||
std::size_t nb_vertices() const
|
||||
{
|
||||
return arr1.number_of_vertices() + arr2.number_of_vertices();
|
||||
}
|
||||
|
||||
std::size_t min_end_index (const Curve& c) const
|
||||
{
|
||||
std::size_t min_end_index(const Curve& c) const {
|
||||
if (c.red_halfedge_handle() != typename Curve::HH_red())
|
||||
return reinterpret_cast<std::size_t>(c.red_halfedge_handle()->target()->inc());
|
||||
// else
|
||||
|
|
@ -65,8 +59,7 @@ public:
|
|||
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())
|
||||
return reinterpret_cast<std::size_t>(c.red_halfedge_handle()->source()->inc());
|
||||
// else
|
||||
|
|
@ -74,52 +67,36 @@ public:
|
|||
return reinterpret_cast<std::size_t>(c.blue_halfedge_handle()->source()->inc());
|
||||
}
|
||||
|
||||
const Curve& curve (const Curve& c) const
|
||||
{
|
||||
return c;
|
||||
}
|
||||
const Curve& curve(const Curve& c) const { return c; }
|
||||
|
||||
// Initializes indices by squatting Vertex::inc();
|
||||
void before_init() const
|
||||
{
|
||||
void before_init() const {
|
||||
std::size_t idx = 0;
|
||||
backup_inc.resize (nb_vertices());
|
||||
for (typename Arr1::Vertex_const_iterator vit = arr1.vertices_begin();
|
||||
vit != arr1.vertices_end(); ++vit, ++idx)
|
||||
{
|
||||
CGAL_assertion (idx < backup_inc.size());
|
||||
backup_inc[idx] = vit->inc();
|
||||
vit->set_inc (reinterpret_cast<void*>(idx));
|
||||
m_backup_inc.resize (nb_vertices());
|
||||
for (auto vit = m_arr1.vertices_begin(); vit != m_arr1.vertices_end(); ++vit, ++idx) {
|
||||
CGAL_assertion(idx < m_backup_inc.size());
|
||||
m_backup_inc[idx] = vit->inc();
|
||||
vit->set_inc(reinterpret_cast<void*>(idx));
|
||||
}
|
||||
for (typename Arr2::Vertex_const_iterator vit = arr2.vertices_begin();
|
||||
vit != arr2.vertices_end(); ++vit, ++idx)
|
||||
{
|
||||
CGAL_assertion (idx < backup_inc.size());
|
||||
backup_inc[idx] = vit->inc();
|
||||
vit->set_inc (reinterpret_cast<void*>(idx));
|
||||
for (auto vit = m_arr2.vertices_begin(); vit != m_arr2.vertices_end(); ++vit, ++idx) {
|
||||
CGAL_assertion(idx < m_backup_inc.size());
|
||||
m_backup_inc[idx] = vit->inc();
|
||||
vit->set_inc(reinterpret_cast<void*>(idx));
|
||||
}
|
||||
}
|
||||
|
||||
// Restores state of arrangements before index squatting
|
||||
void after_init() const
|
||||
{
|
||||
void after_init() const {
|
||||
std::size_t idx = 0;
|
||||
for (typename Arr1::Vertex_const_iterator vit = arr1.vertices_begin();
|
||||
vit != arr1.vertices_end(); ++vit, ++idx)
|
||||
{
|
||||
CGAL_assertion (idx < backup_inc.size());
|
||||
vit->set_inc (backup_inc[idx]);
|
||||
for (auto vit = m_arr1.vertices_begin(); vit != m_arr1.vertices_end(); ++vit, ++idx) {
|
||||
CGAL_assertion(idx < m_backup_inc.size());
|
||||
vit->set_inc(m_backup_inc[idx]);
|
||||
}
|
||||
for (typename Arr2::Vertex_const_iterator vit = arr2.vertices_begin();
|
||||
vit != arr2.vertices_end(); ++vit, ++idx)
|
||||
{
|
||||
CGAL_assertion (idx < backup_inc.size());
|
||||
vit->set_inc (backup_inc[idx]);
|
||||
for (auto vit = m_arr2.vertices_begin(); vit != m_arr2.vertices_end(); ++vit, ++idx) {
|
||||
CGAL_assertion(idx < m_backup_inc.size());
|
||||
vit->set_inc(m_backup_inc[idx]);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
/*! Compute the overlay of two input arrangements.
|
||||
|
|
@ -148,64 +125,55 @@ template <typename GeometryTraitsA_2,
|
|||
typename TopologyTraitsB,
|
||||
typename TopologyTraitsRes,
|
||||
typename OverlayTraits>
|
||||
void
|
||||
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)
|
||||
{
|
||||
typedef GeometryTraitsA_2 Agt2;
|
||||
typedef GeometryTraitsB_2 Bgt2;
|
||||
typedef GeometryTraitsRes_2 Rgt2;
|
||||
typedef TopologyTraitsA Att;
|
||||
typedef TopologyTraitsB Btt;
|
||||
typedef TopologyTraitsRes Rtt;
|
||||
typedef OverlayTraits Overlay_traits;
|
||||
void overlay(const Arrangement_on_surface_2<GeometryTraitsA_2, TopologyTraitsA>& arr1,
|
||||
const Arrangement_on_surface_2<GeometryTraitsB_2, TopologyTraitsB>& arr2,
|
||||
Arrangement_on_surface_2<GeometryTraitsRes_2, TopologyTraitsRes>& arr,
|
||||
OverlayTraits& ovl_tr) {
|
||||
using Agt2 = GeometryTraitsA_2;
|
||||
using Bgt2 = GeometryTraitsB_2;
|
||||
using Rgt2 = GeometryTraitsRes_2;
|
||||
using Att = TopologyTraitsA;
|
||||
using Btt = TopologyTraitsB;
|
||||
using Rtt = TopologyTraitsRes;
|
||||
using Overlay_traits = OverlayTraits;
|
||||
|
||||
typedef Arrangement_on_surface_2<Agt2, Att> Arr_a;
|
||||
typedef Arrangement_on_surface_2<Bgt2, Btt> Arr_b;
|
||||
typedef Arrangement_on_surface_2<Rgt2, Rtt> Arr_res;
|
||||
typedef typename Arr_res::Allocator Allocator;
|
||||
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).
|
||||
typedef typename Agt2::Point_2 A_point;
|
||||
typedef typename Bgt2::Point_2 B_point;
|
||||
typedef typename Rgt2::Point_2 Res_point;
|
||||
using A_point = typename Agt2::Point_2;
|
||||
using B_point = typename Bgt2::Point_2;
|
||||
using Res_point = typename Rgt2::Point_2;
|
||||
static_assert(std::is_convertible<A_point, Res_point>::value);
|
||||
static_assert(std::is_convertible<B_point, Res_point>::value);
|
||||
|
||||
typedef typename Agt2::X_monotone_curve_2 A_xcv;
|
||||
typedef typename Bgt2::X_monotone_curve_2 B_xcv;
|
||||
typedef typename Rgt2::X_monotone_curve_2 Res_xcv;
|
||||
using A_xcv = typename Agt2::X_monotone_curve_2;
|
||||
using B_xcv = typename Bgt2::X_monotone_curve_2;
|
||||
using Res_xcv = typename Rgt2::X_monotone_curve_2;
|
||||
static_assert(std::is_convertible<A_xcv, Res_xcv>::value);
|
||||
static_assert(std::is_convertible<B_xcv, Res_xcv>::value);
|
||||
|
||||
typedef Arr_traits_basic_adaptor_2<Rgt2> Gt_adaptor_2;
|
||||
typedef Arr_overlay_traits_2<Gt_adaptor_2, Arr_a, Arr_b>
|
||||
Ovl_gt2;
|
||||
typedef Arr_overlay_event<Ovl_gt2, Arr_res, Allocator>
|
||||
Ovl_event;
|
||||
typedef Arr_overlay_subcurve<Ovl_gt2, Ovl_event, Allocator>
|
||||
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;
|
||||
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 Ovl_visitor = Arr_overlay_ss_visitor<Ovl_helper, Overlay_traits>;
|
||||
|
||||
typedef typename Ovl_gt2::X_monotone_curve_2 Ovl_x_monotone_curve_2;
|
||||
typedef typename Ovl_gt2::Point_2 Ovl_point_2;
|
||||
typedef typename Ovl_gt2::Cell_handle_red Cell_handle_red;
|
||||
typedef typename Ovl_gt2::Optional_cell_red Optional_cell_red;
|
||||
typedef typename Ovl_gt2::Cell_handle_blue Cell_handle_blue;
|
||||
typedef typename Ovl_gt2::Optional_cell_blue Optional_cell_blue;
|
||||
using Ovl_x_monotone_curve_2 = typename Ovl_gt2::X_monotone_curve_2;
|
||||
using Ovl_point_2 = typename Ovl_gt2::Point_2;
|
||||
using Cell_handle_red = typename Ovl_gt2::Cell_handle_red;
|
||||
using Optional_cell_red = typename Ovl_gt2::Optional_cell_red;
|
||||
using Cell_handle_blue = typename Ovl_gt2::Cell_handle_blue;
|
||||
using Optional_cell_blue = typename Ovl_gt2::Optional_cell_blue;
|
||||
|
||||
CGAL_USE_TYPE(Optional_cell_red);
|
||||
CGAL_USE_TYPE(Optional_cell_blue);
|
||||
|
||||
// The result arrangement cannot be on of the input arrangements.
|
||||
CGAL_precondition(((void*)(&arr) != (void*)(&arr1)) &&
|
||||
((void*)(&arr) != (void*)(&arr2)));
|
||||
CGAL_precondition(((void*)(&arr) != (void*)(&arr1)) && ((void*)(&arr) != (void*)(&arr2)));
|
||||
|
||||
// Prepare a vector of extended x-monotone curves that represent all edges
|
||||
// in both input arrangements. Each curve is associated with a halfedge
|
||||
|
|
@ -216,23 +184,20 @@ overlay(const Arrangement_on_surface_2<GeometryTraitsA_2, TopologyTraitsA>& arr1
|
|||
xcvs_vec(arr1.number_of_edges() + arr2.number_of_edges());
|
||||
unsigned int i = 0;
|
||||
|
||||
typename Arr_a::Edge_const_iterator eit1;
|
||||
for (eit1 = arr1.edges_begin(); eit1 != arr1.edges_end(); ++eit1, ++i) {
|
||||
for (auto eit1 = arr1.edges_begin(); eit1 != arr1.edges_end(); ++eit1, ++i) {
|
||||
typename Arr_a::Halfedge_const_handle he1 = eit1;
|
||||
if (he1->direction() != ARR_RIGHT_TO_LEFT) he1 = he1->twin();
|
||||
xcvs_vec[i] = Ovl_x_monotone_curve_2(eit1->curve(), he1, invalid_he2);
|
||||
}
|
||||
|
||||
typename Arr_b::Edge_const_iterator eit2;
|
||||
for (eit2 = arr2.edges_begin(); eit2 != arr2.edges_end(); ++eit2, ++i) {
|
||||
for (auto eit2 = arr2.edges_begin(); eit2 != arr2.edges_end(); ++eit2, ++i) {
|
||||
typename Arr_b::Halfedge_const_handle he2 = eit2;
|
||||
if (he2->direction() != ARR_RIGHT_TO_LEFT) he2 = he2->twin();
|
||||
xcvs_vec[i] = Ovl_x_monotone_curve_2(eit2->curve(), invalid_he1, he2);
|
||||
}
|
||||
|
||||
// Obtain an extended traits-class object and define the sweep-line visitor.
|
||||
const typename Arr_res::Traits_adaptor_2* traits_adaptor =
|
||||
arr.traits_adaptor();
|
||||
const typename Arr_res::Traits_adaptor_2* traits_adaptor = arr.traits_adaptor();
|
||||
|
||||
/* We would like to avoid copy construction of the geometry traits class.
|
||||
* Copy construction is undesired, because it may results with data
|
||||
|
|
@ -246,29 +211,22 @@ overlay(const Arrangement_on_surface_2<GeometryTraitsA_2, TopologyTraitsA>& arr1
|
|||
* Use the form 'A a(*b);' and not ''A a = b;' to handle the case where A has
|
||||
* only an implicit constructor, (which takes *b as a parameter).
|
||||
*/
|
||||
std::conditional_t<std::is_same_v<Gt_adaptor_2, Ovl_gt2>,
|
||||
const Ovl_gt2&, Ovl_gt2>
|
||||
ex_traits(*traits_adaptor);
|
||||
std::conditional_t<std::is_same_v<Gt_adaptor_2, Ovl_gt2>, const Ovl_gt2&, Ovl_gt2> ex_traits(*traits_adaptor);
|
||||
|
||||
Ovl_visitor visitor(&arr1, &arr2, &arr, &ovl_tr);
|
||||
Ss2::Surface_sweep_2<Ovl_visitor> surface_sweep(&ex_traits, &visitor);
|
||||
|
||||
// In case both arrangement do not contain isolated vertices, go on and
|
||||
// overlay them.
|
||||
const std::size_t total_iso_verts =
|
||||
arr1.number_of_isolated_vertices() + arr2.number_of_isolated_vertices();
|
||||
const std::size_t total_iso_verts = arr1.number_of_isolated_vertices() + arr2.number_of_isolated_vertices();
|
||||
|
||||
if (total_iso_verts == 0) {
|
||||
// Clear the result arrangement and perform the sweep to construct it.
|
||||
arr.clear();
|
||||
if (std::is_same<typename Agt2::Bottom_side_category,
|
||||
Arr_contracted_side_tag>::value)
|
||||
surface_sweep.sweep (xcvs_vec.begin(), xcvs_vec.end());
|
||||
if (std::is_same<typename Agt2::Bottom_side_category, Arr_contracted_side_tag>::value)
|
||||
surface_sweep.sweep(xcvs_vec.begin(), xcvs_vec.end());
|
||||
else
|
||||
surface_sweep.indexed_sweep (xcvs_vec,
|
||||
Indexed_sweep_accessor
|
||||
<Arr_a, Arr_b, Ovl_x_monotone_curve_2>
|
||||
(arr1, arr2));
|
||||
surface_sweep.indexed_sweep(xcvs_vec, Indexed_sweep_accessor<Arr_a, Arr_b, Ovl_x_monotone_curve_2>(arr1, arr2));
|
||||
xcvs_vec.clear();
|
||||
return;
|
||||
}
|
||||
|
|
@ -278,38 +236,29 @@ overlay(const Arrangement_on_surface_2<GeometryTraitsA_2, TopologyTraitsA>& arr1
|
|||
std::vector<Ovl_point_2> pts_vec(total_iso_verts);
|
||||
|
||||
i = 0;
|
||||
typename Arr_a::Vertex_const_iterator vit1;
|
||||
for (vit1 = arr1.vertices_begin(); vit1 != arr1.vertices_end(); ++vit1) {
|
||||
for (auto vit1 = arr1.vertices_begin(); vit1 != arr1.vertices_end(); ++vit1) {
|
||||
if (vit1->is_isolated()) {
|
||||
typename Arr_a::Vertex_const_handle v1 = vit1;
|
||||
pts_vec[i++] =
|
||||
Ovl_point_2(vit1->point(), std::make_optional(Cell_handle_red(v1)),
|
||||
std::optional<Cell_handle_blue>());
|
||||
pts_vec[i++] = Ovl_point_2(vit1->point(), std::make_optional(Cell_handle_red(v1)),
|
||||
std::optional<Cell_handle_blue>());
|
||||
}
|
||||
}
|
||||
|
||||
typename Arr_b::Vertex_const_iterator vit2;
|
||||
for (vit2 = arr2.vertices_begin(); vit2 != arr2.vertices_end(); ++vit2) {
|
||||
for (auto vit2 = arr2.vertices_begin(); vit2 != arr2.vertices_end(); ++vit2) {
|
||||
if (vit2->is_isolated()) {
|
||||
typename Arr_b::Vertex_const_handle v2 = vit2;
|
||||
pts_vec[i++] =
|
||||
Ovl_point_2(vit2->point(), std::optional<Cell_handle_red>(),
|
||||
std::make_optional(Cell_handle_blue(v2)));
|
||||
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_vec.begin(), xcvs_vec.end(),
|
||||
pts_vec.begin(), pts_vec.end());
|
||||
if (std::is_same<typename Agt2::Bottom_side_category, Arr_contracted_side_tag>::value)
|
||||
surface_sweep.sweep(xcvs_vec.begin(), xcvs_vec.end(), pts_vec.begin(), pts_vec.end());
|
||||
else
|
||||
surface_sweep.indexed_sweep (xcvs_vec,
|
||||
Indexed_sweep_accessor
|
||||
<Arr_a, Arr_b, Ovl_x_monotone_curve_2>
|
||||
(arr1, arr2),
|
||||
pts_vec.begin(), pts_vec.end());
|
||||
surface_sweep.indexed_sweep(xcvs_vec, Indexed_sweep_accessor<Arr_a, Arr_b, Ovl_x_monotone_curve_2>(arr1, arr2),
|
||||
pts_vec.begin(), pts_vec.end());
|
||||
xcvs_vec.clear();
|
||||
pts_vec.clear();
|
||||
}
|
||||
|
|
@ -325,20 +274,18 @@ template <typename GeometryTraitsA_2,
|
|||
typename TopologyTraitsA,
|
||||
typename TopologyTraitsB,
|
||||
typename TopologyTraitsRes>
|
||||
void
|
||||
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)
|
||||
{
|
||||
typedef GeometryTraitsA_2 Agt2;
|
||||
typedef GeometryTraitsB_2 Bgt2;
|
||||
typedef GeometryTraitsRes_2 Rgt2;
|
||||
typedef TopologyTraitsA Att;
|
||||
typedef TopologyTraitsB Btt;
|
||||
typedef TopologyTraitsRes Rtt;
|
||||
typedef Arrangement_on_surface_2<Agt2, Att> Arr_a;
|
||||
typedef Arrangement_on_surface_2<Bgt2, Btt> Arr_b;
|
||||
typedef Arrangement_on_surface_2<Rgt2, Rtt> Arr_res;
|
||||
void 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;
|
||||
overlay(arr1, arr2, arr, ovl_traits);
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
#include <variant>
|
||||
|
||||
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
||||
#include <CGAL/Cartesian.h>
|
||||
#include <CGAL/Simple_cartesian.h>
|
||||
#include <CGAL/tags.h>
|
||||
#include <CGAL/intersections.h>
|
||||
#include <CGAL/Arr_tags.h>
|
||||
|
|
@ -52,35 +52,32 @@ class Arr_segment_2;
|
|||
template <typename Kernel_ = Exact_predicates_exact_constructions_kernel>
|
||||
class Arr_segment_traits_2 : public Kernel_ {
|
||||
friend class Arr_segment_2<Kernel_>;
|
||||
|
||||
public:
|
||||
typedef Kernel_ Kernel;
|
||||
typedef typename Kernel::FT FT;
|
||||
using Kernel = Kernel_;
|
||||
using FT = typename Kernel::FT;
|
||||
|
||||
typedef typename Algebraic_structure_traits<FT>::Is_exact
|
||||
Has_exact_division;
|
||||
using Has_exact_division = typename Algebraic_structure_traits<FT>::Is_exact;
|
||||
|
||||
// Category tags:
|
||||
typedef Tag_true Has_left_category;
|
||||
typedef Tag_true Has_merge_category;
|
||||
typedef Tag_false Has_do_intersect_category;
|
||||
using Has_left_category = Tag_true;
|
||||
using Has_merge_category = Tag_true;
|
||||
using Has_do_intersect_category = Tag_false;
|
||||
|
||||
typedef Arr_oblivious_side_tag Left_side_category;
|
||||
typedef Arr_oblivious_side_tag Bottom_side_category;
|
||||
typedef Arr_oblivious_side_tag Top_side_category;
|
||||
typedef Arr_oblivious_side_tag Right_side_category;
|
||||
using Left_side_category = Arr_oblivious_side_tag;
|
||||
using Bottom_side_category = Arr_oblivious_side_tag;
|
||||
using Top_side_category = Arr_oblivious_side_tag;
|
||||
using Right_side_category = Arr_oblivious_side_tag;
|
||||
|
||||
typedef typename Kernel::Line_2 Line_2;
|
||||
typedef CGAL::Segment_assertions<Arr_segment_traits_2<Kernel> >
|
||||
Segment_assertions;
|
||||
using Line_2 = typename Kernel::Line_2;
|
||||
using Segment_assertions = CGAL::Segment_assertions<Arr_segment_traits_2<Kernel>>;
|
||||
|
||||
/*! \class Representation of a segment with cached data.
|
||||
*/
|
||||
class _Segment_cached_2 {
|
||||
public:
|
||||
typedef typename Kernel::Line_2 Line_2;
|
||||
typedef typename Kernel::Segment_2 Segment_2;
|
||||
typedef typename Kernel::Point_2 Point_2;
|
||||
using Line_2 = typename Kernel::Line_2;
|
||||
using Segment_2 = typename Kernel::Segment_2;
|
||||
using Point_2 = typename Kernel::Point_2;
|
||||
|
||||
protected:
|
||||
mutable Line_2 m_l; // the line that supports the segment.
|
||||
|
|
@ -228,10 +225,10 @@ public:
|
|||
|
||||
public:
|
||||
// Traits objects
|
||||
typedef typename Kernel::Point_2 Point_2;
|
||||
typedef Arr_segment_2<Kernel> X_monotone_curve_2;
|
||||
typedef Arr_segment_2<Kernel> Curve_2;
|
||||
typedef unsigned int Multiplicity;
|
||||
using Point_2 = typename Kernel::Point_2;
|
||||
using X_monotone_curve_2 = Arr_segment_2<Kernel>;
|
||||
using Curve_2 = Arr_segment_2<Kernel>;
|
||||
using Multiplicity = std::size_t;
|
||||
|
||||
public:
|
||||
/*! constructs default. */
|
||||
|
|
@ -242,7 +239,7 @@ public:
|
|||
|
||||
class Compare_x_2 {
|
||||
protected:
|
||||
typedef Arr_segment_traits_2<Kernel> Traits;
|
||||
using Traits = Arr_segment_traits_2<Kernel>;
|
||||
|
||||
//! The traits (in case it has state).
|
||||
const Traits& m_traits;
|
||||
|
|
@ -262,8 +259,7 @@ public:
|
|||
* `SMALLER` if x(p1) < x(p2);
|
||||
* `EQUAL` if x(p1) = x(p2).
|
||||
*/
|
||||
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 Kernel& kernel = m_traits;
|
||||
return (kernel.compare_x_2_object()(p1, p2));
|
||||
}
|
||||
|
|
@ -274,7 +270,7 @@ public:
|
|||
|
||||
class Compare_xy_2 {
|
||||
protected:
|
||||
typedef Arr_segment_traits_2<Kernel> Traits;
|
||||
using Traits = Arr_segment_traits_2<Kernel>;
|
||||
|
||||
/*! The traits (in case it has state) */
|
||||
const Traits& m_traits;
|
||||
|
|
@ -294,8 +290,7 @@ public:
|
|||
* SMALLER if x(p1) < x(p2), or if x(p1) = x(p2) and y(p1) < y(p2);
|
||||
* EQUAL if the two points are equal.
|
||||
*/
|
||||
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 Kernel& kernel = m_traits;
|
||||
return (kernel.compare_xy_2_object()(p1, p2));
|
||||
}
|
||||
|
|
@ -347,7 +342,7 @@ public:
|
|||
|
||||
class Compare_y_at_x_2 {
|
||||
protected:
|
||||
typedef Arr_segment_traits_2<Kernel> Traits;
|
||||
using Traits = Arr_segment_traits_2<Kernel>;
|
||||
|
||||
/*! The traits (in case it has state) */
|
||||
const Traits& m_traits;
|
||||
|
|
@ -369,8 +364,7 @@ public:
|
|||
* `EQUAL` if `p` lies on the curve.
|
||||
*/
|
||||
Comparison_result operator()(const Point_2& p,
|
||||
const X_monotone_curve_2& cv) const
|
||||
{
|
||||
const X_monotone_curve_2& cv) const {
|
||||
CGAL_precondition(m_traits.is_in_x_range_2_object()(cv, p));
|
||||
|
||||
const Kernel& kernel = m_traits;
|
||||
|
|
@ -396,7 +390,7 @@ public:
|
|||
|
||||
class Compare_y_at_x_left_2 {
|
||||
protected:
|
||||
typedef Arr_segment_traits_2<Kernel> Traits;
|
||||
using Traits = Arr_segment_traits_2<Kernel>;
|
||||
|
||||
/*! The traits (in case it has state) */
|
||||
const Traits& m_traits;
|
||||
|
|
@ -421,8 +415,7 @@ public:
|
|||
*/
|
||||
Comparison_result operator()(const X_monotone_curve_2& cv1,
|
||||
const X_monotone_curve_2& cv2,
|
||||
const Point_2& CGAL_assertion_code(p)) const
|
||||
{
|
||||
const Point_2& CGAL_assertion_code(p)) const {
|
||||
const Kernel& kernel = m_traits;
|
||||
|
||||
// Make sure that p lies on both curves, and that both are defined to its
|
||||
|
|
@ -450,7 +443,7 @@ public:
|
|||
|
||||
class Compare_y_at_x_right_2 {
|
||||
protected:
|
||||
typedef Arr_segment_traits_2<Kernel> Traits;
|
||||
using Traits = Arr_segment_traits_2<Kernel>;
|
||||
|
||||
/*! The traits (in case it has state) */
|
||||
const Traits& m_traits;
|
||||
|
|
@ -475,8 +468,7 @@ public:
|
|||
*/
|
||||
Comparison_result operator()(const X_monotone_curve_2& cv1,
|
||||
const X_monotone_curve_2& cv2,
|
||||
const Point_2& CGAL_assertion_code(p)) const
|
||||
{
|
||||
const Point_2& CGAL_assertion_code(p)) const {
|
||||
const Kernel& kernel = m_traits;
|
||||
|
||||
// Make sure that p lies on both curves, and that both are defined to its
|
||||
|
|
@ -502,7 +494,7 @@ public:
|
|||
|
||||
class Equal_2 {
|
||||
protected:
|
||||
typedef Arr_segment_traits_2<Kernel> Traits;
|
||||
using Traits = Arr_segment_traits_2<Kernel>;
|
||||
|
||||
/*! The traits (in case it has state) */
|
||||
const Traits& m_traits;
|
||||
|
|
@ -522,8 +514,7 @@ public:
|
|||
* \return (true) if the two curves are the same; (false) otherwise.
|
||||
*/
|
||||
bool operator()(const X_monotone_curve_2& cv1,
|
||||
const X_monotone_curve_2& cv2) const
|
||||
{
|
||||
const X_monotone_curve_2& cv2) const {
|
||||
const Kernel& kernel = m_traits;
|
||||
typename Kernel::Equal_2 equal = kernel.equal_2_object();
|
||||
|
||||
|
|
@ -536,8 +527,7 @@ public:
|
|||
* \param p2 the second point.
|
||||
* \return (true) if the two point are the same; (false) otherwise.
|
||||
*/
|
||||
bool operator()(const Point_2& p1, const Point_2& p2) const
|
||||
{
|
||||
bool operator()(const Point_2& p1, const Point_2& p2) const {
|
||||
const Kernel& kernel = m_traits;
|
||||
return (kernel.equal_2_object()(p1, p2));
|
||||
}
|
||||
|
|
@ -566,11 +556,9 @@ public:
|
|||
* \return the past-the-end output iterator.
|
||||
*/
|
||||
template <typename OutputIterator>
|
||||
OutputIterator operator()(const Curve_2& cv, OutputIterator oi) const
|
||||
{
|
||||
OutputIterator operator()(const Curve_2& cv, OutputIterator oi) const {
|
||||
// Wrap the segment with a variant.
|
||||
typedef std::variant<Point_2, X_monotone_curve_2>
|
||||
Make_x_monotone_result;
|
||||
using Make_x_monotone_result = std::variant<Point_2, X_monotone_curve_2>;
|
||||
*oi++ = Make_x_monotone_result(cv);
|
||||
return oi;
|
||||
}
|
||||
|
|
@ -582,7 +570,7 @@ public:
|
|||
|
||||
class Split_2 {
|
||||
protected:
|
||||
typedef Arr_segment_traits_2<Kernel> Traits;
|
||||
using Traits = Arr_segment_traits_2<Kernel>;
|
||||
|
||||
/*! The traits (in case it has state) */
|
||||
const Traits& m_traits;
|
||||
|
|
@ -595,7 +583,7 @@ public:
|
|||
friend class Arr_segment_traits_2<Kernel>;
|
||||
|
||||
public:
|
||||
/*! split a given \f$x\f$-monotone curve at a given point into two
|
||||
/*! splits a given \f$x\f$-monotone curve at a given point into two
|
||||
* sub-curves.
|
||||
* \param cv the curve to split
|
||||
* \param p the split point.
|
||||
|
|
@ -604,8 +592,7 @@ public:
|
|||
* \pre `p` lies on cv but is not one of its endpoints.
|
||||
*/
|
||||
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 {
|
||||
// Make sure that p lies on the interior of the curve.
|
||||
CGAL_precondition_code(const Kernel& kernel = m_traits;
|
||||
auto compare_xy = kernel.compare_xy_2_object());
|
||||
|
|
@ -628,7 +615,7 @@ public:
|
|||
|
||||
class Intersect_2 {
|
||||
protected:
|
||||
typedef Arr_segment_traits_2<Kernel> Traits;
|
||||
using Traits = Arr_segment_traits_2<Kernel>;
|
||||
|
||||
/*! The traits (in case it has state) */
|
||||
const Traits& m_traits;
|
||||
|
|
@ -644,8 +631,7 @@ public:
|
|||
// this point, we already know which point is left / right for
|
||||
// both segments
|
||||
bool do_intersect(const Point_2& A1, const Point_2& A2,
|
||||
const Point_2& B1, const Point_2& B2) const
|
||||
{
|
||||
const Point_2& B1, const Point_2& B2) const {
|
||||
const Kernel& kernel = m_traits;
|
||||
auto compare_xy = kernel.compare_xy_2_object();
|
||||
namespace interx = CGAL::Intersections::internal;
|
||||
|
|
@ -686,8 +672,7 @@ public:
|
|||
/*! determines whether the bounding boxes of two segments overlap
|
||||
*/
|
||||
bool do_bboxes_overlap(const X_monotone_curve_2& cv1,
|
||||
const X_monotone_curve_2& cv2) const
|
||||
{
|
||||
const X_monotone_curve_2& cv2) const {
|
||||
const Kernel& kernel = m_traits;
|
||||
auto construct_bbox = kernel.construct_bbox_2_object();
|
||||
auto bbox1 = construct_bbox(cv1.source()) + construct_bbox(cv1.target());
|
||||
|
|
@ -707,9 +692,8 @@ public:
|
|||
template <typename OutputIterator>
|
||||
OutputIterator operator()(const X_monotone_curve_2& cv1,
|
||||
const X_monotone_curve_2& cv2,
|
||||
OutputIterator oi) const
|
||||
{
|
||||
typedef std::pair<Point_2, Multiplicity> Intersection_point;
|
||||
OutputIterator oi) const {
|
||||
using Intersection_point = std::pair<Point_2, Multiplicity>;
|
||||
|
||||
// Early ending with Bbox overlapping test
|
||||
if (! do_bboxes_overlap(cv1, cv2)) return oi;
|
||||
|
|
@ -787,7 +771,7 @@ public:
|
|||
|
||||
class Are_mergeable_2 {
|
||||
protected:
|
||||
typedef Arr_segment_traits_2<Kernel> Traits;
|
||||
using Traits = Arr_segment_traits_2<Kernel>;
|
||||
|
||||
/*! The traits (in case it has state) */
|
||||
const Traits& m_traits;
|
||||
|
|
@ -808,8 +792,7 @@ public:
|
|||
* \pre `cv1` and `cv2` share a common endpoint.
|
||||
*/
|
||||
bool operator()(const X_monotone_curve_2& cv1,
|
||||
const X_monotone_curve_2& cv2) const
|
||||
{
|
||||
const X_monotone_curve_2& cv2) const {
|
||||
const Kernel& kernel = m_traits;
|
||||
typename Kernel::Equal_2 equal = kernel.equal_2_object();
|
||||
if (! equal(cv1.right(), cv2.left()) &&
|
||||
|
|
@ -832,7 +815,7 @@ public:
|
|||
*/
|
||||
class Merge_2 {
|
||||
protected:
|
||||
typedef Arr_segment_traits_2<Kernel> Traits;
|
||||
using Traits = Arr_segment_traits_2<Kernel>;
|
||||
|
||||
/*! The traits (in case it has state) */
|
||||
const Traits& m_traits;
|
||||
|
|
@ -853,14 +836,13 @@ public:
|
|||
*/
|
||||
void operator()(const X_monotone_curve_2& cv1,
|
||||
const X_monotone_curve_2& cv2,
|
||||
X_monotone_curve_2& c) const
|
||||
{
|
||||
X_monotone_curve_2& c) const {
|
||||
CGAL_precondition(m_traits.are_mergeable_2_object()(cv1, cv2));
|
||||
|
||||
const Kernel& kernel = m_traits;
|
||||
auto equal = kernel.equal_2_object();
|
||||
|
||||
// Check which curve extends to the right of the other.
|
||||
// checks which curve extends to the right of the other.
|
||||
if (equal(cv1.right(), cv2.left())) {
|
||||
// cv2 extends cv1 to the right.
|
||||
c = cv1;
|
||||
|
|
@ -882,9 +864,9 @@ public:
|
|||
|
||||
/// \name Functor definitions for the landmarks point-location strategy.
|
||||
//@{
|
||||
typedef double Approximate_number_type;
|
||||
typedef CGAL::Cartesian<Approximate_number_type> Approximate_kernel;
|
||||
typedef Approximate_kernel::Point_2 Approximate_point_2;
|
||||
using Approximate_number_type = double;
|
||||
using Approximate_kernel = CGAL::Simple_cartesian<Approximate_number_type>;
|
||||
using Approximate_point_2 = Approximate_kernel::Point_2;
|
||||
|
||||
class Approximate_2 {
|
||||
protected:
|
||||
|
|
@ -927,12 +909,8 @@ public:
|
|||
auto max_vertex = m_traits.construct_max_vertex_2_object();
|
||||
const auto& src = (l2r) ? min_vertex(xcv) : max_vertex(xcv);
|
||||
const auto& trg = (l2r) ? max_vertex(xcv) : min_vertex(xcv);
|
||||
auto xs = CGAL::to_double(src.x());
|
||||
auto ys = CGAL::to_double(src.y());
|
||||
auto xt = CGAL::to_double(trg.x());
|
||||
auto yt = CGAL::to_double(trg.y());
|
||||
*oi++ = Approximate_point_2(xs, ys);
|
||||
*oi++ = Approximate_point_2(xt, yt);
|
||||
*oi++ = operator()(src);
|
||||
*oi++ = operator()(trg);
|
||||
return oi;
|
||||
}
|
||||
};
|
||||
|
|
@ -943,7 +921,7 @@ public:
|
|||
//! Functor
|
||||
class Construct_x_monotone_curve_2 {
|
||||
protected:
|
||||
typedef Arr_segment_traits_2<Kernel> Traits;
|
||||
using Traits = Arr_segment_traits_2<Kernel>;
|
||||
|
||||
//! The traits (in case it has state).
|
||||
const Traits& m_traits;
|
||||
|
|
@ -956,7 +934,7 @@ public:
|
|||
friend class Arr_segment_traits_2<Kernel>;
|
||||
|
||||
public:
|
||||
typedef typename Kernel::Segment_2 Segment_2;
|
||||
using Segment_2 = typename Kernel::Segment_2;
|
||||
|
||||
/*! obtains an \f$x\f$-monotone curve connecting two given endpoints.
|
||||
* \param source the first point.
|
||||
|
|
@ -965,8 +943,7 @@ public:
|
|||
* \return a segment connecting `source` and `target`.
|
||||
*/
|
||||
X_monotone_curve_2 operator()(const Point_2& source,
|
||||
const Point_2& target) const
|
||||
{
|
||||
const Point_2& target) const {
|
||||
const Kernel& kernel = m_traits;
|
||||
auto line = kernel.construct_line_2_object()(source, target);
|
||||
Comparison_result res = kernel.compare_xy_2_object()(source, target);
|
||||
|
|
@ -985,8 +962,7 @@ public:
|
|||
* \pre the segment is not degenerate.
|
||||
* \return a segment that is the same as `seg`..
|
||||
*/
|
||||
X_monotone_curve_2 operator()(const Segment_2& seg) const
|
||||
{
|
||||
X_monotone_curve_2 operator()(const Segment_2& seg) const {
|
||||
const Kernel& kernel = m_traits;
|
||||
auto line = kernel.construct_line_2_object()(seg);
|
||||
auto vertex_ctr = kernel.construct_vertex_2_object();
|
||||
|
|
@ -1011,8 +987,7 @@ public:
|
|||
*/
|
||||
X_monotone_curve_2 operator()(const Line_2& line,
|
||||
const Point_2& source,
|
||||
const Point_2& target) const
|
||||
{
|
||||
const Point_2& target) const {
|
||||
const Kernel& kernel = m_traits;
|
||||
CGAL_precondition
|
||||
(Segment_assertions::_assert_is_point_on(source, line,
|
||||
|
|
@ -1039,7 +1014,7 @@ public:
|
|||
//@{
|
||||
|
||||
//! Functor
|
||||
typedef Construct_x_monotone_curve_2 Construct_curve_2;
|
||||
using Construct_curve_2 = Construct_x_monotone_curve_2;
|
||||
|
||||
/*! obtains a `Construct_curve_2` functor object. */
|
||||
Construct_curve_2 construct_curve_2_object() const
|
||||
|
|
@ -1051,7 +1026,7 @@ public:
|
|||
|
||||
class Trim_2 {
|
||||
protected:
|
||||
typedef Arr_segment_traits_2<Kernel> Traits;
|
||||
using Traits = Arr_segment_traits_2<Kernel>;
|
||||
|
||||
/*! The traits (in case it has state). */
|
||||
const Traits& m_traits;
|
||||
|
|
@ -1074,8 +1049,7 @@ public:
|
|||
public:
|
||||
X_monotone_curve_2 operator()(const X_monotone_curve_2& xcv,
|
||||
const Point_2& src,
|
||||
const Point_2& tgt)const
|
||||
{
|
||||
const Point_2& tgt) const {
|
||||
CGAL_precondition_code(Equal_2 equal = m_traits.equal_2_object());
|
||||
CGAL_precondition_code(Compare_y_at_x_2 compare_y_at_x =
|
||||
m_traits.compare_y_at_x_2_object());
|
||||
|
|
@ -1119,7 +1093,7 @@ public:
|
|||
|
||||
class Construct_opposite_2 {
|
||||
public:
|
||||
/*! Construct an opposite \f$x\f$-monotone (with swapped source and target).
|
||||
/*! constructs an opposite \f$x\f$-monotone (with swapped source and target).
|
||||
* \param cv the curve.
|
||||
* \return the opposite curve.
|
||||
*/
|
||||
|
|
@ -1137,12 +1111,12 @@ public:
|
|||
|
||||
class Is_in_x_range_2 {
|
||||
protected:
|
||||
typedef Arr_segment_traits_2<Kernel> Traits;
|
||||
using Traits = Arr_segment_traits_2<Kernel>;
|
||||
|
||||
//! The traits (in case it has state).
|
||||
const Traits& m_traits;
|
||||
|
||||
/*! Construct
|
||||
/*! constructs
|
||||
* \param traits the traits (in case it has state)
|
||||
*/
|
||||
Is_in_x_range_2(const Traits& traits) : m_traits(traits) {}
|
||||
|
|
@ -1156,8 +1130,7 @@ public:
|
|||
* \param p the point.
|
||||
* \return true if p is in the \f$x\f$-range of cv; false otherwise.
|
||||
*/
|
||||
bool operator()(const X_monotone_curve_2& cv, const Point_2& p) const
|
||||
{
|
||||
bool operator()(const X_monotone_curve_2& cv, const Point_2& p) const {
|
||||
const Kernel& kernel = m_traits;
|
||||
auto compare_x = kernel.compare_x_2_object();
|
||||
Comparison_result res1 = compare_x(p, cv.left());
|
||||
|
|
@ -1176,7 +1149,7 @@ public:
|
|||
|
||||
class Is_in_y_range_2 {
|
||||
protected:
|
||||
typedef Arr_segment_traits_2<Kernel> Traits;
|
||||
using Traits = Arr_segment_traits_2<Kernel>;
|
||||
|
||||
//! The traits (in case it has state).
|
||||
const Traits& m_traits;
|
||||
|
|
@ -1195,8 +1168,7 @@ public:
|
|||
* \param p the point.
|
||||
* \return true if p is in the \f$y\f$-range of cv; false otherwise.
|
||||
*/
|
||||
bool operator()(const X_monotone_curve_2& cv, const Point_2& p) const
|
||||
{
|
||||
bool operator()(const X_monotone_curve_2& cv, const Point_2& p) const {
|
||||
const Kernel& kernel = m_traits;
|
||||
auto compare_y = kernel.compare_y_2_object();
|
||||
Comparison_result res1 = compare_y(p, cv.left());
|
||||
|
|
@ -1232,8 +1204,7 @@ template <typename Kernel>
|
|||
Arr_segment_traits_2<Kernel>::
|
||||
_Segment_cached_2::_Segment_cached_2(const Segment_2& seg) :
|
||||
m_is_vert(false),
|
||||
m_is_computed(false)
|
||||
{
|
||||
m_is_computed(false) {
|
||||
Kernel kernel;
|
||||
auto vertex_ctr = kernel.construct_vertex_2_object();
|
||||
|
||||
|
|
@ -1255,8 +1226,7 @@ _Segment_cached_2::_Segment_cached_2(const Point_2& source,
|
|||
m_ps(source),
|
||||
m_pt(target),
|
||||
m_is_vert(false),
|
||||
m_is_computed(false)
|
||||
{
|
||||
m_is_computed(false) {
|
||||
Kernel kernel;
|
||||
|
||||
Comparison_result res = kernel.compare_xy_2_object()(m_ps, m_pt);
|
||||
|
|
@ -1274,8 +1244,7 @@ _Segment_cached_2::_Segment_cached_2(const Line_2& line,
|
|||
const Point_2& target) :
|
||||
m_l(line),
|
||||
m_ps(source),
|
||||
m_pt(target)
|
||||
{
|
||||
m_pt(target) {
|
||||
Kernel kernel;
|
||||
|
||||
CGAL_precondition
|
||||
|
|
@ -1312,8 +1281,7 @@ _Segment_cached_2(const Line_2& line,
|
|||
//! \brief assigns.
|
||||
template <typename Kernel>
|
||||
const typename Arr_segment_traits_2<Kernel>::_Segment_cached_2&
|
||||
Arr_segment_traits_2<Kernel>::_Segment_cached_2::operator=(const Segment_2& seg)
|
||||
{
|
||||
Arr_segment_traits_2<Kernel>::_Segment_cached_2::operator=(const Segment_2& seg) {
|
||||
Kernel kernel;
|
||||
auto vertex_ctr = kernel.construct_vertex_2_object();
|
||||
|
||||
|
|
@ -1338,8 +1306,7 @@ Arr_segment_traits_2<Kernel>::_Segment_cached_2::operator=(const Segment_2& seg)
|
|||
//! \brief obtains the supporting line.
|
||||
template <typename Kernel>
|
||||
const typename Kernel::Line_2&
|
||||
Arr_segment_traits_2<Kernel>::_Segment_cached_2::line() const
|
||||
{
|
||||
Arr_segment_traits_2<Kernel>::_Segment_cached_2::line() const {
|
||||
if (!m_is_computed) {
|
||||
Kernel kernel;
|
||||
m_l = kernel.construct_line_2_object()(m_ps, m_pt);
|
||||
|
|
@ -1351,8 +1318,7 @@ Arr_segment_traits_2<Kernel>::_Segment_cached_2::line() const
|
|||
|
||||
//! \brief determines whether the curve is vertical.
|
||||
template <typename Kernel>
|
||||
bool Arr_segment_traits_2<Kernel>::_Segment_cached_2::is_vertical() const
|
||||
{
|
||||
bool Arr_segment_traits_2<Kernel>::_Segment_cached_2::is_vertical() const {
|
||||
// Force computation of line is orientation is still unknown
|
||||
if (! m_is_computed) line();
|
||||
CGAL_precondition(!m_is_degen);
|
||||
|
|
@ -1397,8 +1363,7 @@ Arr_segment_traits_2<Kernel>::_Segment_cached_2::right() const
|
|||
|
||||
//! \brief sets the (lexicographically) left endpoint.
|
||||
template <typename Kernel>
|
||||
void Arr_segment_traits_2<Kernel>::_Segment_cached_2::set_left(const Point_2& p)
|
||||
{
|
||||
void Arr_segment_traits_2<Kernel>::_Segment_cached_2::set_left(const Point_2& p) {
|
||||
CGAL_precondition(! m_is_degen);
|
||||
CGAL_precondition_code(Kernel kernel);
|
||||
CGAL_precondition
|
||||
|
|
@ -1411,8 +1376,7 @@ void Arr_segment_traits_2<Kernel>::_Segment_cached_2::set_left(const Point_2& p)
|
|||
|
||||
//! \brief sets the (lexicographically) right endpoint.
|
||||
template <typename Kernel>
|
||||
void Arr_segment_traits_2<Kernel>::_Segment_cached_2::set_right(const Point_2& p)
|
||||
{
|
||||
void Arr_segment_traits_2<Kernel>::_Segment_cached_2::set_right(const Point_2& p) {
|
||||
CGAL_precondition(! m_is_degen);
|
||||
CGAL_precondition_code(Kernel kernel);
|
||||
CGAL_precondition
|
||||
|
|
@ -1428,8 +1392,7 @@ void Arr_segment_traits_2<Kernel>::_Segment_cached_2::set_right(const Point_2& p
|
|||
*/
|
||||
template <typename Kernel>
|
||||
bool Arr_segment_traits_2<Kernel>::_Segment_cached_2::
|
||||
is_in_x_range(const Point_2& p) const
|
||||
{
|
||||
is_in_x_range(const Point_2& p) const {
|
||||
Kernel kernel;
|
||||
typename Kernel::Compare_x_2 compare_x = kernel.compare_x_2_object();
|
||||
const Comparison_result res1 = compare_x(p, left());
|
||||
|
|
@ -1446,8 +1409,7 @@ is_in_x_range(const Point_2& p) const
|
|||
*/
|
||||
template <typename Kernel>
|
||||
bool Arr_segment_traits_2<Kernel>::_Segment_cached_2::
|
||||
is_in_y_range(const Point_2& p) const
|
||||
{
|
||||
is_in_y_range(const Point_2& p) const {
|
||||
Kernel kernel;
|
||||
typename Kernel::Compare_y_2 compare_y = kernel.compare_y_2_object();
|
||||
const Comparison_result res1 = compare_y(p, left());
|
||||
|
|
@ -1464,31 +1426,31 @@ is_in_y_range(const Point_2& p) const
|
|||
*/
|
||||
template <typename Kernel_>
|
||||
class Arr_segment_2 : public Arr_segment_traits_2<Kernel_>::_Segment_cached_2 {
|
||||
typedef Kernel_ Kernel;
|
||||
using Kernel = Kernel_;
|
||||
|
||||
typedef typename Arr_segment_traits_2<Kernel>::_Segment_cached_2 Base;
|
||||
typedef typename Kernel::Segment_2 Segment_2;
|
||||
typedef typename Kernel::Point_2 Point_2;
|
||||
typedef typename Kernel::Line_2 Line_2;
|
||||
using Base = typename Arr_segment_traits_2<Kernel>::_Segment_cached_2;
|
||||
using Segment_2 = typename Kernel::Segment_2;
|
||||
using Point_2 = typename Kernel::Point_2;
|
||||
using Line_2 = typename Kernel::Line_2;
|
||||
|
||||
public:
|
||||
/*! Construct default. */
|
||||
/*! constructs default. */
|
||||
Arr_segment_2();
|
||||
|
||||
/*! Construct a segment from a "kernel" segment.
|
||||
/*! constructs a segment from a "kernel" segment.
|
||||
* \param seg the segment.
|
||||
* \pre the segment is not degenerate.
|
||||
*/
|
||||
Arr_segment_2(const Segment_2& seg);
|
||||
|
||||
/*! Construct a segment from two endpoints.
|
||||
/*! constructs a segment from two endpoints.
|
||||
* \param source the source point.
|
||||
* \param target the target point.
|
||||
* \pre `source` and `target` are not equal.
|
||||
*/
|
||||
Arr_segment_2(const Point_2& source, const Point_2& target);
|
||||
|
||||
/*! Construct a segment from a line and two endpoints.
|
||||
/*! constructs a segment from a line and two endpoints.
|
||||
* \param line the supporting line.
|
||||
* \param source the source point.
|
||||
* \param target the target point.
|
||||
|
|
@ -1498,7 +1460,7 @@ public:
|
|||
Arr_segment_2(const Line_2& line,
|
||||
const Point_2& source, const Point_2& target);
|
||||
|
||||
/*! Construct a segment from all fields.
|
||||
/*! constructs a segment from all fields.
|
||||
* \param line the supporting line.
|
||||
* \param source the source point.
|
||||
* \param target the target point.
|
||||
|
|
@ -1510,11 +1472,11 @@ public:
|
|||
const Point_2& source, const Point_2& target,
|
||||
bool is_directed_right, bool is_vert, bool is_degen);
|
||||
|
||||
/*! Cast to a segment.
|
||||
/*! casts to a segment.
|
||||
*/
|
||||
operator Segment_2() const;
|
||||
|
||||
/*! Flip the segment (swap its source and target).
|
||||
/*! flips the segment (swap its source and target).
|
||||
*/
|
||||
Arr_segment_2 flip() const;
|
||||
|
||||
|
|
@ -1558,8 +1520,7 @@ Arr_segment_2<Kernel>::Arr_segment_2(const Line_2& line,
|
|||
|
||||
//! \brief casts to a segment.
|
||||
template <typename Kernel>
|
||||
Arr_segment_2<Kernel>::operator typename Kernel::Segment_2() const
|
||||
{
|
||||
Arr_segment_2<Kernel>::operator typename Kernel::Segment_2() const {
|
||||
Kernel kernel;
|
||||
auto seg_ctr = kernel.construct_segment_2_object();
|
||||
return seg_ctr(this->source(), this->target());
|
||||
|
|
@ -1567,8 +1528,7 @@ Arr_segment_2<Kernel>::operator typename Kernel::Segment_2() const
|
|||
|
||||
//! \brief flips the segment (swap its source and target).
|
||||
template <typename Kernel>
|
||||
Arr_segment_2<Kernel> Arr_segment_2<Kernel>::flip() const
|
||||
{
|
||||
Arr_segment_2<Kernel> Arr_segment_2<Kernel>::flip() const {
|
||||
return Arr_segment_2(this->line(), this->target(), this->source(),
|
||||
! (this->is_directed_right()), this->is_vertical(),
|
||||
this->is_degenerate());
|
||||
|
|
@ -1586,8 +1546,7 @@ Bbox_2 Arr_segment_2<Kernel>::bbox() const
|
|||
/*! Exporter for the segment class used by the traits-class.
|
||||
*/
|
||||
template <typename Kernel, typename OutputStream>
|
||||
OutputStream& operator<<(OutputStream& os, const Arr_segment_2<Kernel>& seg)
|
||||
{
|
||||
OutputStream& operator<<(OutputStream& os, const Arr_segment_2<Kernel>& seg) {
|
||||
os << static_cast<typename Kernel::Segment_2>(seg);
|
||||
return (os);
|
||||
}
|
||||
|
|
@ -1595,8 +1554,7 @@ OutputStream& operator<<(OutputStream& os, const Arr_segment_2<Kernel>& seg)
|
|||
/*! Importer for the segment class used by the traits-class.
|
||||
*/
|
||||
template <typename Kernel, typename InputStream>
|
||||
InputStream& operator>>(InputStream& is, Arr_segment_2<Kernel>& seg)
|
||||
{
|
||||
InputStream& operator>>(InputStream& is, Arr_segment_2<Kernel>& seg) {
|
||||
typename Kernel::Segment_2 kernel_seg;
|
||||
is >> kernel_seg;
|
||||
seg = kernel_seg;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -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
|
||||
|
|
@ -8,9 +8,9 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
||||
//
|
||||
//
|
||||
// Author(s): Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||
// Ron Wein <wein@post.tau.ac.il>
|
||||
// Efi Fogel <efif@post.tau.ac.il>
|
||||
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||
// Ron Wein <wein@post.tau.ac.il>
|
||||
// Efi Fogel <efif@post.tau.ac.il>
|
||||
|
||||
#ifndef CGAL_ARR_NO_INTERSECTION_INSERTION_SS_VISITOR_H
|
||||
#define CGAL_ARR_NO_INTERSECTION_INSERTION_SS_VISITOR_H
|
||||
|
|
@ -42,35 +42,33 @@ class Arr_no_intersection_insertion_ss_visitor :
|
|||
public Arr_construction_ss_visitor<
|
||||
Helper_,
|
||||
typename Default::Get<Visitor_, Arr_no_intersection_insertion_ss_visitor<
|
||||
Helper_, Visitor_> >::type>
|
||||
{
|
||||
Helper_, Visitor_> >::type> {
|
||||
public:
|
||||
typedef Helper_ Helper;
|
||||
using Helper = Helper_;
|
||||
|
||||
typedef typename Helper::Geometry_traits_2 Geometry_traits_2;
|
||||
typedef typename Helper::Event Event;
|
||||
typedef typename Helper::Subcurve Subcurve;
|
||||
using Geometry_traits_2 = typename Helper::Geometry_traits_2;
|
||||
using Event = typename Helper::Event;
|
||||
using Subcurve = typename Helper::Subcurve;
|
||||
|
||||
private:
|
||||
typedef Geometry_traits_2 Gt2;
|
||||
typedef Arr_no_intersection_insertion_ss_visitor<Helper, Visitor_>
|
||||
Self;
|
||||
typedef typename Default::Get<Visitor_, Self>::type Visitor;
|
||||
typedef Arr_construction_ss_visitor<Helper, Visitor> Base;
|
||||
using Gt2 = Geometry_traits_2;
|
||||
using Self = Arr_no_intersection_insertion_ss_visitor<Helper, Visitor_>;
|
||||
using Visitor = typename Default::Get<Visitor_, Self>::type;
|
||||
using Base = Arr_construction_ss_visitor<Helper, Visitor>;
|
||||
|
||||
public:
|
||||
typedef typename Gt2::X_monotone_curve_2 X_monotone_curve_2;
|
||||
typedef typename Gt2::Point_2 Point_2;
|
||||
using X_monotone_curve_2 = typename Gt2::X_monotone_curve_2;
|
||||
using Point_2 = typename Gt2::Point_2;
|
||||
using Multiplicity = typename Gt2::Multiplicity;
|
||||
|
||||
protected:
|
||||
typedef typename Subcurve::Status_line_iterator Status_line_iterator;
|
||||
typedef typename Base::Event_subcurve_reverse_iterator
|
||||
Event_subcurve_reverse_iterator;
|
||||
using Status_line_iterator = typename Subcurve::Status_line_iterator;
|
||||
using Event_subcurve_reverse_iterator = typename Base::Event_subcurve_reverse_iterator;
|
||||
|
||||
typedef typename Helper::Arrangement_2 Arrangement_2;
|
||||
typedef typename Arrangement_2::Vertex_handle Vertex_handle;
|
||||
typedef typename Arrangement_2::Halfedge_handle Halfedge_handle;
|
||||
typedef typename Arrangement_2::Face_handle Face_handle;
|
||||
using Arrangement_2 = typename Helper::Arrangement_2;
|
||||
using Vertex_handle = typename Arrangement_2::Vertex_handle;
|
||||
using Halfedge_handle = typename Arrangement_2::Halfedge_handle;
|
||||
using Face_handle = typename Arrangement_2::Face_handle;
|
||||
|
||||
public:
|
||||
/*! Constructor. */
|
||||
|
|
@ -103,13 +101,12 @@ public:
|
|||
{}
|
||||
|
||||
void update_event(Event* /* e */, Subcurve* /* sc1 */, Subcurve* /* sc2 */,
|
||||
bool /* is_new */)
|
||||
bool /* is_new */, Multiplicity /* multiplicity */)
|
||||
{}
|
||||
|
||||
void update_event(Event* /* e */, Subcurve* /* sc1 */) {}
|
||||
|
||||
void update_event(Event* e, const Point_2& pt, bool /* is_new */)
|
||||
{
|
||||
void update_event(Event* e, const Point_2& pt, bool /* is_new */) {
|
||||
Vertex_handle invalid_v;
|
||||
if (e->point().vertex_handle() == invalid_v)
|
||||
e->point().set_vertex_handle(pt.vertex_handle());
|
||||
|
|
@ -241,8 +238,7 @@ void Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::before_sweep()
|
|||
//
|
||||
template <typename Hlpr, typename 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.
|
||||
this->m_helper.before_handle_event(event);
|
||||
|
||||
|
|
@ -330,8 +326,7 @@ before_handle_event(Event* event)
|
|||
//
|
||||
template <typename Hlpr, typename 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;
|
||||
if (cv.halfedge_handle() != invalid_he) return false;
|
||||
// Insert the curve into the arrangement
|
||||
|
|
@ -344,8 +339,7 @@ add_subcurve_(const X_monotone_curve_2& cv, Subcurve* sc)
|
|||
//
|
||||
template <typename Hlpr, typename 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;
|
||||
|
||||
Halfedge_handle next_ccw_he =
|
||||
|
|
@ -359,8 +353,7 @@ add_subcurve(const X_monotone_curve_2& cv, Subcurve* sc)
|
|||
template <typename Hlpr, typename Vis>
|
||||
typename Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::Halfedge_handle
|
||||
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);
|
||||
Vertex_handle last_v = last_event->point().vertex_handle();
|
||||
Vertex_handle curr_v = this->current_event()->point().vertex_handle();
|
||||
|
|
@ -385,8 +378,7 @@ template <typename Hlpr, typename Vis>
|
|||
typename Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::Halfedge_handle
|
||||
Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::
|
||||
insert_from_left_vertex(const X_monotone_curve_2& cv, Halfedge_handle he,
|
||||
Subcurve* sc)
|
||||
{
|
||||
Subcurve* sc) {
|
||||
Vertex_handle curr_v = this->current_event()->point().vertex_handle();
|
||||
if (curr_v != Vertex_handle())
|
||||
return (this->m_arr->insert_at_vertices(cv.base(), he, curr_v));
|
||||
|
|
@ -400,8 +392,7 @@ template <typename Hlpr, typename Vis>
|
|||
typename Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::Halfedge_handle
|
||||
Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::
|
||||
insert_from_right_vertex(const X_monotone_curve_2& cv, Halfedge_handle he,
|
||||
Subcurve* sc)
|
||||
{
|
||||
Subcurve* sc) {
|
||||
Event* last_event = this->last_event_on_subcurve(sc);
|
||||
Vertex_handle last_v = last_event->point().vertex_handle();
|
||||
if (last_v != Vertex_handle())
|
||||
|
|
@ -426,8 +417,7 @@ insert_at_vertices(const X_monotone_curve_2& cv,
|
|||
template <typename Hlpr, typename Vis>
|
||||
typename Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::Vertex_handle
|
||||
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 (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>
|
||||
typename Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::Halfedge_handle
|
||||
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
|
||||
// already been created.
|
||||
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
|
||||
Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::
|
||||
_insert_from_left_vertex(const X_monotone_curve_2& cv,
|
||||
Halfedge_handle prev, Subcurve* sc)
|
||||
{
|
||||
Halfedge_handle prev, Subcurve* sc) {
|
||||
// Check if the vertex to be associated with the right end of the curve has
|
||||
// already been created.
|
||||
Event* curr_event = this->current_event();
|
||||
|
|
@ -551,8 +539,7 @@ template <typename Hlpr, typename Vis>
|
|||
typename Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::Halfedge_handle
|
||||
Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::
|
||||
_insert_from_right_vertex(const X_monotone_curve_2& cv, Halfedge_handle prev,
|
||||
Subcurve* sc)
|
||||
{
|
||||
Subcurve* sc) {
|
||||
// Check if the vertex to be associated with the left end of the curve has
|
||||
// already been created.
|
||||
Event* last_event = this->last_event_on_subcurve(sc);
|
||||
|
|
@ -589,8 +576,7 @@ typename Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::Halfedge_handle
|
|||
Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::
|
||||
_insert_at_vertices(const X_monotone_curve_2& cv,
|
||||
Halfedge_handle prev1, Halfedge_handle prev2,
|
||||
Subcurve* sc, bool& new_face_created)
|
||||
{
|
||||
Subcurve* sc, bool& new_face_created) {
|
||||
// Perform the insertion.
|
||||
new_face_created = false;
|
||||
bool swapped_predecessors = false;
|
||||
|
|
@ -632,8 +618,7 @@ _insert_at_vertices(const X_monotone_curve_2& cv,
|
|||
template <typename Hlpr, typename Vis>
|
||||
typename Arr_no_intersection_insertion_ss_visitor<Hlpr, Vis>::Face_handle
|
||||
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
|
||||
// with a valid arrangement halfedge.
|
||||
const Halfedge_handle invalid_he;
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
||||
//
|
||||
//
|
||||
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||
// Ron Wein <wein@post.tau.ac.il>
|
||||
// Efi Fogel <efif@post.tau.ac.il>
|
||||
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||
// Ron Wein <wein@post.tau.ac.il>
|
||||
// Efi Fogel <efif@post.tau.ac.il>
|
||||
|
||||
#ifndef CGAL_ARR_OVERLAY_SS_VISITOR_H
|
||||
#define CGAL_ARR_OVERLAY_SS_VISITOR_H
|
||||
|
|
@ -40,92 +40,80 @@ namespace CGAL {
|
|||
* arrangement, creating a result arrangement. All three arrangements are
|
||||
* embedded on the same type of surface and use the same geometry traits.
|
||||
*/
|
||||
template <typename OverlayHelper, typename OverlayTraits,
|
||||
typename Visitor_ = Default>
|
||||
template <typename OverlayHelper, typename OverlayTraits, typename Visitor_ = Default>
|
||||
class Arr_overlay_ss_visitor :
|
||||
public Arr_construction_ss_visitor<
|
||||
typename OverlayHelper::Construction_helper,
|
||||
typename Default::Get<Visitor_,
|
||||
Arr_overlay_ss_visitor<OverlayHelper, OverlayTraits,
|
||||
Visitor_> >::type>
|
||||
{
|
||||
Arr_overlay_ss_visitor<OverlayHelper, OverlayTraits, Visitor_> >::type> {
|
||||
public:
|
||||
typedef OverlayHelper Overlay_helper;
|
||||
typedef OverlayTraits Overlay_traits;
|
||||
using Overlay_helper = OverlayHelper;
|
||||
using Overlay_traits = OverlayTraits;
|
||||
|
||||
typedef typename Overlay_helper::Geometry_traits_2 Geometry_traits_2;
|
||||
typedef typename Overlay_helper::Event Event;
|
||||
typedef typename Overlay_helper::Subcurve Subcurve;
|
||||
using Geometry_traits_2 = typename Overlay_helper::Geometry_traits_2;
|
||||
using Event = typename Overlay_helper::Event;
|
||||
using Subcurve = typename Overlay_helper::Subcurve;
|
||||
|
||||
typedef typename Overlay_helper::Arrangement_red_2 Arrangement_red_2;
|
||||
typedef typename Overlay_helper::Arrangement_blue_2 Arrangement_blue_2;
|
||||
|
||||
typedef typename Overlay_helper::Construction_helper Construction_helper;
|
||||
using Arrangement_red_2 = typename Overlay_helper::Arrangement_red_2;
|
||||
using Arrangement_blue_2 = typename Overlay_helper::Arrangement_blue_2;
|
||||
|
||||
using Construction_helper = typename Overlay_helper::Construction_helper;
|
||||
|
||||
private:
|
||||
typedef Geometry_traits_2 Gt2;
|
||||
typedef Arrangement_red_2 Ar2;
|
||||
typedef Arrangement_blue_2 Ab2;
|
||||
using Gt2 = Geometry_traits_2;
|
||||
using Ar2 = Arrangement_red_2;
|
||||
using Ab2 = Arrangement_blue_2;
|
||||
|
||||
typedef Arr_overlay_ss_visitor<Overlay_helper, Overlay_traits, Visitor_>
|
||||
Self;
|
||||
typedef typename Default::Get<Visitor_, Self>::type Visitor;
|
||||
typedef Arr_construction_ss_visitor<Construction_helper, Visitor>
|
||||
Base;
|
||||
using Self = Arr_overlay_ss_visitor<Overlay_helper, Overlay_traits, Visitor_>;
|
||||
using Visitor = typename Default::Get<Visitor_, Self>::type;
|
||||
using Base = Arr_construction_ss_visitor<Construction_helper, Visitor>;
|
||||
|
||||
public:
|
||||
typedef typename Gt2::X_monotone_curve_2 X_monotone_curve_2;
|
||||
typedef typename Gt2::Point_2 Point_2;
|
||||
using X_monotone_curve_2 = typename Gt2::X_monotone_curve_2;
|
||||
using Point_2 = typename Gt2::Point_2;
|
||||
using Multiplicity = typename Gt2::Multiplicity;
|
||||
|
||||
// The input arrangements (the "red" and the "blue" one):
|
||||
typedef typename Ar2::Halfedge_const_handle Halfedge_handle_red;
|
||||
typedef typename Ar2::Face_const_handle Face_handle_red;
|
||||
typedef typename Ar2::Vertex_const_handle Vertex_handle_red;
|
||||
using Halfedge_handle_red = typename Ar2::Halfedge_const_handle;
|
||||
using Face_handle_red = typename Ar2::Face_const_handle;
|
||||
using Vertex_handle_red = typename Ar2::Vertex_const_handle;
|
||||
|
||||
typedef typename Ab2::Halfedge_const_handle Halfedge_handle_blue;
|
||||
typedef typename Ab2::Face_const_handle Face_handle_blue;
|
||||
typedef typename Ab2::Vertex_const_handle Vertex_handle_blue;
|
||||
using Halfedge_handle_blue = typename Ab2::Halfedge_const_handle;
|
||||
using Face_handle_blue = typename Ab2::Face_const_handle;
|
||||
using Vertex_handle_blue = typename Ab2::Vertex_const_handle;
|
||||
|
||||
// The resulting arrangement:
|
||||
typedef typename Overlay_helper::Arrangement_2 Arrangement_2;
|
||||
typedef typename Arrangement_2::Halfedge_handle Halfedge_handle;
|
||||
typedef typename Arrangement_2::Face_handle Face_handle;
|
||||
typedef typename Arrangement_2::Vertex_handle Vertex_handle;
|
||||
typedef typename Arrangement_2::Ccb_halfedge_circulator
|
||||
Ccb_halfedge_circulator;
|
||||
typedef typename Arrangement_2::Outer_ccb_iterator Outer_ccb_iterator;
|
||||
using Arrangement_2 = typename Overlay_helper::Arrangement_2;
|
||||
using Halfedge_handle = typename Arrangement_2::Halfedge_handle;
|
||||
using Face_handle = typename Arrangement_2::Face_handle;
|
||||
using Vertex_handle = typename Arrangement_2::Vertex_handle;
|
||||
using Ccb_halfedge_circulator = typename Arrangement_2::Ccb_halfedge_circulator;
|
||||
using Outer_ccb_iterator = typename Arrangement_2::Outer_ccb_iterator;
|
||||
|
||||
typedef typename Base::Event_subcurve_iterator
|
||||
Event_subcurve_iterator;
|
||||
typedef typename Base::Event_subcurve_reverse_iterator
|
||||
Event_subcurve_reverse_iterator;
|
||||
typedef typename Base::Status_line_iterator Status_line_iterator;
|
||||
using Event_subcurve_iterator = typename Base::Event_subcurve_iterator;
|
||||
using Event_subcurve_reverse_iterator = typename Base::Event_subcurve_reverse_iterator;
|
||||
using Status_line_iterator = typename Base::Status_line_iterator;
|
||||
|
||||
protected:
|
||||
typedef typename Gt2::Cell_handle_red Cell_handle_red;
|
||||
typedef typename Gt2::Optional_cell_red Optional_cell_red;
|
||||
typedef typename Gt2::Cell_handle_blue Cell_handle_blue;
|
||||
typedef typename Gt2::Optional_cell_blue Optional_cell_blue;
|
||||
using Cell_handle_red = typename Gt2::Cell_handle_red;
|
||||
using Optional_cell_red = typename Gt2::Optional_cell_red;
|
||||
using Cell_handle_blue = typename Gt2::Cell_handle_blue;
|
||||
using Optional_cell_blue = typename Gt2::Optional_cell_blue;
|
||||
|
||||
typedef std::pair<Halfedge_handle_red, Halfedge_handle_blue>
|
||||
Halfedge_info;
|
||||
typedef Unique_hash_map<Halfedge_handle, Halfedge_info>
|
||||
Halfedge_map;
|
||||
using Halfedge_info = std::pair<Halfedge_handle_red, Halfedge_handle_blue>;
|
||||
using Halfedge_map = Unique_hash_map<Halfedge_handle, Halfedge_info>;
|
||||
|
||||
typedef std::pair<Cell_handle_red, Cell_handle_blue> Handle_info;
|
||||
typedef std::unordered_map<Vertex_handle, Handle_info, Handle_hash_function>
|
||||
Vertex_map;
|
||||
using Handle_info = std::pair<Cell_handle_red, Cell_handle_blue>;
|
||||
using Vertex_map = std::unordered_map<Vertex_handle, Handle_info, Handle_hash_function>;
|
||||
|
||||
// Side categoties:
|
||||
typedef typename Gt2::Left_side_category Left_side_category;
|
||||
typedef typename Gt2::Bottom_side_category Bottom_side_category;
|
||||
typedef typename Gt2::Top_side_category Top_side_category;
|
||||
typedef typename Gt2::Right_side_category Right_side_category;
|
||||
using Left_side_category = typename Gt2::Left_side_category;
|
||||
using Bottom_side_category = typename Gt2::Bottom_side_category;
|
||||
using Top_side_category = typename Gt2::Top_side_category;
|
||||
using Right_side_category = typename Gt2::Right_side_category;
|
||||
|
||||
typedef typename Arr_has_identified_sides<Left_side_category,
|
||||
Bottom_side_category>::result
|
||||
Has_identified_sides_category;
|
||||
using Has_identified_sides_category =
|
||||
typename Arr_has_identified_sides<Left_side_category, Bottom_side_category>::result;
|
||||
|
||||
// Data members:
|
||||
Overlay_traits* m_overlay_traits; // The overlay traits object.
|
||||
|
|
@ -195,10 +183,9 @@ public:
|
|||
void update_event(Event* /* e */,
|
||||
Subcurve* /* c1 */,
|
||||
Subcurve* /* c2 */,
|
||||
bool CGAL_assertion_code(is_new))
|
||||
{
|
||||
CGAL_assertion(is_new == true);
|
||||
}
|
||||
bool CGAL_assertion_code(is_new),
|
||||
Multiplicity /* multiplicity */)
|
||||
{ CGAL_assertion(is_new == true); }
|
||||
|
||||
/*! Update an event. */
|
||||
void update_event(Event* e, Subcurve* sc);
|
||||
|
|
@ -407,9 +394,8 @@ protected:
|
|||
//-----------------------------------------------------------------------------
|
||||
// A notification issued before the sweep process starts.
|
||||
//
|
||||
template <typename OvlHlpr, typename OvlTr, typename Vis>
|
||||
void Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::before_sweep()
|
||||
{
|
||||
template <typename OvlHlpr, typename OvlTr, typename Vis>
|
||||
void Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::before_sweep() {
|
||||
// Initialize the necessary fields in the base construction visitor.
|
||||
// Note that the construction visitor also informs its helper class that
|
||||
// the sweep process is about to start.
|
||||
|
|
@ -425,8 +411,7 @@ protected:
|
|||
//
|
||||
template <typename OvlHlpr, typename OvlTr, typename Vis>
|
||||
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
|
||||
// class on the 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>
|
||||
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.
|
||||
bool res = Base::after_handle_event(event, iter, flag);
|
||||
|
||||
|
|
@ -497,8 +481,7 @@ update_event(Event* e,
|
|||
const Point_2& end_point,
|
||||
const X_monotone_curve_2& /* cv */,
|
||||
Arr_curve_end /* cv_end */,
|
||||
bool /* is_new */)
|
||||
{
|
||||
bool /* is_new */) {
|
||||
// Nothing to do in case of an event at infinity.
|
||||
CGAL_assertion(e->is_closed());
|
||||
|
||||
|
|
@ -513,8 +496,7 @@ update_event(Event* e,
|
|||
//
|
||||
template <typename OvlHlpr, typename OvlTr, typename Vis>
|
||||
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.
|
||||
Point_2& pt = e->point();
|
||||
|
||||
|
|
@ -538,8 +520,7 @@ template <typename OvlHlpr, typename OvlTr, typename Vis>
|
|||
void
|
||||
Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::update_event(Event* e,
|
||||
const Point_2& p,
|
||||
bool /* is_new */)
|
||||
{
|
||||
bool /* is_new */) {
|
||||
// Update the red and blue objects associated with the point as necessary.
|
||||
Point_2& pt = e->point();
|
||||
if (pt.is_red_cell_empty()) pt.set_red_cell(p.red_cell());
|
||||
|
|
@ -550,8 +531,7 @@ Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::update_event(Event* e,
|
|||
// A notification issued when the sweep process has ended.
|
||||
//
|
||||
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();
|
||||
|
||||
// Notify boundary vertices:
|
||||
|
|
@ -580,8 +560,7 @@ void Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::after_sweep()
|
|||
template <typename OvlHlpr, typename OvlTr, typename Vis>
|
||||
typename Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::Halfedge_handle
|
||||
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.
|
||||
Halfedge_handle new_he = Base::insert_in_face_interior(cv, sc);
|
||||
_map_halfedge_and_twin(new_he,
|
||||
|
|
@ -615,8 +594,7 @@ typename Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::Halfedge_handle
|
|||
Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::
|
||||
insert_from_left_vertex(const X_monotone_curve_2& cv,
|
||||
Halfedge_handle prev,
|
||||
Subcurve* sc)
|
||||
{
|
||||
Subcurve* sc) {
|
||||
_map_boundary_vertices(this->last_event_on_subcurve(sc), prev->target(),
|
||||
Has_identified_sides_category());
|
||||
|
||||
|
|
@ -647,8 +625,7 @@ typename Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::Halfedge_handle
|
|||
Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::
|
||||
insert_from_right_vertex(const X_monotone_curve_2& cv,
|
||||
Halfedge_handle prev,
|
||||
Subcurve* sc)
|
||||
{
|
||||
Subcurve* sc) {
|
||||
_map_boundary_vertices(this->current_event(), prev->target(),
|
||||
Has_identified_sides_category());
|
||||
|
||||
|
|
@ -680,8 +657,7 @@ insert_at_vertices(const X_monotone_curve_2& cv,
|
|||
Halfedge_handle prev1,
|
||||
Halfedge_handle prev2,
|
||||
Subcurve* sc,
|
||||
bool& new_face_created)
|
||||
{
|
||||
bool& new_face_created) {
|
||||
// Insert the halfedge using the base construction visitor. Note that the
|
||||
// resulting halfedge is always incident to the new face (if one created).
|
||||
Halfedge_handle new_he =
|
||||
|
|
@ -795,8 +771,7 @@ template <typename OvlHlpr, typename OvlTr, typename Vis>
|
|||
typename Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::Vertex_handle
|
||||
Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::
|
||||
insert_isolated_vertex(const Point_2& pt,
|
||||
Status_line_iterator iter)
|
||||
{
|
||||
Status_line_iterator iter) {
|
||||
// Insert the isolated vertex using the base construction visitor.
|
||||
Vertex_handle new_v = Base::insert_isolated_vertex(pt, iter);
|
||||
|
||||
|
|
@ -897,14 +872,13 @@ template <typename OvlHlpr, typename OvlTr, typename Vis>
|
|||
void Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::
|
||||
_map_halfedge_and_twin(Halfedge_handle he,
|
||||
Halfedge_handle_red red_he,
|
||||
Halfedge_handle_blue blue_he)
|
||||
{
|
||||
Halfedge_handle_blue blue_he) {
|
||||
if (he->direction() == ARR_LEFT_TO_RIGHT) he = he->twin();
|
||||
|
||||
// Obtain the twin red and blue halfedges (if they are valid). Note that
|
||||
// the original halfedges are always directed from right to left.
|
||||
Halfedge_handle_red red_he_twin;
|
||||
Halfedge_handle_blue blue_he_twin;
|
||||
Halfedge_handle_red red_he_twin;
|
||||
Halfedge_handle_blue blue_he_twin;
|
||||
|
||||
if (red_he != Halfedge_handle_red()) red_he_twin = red_he->twin();
|
||||
if (blue_he != Halfedge_handle_blue()) blue_he_twin = blue_he->twin();
|
||||
|
|
@ -922,8 +896,7 @@ _map_halfedge_and_twin(Halfedge_handle he,
|
|||
//
|
||||
template <typename OvlHlpr, typename OvlTr, typename 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.
|
||||
if ((event->parameter_space_in_x() != ARR_INTERIOR) ||
|
||||
(event->parameter_space_in_y() != ARR_INTERIOR))
|
||||
|
|
@ -938,8 +911,7 @@ _map_boundary_vertices(Event* event, Vertex_handle v, std::bool_constant<true>)
|
|||
if (red_handle_p) info.first = *red_handle_p;
|
||||
|
||||
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,
|
||||
// they must represt either vertex or edge handles. In this case it is
|
||||
// safe to apply the call to the overlay traits and erase the record,
|
||||
|
|
@ -974,8 +946,7 @@ void Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::
|
|||
_create_vertex(Event* event,
|
||||
Vertex_handle new_v,
|
||||
Subcurve* sc,
|
||||
std::bool_constant<true>)
|
||||
{
|
||||
std::bool_constant<true>) {
|
||||
const Point_2& pt = event->point();
|
||||
const Cell_handle_red* red_handle = pt.red_cell_handle();
|
||||
const Cell_handle_blue* blue_handle = pt.blue_cell_handle();
|
||||
|
|
@ -983,8 +954,7 @@ _create_vertex(Event* event,
|
|||
// If the vertex is on the boundary, postpone the notification, but
|
||||
// update the red and objects in case they are empty.
|
||||
if ((event->parameter_space_in_x() != ARR_INTERIOR) ||
|
||||
(event->parameter_space_in_y() != ARR_INTERIOR))
|
||||
{
|
||||
(event->parameter_space_in_y() != ARR_INTERIOR)) {
|
||||
if (!red_handle) {
|
||||
CGAL_assertion(blue_handle != nullptr);
|
||||
// Obtain the red face by looking for a subcurve above.
|
||||
|
|
@ -1020,8 +990,7 @@ void Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::
|
|||
_create_vertex(Event* event,
|
||||
Vertex_handle new_v,
|
||||
Subcurve* sc,
|
||||
std::bool_constant<false>)
|
||||
{
|
||||
std::bool_constant<false>) {
|
||||
const Point_2& pt = event->point();
|
||||
const Cell_handle_red* red_handle = pt.red_cell_handle();
|
||||
const Cell_handle_blue* blue_handle = pt.blue_cell_handle();
|
||||
|
|
@ -1063,8 +1032,7 @@ _create_vertex(Event* event,
|
|||
template <typename OvlHlpr, typename OvlTr, typename Vis>
|
||||
void Arr_overlay_ss_visitor<OvlHlpr, OvlTr, Vis>::
|
||||
_create_edge(Subcurve* sc,
|
||||
Halfedge_handle new_he)
|
||||
{
|
||||
Halfedge_handle new_he) {
|
||||
// Note that the "red" and "blue" halfedges are always directed from right
|
||||
// to left, so we make sure the overlaid halfedge is also directed from
|
||||
// right to left.
|
||||
|
|
|
|||
|
|
@ -588,7 +588,7 @@ private:
|
|||
|
||||
#ifdef CGAL_USE_BASIC_VIEWER
|
||||
//!
|
||||
void draw_unimplemented() {
|
||||
inline void draw_unimplemented() {
|
||||
CGAL_error_msg("Geometry traits type of arrangement is required to support approximation of Point_2 and "
|
||||
"X_monotone_curve_2. Traits on curved surfaces needs additional support for parameterization.");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1563,10 +1563,10 @@ does_satisfy_link_condition(typename boost::graph_traits<Graph>::edge_descriptor
|
|||
*
|
||||
* After the collapse of edge `e` the following holds:
|
||||
* - The edge `e` is no longer in `g`.
|
||||
* - The faces incident to edge `e` are no longer in `g`.
|
||||
* - The triangle faces incident to edge `e` are no longer in `g`.
|
||||
* - `v0` is no longer in `g`.
|
||||
* - If `h` is not a border halfedge, `p_h` is no longer in `g` and is replaced by `o_n_h`.
|
||||
* - If the opposite of `h` is not a border halfedge, `p_o_h` is no longer in `g` and is replaced by `o_n_o_h`.
|
||||
* - If `h` is part of a triangle face, `p_h` is no longer in `g` and is replaced by `o_n_h`.
|
||||
* - If the opposite of `h` is part of a triangle face, `p_o_h` is no longer in `g` and is replaced by `o_n_o_h`.
|
||||
* - The halfedges kept in `g` that had `v0` as target and source now have `v1` as target and source, respectively.
|
||||
* - No other incidence information is changed in `g`.
|
||||
*
|
||||
|
|
@ -1595,9 +1595,8 @@ collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor e,
|
|||
bool lBottomFaceExists = ! is_border(qp,g);
|
||||
bool lTopLeftFaceExists = lTopFaceExists && ! is_border(pt,g);
|
||||
bool lBottomRightFaceExists = lBottomFaceExists && ! is_border(qb,g);
|
||||
|
||||
CGAL_precondition( !lTopFaceExists || (lTopFaceExists && ( degree(target(pt, g), g) > 2 ) ) ) ;
|
||||
CGAL_precondition( !lBottomFaceExists || (lBottomFaceExists && ( degree(target(qb, g), g) > 2 ) ) ) ;
|
||||
bool lBottomIsTriangle = lBottomFaceExists && is_triangle(qp,g);
|
||||
bool lTopIsTriangle = lTopFaceExists && is_triangle(pq,g);
|
||||
|
||||
vertex_descriptor q = target(pq, g);
|
||||
vertex_descriptor p = source(pq, g);
|
||||
|
|
@ -1605,7 +1604,7 @@ collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor e,
|
|||
|
||||
bool lP_Erased = false;
|
||||
|
||||
if ( lTopFaceExists )
|
||||
if ( lTopIsTriangle)
|
||||
{
|
||||
CGAL_precondition( ! is_border(opposite(pt, g),g) ) ; // p-q-t is a face of the mesh
|
||||
if ( lTopLeftFaceExists )
|
||||
|
|
@ -1632,7 +1631,7 @@ collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor e,
|
|||
}
|
||||
}
|
||||
|
||||
if ( lBottomFaceExists )
|
||||
if ( lBottomIsTriangle)
|
||||
{
|
||||
CGAL_precondition( ! is_border(opposite(qb, g),g) ) ; // p-q-b is a face of the mesh
|
||||
if ( lBottomRightFaceExists )
|
||||
|
|
@ -1679,7 +1678,7 @@ collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor e,
|
|||
* collapses an edge in a graph having non-collapsable edges.
|
||||
*
|
||||
* Let `h` be the halfedge of `e`, and let `v0` and `v1` be the source and target vertices of `h`.
|
||||
* Collapses the edge `e` replacing it with `v1`, as described in the paragraph above
|
||||
* Collapses the edge `e` replacing it with `v1`, as described in the other overload
|
||||
* and guarantees that an edge `e2`, for which `get(edge_is_constrained_map, e2)==true`,
|
||||
* is not removed after the collapse.
|
||||
*
|
||||
|
|
@ -1689,14 +1688,14 @@ collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor e,
|
|||
*
|
||||
* \returns vertex `v1`.
|
||||
* \pre This function requires `g` to be an oriented 2-manifold with or without boundaries.
|
||||
* Furthermore, the edge `v0v1` must satisfy the link condition, which guarantees that the surface mesh is also 2-manifold after the edge collapse.
|
||||
* \pre `get(edge_is_constrained_map, v0v1) == false`.
|
||||
* Furthermore, the edge `e` must satisfy the link condition, which guarantees that the surface mesh is also 2-manifold after the edge collapse.
|
||||
* \pre `get(edge_is_constrained_map, e) == false`.
|
||||
* \pre `v0` and `v1` are not both incident to a constrained edge.
|
||||
*/
|
||||
|
||||
template<typename Graph, typename EdgeIsConstrainedMap>
|
||||
typename boost::graph_traits<Graph>::vertex_descriptor
|
||||
collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor v0v1,
|
||||
collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor e,
|
||||
Graph& g,
|
||||
EdgeIsConstrainedMap Edge_is_constrained_map)
|
||||
{
|
||||
|
|
@ -1704,11 +1703,11 @@ collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor v0v1,
|
|||
typedef typename Traits::vertex_descriptor vertex_descriptor;
|
||||
typedef typename Traits::halfedge_descriptor halfedge_descriptor;
|
||||
|
||||
CGAL_precondition(is_valid_edge_descriptor(v0v1, g));
|
||||
CGAL_precondition(does_satisfy_link_condition(v0v1,g));
|
||||
CGAL_precondition(!get(Edge_is_constrained_map, v0v1));
|
||||
CGAL_precondition(is_valid_edge_descriptor(e, g));
|
||||
CGAL_precondition(does_satisfy_link_condition(e,g));
|
||||
CGAL_precondition(!get(Edge_is_constrained_map, e));
|
||||
|
||||
halfedge_descriptor pq = halfedge(v0v1,g);
|
||||
halfedge_descriptor pq = halfedge(e,g);
|
||||
|
||||
halfedge_descriptor qp = opposite(pq,g);
|
||||
halfedge_descriptor pt = opposite(prev(pq,g),g);
|
||||
|
|
@ -1718,6 +1717,8 @@ collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor v0v1,
|
|||
|
||||
bool lTopFaceExists = ! is_border(pq,g) ;
|
||||
bool lBottomFaceExists = ! is_border(qp,g) ;
|
||||
bool lTopIsTriangle = lTopFaceExists && is_triangle(pq,g);
|
||||
bool lBottomIsTriangle = lBottomFaceExists && is_triangle(qp,g);
|
||||
|
||||
vertex_descriptor q = target(pq,g);
|
||||
vertex_descriptor p = source(pq,g);
|
||||
|
|
@ -1728,7 +1729,7 @@ collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor v0v1,
|
|||
|
||||
// If the top facet exists, we need to choose one out of the two edges which one disappears:
|
||||
// p-t if it is not constrained and t-q otherwise
|
||||
if ( lTopFaceExists )
|
||||
if ( lTopIsTriangle )
|
||||
{
|
||||
if ( !get(Edge_is_constrained_map,edge(pt,g)) )
|
||||
{
|
||||
|
|
@ -1742,7 +1743,7 @@ collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor v0v1,
|
|||
|
||||
// If the bottom facet exists, we need to choose one out of the two edges which one disappears:
|
||||
// q-b if it is not constrained and b-p otherwise
|
||||
if ( lBottomFaceExists )
|
||||
if ( lBottomIsTriangle )
|
||||
{
|
||||
if ( !get(Edge_is_constrained_map,edge(qb,g)) )
|
||||
{
|
||||
|
|
@ -1753,7 +1754,7 @@ collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor v0v1,
|
|||
}
|
||||
}
|
||||
|
||||
if (lTopFaceExists && lBottomFaceExists)
|
||||
if (lTopIsTriangle && lBottomIsTriangle)
|
||||
{
|
||||
if ( face(edges_to_erase[0],g) == face(edges_to_erase[1],g)
|
||||
&& (! is_border(edges_to_erase[0],g)) )
|
||||
|
|
@ -1800,7 +1801,7 @@ collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor v0v1,
|
|||
}
|
||||
else
|
||||
{
|
||||
if (lTopFaceExists)
|
||||
if (lTopIsTriangle)
|
||||
{
|
||||
if (!(is_border(edges_to_erase[0],g))){
|
||||
join_face(edges_to_erase[0],g);
|
||||
|
|
@ -1815,21 +1816,32 @@ collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor v0v1,
|
|||
remove_face(opposite(edges_to_erase[0],g),g);
|
||||
return q;
|
||||
}
|
||||
|
||||
if (! (is_border(edges_to_erase[0],g))){
|
||||
// q will be removed, swap it with p
|
||||
internal::swap_vertices(p, q, g);
|
||||
join_face(edges_to_erase[0],g);
|
||||
join_vertex(qp,g);
|
||||
return q;
|
||||
}
|
||||
if(!is_border(opposite(next(qp,g),g),g))
|
||||
else
|
||||
{
|
||||
// q will be removed, swap it with p
|
||||
internal::swap_vertices(p, q, g);
|
||||
if (lBottomIsTriangle)
|
||||
{
|
||||
if (! (is_border(edges_to_erase[0],g))){
|
||||
// q will be removed, swap it with p
|
||||
internal::swap_vertices(p, q, g);
|
||||
join_face(edges_to_erase[0],g);
|
||||
CGAL_assertion(source(qp,g)==p);
|
||||
join_vertex(qp,g);
|
||||
return q;
|
||||
}
|
||||
if(!is_border(opposite(next(qp,g),g),g))
|
||||
{
|
||||
// q will be removed, swap it with p
|
||||
internal::swap_vertices(p, q, g);
|
||||
}
|
||||
remove_face(opposite(edges_to_erase[0],g),g);
|
||||
return q;
|
||||
}
|
||||
else
|
||||
{
|
||||
join_vertex(pq,g);
|
||||
return q;
|
||||
}
|
||||
}
|
||||
remove_face(opposite(edges_to_erase[0],g),g);
|
||||
return q;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
#include <CGAL/boost/graph/IO/Generic_facegraph_builder.h>
|
||||
#include <CGAL/Named_function_parameters.h>
|
||||
#include <CGAL/boost/graph/named_params_helper.h>
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
|
|
@ -44,7 +45,7 @@ class PLY_builder
|
|||
typedef typename Base::Face_container Face_container;
|
||||
|
||||
public:
|
||||
PLY_builder(std::istream& is) : Base(is) { }
|
||||
PLY_builder(std::istream& is, std::string& comments) : Base(is), comments(comments) { }
|
||||
|
||||
template <typename NamedParameters>
|
||||
bool read(std::istream& is,
|
||||
|
|
@ -52,19 +53,22 @@ public:
|
|||
Face_container& faces,
|
||||
const NamedParameters& np)
|
||||
{
|
||||
return read_PLY(is, points, faces, np);
|
||||
return read_PLY(is, points, faces, comments, np);
|
||||
}
|
||||
|
||||
std::string& comments;
|
||||
};
|
||||
|
||||
template <typename Graph, typename CGAL_NP_TEMPLATE_PARAMETERS>
|
||||
bool read_PLY_BGL(std::istream& is,
|
||||
Graph& g,
|
||||
std::string& comments,
|
||||
const CGAL_NP_CLASS& np = parameters::default_values())
|
||||
{
|
||||
typedef typename CGAL::GetVertexPointMap<Graph, CGAL_NP_CLASS>::type VPM;
|
||||
typedef typename boost::property_traits<VPM>::value_type Point;
|
||||
|
||||
internal::PLY_builder<Graph, Point> builder(is);
|
||||
internal::PLY_builder<Graph, Point> builder(is, comments);
|
||||
return builder(g, np);
|
||||
}
|
||||
|
||||
|
|
@ -84,6 +88,7 @@ bool read_PLY_BGL(std::istream& is,
|
|||
|
||||
\param is the input stream
|
||||
\param g the graph to be built from the input data
|
||||
\param comments a string included line by line in the header of the PLY stream (each line will be precedeed by "comment ")
|
||||
\param np optional \ref bgl_namedparameters "Named Parameters" described below
|
||||
|
||||
\cgalNamedParamsBegin
|
||||
|
|
@ -132,15 +137,31 @@ template <typename Graph,
|
|||
typename CGAL_NP_TEMPLATE_PARAMETERS>
|
||||
bool read_PLY(std::istream& is,
|
||||
Graph& g,
|
||||
std::string& comments,
|
||||
const CGAL_NP_CLASS& np = parameters::default_values()
|
||||
#ifndef DOXYGEN_RUNNING
|
||||
, std::enable_if_t<!internal::is_Point_set_or_Range_or_Iterator<Graph>::value>* = nullptr
|
||||
#endif
|
||||
)
|
||||
{
|
||||
return internal::read_PLY_BGL(is, g, np);
|
||||
return internal::read_PLY_BGL(is, g, comments, np);
|
||||
}
|
||||
|
||||
template <typename Graph,
|
||||
typename CGAL_NP_TEMPLATE_PARAMETERS>
|
||||
bool read_PLY(std::istream& is,
|
||||
Graph& g,
|
||||
const CGAL_NP_CLASS& np = parameters::default_values()
|
||||
#ifndef DOXYGEN_RUNNING
|
||||
, std::enable_if_t<!internal::is_Point_set_or_Range_or_Iterator<Graph>::value>* = nullptr
|
||||
#endif
|
||||
)
|
||||
{
|
||||
std::string unused_comments;
|
||||
return internal::read_PLY_BGL(is, g, unused_comments, np);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\ingroup PkgBGLIoFuncsPLY
|
||||
|
||||
|
|
@ -153,6 +174,7 @@ bool read_PLY(std::istream& is,
|
|||
|
||||
\param fname the name of the input file
|
||||
\param g the graph to be built from the input data
|
||||
\param comments a string included line by line in the header of the PLY stream (each line will be precedeed by "comment" )
|
||||
\param np optional \ref bgl_namedparameters "Named Parameters" described below
|
||||
|
||||
\cgalNamedParamsBegin
|
||||
|
|
@ -207,6 +229,7 @@ template <typename Graph,
|
|||
typename CGAL_NP_TEMPLATE_PARAMETERS>
|
||||
bool read_PLY(const std::string& fname,
|
||||
Graph& g,
|
||||
std::string& comments,
|
||||
const CGAL_NP_CLASS& np = parameters::default_values()
|
||||
#ifndef DOXYGEN_RUNNING
|
||||
, std::enable_if_t<!internal::is_Point_set_or_Range_or_Iterator<Graph>::value>* = nullptr
|
||||
|
|
@ -218,16 +241,29 @@ bool read_PLY(const std::string& fname,
|
|||
{
|
||||
std::ifstream is(fname, std::ios::binary);
|
||||
CGAL::IO::set_mode(is, CGAL::IO::BINARY);
|
||||
return internal::read_PLY_BGL(is, g, np);
|
||||
return read_PLY(is, g, comments, np);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::ifstream is(fname);
|
||||
CGAL::IO::set_mode(is, CGAL::IO::ASCII);
|
||||
return internal::read_PLY_BGL(is, g, np);
|
||||
return read_PLY(is, g, comments, np);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Graph,
|
||||
typename CGAL_NP_TEMPLATE_PARAMETERS>
|
||||
bool read_PLY(const std::string& fname,
|
||||
Graph& g,
|
||||
const CGAL_NP_CLASS& np = parameters::default_values()
|
||||
#ifndef DOXYGEN_RUNNING
|
||||
, std::enable_if_t<!internal::is_Point_set_or_Range_or_Iterator<Graph>::value>* = nullptr
|
||||
#endif
|
||||
)
|
||||
{
|
||||
std::string unused_comment;
|
||||
return read_PLY(fname, g, unused_comment, np);
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Write
|
||||
|
|
@ -259,6 +295,15 @@ bool read_PLY(const std::string& fname,
|
|||
must be available in `Graph`.}
|
||||
\cgalParamNEnd
|
||||
|
||||
\cgalParamNBegin{vertex_normal_map}
|
||||
\cgalParamDescription{a property map associating normals to the vertices of `g`}
|
||||
\cgalParamType{a class model of `ReadablePropertyMap` with `boost::graph_traits<Graph>::%vertex_descriptor`
|
||||
as key type and `%Vector_3` as value type}
|
||||
\cgalParamDefault{`boost::get(CGAL::vertex_point, g)`}
|
||||
\cgalParamExtra{If this parameter is omitted, an internal property map for `CGAL::vertex_point_t`
|
||||
must be available in `Graph`.}
|
||||
\cgalParamNEnd
|
||||
|
||||
\cgalParamNBegin{vertex_index_map}
|
||||
\cgalParamDescription{a property map associating to each vertex of `graph` a unique index}
|
||||
\cgalParamType{a class model of `WritablePropertyMap` with `boost::graph_traits<Graph>::%vertex_descriptor`
|
||||
|
|
@ -326,6 +371,8 @@ bool write_PLY(std::ostream& os,
|
|||
|
||||
bool has_vcolor = !is_default_parameter<CGAL_NP_CLASS, internal_np::vertex_color_map_t>::value;
|
||||
bool has_fcolor = !is_default_parameter<CGAL_NP_CLASS, internal_np::face_color_map_t>::value;
|
||||
constexpr bool has_vnormal = !is_default_parameter<CGAL_NP_CLASS, internal_np::vertex_normal_map_t>::value;
|
||||
|
||||
VIMap vim = CGAL::get_initialized_vertex_index_map(g, np);
|
||||
Vpm vpm = choose_parameter(get_parameter(np, internal_np::vertex_point),
|
||||
get_const_property_map(boost::vertex_point, g));
|
||||
|
|
@ -351,8 +398,20 @@ bool write_PLY(std::ostream& os,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
os << "element vertex " << vertices(g).size() << std::endl;
|
||||
internal::output_property_header(os, make_ply_point_writer (CGAL::Identity_property_map<Point_3>()));
|
||||
if constexpr (std::is_same<typename Kernel_traits<Point_3>::Kernel::FT, float>::value)
|
||||
{
|
||||
internal::output_property_header(os, make_ply_point_writer (CGAL::Identity_property_map<Point_3>()));
|
||||
}
|
||||
else
|
||||
{
|
||||
typedef typename Kernel_traits<Point_3>::Kernel K;
|
||||
typedef decltype(std::declval<CGAL::Cartesian_converter<K, Epick> >().operator()(std::declval<Point_3>())) Target_point;
|
||||
auto fvpm = CGAL::make_cartesian_converter_property_map<Target_point>(vpm);
|
||||
internal::output_property_header(os, make_ply_point_writer (fvpm));
|
||||
}
|
||||
|
||||
//if vcm is not default add v:color property
|
||||
if(has_vcolor)
|
||||
{
|
||||
|
|
@ -362,10 +421,30 @@ bool write_PLY(std::ostream& os,
|
|||
<< "property uchar alpha" << std::endl;
|
||||
}
|
||||
|
||||
if constexpr (has_vnormal)
|
||||
{
|
||||
auto vnm = get_parameter(np, internal_np::vertex_normal_map);
|
||||
typedef decltype(vnm) Normal_map;
|
||||
typedef typename Normal_map::value_type Vector_3;
|
||||
typedef typename Kernel_traits<Vector_3>::Kernel K;
|
||||
typedef typename K::FT FT;
|
||||
if constexpr (std::is_same<FT, float>::value)
|
||||
{
|
||||
internal::output_property_header(os, make_ply_normal_writer (CGAL::Identity_property_map<Vector_3>()));
|
||||
}
|
||||
else
|
||||
{
|
||||
typedef decltype(std::declval<CGAL::Cartesian_converter<K, Epick> >().operator()(std::declval<Vector_3>())) Target_vector;
|
||||
auto fvnm = CGAL::make_cartesian_converter_property_map<Target_vector>(vnm);
|
||||
internal::output_property_header(os, make_ply_normal_writer (fvnm));
|
||||
}
|
||||
}
|
||||
|
||||
os << "element face " << faces(g).size() << std::endl;
|
||||
internal::output_property_header(
|
||||
os, std::make_pair(CGAL::Identity_property_map<std::vector<std::size_t> >(),
|
||||
PLY_property<std::vector<int> >("vertex_indices")));
|
||||
|
||||
//if fcm is not default add f:color property
|
||||
if(has_fcolor)
|
||||
{
|
||||
|
|
@ -378,8 +457,42 @@ bool write_PLY(std::ostream& os,
|
|||
|
||||
for(vertex_descriptor vd : vertices(g))
|
||||
{
|
||||
const Point_3& p = get(vpm, vd);
|
||||
internal::output_properties(os, &p, make_ply_point_writer (CGAL::Identity_property_map<Point_3>()));
|
||||
if constexpr (std::is_same<typename Kernel_traits<Point_3>::Kernel::FT, float>::value)
|
||||
{
|
||||
decltype(auto) p = get(vpm, vd);
|
||||
internal::output_properties(os, &p, make_ply_point_writer (CGAL::Identity_property_map<Point_3>()));
|
||||
}
|
||||
else
|
||||
{
|
||||
typedef typename Kernel_traits<Point_3>::Kernel K;
|
||||
typedef CGAL::cpp20::remove_cvref_t<decltype(std::declval<CGAL::Cartesian_converter<K, Epick> >().operator()(std::declval<Point_3>()))> Target_point;
|
||||
CGAL::Cartesian_converter_property_map<Target_point, Vpm> fvpm = CGAL::make_cartesian_converter_property_map<Target_point>(vpm);
|
||||
decltype(auto) fp = get(fvpm, vd);
|
||||
internal::output_properties(os, &fp, make_ply_point_writer (CGAL::Identity_property_map<Target_point>()));
|
||||
}
|
||||
|
||||
std::cout << "using generic writer" << std::endl;
|
||||
|
||||
if constexpr (!parameters::is_default_parameter<CGAL_NP_CLASS, internal_np::vertex_normal_map_t>::value)
|
||||
{
|
||||
auto vnm = get_parameter(np, internal_np::vertex_normal_map);
|
||||
typedef decltype(vnm) Normal_map;
|
||||
typedef typename Normal_map::value_type Vector_3;
|
||||
|
||||
if constexpr (std::is_same<typename Kernel_traits<Vector_3>::Kernel::FT, float>::value)
|
||||
{
|
||||
decltype(auto) vec = get(vnm,vd);
|
||||
internal::output_properties(os, &vec, make_ply_normal_writer (CGAL::Identity_property_map<Vector_3>()));
|
||||
}
|
||||
else
|
||||
{
|
||||
typedef typename Kernel_traits<Vector_3>::Kernel K;
|
||||
typedef CGAL::cpp20::remove_cvref_t<decltype(std::declval<CGAL::Cartesian_converter<K, Epick> >().operator()(std::declval<Vector_3>()))> Target_vector;
|
||||
auto fvnm = CGAL::make_cartesian_converter_property_map<Target_vector>(vnm);
|
||||
decltype(auto) fvec = get(fvnm, vd);
|
||||
internal::output_properties(os, &fvec, make_ply_normal_writer (CGAL::Identity_property_map<Target_vector>()));
|
||||
}
|
||||
}
|
||||
if(has_vcolor)
|
||||
{
|
||||
const CGAL::IO::Color& c = get(vcm, vd);
|
||||
|
|
@ -455,6 +568,15 @@ bool write_PLY(std::ostream& os, const Graph& g, const CGAL_NP_CLASS& np = param
|
|||
must be available in `Graph`.}
|
||||
\cgalParamNEnd
|
||||
|
||||
\cgalParamNBegin{vertex_normal_map}
|
||||
\cgalParamDescription{a property map associating normals to the vertices of `g`}
|
||||
\cgalParamType{a class model of `ReadablePropertyMap` with `boost::graph_traits<Graph>::%vertex_descriptor`
|
||||
as key type and `%Vector_3` as value type}
|
||||
\cgalParamDefault{`boost::get(CGAL::vertex_point, g)`}
|
||||
\cgalParamExtra{If this parameter is omitted, an internal property map for `CGAL::vertex_point_t`
|
||||
must be available in `Graph`.}
|
||||
\cgalParamNEnd
|
||||
|
||||
\cgalParamNBegin{vertex_index_map}
|
||||
\cgalParamDescription{a property map associating to each vertex of `graph` a unique index between `0` and `num_vertices(graph) - 1`}
|
||||
\cgalParamType{a class model of `ReadablePropertyMap` with `boost::graph_traits<Graph>::%vertex_descriptor`
|
||||
|
|
|
|||
|
|
@ -1,13 +1,19 @@
|
|||
Algebraic_foundations
|
||||
Arithmetic_kernel
|
||||
BGL
|
||||
Cartesian_kernel
|
||||
Circulator
|
||||
Distance_2
|
||||
Distance_3
|
||||
Filtered_kernel
|
||||
Homogeneous_kernel
|
||||
Hash_map
|
||||
Installation
|
||||
Intersections_2
|
||||
Intersections_3
|
||||
Interval_support
|
||||
Kernel_23
|
||||
Kernel_d
|
||||
Modular_arithmetic
|
||||
Number_types
|
||||
Profiling_tools
|
||||
|
|
@ -15,3 +21,4 @@ Property_map
|
|||
Random_numbers
|
||||
STL_Extension
|
||||
Stream_support
|
||||
CGAL_Core
|
||||
|
|
|
|||
|
|
@ -0,0 +1,42 @@
|
|||
OFF
|
||||
25 13 0
|
||||
|
||||
0.39160239696502686 1.3864846229553223 4.8046874923102223e-08
|
||||
0.053782559931278229 1.3864846229553223 4.8046874923102223e-08
|
||||
-0.94644606113433838 1.6651756763458252 4.8046874923102223e-08
|
||||
-1.3082554340362549 1.7385153770446777 4.8046874923102223e-08
|
||||
-1.3033660650253296 1.1860226392745972 4.8046874923102223e-08
|
||||
1.61628258228302 -0.17601536214351654 4.8046874923102223e-08
|
||||
0.55834579467773438 -0.19216139614582062 4.8046874923102223e-08
|
||||
0.053782559931278229 -0.17601536214351654 4.8046874923102223e-08
|
||||
-0.24240998923778534 -0.22679123282432556 4.8046874923102223e-08
|
||||
-0.58168435096740723 -0.25845989584922791 4.8046874923102223e-08
|
||||
-1.2915089130401611 -0.17601536214351654 4.8046874923102223e-08
|
||||
-1.50871741771698 -0.17601536214351654 4.8046874923102223e-08
|
||||
1.61628258228302 -1.7385153770446777 4.8046874923102223e-08
|
||||
1.1978726387023926 -1.7385153770446777 4.8046874923102223e-08
|
||||
0.71942150592803955 -1.7385153770446777 4.8046874923102223e-08
|
||||
0.053782559931278229 -1.7385153770446777 4.8046874923102223e-08
|
||||
-0.73973840475082397 -1.7385153770446777 4.8046874923102223e-08
|
||||
1.61628258228302 0.36264327168464661 4.8046874923102223e-08
|
||||
-0.26156377792358398 0.45463424921035767 4.8046874923102223e-08
|
||||
-0.028661971911787987 -0.78840988874435425 4.8046874923102223e-08
|
||||
0.053782559931278229 -1.2213115692138672 4.8046874923102223e-08
|
||||
-1.5918357372283936 1.5331641435623169 4.8046874923102223e-08
|
||||
-1.6162823438644409 0.87338578701019287 4.8046874923102223e-08
|
||||
-1.50871741771698 -0.0072435899637639523 4.8046874923102223e-08
|
||||
-1.50871741771698 -1.3000825643539429 4.8046874923102223e-08
|
||||
7 18 2 3 4 22 9 8
|
||||
3 2 18 1
|
||||
7 18 7 6 5 17 0 1
|
||||
7 12 5 6 7 8 19 13
|
||||
6 11 24 16 15 20 10
|
||||
3 9 19 8
|
||||
4 10 20 19 9
|
||||
3 7 18 8
|
||||
3 14 20 15
|
||||
4 13 19 20 14
|
||||
3 3 21 4
|
||||
4 9 22 23 10
|
||||
3 10 23 11
|
||||
|
||||
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
#include <CGAL/boost/graph/Euler_operations.h>
|
||||
#include <CGAL/boost/graph/IO/OFF.h>
|
||||
|
||||
#include <boost/range/distance.hpp>
|
||||
|
||||
#include <string>
|
||||
|
|
@ -213,12 +212,30 @@ collapse_edge_test()
|
|||
assert(found == 2);
|
||||
CGAL::clear(test_mesh);
|
||||
}
|
||||
// Case 6 non pure triangle mesh
|
||||
{
|
||||
Mesh ref;
|
||||
if(!CGAL::IO::read_OFF("data/polygon_mesh_to_collapse.off", ref))
|
||||
{
|
||||
std::cout << "Error reading file: data/polygon_mesh_to_collapse.off" << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
std::size_t nbe=halfedges(ref).size();
|
||||
for (std::size_t i=0; i< nbe; ++i)
|
||||
{
|
||||
Mesh m = ref;
|
||||
auto h = *std::next(halfedges(m).begin(), i);
|
||||
|
||||
if (CGAL::Euler::does_satisfy_link_condition(edge(h,m),m))
|
||||
CGAL::Euler::collapse_edge(edge(h,m), m);
|
||||
assert(CGAL::is_valid_polygon_mesh(m));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
collapse_edge_test<Polyhedron>();
|
||||
collapse_edge_test<SM>();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
# Created by the script cgal_create_cmake_script.
|
||||
# This is the CMake script for compiling a CGAL application.
|
||||
|
||||
project(Barycentric_coordinates_2_Benchmarks)
|
||||
|
||||
cmake_minimum_required(VERSION 3.12...3.31)
|
||||
project(Barycentric_coordinates_2_Benchmarks)
|
||||
|
||||
find_package(CGAL REQUIRED COMPONENTS Core)
|
||||
|
||||
|
|
@ -14,8 +12,9 @@ create_single_source_cgal_program("benchmark_polygon_16_vertices.cpp")
|
|||
create_single_source_cgal_program("benchmark_polygon_100_vertices.cpp")
|
||||
create_single_source_cgal_program("benchmark_mv_34_vertices.cpp")
|
||||
|
||||
find_package(Eigen3 3.1.0 QUIET) # (3.1.0 or greater)
|
||||
find_package(Eigen3 QUIET)
|
||||
include(CGAL_Eigen3_support)
|
||||
|
||||
if(TARGET CGAL::Eigen3_support)
|
||||
create_single_source_cgal_program("benchmark_hm_4_vertices.cpp")
|
||||
target_link_libraries(benchmark_hm_4_vertices PRIVATE CGAL::Eigen3_support)
|
||||
|
|
|
|||
|
|
@ -17,8 +17,9 @@ create_single_source_cgal_program("terrain_height_modeling.cpp")
|
|||
# this code is deprecated:
|
||||
create_single_source_cgal_program("deprecated_coordinates.cpp")
|
||||
|
||||
find_package(Eigen3 3.1.0 QUIET) # (3.1.0 or greater)
|
||||
find_package(Eigen3 QUIET)
|
||||
include(CGAL_Eigen3_support)
|
||||
|
||||
if(TARGET CGAL::Eigen3_support)
|
||||
create_single_source_cgal_program("affine_coordinates.cpp")
|
||||
target_link_libraries(affine_coordinates PRIVATE CGAL::Eigen3_support)
|
||||
|
|
|
|||
|
|
@ -42,8 +42,9 @@ create_single_source_cgal_program("test_wp_deprecated_api.cpp")
|
|||
create_single_source_cgal_program("test_mv_deprecated_api.cpp")
|
||||
create_single_source_cgal_program("test_dh_deprecated_api.cpp")
|
||||
|
||||
find_package(Eigen3 3.1.0 QUIET) # (3.1.0 or greater)
|
||||
find_package(Eigen3 QUIET)
|
||||
include(CGAL_Eigen3_support)
|
||||
|
||||
if(TARGET CGAL::Eigen3_support)
|
||||
create_single_source_cgal_program("test_hm_unit_square.cpp")
|
||||
target_link_libraries(test_hm_unit_square PRIVATE CGAL::Eigen3_support)
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ project(Basic_viewer_Examples)
|
|||
|
||||
#CGAL_Qt6 is needed for the drawing.
|
||||
find_package(CGAL REQUIRED OPTIONAL_COMPONENTS Qt6)
|
||||
find_package(Eigen3 3.1.0)
|
||||
find_package(Eigen3 QUIET)
|
||||
include(CGAL_Eigen3_support)
|
||||
|
||||
create_single_source_cgal_program("draw_lcc.cpp")
|
||||
|
|
|
|||
|
|
@ -700,15 +700,29 @@ swap its source and target points).
|
|||
The traits classes `Arr_segment_traits_2`,
|
||||
`Arr_non_caching_segment_traits_2`, `Arr_circle_segment_traits_2`,
|
||||
`Arr_conic_traits_2` and `Arr_rational_function_traits_2`, which are
|
||||
bundled in the `Arrangement_2` package and distributed with \cgal,
|
||||
are all models of the refined concept
|
||||
`AosDirectionalXMonotoneTraits_2`.\cgalFootnote{The \cgalFootnoteCode{Arr_polyline_traits_2} class is <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.}
|
||||
bundled in the `Arrangement_2` package and distributed with \cgal, are
|
||||
all models of the refined concept
|
||||
`AosDirectionalXMonotoneTraits_2`.\cgalFootnote{The
|
||||
\cgalFootnoteCode{Arr_polyline_traits_2} class is <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
|
||||
`AosXMonotoneTraits_2` concept, operations are robust only
|
||||
when exact arithmetic is used. When inexact arithmetic is used,
|
||||
(nearly) degenerate configurations may result in abnormal termination
|
||||
of the program or even incorrect results.
|
||||
Operations on polygons (or general polygons) are guaranteed to be
|
||||
robust only if the operations of the geometry traits used to carry out
|
||||
the high-level operations are robust. Most operations on polygons use
|
||||
geometry traits constructors, as they generate new polygons; such
|
||||
constructors are guaranteed to be robust only if the kernel in use
|
||||
supports exact constructions, such as the EPEC (Exact Predicate Exact
|
||||
Construction) kernel. The `do_intersect()` overloaded predicates that
|
||||
operate on (linear) polygons are exceptions, as they only use geometry
|
||||
traits predicates; such predicates are guaranteed to be robust only if
|
||||
the kernel in use supports exact predicates, such as the EPIC (Exact
|
||||
Predicate Inexact Construction) kernel. When inexact arithmetic is
|
||||
used, (nearly) degenerate configurations may result in abnormal
|
||||
termination of the program or even incorrect results.
|
||||
|
||||
\subsection bso_sseccirc_seg Operating on Polygons with Circular Arcs
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
* </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
|
||||
* treated as a cyclic sequence of single (\f$x\f$-monotone) segments or as a
|
||||
* cyclic sequence of (\f$x\f$-monotone) polylines. If substituted with
|
||||
|
|
@ -28,7 +32,7 @@ namespace CGAL {
|
|||
* to a standard polygon. If substituted with `CGAL::Tag_false`, the input
|
||||
* polygon is used as is. Refer to \ref bso_ssectraits_sel for more information.
|
||||
*
|
||||
* - The types `Type` and `Type2` of the parameters must be convertible to the
|
||||
* - The types `Type1` and `Type2` of the parameters must be convertible to the
|
||||
* types specified in a row in the table below, respectively.
|
||||
* - The types that apply to signature (<b>1.1.</b>) above are restricted to those
|
||||
* 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_difference `CGAL::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>
|
||||
* </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
|
||||
* are treated as cyclic sequences of single (\f$x\f$-monotone) segments or as
|
||||
* cyclic sequences of (\f$x\f$-monotone) polylines. If substituted with
|
||||
|
|
@ -264,6 +274,8 @@ namespace CGAL {
|
|||
* \sa \link boolean_intersection `CGAL::intersection()` \endlink
|
||||
* \sa \link boolean_join `CGAL::join()` \endlink
|
||||
* \sa \link boolean_symmetric_difference `CGAL::symmetric_difference()` \endlink
|
||||
* \sa Polygon_2<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
|
||||
* the following signatures:
|
||||
* <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.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>1.</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>
|
||||
* </table>
|
||||
*
|
||||
* There are also function templates that accept one or two ranges of input polygons:
|
||||
* <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.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>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.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>3.</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>5.</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>
|
||||
* </table>
|
||||
*
|
||||
* \tparam UsePolylines determines whether the boundary of the input polygons
|
||||
* are treated as a cyclic sequence of single (\f$x\f$-monotone) segments or as
|
||||
* a cyclic sequence of (\f$x\f$-monotone) polylines. If substituted with
|
||||
* `CGAL::Tag_true`, which is the default, the input polygons are converted to
|
||||
* general polygons bounded by polylines before the operation is actually
|
||||
* performed. If substituted with `CGAL::Tag_false`, the input polygons are used
|
||||
* as is. Refer to \ref bso_ssectraits_sel for more information.
|
||||
*
|
||||
* - The types `Type1` and `Type2` of the parameters of
|
||||
* `InputIterator1::value_type` and `InputIterator2::value_type` must be
|
||||
* convertible to the types specified in a row in the table below,
|
||||
* respectively.
|
||||
*
|
||||
* - The types that apply to signatures (<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`.
|
||||
* \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`.
|
||||
*
|
||||
* <div align="left">
|
||||
* <table cellpadding=3 border="1">
|
||||
|
|
@ -728,6 +714,8 @@ namespace CGAL {
|
|||
* \sa \link boolean_join `CGAL::join()` \endlink
|
||||
* \sa \link boolean_difference `CGAL::difference()` \endlink
|
||||
* \sa \link boolean_symmetric_difference `CGAL::symmetric_difference()` \endlink
|
||||
* \sa Polygon_2<Kernel, Container>
|
||||
* \sa Polygon_with_holes_2<Kernel, Container>
|
||||
*/
|
||||
|
||||
/// @{
|
||||
|
|
@ -735,6 +723,11 @@ namespace CGAL {
|
|||
//////// Traits-less
|
||||
|
||||
/*! determines whether two polygons intersect in their interior.
|
||||
*
|
||||
* The kernel used to instantiate the type of the input polygons must support
|
||||
* exact predicates to guarantee correct results; however, inexact constructions
|
||||
* are tolerated.
|
||||
*
|
||||
* \param pgn1 the 1st input polygon.
|
||||
* \param pgn2 the 2nd input polygon.
|
||||
* \return `true` if `pgn1` and `pgn2` intersect in their interior and `false`
|
||||
|
|
@ -745,25 +738,11 @@ bool do_intersect(const Polygon_2<Kernel, Container>& pgn1,
|
|||
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 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.
|
||||
*
|
||||
* The kernel used to instantiate the type of the input polygons must support
|
||||
* exact predicates to guarantee correct results; however, inexact constructions
|
||||
* are tolerated.
|
||||
*
|
||||
* \param pgn1 the 1st input polygon.
|
||||
* \param pgn2 the 2nd input polygon.
|
||||
* \return `true` if `pgn1` and `pgn2` intersect in their interior and `false`
|
||||
|
|
@ -774,26 +753,11 @@ bool do_intersect(const Polygon_2<Kernel, Container>& pgn1,
|
|||
const Polygon_with_holes_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 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.
|
||||
*
|
||||
* The kernel used to instantiate the type of the input polygons must support
|
||||
* exact predicates to guarantee correct results; however, inexact constructions
|
||||
* are tolerated.
|
||||
*
|
||||
* \param pgn1 the 1st input polygon.
|
||||
* \param pgn2 the 2nd input polygon.
|
||||
* \return `true` if `pgn1` and `pgn2` intersect in their interior and `false`
|
||||
|
|
@ -803,27 +767,12 @@ template <typename Kernel, typename Container>
|
|||
bool do_intersect(const Polygon_with_holes_2<Kernel, Container>& pgn1,
|
||||
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.
|
||||
*
|
||||
* The kernel used to instantiate the type of the input polygons must support
|
||||
* exact predicates to guarantee correct results; however, inexact constructions
|
||||
* are tolerated.
|
||||
*
|
||||
* \param pgn1 the 1st input polygon.
|
||||
* \param pgn2 the 2nd input polygon.
|
||||
* \return `true` if `pgn1` and `pgn2` intersect in their interior and `false`
|
||||
|
|
@ -833,25 +782,6 @@ template <typename Kernel, typename Container>
|
|||
bool do_intersect(const Polygon_with_holes_2<Kernel, Container>& pgn1,
|
||||
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.
|
||||
* \param pgn1 the 1st input polygon.
|
||||
* \param pgn2 the 2nd input polygon.
|
||||
|
|
@ -904,6 +834,13 @@ bool do_intersect(const General_polygon_with_holes_2<Polygon>& pgn1,
|
|||
* of general polygons or a range of general polygons with holes) determines
|
||||
* whether the open polygons (respectively general polygons) in the range have a common
|
||||
* point.
|
||||
*
|
||||
* When the operation is applied to linear polygons (that is, the value type of
|
||||
* the input iterator is either `Polygon_2` or `Polygon_with_holes_2`), the
|
||||
* kernel used to instantiate the type of the input polygons must support exact
|
||||
* predicates to guarantee correct results; however, inexact constructions are
|
||||
* tolerated.
|
||||
*
|
||||
* \param begin the first iterator of the input range. Its value type is
|
||||
* either `Polygon_2` (respectively `General_polygon_2`) or
|
||||
* `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
|
|
@ -917,36 +854,16 @@ bool do_intersect(const General_polygon_with_holes_2<Polygon>& pgn1,
|
|||
template <typename InputIterator>
|
||||
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
|
||||
* with holes (respectively general polygons with holes) determines whether the open
|
||||
* polygons (respectively general polygons) in the two ranges have a common point.
|
||||
*
|
||||
* When the operation is applied to linear polygons (that is, the value type of
|
||||
* any input iterator is either `Polygon_2` or `Polygon_with_holes_2`), the
|
||||
* kernel used to instantiate the type of the input polygons must support exact
|
||||
* predicates to guarantee correct results; however, inexact constructions are
|
||||
* tolerated.
|
||||
*
|
||||
* \param begin1 the first iterator of the 1st input range. Its value type is
|
||||
* `Polygon_2` (respectively `General_polygon_2`).
|
||||
* \param end1 the past-the-end iterator of the 1st input range. Its value
|
||||
|
|
@ -964,40 +881,14 @@ template <typename InputIterator1, typename InputIterator2>
|
|||
bool do_intersect(InputIterator1 begin1, InputIterator1 end1,
|
||||
InputIterator2 begin2, InputIterator2 end2);
|
||||
|
||||
/*! Given a range of polygons (respectively general polygons) and a range of polygons
|
||||
* with holes (respectively general polygons with holes) determines whether the open
|
||||
* polygons (respectively general polygons) in the two ranges have a common point.
|
||||
* \tparam UsePolylines determines whether the boundaries of the polygons in the
|
||||
* input ranges are treated as cyclic sequences of single
|
||||
* (\f$x\f$-monotone) segments or as a cyclic sequences of
|
||||
* (\f$x\f$-monotone) polylines. If substituted with `CGAL::Tag_true`,
|
||||
* which is the default, the input polygons are converted to general
|
||||
* polygon with holes , bounded by polylines before the operation is
|
||||
* actually performed. If substituted with `CGAL::Tag_false`, `pgn1` and
|
||||
* `pgn2` are used as is. Refer to \ref bso_ssectraits_sel for more
|
||||
* information.
|
||||
* \param begin1 the first iterator of the 1st input range. Its value type is
|
||||
* `Polygon_2` (respectively `General_polygon_2`).
|
||||
* \param end1 the past-the-end iterator of the 1st input range. Its value
|
||||
* type is `Polygon_2` (respectively `General_polygon_2`).
|
||||
* \param begin2 the first iterator of the 2nd input range. Its value type
|
||||
* is `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \param end2 the past-the-end iterator of the 2nd input range. Its value
|
||||
* type is `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \return `true` if the pairwise intersections of all open polygons (respectively
|
||||
* general polygons) and polygons with holes (respectively general polygons with
|
||||
* holes) in the ranges [*begin1,*end1) and [*begin2,*end2),
|
||||
* respectively, overlap, and `false` otherwise.
|
||||
*/
|
||||
template <typename InputIterator1, typename InputIterator2,
|
||||
typename UsePolylines>
|
||||
bool do_intersect(InputIterator1 begin1, InputIterator1 end1,
|
||||
InputIterator2 begin2, InputIterator2 end2,
|
||||
UsePolylines = Tag_true());
|
||||
|
||||
//////// With Traits
|
||||
|
||||
/*! determines whether two polygons intersect in their interior.
|
||||
*
|
||||
* The kernel used to instantiate the type of the input polygons must support
|
||||
* exact predicates to guarantee correct results; however, inexact constructions
|
||||
* are tolerated.
|
||||
*
|
||||
* \param pgn1 the 1st input polygon.
|
||||
* \param pgn2 the 2nd input polygon.
|
||||
* \param traits a traits object.
|
||||
|
|
@ -1011,6 +902,11 @@ bool do_intersect(const Polygon_2<Kernel, Container>& pgn1,
|
|||
const GpsTraits& traits);
|
||||
|
||||
/*! determines whether two polygons intersect in their interior.
|
||||
*
|
||||
* The kernel used to instantiate the type of the input polygons must support
|
||||
* exact predicates to guarantee correct results; however, inexact constructions
|
||||
* are tolerated.
|
||||
*
|
||||
* \param pgn1 the 1st input polygon.
|
||||
* \param pgn2 the 2nd input polygon.
|
||||
* \param traits a traits object.
|
||||
|
|
@ -1021,10 +917,14 @@ bool do_intersect(const Polygon_2<Kernel, Container>& pgn1,
|
|||
template <typename Kernel, typename Container, typename GpsTraits>
|
||||
bool do_intersect(const Polygon_2<Kernel, Container>& pgn1,
|
||||
const Polygon_with_holes_2<Kernel, Container>& pgn2,
|
||||
const GpsTraits& traits,
|
||||
const GpsTraits& traits);
|
||||
|
||||
/*! determines whether two polygons intersect in their interior.
|
||||
*
|
||||
* The kernel used to instantiate the type of the input polygons must support
|
||||
* exact predicates to guarantee correct results; however, inexact constructions
|
||||
* are tolerated.
|
||||
*
|
||||
* \param pgn1 the 1st input polygon.
|
||||
* \param pgn2 the 2nd input polygon.
|
||||
* \param traits a traits object.
|
||||
|
|
@ -1038,6 +938,11 @@ bool do_intersect(const Polygon_with_holes_2<Kernel, Container>& pgn1,
|
|||
const GpsTraits& traits);
|
||||
|
||||
/*! determines whether two polygons with holes intersect in their interior.
|
||||
*
|
||||
* The kernel used to instantiate the type of the input polygons must support
|
||||
* exact predicates to guarantee correct results; however, inexact constructions
|
||||
* are tolerated.
|
||||
*
|
||||
* \param pgn1 the 1st input polygon.
|
||||
* \param pgn2 the 2nd input polygon.
|
||||
* \param traits a traits object.
|
||||
|
|
@ -1116,6 +1021,12 @@ bool do_intersect(const General_polygon_with_holes_2<Polygon>& pgn1,
|
|||
* of general polygons or a range of general polygons with holes) determines
|
||||
* whether the open polygons (respectively general polygons) in the range have a common
|
||||
* point.
|
||||
*
|
||||
* When the operation is applied to linear polygons (that is, the value type of
|
||||
* the input iterator is either `Polygon_2` or `Polygon_with_holes_2`), the
|
||||
* traits parameter `GpsTraits` must support exact predicates to guarantee
|
||||
* correct results; however, inexact constructions are tolerated.
|
||||
*
|
||||
* \param begin the first iterator of the input range. Its value type is
|
||||
* either `Polygon_2` (respectively `General_polygon_2`) or
|
||||
* `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
|
|
@ -1135,6 +1046,12 @@ bool do_intersect(InputIterator begin, InputIterator end,
|
|||
/*! Given a range of polygons (respectively general polygons) and a range of polygons
|
||||
* with holes (respectively general polygons with holes) determines whether the open
|
||||
* polygons (respectively general polygons) in the two ranges have a common point.
|
||||
*
|
||||
* When the operation is applied to linear polygons (that is, the value type of
|
||||
* any input iterator is either `Polygon_2` or `Polygon_with_holes_2`), the
|
||||
* traits parameter `GpsTraits` must support exact predicates to guarantee
|
||||
* correct results; however, inexact constructions are tolerated.
|
||||
*
|
||||
* \param begin1 the first iterator of the 1st input range. Its value type is
|
||||
* `Polygon_2` (respectively `General_polygon_2`).
|
||||
* \param end1 the past-the-end iterator of the 1st input range. Its value
|
||||
|
|
@ -1186,6 +1103,10 @@ namespace CGAL {
|
|||
* <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>
|
||||
*
|
||||
* \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
|
||||
* are treated as cyclic sequences of single (\f$x\f$-monotone) segments or as
|
||||
* cyclic sequences of (\f$x\f$-monotone) polylines. If substituted with
|
||||
|
|
@ -1244,6 +1165,8 @@ namespace CGAL {
|
|||
* \sa \link boolean_join `CGAL::join()` \endlink
|
||||
* \sa \link boolean_difference `CGAL::difference()` \endlink
|
||||
* \sa \link boolean_symmetric_difference `CGAL::symmetric_difference()` \endlink
|
||||
* \sa Polygon_2<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>
|
||||
* </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
|
||||
* are treated as cyclic sequences of single (\f$x\f$-monotone) segments or as
|
||||
* cyclic sequences of (\f$x\f$-monotone) polylines. If substituted with
|
||||
|
|
@ -1882,6 +1809,8 @@ namespace CGAL {
|
|||
* \sa \link boolean_intersection `CGAL::intersection()` \endlink
|
||||
* \sa \link boolean_difference `CGAL::difference()` \endlink
|
||||
* \sa \link boolean_symmetric_difference `CGAL::symmetric_difference()` \endlink
|
||||
* \sa Polygon_2<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>
|
||||
* </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
|
||||
* are treated as cyclic sequences of single (\f$x\f$-monotone) segments or as
|
||||
* cyclic sequences of (\f$x\f$-monotone) polylines. If substituted with
|
||||
|
|
@ -2446,6 +2379,8 @@ namespace CGAL {
|
|||
* \param traits an optional traits object.
|
||||
*
|
||||
* \sa \link boolean_do_intersect `CGAL::do_intersect()` \endlink
|
||||
* \sa Polygon_2<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>
|
||||
* </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
|
||||
* are treated as cyclic sequences of single (\f$x\f$-monotone) segments or as
|
||||
* cyclic sequences of (\f$x\f$-monotone) polylines. If substituted with
|
||||
|
|
@ -2879,6 +2818,8 @@ namespace CGAL {
|
|||
* \sa \link boolean_intersection `CGAL::intersection()` \endlink
|
||||
* \sa \link boolean_join `CGAL::join()` \endlink
|
||||
* \sa \link boolean_difference `CGAL::difference()` \endlink
|
||||
* \sa Polygon_2<Kernel, Container>
|
||||
* \sa Polygon_with_holes_2<Kernel, Container>
|
||||
*/
|
||||
|
||||
/// @{
|
||||
|
|
|
|||
|
|
@ -5,27 +5,26 @@
|
|||
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
||||
#include <CGAL/Boolean_set_operations_2.h>
|
||||
|
||||
typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel;
|
||||
typedef Kernel::Point_2 Point_2;
|
||||
typedef CGAL::Polygon_2<Kernel> Polygon_2;
|
||||
using Kernel = CGAL::Exact_predicates_exact_constructions_kernel;
|
||||
using Point_2 = Kernel::Point_2;
|
||||
using Polygon_2 = CGAL::Polygon_2<Kernel>;
|
||||
|
||||
#include "print_utils.h"
|
||||
|
||||
int main ()
|
||||
{
|
||||
int main() {
|
||||
Polygon_2 P;
|
||||
P.push_back (Point_2 (-1,1));
|
||||
P.push_back (Point_2 (0,-1));
|
||||
P.push_back (Point_2 (1,1));
|
||||
std::cout << "P = "; print_polygon (P);
|
||||
P.push_back(Point_2(-1, 1));
|
||||
P.push_back(Point_2(0, -1));
|
||||
P.push_back(Point_2(1, 1));
|
||||
std::cout << "P = "; print_polygon(P);
|
||||
|
||||
Polygon_2 Q;
|
||||
Q.push_back(Point_2 (-1,-1));
|
||||
Q.push_back(Point_2 (1,-1));
|
||||
Q.push_back(Point_2 (0,1));
|
||||
std::cout << "Q = "; print_polygon (Q);
|
||||
Q.push_back(Point_2(-1, -1));
|
||||
Q.push_back(Point_2(1, -1));
|
||||
Q.push_back(Point_2(0, 1));
|
||||
std::cout << "Q = "; print_polygon(Q);
|
||||
|
||||
if ((CGAL::do_intersect (P, Q)))
|
||||
if ((CGAL::do_intersect(P, Q)))
|
||||
std::cout << "The two polygons intersect in their interior." << std::endl;
|
||||
else
|
||||
std::cout << "The two polygons do not intersect." << std::endl;
|
||||
|
|
|
|||
|
|
@ -8,10 +8,10 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
||||
//
|
||||
//
|
||||
// Author(s): Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||
// Ron Wein <wein@post.tau.ac.il>
|
||||
// Efi Fogel <efif@post.tau.ac.il>
|
||||
// Simon Giraudot <simon.giraudot@geometryfactory.com>
|
||||
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||
// Ron Wein <wein@post.tau.ac.il>
|
||||
// Efi Fogel <efif@post.tau.ac.il>
|
||||
// Simon Giraudot <simon.giraudot@geometryfactory.com>
|
||||
|
||||
#ifndef CGAL_BSO_INTERNAL_FUNCTIONS_H
|
||||
#define CGAL_BSO_INTERNAL_FUNCTIONS_H
|
||||
|
|
@ -33,7 +33,7 @@ namespace CGAL {
|
|||
|
||||
// Single
|
||||
// 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) {
|
||||
General_polygon_set_2<Traits> gps(pgn1, traits);
|
||||
return gps.do_intersect(pgn2);
|
||||
|
|
@ -52,7 +52,7 @@ inline bool s_do_intersect(const Pgn1& pgn1, const Pgn2& pgn2) {
|
|||
// With Traits
|
||||
template <typename InputIterator, typename Traits>
|
||||
inline bool r_do_intersect(InputIterator begin, InputIterator end,
|
||||
Traits& traits, unsigned int k=5) {
|
||||
Traits& traits, std::size_t k = 5) {
|
||||
if (begin == end) return false;
|
||||
General_polygon_set_2<Traits> gps(*begin, traits);
|
||||
return gps.do_intersect(std::next(begin), end, k);
|
||||
|
|
@ -61,8 +61,8 @@ inline bool r_do_intersect(InputIterator begin, InputIterator end,
|
|||
// Without Traits
|
||||
template <typename InputIterator>
|
||||
inline bool r_do_intersect(InputIterator begin, InputIterator end,
|
||||
unsigned int k=5) {
|
||||
typedef typename std::iterator_traits<InputIterator>::value_type Pgn;
|
||||
std::size_t k = 5) {
|
||||
using Pgn = typename std::iterator_traits<InputIterator>::value_type;
|
||||
typename Gps_polyline_traits<Pgn>::Traits traits;
|
||||
const typename Gps_polyline_traits<Pgn>::Polyline_traits& ptraits(traits);
|
||||
return r_do_intersect(convert_polygon_iterator(begin, ptraits),
|
||||
|
|
@ -74,7 +74,7 @@ inline bool r_do_intersect(InputIterator begin, InputIterator end,
|
|||
template <typename InputIterator1, typename InputIterator2, typename Traits>
|
||||
inline bool r_do_intersect(InputIterator1 begin1, InputIterator1 end1,
|
||||
InputIterator2 begin2, InputIterator2 end2,
|
||||
Traits& traits, unsigned int k=5) {
|
||||
Traits& traits, std::size_t k = 5) {
|
||||
if (begin1 == end1) return do_intersect(begin2, end2, traits, k);
|
||||
General_polygon_set_2<Traits> gps(*begin1, traits);
|
||||
return gps.do_intersect(std::next(begin1), end1, begin2, end2, k);
|
||||
|
|
@ -84,8 +84,8 @@ inline bool r_do_intersect(InputIterator1 begin1, InputIterator1 end1,
|
|||
template <typename InputIterator1, typename InputIterator2>
|
||||
inline bool r_do_intersect (InputIterator1 begin1, InputIterator1 end1,
|
||||
InputIterator2 begin2, InputIterator2 end2,
|
||||
unsigned int k=5) {
|
||||
typedef typename std::iterator_traits<InputIterator1>::value_type Pgn;
|
||||
std::size_t k = 5) {
|
||||
using Pgn = typename std::iterator_traits<InputIterator1>::value_type;
|
||||
typename Gps_polyline_traits<Pgn>::Traits traits;
|
||||
const typename Gps_polyline_traits<Pgn>::Polyline_traits& ptraits(traits);
|
||||
return r_do_intersect(convert_polygon_iterator(begin1, ptraits),
|
||||
|
|
@ -119,8 +119,7 @@ inline Oriented_side _oriented_side(const Point_2<Kernel>& point,
|
|||
|
||||
// Without Traits (polygon, polygon)
|
||||
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
|
||||
typename Gps_polyline_traits<Pgn1>::Traits 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,
|
||||
OutputIterator oi) {
|
||||
// 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;
|
||||
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>
|
||||
inline OutputIterator r_intersection(InputIterator begin, InputIterator end,
|
||||
OutputIterator oi, Traits& traits,
|
||||
unsigned int k=5) {
|
||||
std::size_t k = 5) {
|
||||
if (begin == end) return (oi);
|
||||
General_polygon_set_2<Traits> gps(*begin, traits);
|
||||
gps.intersection(std::next(begin), end, k);
|
||||
|
|
@ -173,8 +172,8 @@ inline OutputIterator r_intersection(InputIterator begin, InputIterator end,
|
|||
// Without Traits
|
||||
template <typename InputIterator, typename OutputIterator>
|
||||
inline OutputIterator r_intersection(InputIterator begin, InputIterator end,
|
||||
OutputIterator oi, unsigned int k=5) {
|
||||
typedef typename std::iterator_traits<InputIterator>::value_type Pgn;
|
||||
OutputIterator oi, std::size_t k = 5) {
|
||||
using Pgn = typename std::iterator_traits<InputIterator>::value_type;
|
||||
typename Gps_polyline_traits<Pgn>::Traits traits;
|
||||
const typename Gps_polyline_traits<Pgn>::Polyline_traits& ptraits(traits);
|
||||
if (begin == end) return (oi);
|
||||
|
|
@ -190,7 +189,7 @@ template <typename InputIterator1, typename InputIterator2,
|
|||
inline OutputIterator r_intersection(InputIterator1 begin1, InputIterator1 end1,
|
||||
InputIterator2 begin2, InputIterator2 end2,
|
||||
OutputIterator oi, Traits& traits,
|
||||
unsigned int k=5) {
|
||||
std::size_t k = 5) {
|
||||
if (begin1 == end1) return r_intersection(begin2, end2, oi, traits, k);
|
||||
General_polygon_set_2<Traits> gps(*begin1, traits);
|
||||
gps.intersection(std::next(begin1), end1, begin2, end2, k);
|
||||
|
|
@ -203,8 +202,8 @@ template <typename InputIterator1, typename InputIterator2,
|
|||
inline OutputIterator
|
||||
r_intersection(InputIterator1 begin1, InputIterator1 end1,
|
||||
InputIterator2 begin2, InputIterator2 end2,
|
||||
OutputIterator oi, unsigned int k=5) {
|
||||
typedef typename std::iterator_traits<InputIterator1>::value_type Pgn;
|
||||
OutputIterator oi, std::size_t k = 5) {
|
||||
using Pgn = typename std::iterator_traits<InputIterator1>::value_type;
|
||||
typename Gps_polyline_traits<Pgn>::Traits traits;
|
||||
const typename Gps_polyline_traits<Pgn>::Polyline_traits& ptraits(traits);
|
||||
if (begin1 == end1) {
|
||||
|
|
@ -228,7 +227,7 @@ r_intersection(InputIterator1 begin1, InputIterator1 end1,
|
|||
// Polygon_2
|
||||
template <typename 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 =
|
||||
traits.construct_curves_2_object()(pgn);
|
||||
return (itr_pair.first == itr_pair.second);
|
||||
|
|
@ -268,9 +267,9 @@ template <typename Kernel, typename Container,
|
|||
typename Pgn1, typename Pgn2, typename Pwh>
|
||||
inline bool s_join(const Pgn1& pgn1, const Pgn2& pgn2, Pwh& pwh) {
|
||||
// Use the first polygon to determine the (default) traits
|
||||
typedef typename Gps_polyline_traits<Pgn1>::Polyline_traits Polyline_traits;
|
||||
typedef General_polygon_2<Polyline_traits> General_pgn;
|
||||
typedef General_polygon_with_holes_2<General_pgn> General_pwh;
|
||||
using Polyline_traits = typename Gps_polyline_traits<Pgn1>::Polyline_traits;
|
||||
using General_pgn = General_polygon_2<Polyline_traits>;
|
||||
using General_pwh = General_polygon_with_holes_2<General_pgn>;
|
||||
|
||||
General_pwh general_pwh;
|
||||
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>
|
||||
inline OutputIterator r_join(InputIterator begin, InputIterator end,
|
||||
OutputIterator oi, Traits& traits,
|
||||
unsigned int k=5) {
|
||||
std::size_t k = 5) {
|
||||
if (begin == end) return oi;
|
||||
General_polygon_set_2<Traits> gps(*begin, traits);
|
||||
gps.join(std::next(begin), end, k);
|
||||
|
|
@ -297,8 +296,8 @@ inline OutputIterator r_join(InputIterator begin, InputIterator end,
|
|||
// Without traits
|
||||
template <typename InputIterator, typename OutputIterator>
|
||||
inline OutputIterator r_join(InputIterator begin, InputIterator end,
|
||||
OutputIterator oi, unsigned int k=5) {
|
||||
typedef typename std::iterator_traits<InputIterator>::value_type Pgn;
|
||||
OutputIterator oi, std::size_t k = 5) {
|
||||
using Pgn = typename std::iterator_traits<InputIterator>::value_type;
|
||||
typename Gps_polyline_traits<Pgn>::Traits 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,
|
||||
InputIterator2 begin2, InputIterator2 end2,
|
||||
OutputIterator oi, Traits& traits,
|
||||
unsigned int k=5) {
|
||||
std::size_t k = 5) {
|
||||
if (begin1 == end1) return r_join(begin2, end2, oi, traits, k);
|
||||
General_polygon_set_2<Traits> gps(*begin1, traits);
|
||||
gps.join(std::next(begin1), end1, begin2, end2, k);
|
||||
|
|
@ -328,8 +327,8 @@ template <typename InputIterator1, typename InputIterator2,
|
|||
typename OutputIterator>
|
||||
inline OutputIterator r_join(InputIterator1 begin1, InputIterator1 end1,
|
||||
InputIterator2 begin2, InputIterator2 end2,
|
||||
OutputIterator oi, unsigned int k=5) {
|
||||
typedef typename std::iterator_traits<InputIterator1>::value_type Pgn;
|
||||
OutputIterator oi, std::size_t k = 5) {
|
||||
using Pgn = typename std::iterator_traits<InputIterator1>::value_type;
|
||||
typename Gps_polyline_traits<Pgn>::Traits traits;
|
||||
const typename Gps_polyline_traits<Pgn>::Polyline_traits& ptraits(traits);
|
||||
if (begin1 == end1) {
|
||||
|
|
@ -361,10 +360,9 @@ inline OutputIterator _difference(const Pgn1& pgn1, const Pgn2& pgn2,
|
|||
template <typename Kernel, typename Container,
|
||||
typename Pgn1, typename Pgn2, typename OutputIterator>
|
||||
inline OutputIterator _difference(const Pgn1& pgn1, const Pgn2& pgn2,
|
||||
OutputIterator oi)
|
||||
{
|
||||
OutputIterator oi) {
|
||||
// Use the first polygon to determine the (default) traits
|
||||
typedef typename Gps_polyline_traits<Pgn1>::Polyline_traits Polyline_traits;
|
||||
using Polyline_traits = typename Gps_polyline_traits<Pgn1>::Polyline_traits;
|
||||
|
||||
typename Gps_polyline_traits<Pgn1>::Traits 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,
|
||||
OutputIterator oi) {
|
||||
// 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;
|
||||
const Polyline_traits& ptraits(traits);
|
||||
s_symmetric_difference(convert_polygon(pgn1, ptraits),
|
||||
|
|
@ -409,7 +407,7 @@ template <typename InputIterator, typename OutputIterator, typename Traits>
|
|||
inline
|
||||
OutputIterator r_symmetric_difference(InputIterator begin, InputIterator end,
|
||||
OutputIterator oi, Traits& traits,
|
||||
unsigned int k=5) {
|
||||
std::size_t k = 5) {
|
||||
if (begin == end) return (oi);
|
||||
General_polygon_set_2<Traits> gps(*begin, traits);
|
||||
gps.symmetric_difference(std::next(begin), end, k);
|
||||
|
|
@ -421,9 +419,8 @@ template <typename InputIterator, typename OutputIterator>
|
|||
inline OutputIterator r_symmetric_difference(InputIterator begin,
|
||||
InputIterator end,
|
||||
OutputIterator oi,
|
||||
unsigned int k=5)
|
||||
{
|
||||
typedef typename std::iterator_traits<InputIterator>::value_type Pgn;
|
||||
std::size_t k = 5) {
|
||||
using Pgn = typename std::iterator_traits<InputIterator>::value_type;
|
||||
typename Gps_polyline_traits<Pgn>::Traits traits;
|
||||
const typename Gps_polyline_traits<Pgn>::Polyline_traits& ptraits(traits);
|
||||
if (begin == end) return (oi);
|
||||
|
|
@ -441,8 +438,7 @@ inline OutputIterator r_symmetric_difference(InputIterator1 begin1,
|
|||
InputIterator2 begin2,
|
||||
InputIterator2 end2,
|
||||
OutputIterator oi, Traits& traits,
|
||||
unsigned int k=5)
|
||||
{
|
||||
std::size_t k = 5) {
|
||||
if (begin1 == end1) return r_symmetric_difference(begin2, end2, oi, traits, k);
|
||||
General_polygon_set_2<Traits> gps(*begin1, traits);
|
||||
gps.symmetric_difference(std::next(begin1), end1, begin2, end2, k);
|
||||
|
|
@ -457,8 +453,8 @@ inline OutputIterator r_symmetric_difference(InputIterator1 begin1,
|
|||
InputIterator2 begin2,
|
||||
InputIterator2 end2,
|
||||
OutputIterator oi,
|
||||
unsigned int k=5) {
|
||||
typedef typename std::iterator_traits<InputIterator1>::value_type Pgn;
|
||||
std::size_t k = 5) {
|
||||
using Pgn = typename std::iterator_traits<InputIterator1>::value_type;
|
||||
typename Gps_polyline_traits<Pgn>::Traits traits;
|
||||
const typename Gps_polyline_traits<Pgn>::Polyline_traits& ptraits(traits);
|
||||
if (begin1 == end1){
|
||||
|
|
@ -522,10 +518,10 @@ OutputIterator _complement(const General_polygon_with_holes_2<Pgn>& pgn,
|
|||
template <typename Kernel, typename Container, typename Pwh>
|
||||
void _complement(const Polygon_2<Kernel, Container>& pgn, Pwh& pwh) {
|
||||
// Use the polygon to determine the (default) traits
|
||||
typedef Polygon_2<Kernel, Container> Pgn;
|
||||
typedef typename Gps_polyline_traits<Pgn>::Polyline_traits Polyline_traits;
|
||||
typedef General_polygon_2<Polyline_traits> General_pgn;
|
||||
typedef General_polygon_with_holes_2<General_pgn> General_pwh;
|
||||
using Pgn = Polygon_2<Kernel, Container>;
|
||||
using Polyline_traits = typename Gps_polyline_traits<Pgn>::Polyline_traits;
|
||||
using General_pgn = General_polygon_2<Polyline_traits>;
|
||||
using General_pwh = General_polygon_with_holes_2<General_pgn>;
|
||||
|
||||
General_pwh general_pwh;
|
||||
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 oi) {
|
||||
// Use the polygon with holes to determine the (default) traits
|
||||
typedef Polygon_with_holes_2<Kernel, Container> Pgn;
|
||||
typedef typename Gps_polyline_traits<Pgn>::Polyline_traits Polyline_traits;
|
||||
using Pgn = Polygon_with_holes_2<Kernel, Container>;
|
||||
using Polyline_traits = typename Gps_polyline_traits<Pgn>::Polyline_traits;
|
||||
|
||||
typename Gps_polyline_traits<Pgn>::Traits traits;
|
||||
const Polyline_traits& ptraits(traits);
|
||||
|
|
|
|||
|
|
@ -7,12 +7,11 @@
|
|||
// $Id$
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
||||
//
|
||||
//
|
||||
// Author(s): Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||
// Efi Fogel <efifogel@gmail.com>
|
||||
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||
// Efi Fogel <efifogel@gmail.com>
|
||||
|
||||
#ifndef CGAL_BSO_2_GPS_AGG_META_TRAITS_H
|
||||
#define CGAL_BSO_2_GPS_AGG_META_TRAITS_H
|
||||
#ifndef CGAL_GPS_AGG_META_TRAITS_H
|
||||
#define CGAL_GPS_AGG_META_TRAITS_H
|
||||
|
||||
#include <CGAL/license/Boolean_set_operations_2.h>
|
||||
|
||||
|
|
@ -24,18 +23,17 @@
|
|||
namespace CGAL {
|
||||
|
||||
template <typename Arrangement_>
|
||||
class Gps_agg_curve_data : public Curve_with_halfedge<Arrangement_>
|
||||
{
|
||||
class Gps_agg_curve_data : public Curve_with_halfedge<Arrangement_> {
|
||||
protected:
|
||||
typedef Arrangement_ Arrangement;
|
||||
typedef typename Arrangement::Halfedge_handle Halfedge_handle;
|
||||
typedef Curve_with_halfedge<Arrangement_> Base;
|
||||
using Arrangement = Arrangement_;
|
||||
using Halfedge_handle = typename Arrangement::Halfedge_handle;
|
||||
using Base = Curve_with_halfedge<Arrangement_>;
|
||||
|
||||
const Arrangement* m_arr; // pointer to the arrangement containing the edge.
|
||||
unsigned int m_bc; // the boundary counter of the halfedge with the same
|
||||
std::size_t m_bc; // the boundary counter of the halfedge with the same
|
||||
// direction as the curve
|
||||
|
||||
unsigned int m_twin_bc; // the boundary counter of the halfedge with the same
|
||||
std::size_t m_twin_bc; // the boundary counter of the halfedge with the same
|
||||
// direction as the curve
|
||||
|
||||
public:
|
||||
|
|
@ -47,24 +45,24 @@ public:
|
|||
{}
|
||||
|
||||
Gps_agg_curve_data(const Arrangement* arr, Halfedge_handle he,
|
||||
unsigned int bc, unsigned int twin_bc) :
|
||||
std::size_t bc, std::size_t twin_bc) :
|
||||
Base(he),
|
||||
m_arr(arr),
|
||||
m_bc(bc),
|
||||
m_twin_bc(twin_bc)
|
||||
{}
|
||||
|
||||
unsigned int bc() const { return m_bc; }
|
||||
std::size_t bc() const { return m_bc; }
|
||||
|
||||
unsigned int twin_bc() const { return m_twin_bc; }
|
||||
std::size_t twin_bc() const { return m_twin_bc; }
|
||||
|
||||
unsigned int& bc() { return m_bc; }
|
||||
std::size_t& bc() { return m_bc; }
|
||||
|
||||
unsigned int& twin_bc() { return m_twin_bc; }
|
||||
std::size_t& twin_bc() { return m_twin_bc; }
|
||||
|
||||
void set_bc(unsigned int bc) { m_bc = bc; }
|
||||
void set_bc(std::size_t bc) { m_bc = bc; }
|
||||
|
||||
void set_twin_bc(unsigned int twin_bc) { m_twin_bc = twin_bc; }
|
||||
void set_twin_bc(std::size_t twin_bc) { m_twin_bc = twin_bc; }
|
||||
|
||||
const Arrangement* arr() const { return m_arr; }
|
||||
};
|
||||
|
|
@ -73,54 +71,50 @@ template <typename Arrangement_>
|
|||
class Gps_agg_meta_traits :
|
||||
public Gps_traits_decorator<typename Arrangement_::Traits_adaptor_2,
|
||||
Gps_agg_curve_data<Arrangement_>,
|
||||
Point_with_vertex<Arrangement_> >
|
||||
{
|
||||
typedef Arrangement_ Arrangement;
|
||||
typedef Arrangement Arr;
|
||||
Point_with_vertex<Arrangement_>> {
|
||||
using Arrangement = Arrangement_;
|
||||
using Arr = Arrangement;
|
||||
|
||||
typedef typename Arr::Traits_adaptor_2 Traits;
|
||||
typedef Traits Gt2;
|
||||
using Traits = typename Arr::Traits_adaptor_2;
|
||||
using Gt2 = Traits;
|
||||
|
||||
typedef typename Gt2::X_monotone_curve_2 Base_x_monotone_curve_2;
|
||||
typedef typename Gt2::Point_2 Base_point_2;
|
||||
typedef typename Gt2::Construct_min_vertex_2 Base_Construct_min_vertex_2;
|
||||
typedef typename Gt2::Construct_max_vertex_2 Base_Construct_max_vertex_2;
|
||||
typedef typename Gt2::Compare_endpoints_xy_2 Base_Compare_endpoints_xy_2;
|
||||
typedef typename Gt2::Compare_xy_2 Base_Compare_xy_2;
|
||||
typedef typename Gt2::Compare_y_at_x_right_2 Base_Compare_y_at_x_right_2;
|
||||
typedef typename Gt2::Compare_y_at_x_2 Base_Compare_y_at_x_2;
|
||||
typedef typename Gt2::Intersect_2 Base_Intersect_2;
|
||||
typedef typename Gt2::Split_2 Base_Split_2;
|
||||
using Base_x_monotone_curve_2 = typename Gt2::X_monotone_curve_2;
|
||||
using Base_point_2 = typename Gt2::Point_2;
|
||||
using Base_Construct_min_vertex_2 = typename Gt2::Construct_min_vertex_2;
|
||||
using Base_Construct_max_vertex_2 = typename Gt2::Construct_max_vertex_2;
|
||||
using Base_Compare_endpoints_xy_2 = typename Gt2::Compare_endpoints_xy_2;
|
||||
using Base_Compare_xy_2 = typename Gt2::Compare_xy_2;
|
||||
using Base_Compare_y_at_x_right_2 = typename Gt2::Compare_y_at_x_right_2;
|
||||
using Base_Compare_y_at_x_2 = typename Gt2::Compare_y_at_x_2;
|
||||
using Base_Intersect_2 = typename Gt2::Intersect_2;
|
||||
using Base_Split_2 = typename Gt2::Split_2;
|
||||
|
||||
typedef typename Gt2::Parameter_space_in_x_2 Base_Parameter_space_in_x_2;
|
||||
typedef typename Gt2::Compare_y_near_boundary_2
|
||||
Base_Compare_y_near_boundary_2;
|
||||
using Base_Parameter_space_in_x_2 = typename Gt2::Parameter_space_in_x_2;
|
||||
using Base_Compare_y_near_boundary_2 = typename Gt2::Compare_y_near_boundary_2;
|
||||
|
||||
typedef typename Gt2::Parameter_space_in_y_2 Base_Parameter_space_in_y_2;
|
||||
typedef typename Gt2::Compare_x_near_boundary_2
|
||||
Base_Compare_x_near_boundary_2;
|
||||
using Base_Parameter_space_in_y_2 = typename Gt2::Parameter_space_in_y_2;
|
||||
using Base_Compare_x_near_boundary_2 = typename Gt2::Compare_x_near_boundary_2;
|
||||
|
||||
public:
|
||||
typedef typename Gt2::Multiplicity Multiplicity;
|
||||
typedef Gps_agg_curve_data<Arr> Curve_data;
|
||||
typedef Point_with_vertex<Arr> Point_data;
|
||||
using Multiplicity = typename Gt2::Multiplicity;
|
||||
using Curve_data = Gps_agg_curve_data<Arr>;
|
||||
using Point_data = Point_with_vertex<Arr>;
|
||||
|
||||
private:
|
||||
typedef Gps_agg_meta_traits<Arrangement> Self;
|
||||
typedef Gps_traits_decorator<Gt2, Curve_data, Point_data> Base;
|
||||
using Self = Gps_agg_meta_traits<Arrangement>;
|
||||
using Base = Gps_traits_decorator<Gt2, Curve_data, Point_data>;
|
||||
|
||||
public:
|
||||
typedef typename Base::X_monotone_curve_2 X_monotone_curve_2;
|
||||
typedef typename Base::Point_2 Point_2;
|
||||
typedef typename Gt2::Has_left_category Has_left_category;
|
||||
typedef typename Gt2::Has_merge_category Has_merge_category;
|
||||
typedef typename Gt2::Has_do_intersect_category
|
||||
Has_do_intersect_category;
|
||||
using X_monotone_curve_2 = typename Base::X_monotone_curve_2;
|
||||
using Point_2 = typename Base::Point_2;
|
||||
using Has_left_category = typename Gt2::Has_left_category;
|
||||
using Has_merge_category = typename Gt2::Has_merge_category;
|
||||
using Has_do_intersect_category = typename Gt2::Has_do_intersect_category;
|
||||
|
||||
typedef typename Arr::Left_side_category Left_side_category;
|
||||
typedef typename Arr::Bottom_side_category Bottom_side_category;
|
||||
typedef typename Arr::Top_side_category Top_side_category;
|
||||
typedef typename Arr::Right_side_category Right_side_category;
|
||||
using Left_side_category = typename Arr::Left_side_category;
|
||||
using Bottom_side_category = typename Arr::Bottom_side_category;
|
||||
using Top_side_category = typename Arr::Top_side_category;
|
||||
using Right_side_category = typename Arr::Right_side_category;
|
||||
|
||||
// a side is either oblivious or open (unbounded)
|
||||
static_assert(std::is_same<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 ||
|
||||
std::is_same<Right_side_category, Arr_open_side_tag>::value);
|
||||
|
||||
typedef typename Arr::Halfedge_handle Halfedge_handle;
|
||||
typedef typename Arr::Vertex_handle Vertex_handle;
|
||||
using Halfedge_handle = typename Arr::Halfedge_handle;
|
||||
using Vertex_handle = typename Arr::Vertex_handle;
|
||||
|
||||
Gps_agg_meta_traits() {}
|
||||
|
||||
|
|
@ -152,16 +146,13 @@ public:
|
|||
template <typename OutputIterator>
|
||||
OutputIterator operator()(const X_monotone_curve_2& cv1,
|
||||
const X_monotone_curve_2& cv2,
|
||||
OutputIterator oi) const
|
||||
{
|
||||
OutputIterator oi) const {
|
||||
// Check whether the curves are already in the same arrangement, and thus
|
||||
// must be interior-disjoint
|
||||
if (cv1.data().arr() == cv2.data().arr()) return oi;
|
||||
|
||||
typedef const std::pair<Base_point_2, Multiplicity>
|
||||
Intersection_base_point;
|
||||
typedef std::variant<Intersection_base_point, Base_x_monotone_curve_2>
|
||||
Intersection_base_result;
|
||||
using Intersection_base_point = const std::pair<Base_point_2, Multiplicity>;
|
||||
using Intersection_base_result = std::variant<Intersection_base_point, Base_x_monotone_curve_2>;
|
||||
|
||||
const auto* base_traits = m_traits.m_base_traits;
|
||||
auto base_cmp_xy = base_traits->compare_xy_2_object();
|
||||
|
|
@ -191,8 +182,8 @@ public:
|
|||
const Base_x_monotone_curve_2* overlap_cv =
|
||||
std::get_if<Base_x_monotone_curve_2>(&xection);
|
||||
CGAL_assertion(overlap_cv != nullptr);
|
||||
unsigned int ov_bc;
|
||||
unsigned int ov_twin_bc;
|
||||
std::size_t ov_bc;
|
||||
std::size_t ov_twin_bc;
|
||||
if (base_cmp_endpoints(cv1) == base_cmp_endpoints(cv2)) {
|
||||
// cv1 and cv2 have the same directions
|
||||
ov_bc = cv1.data().bc() + cv2.data().bc();
|
||||
|
|
@ -230,8 +221,7 @@ public:
|
|||
Split_2(const Base_Split_2& base) : m_base_split(base) {}
|
||||
|
||||
void operator()(const X_monotone_curve_2& cv, const Point_2 & p,
|
||||
X_monotone_curve_2& c1, X_monotone_curve_2& c2) const
|
||||
{
|
||||
X_monotone_curve_2& c1, X_monotone_curve_2& c2) const {
|
||||
m_base_split(cv.base(), p.base(), c1.base(), c2.base());
|
||||
const Curve_data& cv_data = cv.data();
|
||||
c1.set_data(Curve_data(cv_data.arr(), Halfedge_handle(), cv_data.bc(),
|
||||
|
|
@ -259,8 +249,7 @@ public:
|
|||
* \param cv The curve.
|
||||
* \return The left endpoint.
|
||||
*/
|
||||
Point_2 operator()(const X_monotone_curve_2 & cv) const
|
||||
{
|
||||
Point_2 operator()(const X_monotone_curve_2 & cv) const {
|
||||
if (cv.data().halfedge() == Halfedge_handle())
|
||||
return (Point_2(m_base(cv.base())));
|
||||
|
||||
|
|
@ -272,8 +261,7 @@ public:
|
|||
};
|
||||
|
||||
/*! Get a Construct_min_vertex_2 functor object. */
|
||||
Construct_min_vertex_2 construct_min_vertex_2_object() const
|
||||
{
|
||||
Construct_min_vertex_2 construct_min_vertex_2_object() const {
|
||||
return Construct_min_vertex_2(this->m_base_traits->
|
||||
construct_min_vertex_2_object());
|
||||
}
|
||||
|
|
@ -285,15 +273,14 @@ public:
|
|||
|
||||
public:
|
||||
Construct_max_vertex_2(const Base_Construct_max_vertex_2& base) :
|
||||
m_base(base)
|
||||
m_base(base)
|
||||
{}
|
||||
|
||||
/*! Obtain the right endpoint of the x-monotone curve (segment).
|
||||
* \param cv The curve.
|
||||
* \return The right endpoint.
|
||||
*/
|
||||
Point_2 operator()(const X_monotone_curve_2& cv) const
|
||||
{
|
||||
Point_2 operator()(const X_monotone_curve_2& cv) const {
|
||||
if (cv.data().halfedge() == Halfedge_handle())
|
||||
return (Point_2(m_base(cv.base())));
|
||||
|
||||
|
|
@ -304,8 +291,7 @@ public:
|
|||
};
|
||||
|
||||
/*! Get a Construct_min_vertex_2 functor object. */
|
||||
Construct_max_vertex_2 construct_max_vertex_2_object() const
|
||||
{
|
||||
Construct_max_vertex_2 construct_max_vertex_2_object() const {
|
||||
return Construct_max_vertex_2(this->m_base_traits->
|
||||
construct_max_vertex_2_object());
|
||||
}
|
||||
|
|
@ -321,8 +307,7 @@ public:
|
|||
* \param cv The curve.
|
||||
* \return The left endpoint.
|
||||
*/
|
||||
Comparison_result operator()(const Point_2& p1, const Point_2& p2) const
|
||||
{
|
||||
Comparison_result operator()(const Point_2& p1, const Point_2& p2) const {
|
||||
const Point_data& inf1 = p1.data();
|
||||
const Point_data& inf2 = p2.data();
|
||||
|
||||
|
|
@ -390,8 +375,7 @@ public:
|
|||
};
|
||||
|
||||
/*! Obtain a Construct_min_vertex_2 functor object. */
|
||||
Compare_y_near_boundary_2 compare_y_near_boundary_2_object() const
|
||||
{
|
||||
Compare_y_near_boundary_2 compare_y_near_boundary_2_object() const {
|
||||
return Compare_y_near_boundary_2(this->m_base_traits->
|
||||
compare_y_near_boundary_2_object()
|
||||
);
|
||||
|
|
@ -429,8 +413,7 @@ public:
|
|||
};
|
||||
|
||||
/*! Obtain a Construct_min_vertex_2 functor object. */
|
||||
Parameter_space_in_y_2 parameter_space_in_y_2_object() const
|
||||
{
|
||||
Parameter_space_in_y_2 parameter_space_in_y_2_object() const {
|
||||
return Parameter_space_in_y_2(this->m_base_traits->
|
||||
parameter_space_in_y_2_object());
|
||||
}
|
||||
|
|
@ -462,8 +445,7 @@ public:
|
|||
};
|
||||
|
||||
/*! Obtain a Construct_min_vertex_2 functor object. */
|
||||
Compare_x_near_boundary_2 compare_x_near_boundary_2_object() const
|
||||
{
|
||||
Compare_x_near_boundary_2 compare_x_near_boundary_2_object() const {
|
||||
return Compare_x_near_boundary_2(this->m_base_traits->
|
||||
compare_x_near_boundary_2_object());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,11 +7,12 @@
|
|||
// $Id$
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
||||
//
|
||||
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||
// Ophir Setter <ophir.setter@cs.tau.ac.il>
|
||||
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||
// Ophir Setter <ophir.setter@cs.tau.ac.il>
|
||||
// Efi Fogel <efifogel@gmail.com>
|
||||
|
||||
#ifndef CGAL_BSO_2_GPS_AGG_OP_H
|
||||
#define CGAL_BSO_2_GPS_AGG_OP_H
|
||||
#ifndef CGAL_GPS_AGG_OP_H
|
||||
#define CGAL_GPS_AGG_OP_H
|
||||
|
||||
#include <CGAL/license/Boolean_set_operations_2.h>
|
||||
|
||||
|
|
@ -19,8 +20,8 @@
|
|||
*
|
||||
* The class Gps_agg_op is responsible for aggregated Boolean set operations
|
||||
* depending on a visitor template parameter. It uses the surface-sweep
|
||||
* algorithm from the arrangement packages to overlay all the polygon sets, and
|
||||
* then it uses a BFS that determines which of the faces is contained in the
|
||||
* algorithm from the surface-sweep package to overlay all the polygon sets, and
|
||||
* then it uses a BFS that determines which of the faces are contained in the
|
||||
* result using the visitor.
|
||||
*/
|
||||
|
||||
|
|
@ -37,31 +38,31 @@
|
|||
|
||||
namespace CGAL {
|
||||
|
||||
template <typename Arrangement_, typename BfsVisitor>
|
||||
template <typename Arrangement_, typename BfsVisitor, template <typename, typename, typename> class SweepVisitor>
|
||||
class Gps_agg_op {
|
||||
typedef Arrangement_ Arrangement_2;
|
||||
typedef BfsVisitor Bfs_visitor;
|
||||
using Arrangement_2 = Arrangement_;
|
||||
using Bfs_visitor = BfsVisitor;
|
||||
|
||||
typedef typename Arrangement_2::Traits_adaptor_2 Geometry_traits_2;
|
||||
typedef typename Arrangement_2::Topology_traits Topology_traits;
|
||||
using Geometry_traits_2 = typename Arrangement_2::Traits_adaptor_2;
|
||||
using Topology_traits = typename Arrangement_2::Topology_traits;
|
||||
|
||||
typedef Arrangement_2 Arr;
|
||||
typedef Geometry_traits_2 Gt2;
|
||||
typedef Topology_traits Tt;
|
||||
using Arr = Arrangement_2;
|
||||
using Gt2 = Geometry_traits_2;
|
||||
using Tt = Topology_traits;
|
||||
|
||||
typedef typename Gt2::Curve_const_iterator Curve_const_iterator;
|
||||
typedef Gps_agg_meta_traits<Arr> Mgt2;
|
||||
typedef typename Mgt2::Curve_data Curve_data;
|
||||
typedef typename Mgt2::X_monotone_curve_2 Meta_X_monotone_curve_2;
|
||||
using Curve_const_iterator = typename Gt2::Curve_const_iterator;
|
||||
using Mgt2 = Gps_agg_meta_traits<Arr>;
|
||||
using Curve_data = typename Mgt2::Curve_data;
|
||||
using Meta_X_monotone_curve_2 = typename Mgt2::X_monotone_curve_2;
|
||||
|
||||
typedef typename Arr::Halfedge_handle Halfedge_handle;
|
||||
typedef typename Arr::Halfedge_iterator Halfedge_iterator;
|
||||
typedef typename Arr::Face_handle Face_handle;
|
||||
typedef typename Arr::Edge_iterator Edge_iterator;
|
||||
typedef typename Arr::Vertex_handle Vertex_handle;
|
||||
typedef typename Arr::Allocator Allocator;
|
||||
using Halfedge_handle = typename Arr::Halfedge_handle;
|
||||
using Halfedge_iterator = typename Arr::Halfedge_iterator;
|
||||
using Face_handle = typename Arr::Face_handle;
|
||||
using Edge_iterator = typename Arr::Edge_iterator;
|
||||
using Vertex_handle = typename Arr::Vertex_handle;
|
||||
using Allocator = typename Arr::Allocator;
|
||||
|
||||
typedef std::pair<Arr*, 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.
|
||||
// However, the arrangement is parametrized with the Gt2 geometry traits,
|
||||
|
|
@ -70,21 +71,16 @@ class Gps_agg_op {
|
|||
// We cannot parameterized the arrangement with the Mgt2 geometry
|
||||
// traits to start with, because it extends the curve type with arrangement
|
||||
// dependent types. (It is parameterized with the arrangement type.)
|
||||
typedef Indexed_event<Mgt2, Arr, Allocator> Event;
|
||||
typedef Arr_construction_subcurve<Mgt2, Event, Allocator>
|
||||
Subcurve;
|
||||
typedef typename Tt::template Construction_helper<Event, Subcurve>
|
||||
Helper_tmp;
|
||||
typedef typename Helper_tmp::template rebind<Mgt2, Arr, Event, Subcurve>::other
|
||||
Helper;
|
||||
typedef Gps_agg_op_visitor<Helper, Arr> Visitor;
|
||||
typedef Gps_agg_op_surface_sweep_2<Arr, Visitor> Surface_sweep_2;
|
||||
using Event = Indexed_event<Mgt2, Arr, Allocator>;
|
||||
using Subcurve = Arr_construction_subcurve<Mgt2, Event, Allocator>;
|
||||
using Helper_tmp = typename Tt::template Construction_helper<Event, Subcurve>;
|
||||
using Helper = typename Helper_tmp::template rebind<Mgt2, Arr, Event, Subcurve>::other;
|
||||
using Visitor = SweepVisitor<Helper, Arr, Default>;
|
||||
using Surface_sweep_2 = Gps_agg_op_surface_sweep_2<Arr, Visitor>;
|
||||
|
||||
typedef Unique_hash_map<Halfedge_handle, unsigned int>
|
||||
Edges_hash;
|
||||
|
||||
typedef Unique_hash_map<Face_handle, unsigned int> Faces_hash;
|
||||
typedef Gps_bfs_scanner<Arr, Bfs_visitor> Bfs_scanner;
|
||||
using Edges_hash = Unique_hash_map<Halfedge_handle, std::size_t>;
|
||||
using Faces_hash = Unique_hash_map<Face_handle, std::size_t>;
|
||||
using Bfs_scanner = Gps_bfs_scanner<Arr, Bfs_visitor>;
|
||||
|
||||
protected:
|
||||
Arr* m_arr;
|
||||
|
|
@ -95,7 +91,7 @@ protected:
|
|||
Faces_hash m_faces_hash; // maps face to its IC (inside count)
|
||||
|
||||
public:
|
||||
/*! Constructor. */
|
||||
/*! constructs. */
|
||||
Gps_agg_op(Arr& arr, std::vector<Vertex_handle>& vert_vec, const Gt2& tr) :
|
||||
m_arr(&arr),
|
||||
m_traits(new Mgt2(tr)),
|
||||
|
|
@ -103,40 +99,40 @@ public:
|
|||
m_surface_sweep(m_traits, &m_visitor)
|
||||
{}
|
||||
|
||||
void sweep_arrangements(unsigned int lower, unsigned int upper,
|
||||
unsigned int jump, std::vector<Arr_entry>& arr_vec)
|
||||
{
|
||||
std::list<Meta_X_monotone_curve_2> curves_list;
|
||||
|
||||
unsigned int n_inf_pgn = 0; // number of infinite polygons (arrangement
|
||||
std::pair<std::size_t, std::size_t>
|
||||
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::size_t n_inf_pgn = 0; // number of infinite polygons (arrangement
|
||||
// with a contained unbounded face
|
||||
unsigned int n_pgn = 0; // number of polygons (arrangements)
|
||||
unsigned int i;
|
||||
|
||||
for (i = lower; i <= upper; i += jump, ++n_pgn) {
|
||||
std::size_t n_pgn = 0; // number of polygons (arrangements)
|
||||
for (auto i = lower; i <= upper; i += jump, ++n_pgn) {
|
||||
// The BFS scan (after the loop) starts in the reference face,
|
||||
// so we count the number of polygons that contain the reference face.
|
||||
Arr* arr = (arr_vec[i]).first;
|
||||
if (arr->reference_face()->contained()) ++n_inf_pgn;
|
||||
|
||||
Edge_iterator itr = arr->edges_begin();
|
||||
for(; itr != arr->edges_end(); ++itr) {
|
||||
for (auto itr = arr->edges_begin(); itr != arr->edges_end(); ++itr) {
|
||||
// take only relevant edges (which separate between contained and
|
||||
// non-contained faces.
|
||||
Halfedge_iterator he = itr;
|
||||
if(he->face()->contained() == he->twin()->face()->contained())
|
||||
continue;
|
||||
if ((Arr_halfedge_direction)he->direction() == ARR_RIGHT_TO_LEFT)
|
||||
he = he->twin();
|
||||
Halfedge_handle he = itr;
|
||||
if (he->face()->contained() == he->twin()->face()->contained()) continue;
|
||||
if ((Arr_halfedge_direction)he->direction() == ARR_RIGHT_TO_LEFT) he = he->twin();
|
||||
|
||||
Curve_data cv_data(arr, he, 1, 0);
|
||||
curves_list.push_back(Meta_X_monotone_curve_2(he->curve(), cv_data));
|
||||
}
|
||||
}
|
||||
return std::make_pair(n_inf_pgn, n_pgn);
|
||||
}
|
||||
|
||||
m_surface_sweep.sweep(curves_list.begin(), curves_list.end(),
|
||||
lower, upper, jump, arr_vec);
|
||||
|
||||
/*! sweeps the plane without interceptions.
|
||||
*/
|
||||
void sweep_arrangements(std::size_t lower, std::size_t upper, std::size_t jump,
|
||||
std::vector<Arr_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;
|
||||
Bfs_visitor visitor(&m_edges_hash, &m_faces_hash, n_pgn);
|
||||
visitor.visit_ubf(m_arr->faces_begin(), n_inf_pgn);
|
||||
|
|
@ -145,7 +141,69 @@ public:
|
|||
visitor.after_scan(*m_arr);
|
||||
}
|
||||
|
||||
/*! Destruct.
|
||||
/*! sweeps the plane without interceptions, but stop when an intersection occurs.
|
||||
*/
|
||||
bool sweep_intercept_arrangements(std::size_t lower, std::size_t upper, std::size_t jump,
|
||||
std::vector<Arr_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; }
|
||||
};
|
||||
|
|
|
|||
|
|
@ -7,11 +7,12 @@
|
|||
// $Id$
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
||||
//
|
||||
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||
// Ron Wein <wein@post.tau.ac.il>
|
||||
// Author(s) : Baruch Zukerman <baruchzu@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
|
||||
#define CGAL_BSO_2_GSP_AGG_OP_SURFACE_SWEEP_2_H
|
||||
#ifndef CGAL_GSP_AGG_OP_SURFACE_SWEEP_2_H
|
||||
#define CGAL_GSP_AGG_OP_SURFACE_SWEEP_2_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
|
|
@ -27,34 +28,34 @@ namespace Ss2 = Surface_sweep_2;
|
|||
template <typename Arrangement_, typename Visitor_>
|
||||
class Gps_agg_op_surface_sweep_2 : public Ss2::Surface_sweep_2<Visitor_> {
|
||||
public:
|
||||
typedef Arrangement_ Arrangement_2;
|
||||
typedef Visitor_ Visitor;
|
||||
using Arrangement_2 = Arrangement_;
|
||||
using Visitor = Visitor_;
|
||||
|
||||
typedef typename Visitor::Geometry_traits_2 Geometry_traits_2;
|
||||
using Geometry_traits_2 = typename Visitor::Geometry_traits_2;
|
||||
|
||||
typedef Arrangement_2 Arr;
|
||||
typedef Geometry_traits_2 Gt2;
|
||||
using Arr = Arrangement_2;
|
||||
using Gt2 = Geometry_traits_2;
|
||||
|
||||
typedef typename Gt2::Point_2 Point_2;
|
||||
typedef typename Gt2::X_monotone_curve_2 X_monotone_curve_2;
|
||||
using Point_2 = typename Gt2::Point_2;
|
||||
using X_monotone_curve_2 = typename Gt2::X_monotone_curve_2;
|
||||
|
||||
typedef typename Arr::Vertex_handle Vertex_handle;
|
||||
typedef typename Arr::Halfedge_handle Halfedge_handle;
|
||||
using Vertex_handle = typename Arr::Vertex_handle;
|
||||
using Halfedge_handle = typename Arr::Halfedge_handle;
|
||||
|
||||
typedef std::pair<Arr*, 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;
|
||||
typedef typename Visitor::Subcurve Subcurve;
|
||||
using Event = typename Visitor::Event;
|
||||
using Subcurve = typename Visitor::Subcurve;
|
||||
|
||||
typedef typename Base::Event_queue_iterator EventQueueIter;
|
||||
typedef typename Event::Subcurve_iterator EventCurveIter;
|
||||
using EventQueueIter = typename Base::Event_queue_iterator;
|
||||
using EventCurveIter = typename Event::Subcurve_iterator;
|
||||
|
||||
typedef typename Event::Attribute Attribute;
|
||||
using Attribute = typename Event::Attribute;
|
||||
|
||||
typedef std::list<Subcurve*> SubCurveList;
|
||||
typedef typename SubCurveList::iterator SubCurveListIter;
|
||||
using SubCurveList = std::list<Subcurve*>;
|
||||
using SubCurveListIter = typename SubCurveList::iterator;
|
||||
|
||||
public:
|
||||
/*! Constructor.
|
||||
|
|
@ -70,21 +71,17 @@ public:
|
|||
Base(traits, visitor)
|
||||
{}
|
||||
|
||||
/*! Perform the sweep. */
|
||||
template <class CurveInputIterator>
|
||||
void sweep(CurveInputIterator curves_begin, CurveInputIterator curves_end,
|
||||
unsigned int lower, unsigned int upper, unsigned int jump,
|
||||
std::vector<Arr_entry>& arr_vec)
|
||||
{
|
||||
template <typename CurveInputIterator>
|
||||
void pre_process(CurveInputIterator curves_begin, CurveInputIterator curves_end,
|
||||
std::size_t lower, std::size_t upper, std::size_t jump,
|
||||
std::vector<Arr_entry>& arr_vec) {
|
||||
CGAL_assertion(this->m_queue->empty() && this->m_statusLine.size() == 0);
|
||||
|
||||
typedef Unique_hash_map<Vertex_handle, Event*> Vertices_map;
|
||||
typedef typename Gt2::Compare_xy_2 Compare_xy_2;
|
||||
using Vertices_map = Unique_hash_map<Vertex_handle, Event*>;
|
||||
using Compare_xy_2 = typename Gt2::Compare_xy_2;
|
||||
|
||||
this->m_visitor->before_sweep();
|
||||
// Allocate all of the Subcurve objects as one block.
|
||||
this->m_num_of_subCurves =
|
||||
static_cast<unsigned int>(std::distance(curves_begin, curves_end));
|
||||
this->m_num_of_subCurves = static_cast<unsigned int>(std::distance(curves_begin, curves_end));
|
||||
if (this->m_num_of_subCurves > 0)
|
||||
this->m_subCurves =
|
||||
this->m_subCurveAlloc.allocate(this->m_num_of_subCurves);
|
||||
|
|
@ -95,9 +92,9 @@ public:
|
|||
Vertices_map vert_map;
|
||||
Vertex_handle vh;
|
||||
Vertex_handle invalid_v;
|
||||
unsigned int i = lower;
|
||||
unsigned int n = static_cast<unsigned int>((arr_vec[i].second)->size());
|
||||
unsigned int j;
|
||||
std::size_t i = lower;
|
||||
auto n = (arr_vec[i].second)->size();
|
||||
std::size_t j;
|
||||
EventQueueIter q_iter;
|
||||
bool first = true;
|
||||
Attribute event_type;
|
||||
|
|
@ -135,7 +132,7 @@ public:
|
|||
for (i += jump; i <= upper; i += jump) {
|
||||
// Merge the vertices of the other vectors into the existing queue.
|
||||
q_iter = this->m_queue->begin();
|
||||
n = static_cast<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++) {
|
||||
event_type = _type_of_vertex(vh);
|
||||
|
|
@ -170,7 +167,7 @@ public:
|
|||
|
||||
// Go over all curves (which are associated with halfedges) and associate
|
||||
// them with the events we have just created.
|
||||
unsigned int index = 0;
|
||||
std::size_t index = 0;
|
||||
CurveInputIterator iter;
|
||||
Halfedge_handle he;
|
||||
Event* e_left;
|
||||
|
|
@ -194,9 +191,10 @@ public:
|
|||
}
|
||||
|
||||
// Create the subcurve object.
|
||||
typedef decltype(this->m_subCurveAlloc) Subcurve_alloc;
|
||||
std::allocator_traits<Subcurve_alloc>::construct(this->m_subCurveAlloc, this->m_subCurves + index,
|
||||
this->m_masterSubcurve);
|
||||
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);
|
||||
|
|
@ -204,13 +202,174 @@ public:
|
|||
e_right->add_curve_to_left(this->m_subCurves + index);
|
||||
this->_add_curve_to_right(e_left, this->m_subCurves + index);
|
||||
}
|
||||
}
|
||||
|
||||
// Perform the sweep:
|
||||
template <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->_complete_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:
|
||||
|
|
@ -218,8 +377,7 @@ private:
|
|||
* Check if the given vertex is an endpoint of an edge we are going
|
||||
* to use in the sweep.
|
||||
*/
|
||||
Attribute _type_of_vertex(Vertex_handle v)
|
||||
{
|
||||
Attribute _type_of_vertex(Vertex_handle v) {
|
||||
typename Arr::Halfedge_around_vertex_circulator first, circ;
|
||||
|
||||
circ = first = v->incident_halfedges();
|
||||
|
|
@ -232,7 +390,6 @@ private:
|
|||
else return (Event::LEFT_END);
|
||||
}
|
||||
++circ;
|
||||
|
||||
} while (circ != first);
|
||||
|
||||
// If we reached here, we should not keep this vertex.
|
||||
|
|
|
|||
|
|
@ -7,12 +7,12 @@
|
|||
// $Id$
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
||||
//
|
||||
//
|
||||
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||
// Ron Wein <wein@post.tau.ac.il>
|
||||
// Author(s) : Baruch Zukerman <baruchzu@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
|
||||
#define CGAL_BSO_2_GSP_AGG_OP_VISITOR_H
|
||||
#ifndef CGAL_GSP_AGG_OP_VISITOR_H
|
||||
#define CGAL_GSP_AGG_OP_VISITOR_H
|
||||
|
||||
#include <CGAL/license/Boolean_set_operations_2.h>
|
||||
|
||||
|
|
@ -31,33 +31,29 @@ class Gps_agg_op_base_visitor :
|
|||
Helper_,
|
||||
typename Default::Get<Visitor_, Gps_agg_op_base_visitor<Helper_,
|
||||
Arrangement_,
|
||||
Visitor_> >::type>
|
||||
{
|
||||
Visitor_>>::type> {
|
||||
public:
|
||||
typedef Helper_ Helper;
|
||||
typedef Arrangement_ Arrangement_2;
|
||||
using Helper = Helper_;
|
||||
using Arrangement_2 = Arrangement_;
|
||||
|
||||
typedef typename Helper::Geometry_traits_2 Geometry_traits_2;
|
||||
typedef typename Helper::Event Event;
|
||||
typedef typename Helper::Subcurve Subcurve;
|
||||
using Geometry_traits_2 = typename Helper::Geometry_traits_2;
|
||||
using Event = typename Helper::Event;
|
||||
using Subcurve = typename Helper::Subcurve;
|
||||
|
||||
private:
|
||||
typedef Geometry_traits_2 Gt2;
|
||||
typedef Arrangement_2 Arr;
|
||||
|
||||
typedef Gps_agg_op_base_visitor<Helper, Arr, Visitor_>
|
||||
Self;
|
||||
typedef typename Default::Get<Visitor_, Self>::type Visitor;
|
||||
typedef Arr_construction_ss_visitor<Helper, Visitor> Base;
|
||||
using Gt2 = Geometry_traits_2;
|
||||
using Arr = Arrangement_2;
|
||||
using Self = Gps_agg_op_base_visitor<Helper, Arr, Visitor_>;
|
||||
using Visitor = typename Default::Get<Visitor_, Self>::type;
|
||||
using Base = Arr_construction_ss_visitor<Helper, Visitor>;
|
||||
|
||||
public:
|
||||
typedef typename Arr::Halfedge_handle Halfedge_handle;
|
||||
typedef typename Arr::Vertex_handle Vertex_handle;
|
||||
typedef typename Gt2::X_monotone_curve_2 X_monotone_curve_2;
|
||||
typedef typename Gt2::Point_2 Point_2;
|
||||
using Halfedge_handle = typename Arr::Halfedge_handle;
|
||||
using Vertex_handle = typename Arr::Vertex_handle;
|
||||
using X_monotone_curve_2 = typename Gt2::X_monotone_curve_2;
|
||||
using Point_2 = typename Gt2::Point_2;
|
||||
|
||||
typedef Unique_hash_map<Halfedge_handle, unsigned int>
|
||||
Edges_hash;
|
||||
using Edges_hash = Unique_hash_map<Halfedge_handle, std::size_t>;
|
||||
|
||||
protected:
|
||||
Edges_hash* m_edges_hash; // maps halfedges to their BC (coundary counter)
|
||||
|
|
@ -72,8 +68,7 @@ public:
|
|||
// TODO add mpl-warning
|
||||
|
||||
virtual Halfedge_handle insert_in_face_interior(const X_monotone_curve_2& cv,
|
||||
Subcurve* sc)
|
||||
{
|
||||
Subcurve* sc) {
|
||||
Halfedge_handle he = Base::insert_in_face_interior(cv, sc);
|
||||
insert_edge_to_hash(he, cv);
|
||||
return he;
|
||||
|
|
@ -83,8 +78,7 @@ public:
|
|||
Halfedge_handle hhandle,
|
||||
Halfedge_handle prev,
|
||||
Subcurve* sc,
|
||||
bool& new_face_created)
|
||||
{
|
||||
bool& new_face_created) {
|
||||
Halfedge_handle res_he =
|
||||
Base::insert_at_vertices(cv, hhandle, prev, sc, new_face_created);
|
||||
insert_edge_to_hash(res_he, cv);
|
||||
|
|
@ -93,8 +87,7 @@ public:
|
|||
|
||||
virtual Halfedge_handle insert_from_right_vertex(const X_monotone_curve_2& cv,
|
||||
Halfedge_handle he,
|
||||
Subcurve* sc)
|
||||
{
|
||||
Subcurve* sc) {
|
||||
Halfedge_handle res_he = Base::insert_from_right_vertex(cv, he, sc);
|
||||
insert_edge_to_hash(res_he, cv);
|
||||
return res_he;
|
||||
|
|
@ -102,16 +95,14 @@ public:
|
|||
|
||||
virtual Halfedge_handle insert_from_left_vertex(const X_monotone_curve_2& cv,
|
||||
Halfedge_handle he,
|
||||
Subcurve* sc)
|
||||
{
|
||||
Subcurve* sc) {
|
||||
Halfedge_handle res_he = Base::insert_from_left_vertex(cv, he, sc);
|
||||
insert_edge_to_hash(res_he, cv);
|
||||
return res_he;
|
||||
}
|
||||
|
||||
private:
|
||||
void insert_edge_to_hash(Halfedge_handle he, const X_monotone_curve_2& cv)
|
||||
{
|
||||
void insert_edge_to_hash(Halfedge_handle he, const X_monotone_curve_2& cv) {
|
||||
const Comparison_result he_dir =
|
||||
((Arr_halfedge_direction)he->direction() == ARR_LEFT_TO_RIGHT) ?
|
||||
SMALLER : LARGER;
|
||||
|
|
@ -133,54 +124,53 @@ private:
|
|||
|
||||
template <typename Helper_, typename Arrangement_, typename Visitor_ = Default>
|
||||
class Gps_agg_op_visitor :
|
||||
public Gps_agg_op_base_visitor<Helper_, Arrangement_,
|
||||
Gps_agg_op_visitor<Helper_, Arrangement_,
|
||||
Visitor_> >
|
||||
{
|
||||
public Gps_agg_op_base_visitor<
|
||||
Helper_, Arrangement_,
|
||||
typename Default::Get<Visitor_,
|
||||
Gps_agg_op_visitor<Helper_, Arrangement_, Visitor_>>::type> {
|
||||
public:
|
||||
typedef Helper_ Helper;
|
||||
typedef Arrangement_ Arrangement_2;
|
||||
using Helper = Helper_;
|
||||
using Arrangement_2 = Arrangement_;
|
||||
|
||||
typedef typename Helper::Geometry_traits_2 Geometry_traits_2;
|
||||
typedef typename Helper::Event Event;
|
||||
typedef typename Helper::Subcurve Subcurve;
|
||||
using Geometry_traits_2 = typename Helper::Geometry_traits_2;
|
||||
using Event = typename Helper::Event;
|
||||
using Subcurve = typename Helper::Subcurve;
|
||||
|
||||
private:
|
||||
typedef Geometry_traits_2 Gt2;
|
||||
typedef Arrangement_2 Arr;
|
||||
using Gt2 = Geometry_traits_2;
|
||||
using Arr = Arrangement_2;
|
||||
|
||||
typedef Gps_agg_op_visitor<Helper, Arr, Visitor_> Self;
|
||||
typedef typename Default::Get<Visitor_, Self>::type Visitor;
|
||||
typedef Gps_agg_op_base_visitor<Helper, Arr, Visitor> Base;
|
||||
using Self = Gps_agg_op_visitor<Helper, Arr, Visitor_>;
|
||||
using Visitor = typename Default::Get<Visitor_, Self>::type;
|
||||
using Base = Gps_agg_op_base_visitor<Helper, Arr, Visitor>;
|
||||
|
||||
public:
|
||||
typedef typename Base::Halfedge_handle Halfedge_handle;
|
||||
typedef typename Base::Vertex_handle Vertex_handle;
|
||||
typedef typename Gt2::X_monotone_curve_2 X_monotone_curve_2;
|
||||
typedef typename Gt2::Point_2 Point_2;
|
||||
using Edges_hash = typename Base::Edges_hash;
|
||||
using Halfedge_handle = typename Base::Halfedge_handle;
|
||||
using Vertex_handle = typename Base::Vertex_handle;
|
||||
using X_monotone_curve_2 = typename Gt2::X_monotone_curve_2;
|
||||
using Point_2 = typename Gt2::Point_2;
|
||||
|
||||
protected:
|
||||
unsigned int m_event_count; // The number of events so far.
|
||||
std::size_t m_event_count; // The number of events so far.
|
||||
std::vector<Vertex_handle>* m_vertices_vec; // The vertices, sorted in
|
||||
// ascending order.
|
||||
|
||||
public:
|
||||
Gps_agg_op_visitor(Arr* arr, typename Base::Edges_hash* hash,
|
||||
Gps_agg_op_visitor(Arr* arr, Edges_hash* hash,
|
||||
std::vector<Vertex_handle>* vertices_vec) :
|
||||
Base(arr, hash),
|
||||
m_event_count(0),
|
||||
m_vertices_vec(vertices_vec)
|
||||
{}
|
||||
|
||||
void before_handle_event(Event* event)
|
||||
{
|
||||
void before_handle_event(Event* event) {
|
||||
event->set_index(m_event_count);
|
||||
m_event_count++;
|
||||
}
|
||||
|
||||
virtual Halfedge_handle
|
||||
insert_in_face_interior(const X_monotone_curve_2& cv, Subcurve* sc)
|
||||
{
|
||||
insert_in_face_interior(const X_monotone_curve_2& cv, Subcurve* sc) {
|
||||
Halfedge_handle res_he = Base::insert_in_face_interior(cv, sc);
|
||||
|
||||
// We now have a halfedge whose source vertex is associated with the
|
||||
|
|
@ -198,8 +188,7 @@ public:
|
|||
|
||||
virtual Halfedge_handle insert_from_right_vertex(const X_monotone_curve_2& cv,
|
||||
Halfedge_handle he,
|
||||
Subcurve* sc)
|
||||
{
|
||||
Subcurve* sc) {
|
||||
Halfedge_handle res_he = Base::insert_from_right_vertex(cv, he, sc);
|
||||
|
||||
// We now have a halfedge whose target vertex is associated with the
|
||||
|
|
@ -213,9 +202,8 @@ public:
|
|||
|
||||
virtual Halfedge_handle insert_from_left_vertex(const X_monotone_curve_2& cv,
|
||||
Halfedge_handle he,
|
||||
Subcurve* sc)
|
||||
{
|
||||
Halfedge_handle res_he = Base::insert_from_left_vertex(cv, he, sc);
|
||||
Subcurve* sc) {
|
||||
Halfedge_handle res_he = Base::insert_from_left_vertex(cv, he, sc);
|
||||
|
||||
// We now have a halfedge whose target vertex is associated with the
|
||||
// current event(we have already dealt with its source vertex).
|
||||
|
|
@ -223,18 +211,16 @@ public:
|
|||
|
||||
CGAL_assertion((Arr_halfedge_direction)res_he->direction() ==
|
||||
ARR_LEFT_TO_RIGHT);
|
||||
_insert_vertex (curr_event, res_he->target());
|
||||
_insert_vertex(curr_event, res_he->target());
|
||||
return res_he;
|
||||
}
|
||||
|
||||
private:
|
||||
void _insert_vertex(const Event* event, Vertex_handle v)
|
||||
{
|
||||
const unsigned int index = event->index();
|
||||
void _insert_vertex(const Event* event, Vertex_handle v) {
|
||||
const auto index = event->index();
|
||||
if (index >= m_vertices_vec->size()) m_vertices_vec->resize(2 * (index + 1));
|
||||
(*m_vertices_vec)[index] = v;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
} // namespace CGAL
|
||||
|
|
|
|||
|
|
@ -8,90 +8,83 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
||||
//
|
||||
//
|
||||
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||
// Ophir Setter <ophir.setter@cs.tau.ac.il>
|
||||
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||
// Ophir Setter <ophir.setter@cs.tau.ac.il>
|
||||
|
||||
#ifndef CGAL_GPS_BPS_BASE_VISITOR_H
|
||||
#define CGAL_GPS_BPS_BASE_VISITOR_H
|
||||
|
||||
#include <CGAL/license/Boolean_set_operations_2.h>
|
||||
|
||||
|
||||
#include <CGAL/Unique_hash_map.h>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
//! Gps_bfs_base_visitor
|
||||
/*! This is a base class for all visitors that are responsible for merging
|
||||
polygon sets.
|
||||
We use DerivedVisitor for static polymorphism for using contained_criteria
|
||||
which determines if we should mark the face as contained given the inside
|
||||
count of the face.
|
||||
*/
|
||||
template <class Arrangement_, class DerivedVisitor>
|
||||
class Gps_bfs_base_visitor
|
||||
{
|
||||
typedef Arrangement_ Arrangement;
|
||||
typedef typename Arrangement::Face_iterator Face_iterator;
|
||||
typedef typename Arrangement::Halfedge_iterator Halfedge_iterator;
|
||||
* polygon sets.
|
||||
* We use DerivedVisitor for static polymorphism for using contained_criteria
|
||||
* which determines if we should mark the face as contained given the inside
|
||||
* count of the face.
|
||||
*/
|
||||
template <typename Arrangement_, typename DerivedVisitor>
|
||||
class Gps_bfs_base_visitor {
|
||||
using Arrangement = Arrangement_;
|
||||
using Face_iterator = typename Arrangement::Face_iterator;
|
||||
using Halfedge_iterator = typename Arrangement::Halfedge_iterator;
|
||||
|
||||
public:
|
||||
typedef Unique_hash_map<Halfedge_iterator, unsigned int> Edges_hash;
|
||||
typedef Unique_hash_map<Face_iterator, unsigned int> Faces_hash;
|
||||
using Edges_hash = Unique_hash_map<Halfedge_iterator, std::size_t>;
|
||||
using Faces_hash = Unique_hash_map<Face_iterator, std::size_t>;
|
||||
|
||||
protected:
|
||||
Edges_hash* m_edges_hash;
|
||||
Faces_hash* m_faces_hash;
|
||||
unsigned int m_num_of_polygons; // number of polygons
|
||||
Edges_hash* m_edges_hash;
|
||||
Faces_hash* m_faces_hash;
|
||||
std::size_t m_num_of_polygons; // number of polygons
|
||||
|
||||
public:
|
||||
|
||||
Gps_bfs_base_visitor(Edges_hash* edges_hash,
|
||||
Faces_hash* faces_hash,
|
||||
unsigned int n_pgn):
|
||||
std::size_t n_pgn):
|
||||
m_edges_hash(edges_hash),
|
||||
m_faces_hash(faces_hash),
|
||||
m_num_of_polygons(n_pgn)
|
||||
{}
|
||||
|
||||
|
||||
//! discovered_face
|
||||
/*! discovered_face is called by Gps_bfs_scanner when it reveals a new face
|
||||
during a BFS scan. In the BFS traversal we are going from old_face to
|
||||
new_face through the half-edge he.
|
||||
\param old_face The face that was already revealed
|
||||
\param new_face The face that we have just now revealed
|
||||
\param he The half-edge that is used to traverse between them.
|
||||
*/
|
||||
//! discovered_face
|
||||
/*! discovered_face is called by Gps_bfs_scanner when it reveals a new face
|
||||
* during a BFS scan. In the BFS traversal we are going from old_face to
|
||||
* new_face through the half-edge he.
|
||||
* \param old_face The face that was already revealed
|
||||
* \param new_face The face that we have just now revealed
|
||||
* \param he The half-edge that is used to traverse between them.
|
||||
*/
|
||||
void discovered_face(Face_iterator old_face,
|
||||
Face_iterator new_face,
|
||||
Halfedge_iterator he)
|
||||
{
|
||||
unsigned int ic = compute_ic(old_face, new_face, he);
|
||||
Halfedge_iterator he) {
|
||||
std::size_t ic = compute_ic(old_face, new_face, he);
|
||||
|
||||
if (static_cast<DerivedVisitor*>(this)->contained_criteria(ic))
|
||||
new_face->set_contained(true);
|
||||
}
|
||||
|
||||
// mark the unbounded_face (true iff contained)
|
||||
void visit_ubf(Face_iterator ubf, unsigned int ubf_ic)
|
||||
{
|
||||
void visit_ubf(Face_iterator ubf, std::size_t ubf_ic) {
|
||||
CGAL_assertion(ubf->is_unbounded());
|
||||
if(static_cast<DerivedVisitor*>(this)->contained_criteria(ubf_ic))
|
||||
if (static_cast<DerivedVisitor*>(this)->contained_criteria(ubf_ic))
|
||||
ubf->set_contained(true);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
// compute the inside count of a face
|
||||
unsigned int compute_ic(Face_iterator f1,
|
||||
Face_iterator f2,
|
||||
Halfedge_iterator he)
|
||||
{
|
||||
std::size_t compute_ic(Face_iterator f1,
|
||||
Face_iterator f2,
|
||||
Halfedge_iterator he) {
|
||||
CGAL_assertion(m_edges_hash->is_defined(he) &&
|
||||
m_edges_hash->is_defined(he->twin()) &&
|
||||
m_faces_hash->is_defined(f1) &&
|
||||
!m_faces_hash->is_defined(f2));
|
||||
unsigned int ic_f2 =
|
||||
! m_faces_hash->is_defined(f2));
|
||||
std::size_t ic_f2 =
|
||||
(*m_faces_hash)[f1] - (*m_edges_hash)[he] + (*m_edges_hash)[he->twin()];
|
||||
(*m_faces_hash)[f2] = ic_f2;
|
||||
|
||||
|
|
|
|||
|
|
@ -7,59 +7,50 @@
|
|||
// $Id$
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
||||
//
|
||||
//
|
||||
|
||||
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||
// Ophir Setter <ophir.setter@cs.tau.ac.il>
|
||||
|
||||
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||
// Ophir Setter <ophir.setter@cs.tau.ac.il>
|
||||
// Efi Fogel <efifogel@gmail.com>
|
||||
|
||||
#ifndef CGAL_GPS_BFS_INTERSECTION_VISITOR_H
|
||||
#define CGAL_GPS_BFS_INTERSECTION_VISITOR_H
|
||||
|
||||
#include <CGAL/license/Boolean_set_operations_2.h>
|
||||
|
||||
|
||||
#include <CGAL/Boolean_set_operations_2/Gps_bfs_base_visitor.h>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
template <class Arrangement_>
|
||||
template <typename Arrangement_>
|
||||
class Gps_bfs_intersection_visitor :
|
||||
public Gps_bfs_base_visitor<Arrangement_, Gps_bfs_intersection_visitor<Arrangement_> >
|
||||
{
|
||||
typedef Arrangement_ Arrangement;
|
||||
typedef typename Arrangement::Face_iterator Face_iterator;
|
||||
typedef typename Arrangement::Halfedge_iterator Halfedge_iterator;
|
||||
typedef Gps_bfs_intersection_visitor<Arrangement> Self;
|
||||
typedef Gps_bfs_base_visitor<Arrangement, Self> Base;
|
||||
typedef typename Base::Edges_hash Edges_hash;
|
||||
typedef typename Base::Faces_hash Faces_hash;
|
||||
|
||||
public Gps_bfs_base_visitor<Arrangement_, Gps_bfs_intersection_visitor<Arrangement_>> {
|
||||
using Arrangement = Arrangement_;
|
||||
using Face_iterator = typename Arrangement::Face_iterator;
|
||||
using Halfedge_iterator = typename Arrangement::Halfedge_iterator;
|
||||
using Self = Gps_bfs_intersection_visitor<Arrangement>;
|
||||
using Base = Gps_bfs_base_visitor<Arrangement, Self>;
|
||||
using Edges_hash = typename Base::Edges_hash;
|
||||
using Faces_hash = typename Base::Faces_hash;
|
||||
|
||||
public:
|
||||
|
||||
Gps_bfs_intersection_visitor(Edges_hash* edges_hash,
|
||||
Faces_hash* faces_hash,
|
||||
unsigned int n_polygons):
|
||||
std::size_t n_polygons):
|
||||
Base(edges_hash, faces_hash, n_polygons)
|
||||
{}
|
||||
|
||||
|
||||
//! contained_criteria
|
||||
/*! contained_criteria is used to the determine if the face which has
|
||||
inside count should be marked as contained.
|
||||
\param ic the inner count of the talked-about face.
|
||||
\return true if the face of ic, otherwise false.
|
||||
*/
|
||||
bool contained_criteria(unsigned int ic)
|
||||
{
|
||||
//! contained_criteria
|
||||
/*! contained_criteria is used to the determine if the face which has
|
||||
* inside count should be marked as contained.
|
||||
* \param ic the inner count of the talked-about face.
|
||||
* \return true if the face of ic, otherwise false.
|
||||
*/
|
||||
bool contained_criteria(std::size_t ic) {
|
||||
// intersection means that all polygons contain the face.
|
||||
CGAL_assertion(ic <= this->m_num_of_polygons);
|
||||
return (ic == this->m_num_of_polygons);
|
||||
}
|
||||
|
||||
void after_scan(Arrangement&)
|
||||
{}
|
||||
void after_scan(Arrangement&) {}
|
||||
};
|
||||
|
||||
} //namespace CGAL
|
||||
|
|
|
|||
|
|
@ -8,52 +8,46 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
||||
//
|
||||
//
|
||||
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||
// Ophir Setter <ophir.setter@cs.tau.ac.il>
|
||||
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||
// Ophir Setter <ophir.setter@cs.tau.ac.il>
|
||||
|
||||
#ifndef CGAL_GPS_BFS_JOIN_VISITOR_H
|
||||
#define CGAL_GPS_BFS_JOIN_VISITOR_H
|
||||
|
||||
#include <CGAL/license/Boolean_set_operations_2.h>
|
||||
|
||||
|
||||
#include <CGAL/Boolean_set_operations_2/Gps_bfs_base_visitor.h>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
template <class Arrangement_>
|
||||
template <typename Arrangement_>
|
||||
class Gps_bfs_join_visitor :
|
||||
public Gps_bfs_base_visitor<Arrangement_, Gps_bfs_join_visitor<Arrangement_> >
|
||||
{
|
||||
typedef Arrangement_ Arrangement;
|
||||
typedef typename Arrangement::Face_iterator Face_iterator;
|
||||
typedef typename Arrangement::Halfedge_iterator Halfedge_iterator;
|
||||
typedef Gps_bfs_join_visitor<Arrangement> Self;
|
||||
typedef Gps_bfs_base_visitor<Arrangement, Self> Base;
|
||||
typedef typename Base::Edges_hash Edges_hash;
|
||||
typedef typename Base::Faces_hash Faces_hash;
|
||||
public Gps_bfs_base_visitor<Arrangement_, Gps_bfs_join_visitor<Arrangement_>> {
|
||||
using Arrangement = Arrangement_;
|
||||
using Face_iterator = typename Arrangement::Face_iterator;
|
||||
using Halfedge_iterator = typename Arrangement::Halfedge_iterator;
|
||||
using Self = Gps_bfs_join_visitor<Arrangement>;
|
||||
using Base = Gps_bfs_base_visitor<Arrangement, Self>;
|
||||
using Edges_hash = typename Base::Edges_hash;
|
||||
using Faces_hash = typename Base::Faces_hash;
|
||||
|
||||
public:
|
||||
|
||||
Gps_bfs_join_visitor(Edges_hash* edges_hash, Faces_hash* faces_hash, unsigned int n_pgn):
|
||||
Gps_bfs_join_visitor(Edges_hash* edges_hash, Faces_hash* faces_hash, std::size_t n_pgn):
|
||||
Base(edges_hash, faces_hash, n_pgn)
|
||||
{}
|
||||
|
||||
//! contained_criteria
|
||||
/*! contained_criteria is used to the determine if the face which has
|
||||
inside count should be marked as contained.
|
||||
\param ic the inner count of the talked-about face.
|
||||
\return true if the face of ic, otherwise false.
|
||||
*/
|
||||
bool contained_criteria(unsigned int ic)
|
||||
{
|
||||
//! contained_criteria
|
||||
/*! contained_criteria is used to the determine if the face which has
|
||||
* inside count should be marked as contained.
|
||||
* \param ic the inner count of the talked-about face.
|
||||
* \return true if the face of ic, otherwise false.
|
||||
*/
|
||||
bool contained_criteria(std::size_t ic) {
|
||||
// at least one polygon contains the face.
|
||||
return (ic > 0);
|
||||
}
|
||||
|
||||
void after_scan(Arrangement&)
|
||||
{}
|
||||
|
||||
void after_scan(Arrangement&) {}
|
||||
};
|
||||
|
||||
} //namespace CGAL
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
||||
//
|
||||
//
|
||||
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||
// Ophir Setter <ophir.setter@cs.tau.ac.il>
|
||||
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||
// Ophir Setter <ophir.setter@cs.tau.ac.il>
|
||||
|
||||
#ifndef CGAL_GPS_BFS_XOR_VISITOR_H
|
||||
#define CGAL_GPS_BFS_XOR_VISITOR_H
|
||||
|
|
@ -21,73 +21,61 @@
|
|||
|
||||
namespace CGAL {
|
||||
|
||||
template <class Arrangement_>
|
||||
template <typename Arrangement_>
|
||||
class Gps_bfs_xor_visitor :
|
||||
public Gps_bfs_base_visitor<Arrangement_, Gps_bfs_xor_visitor<Arrangement_> >
|
||||
{
|
||||
typedef Arrangement_ Arrangement;
|
||||
typedef typename Arrangement::Face_iterator Face_iterator;
|
||||
typedef typename Arrangement::Halfedge_iterator Halfedge_iterator;
|
||||
typedef Gps_bfs_xor_visitor<Arrangement> Self;
|
||||
typedef Gps_bfs_base_visitor<Arrangement, Self> Base;
|
||||
typedef typename Base::Edges_hash Edges_hash;
|
||||
typedef typename Base::Faces_hash Faces_hash;
|
||||
public Gps_bfs_base_visitor<Arrangement_, Gps_bfs_xor_visitor<Arrangement_>> {
|
||||
using Arrangement = Arrangement_;
|
||||
using Face_iterator = typename Arrangement::Face_iterator;
|
||||
using Halfedge_iterator = typename Arrangement::Halfedge_iterator;
|
||||
using Self = Gps_bfs_xor_visitor<Arrangement>;
|
||||
using Base = Gps_bfs_base_visitor<Arrangement, Self>;
|
||||
using Edges_hash = typename Base::Edges_hash;
|
||||
using Faces_hash = typename Base::Faces_hash;
|
||||
|
||||
public:
|
||||
|
||||
Gps_bfs_xor_visitor(Edges_hash* edges_hash, Faces_hash* faces_hash,
|
||||
unsigned int n_pgn) :
|
||||
std::size_t n_pgn) :
|
||||
Base(edges_hash, faces_hash, n_pgn)
|
||||
{}
|
||||
|
||||
//! contained_criteria
|
||||
//! contained_criteria
|
||||
/*! contained_criteria is used to the determine if the face which has
|
||||
inside count should be marked as contained.
|
||||
\param ic the inner count of the talked-about face.
|
||||
\return true if the face of ic, otherwise false.
|
||||
*/
|
||||
bool contained_criteria(unsigned int ic)
|
||||
{
|
||||
bool contained_criteria(std::size_t ic) {
|
||||
// xor means odd number of polygons.
|
||||
return (ic % 2) == 1;
|
||||
}
|
||||
|
||||
//! after_scan postprocessing after bfs scan.
|
||||
/*! The function fixes some of the curves, to be in the same direction as the
|
||||
half-edges.
|
||||
|
||||
\param arr The given arrangement.
|
||||
*/
|
||||
void after_scan(Arrangement& arr)
|
||||
{
|
||||
typedef typename Arrangement::Geometry_traits_2 Traits;
|
||||
typedef typename Traits::Compare_endpoints_xy_2 Compare_endpoints_xy_2;
|
||||
typedef typename Traits::Construct_opposite_2 Construct_opposite_2;
|
||||
typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2;
|
||||
typedef typename Arrangement::Edge_iterator Edge_iterator;
|
||||
/*! The function fixes some of the curves, to be in the same direction as the
|
||||
* half-edges.
|
||||
*
|
||||
* \param arr The given arrangement.
|
||||
*/
|
||||
void after_scan(Arrangement& arr) {
|
||||
using Traits = typename Arrangement::Geometry_traits_2;
|
||||
using X_monotone_curve_2 = typename Traits::X_monotone_curve_2;
|
||||
|
||||
Traits tr;
|
||||
Compare_endpoints_xy_2 cmp_endpoints =
|
||||
tr.compare_endpoints_xy_2_object();
|
||||
Construct_opposite_2 ctr_opp = tr.construct_opposite_2_object();
|
||||
auto cmp_endpoints = tr.compare_endpoints_xy_2_object();
|
||||
auto ctr_opp = tr.construct_opposite_2_object();
|
||||
|
||||
for(Edge_iterator eit = arr.edges_begin();
|
||||
eit != arr.edges_end();
|
||||
++eit)
|
||||
{
|
||||
Halfedge_iterator he = eit;
|
||||
for (auto eit = arr.edges_begin(); eit != arr.edges_end(); ++eit) {
|
||||
Halfedge_iterator he = eit;
|
||||
const X_monotone_curve_2& cv = he->curve();
|
||||
const bool is_cont = he->face()->contained();
|
||||
const Comparison_result he_res =
|
||||
const bool is_cont = he->face()->contained();
|
||||
const Comparison_result he_res =
|
||||
((Arr_halfedge_direction)he->direction() == ARR_LEFT_TO_RIGHT) ?
|
||||
SMALLER : LARGER;
|
||||
SMALLER : LARGER;
|
||||
const bool has_same_dir = (cmp_endpoints(cv) == he_res);
|
||||
|
||||
if ((is_cont && !has_same_dir) || (!is_cont && has_same_dir))
|
||||
arr.modify_edge(he, ctr_opp(cv));
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
} //namespace CGAL
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
template <class Arrangement_>
|
||||
class Gps_do_intersect_functor
|
||||
{
|
||||
template <typename Arrangement_>
|
||||
class Gps_do_intersect_functor {
|
||||
public:
|
||||
using Arrangement_2 = Arrangement_;
|
||||
|
||||
typedef Arrangement_ Arrangement_2;
|
||||
using Face_const_handle = typename Arrangement_2::Face_const_handle;
|
||||
using Vertex_const_handle = typename Arrangement_2::Vertex_const_handle;
|
||||
using Halfedge_const_handle = typename Arrangement_2::Halfedge_const_handle;
|
||||
|
||||
typedef typename Arrangement_2::Face_const_handle Face_const_handle;
|
||||
typedef typename Arrangement_2::Vertex_const_handle Vertex_const_handle;
|
||||
typedef typename Arrangement_2::Halfedge_const_handle Halfedge_const_handle;
|
||||
|
||||
typedef typename Arrangement_2::Face_handle Face_handle;
|
||||
typedef typename Arrangement_2::Halfedge_handle Halfedge_handle;
|
||||
typedef typename Arrangement_2::Vertex_handle Vertex_handle;
|
||||
using Face_handle = typename Arrangement_2::Face_handle;
|
||||
using Halfedge_handle = typename Arrangement_2::Halfedge_handle;
|
||||
using Vertex_handle = typename Arrangement_2::Vertex_handle;
|
||||
|
||||
// default constructor
|
||||
Gps_do_intersect_functor() : m_found_reg_intersection(false),
|
||||
m_found_boudary_intersection(false)
|
||||
|
||||
Gps_do_intersect_functor() :
|
||||
m_found_reg_intersection(false),
|
||||
m_found_boudary_intersection(false)
|
||||
{}
|
||||
|
||||
void create_face (Face_const_handle f1,
|
||||
Face_const_handle f2,
|
||||
Face_handle )
|
||||
{
|
||||
if(f1->contained() && f2->contained())
|
||||
// found intersection
|
||||
m_found_reg_intersection = true;
|
||||
}
|
||||
void create_face(Face_const_handle f1, Face_const_handle f2, Face_handle)
|
||||
{ if (f1->contained() && f2->contained()) m_found_reg_intersection = true; }
|
||||
|
||||
void create_vertex(Vertex_const_handle, Vertex_const_handle, Vertex_handle)
|
||||
{ m_found_boudary_intersection = true; }
|
||||
|
||||
void create_vertex(Vertex_const_handle ,
|
||||
Vertex_const_handle ,
|
||||
Vertex_handle )
|
||||
{
|
||||
m_found_boudary_intersection = true;
|
||||
}
|
||||
void create_vertex(Vertex_const_handle, Halfedge_const_handle, Vertex_handle)
|
||||
{ m_found_boudary_intersection = true; }
|
||||
|
||||
void create_vertex(Vertex_const_handle ,
|
||||
Halfedge_const_handle ,
|
||||
Vertex_handle )
|
||||
{
|
||||
m_found_boudary_intersection = true;
|
||||
}
|
||||
void create_vertex(Halfedge_const_handle, Vertex_const_handle, Vertex_handle)
|
||||
{ m_found_boudary_intersection = true; }
|
||||
|
||||
void create_vertex(Halfedge_const_handle ,
|
||||
Vertex_const_handle ,
|
||||
Vertex_handle )
|
||||
{
|
||||
m_found_boudary_intersection = true;
|
||||
}
|
||||
void create_vertex(Halfedge_const_handle, Halfedge_const_handle, Vertex_handle) {}
|
||||
|
||||
void create_vertex(Halfedge_const_handle ,
|
||||
Halfedge_const_handle ,
|
||||
Vertex_handle )
|
||||
{}
|
||||
void create_vertex(Face_const_handle, Vertex_const_handle, Vertex_handle) {}
|
||||
|
||||
void create_vertex(Vertex_const_handle, Face_const_handle, Vertex_handle) {}
|
||||
|
||||
void create_vertex(Face_const_handle ,
|
||||
Vertex_const_handle ,
|
||||
Vertex_handle )
|
||||
{}
|
||||
void create_edge(Halfedge_const_handle, Halfedge_const_handle, Halfedge_handle)
|
||||
{ m_found_boudary_intersection = true; }
|
||||
|
||||
void create_vertex(Vertex_const_handle ,
|
||||
Face_const_handle ,
|
||||
Vertex_handle )
|
||||
{}
|
||||
void create_edge(Halfedge_const_handle, Face_const_handle, Halfedge_handle) {}
|
||||
|
||||
void create_edge(Halfedge_const_handle ,
|
||||
Halfedge_const_handle ,
|
||||
Halfedge_handle )
|
||||
{
|
||||
m_found_boudary_intersection = true;
|
||||
}
|
||||
void create_edge(Face_const_handle, Halfedge_const_handle, Halfedge_handle) {}
|
||||
|
||||
void create_edge(Halfedge_const_handle ,
|
||||
Face_const_handle ,
|
||||
Halfedge_handle )
|
||||
{}
|
||||
bool found_reg_intersection() const { return m_found_reg_intersection; }
|
||||
|
||||
void create_edge(Face_const_handle ,
|
||||
Halfedge_const_handle ,
|
||||
Halfedge_handle )
|
||||
{}
|
||||
bool found_boundary_intersection() const { return m_found_boudary_intersection; }
|
||||
|
||||
|
||||
bool found_reg_intersection() const
|
||||
{
|
||||
return m_found_reg_intersection;
|
||||
}
|
||||
|
||||
bool found_boundary_intersection() const
|
||||
{
|
||||
return m_found_boudary_intersection;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
bool m_found_reg_intersection;
|
||||
bool m_found_boudary_intersection;
|
||||
protected:
|
||||
bool m_found_reg_intersection;
|
||||
bool m_found_boudary_intersection;
|
||||
};
|
||||
|
||||
|
||||
} //namespace CGAL
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -7,15 +7,17 @@
|
|||
// $Id$
|
||||
// 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
|
||||
#define CGAL_GPS_MERGE_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_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_xor_visitor.h>
|
||||
#include <CGAL/Boolean_set_operations_2/Gps_bfs_intersection_visitor.h>
|
||||
|
|
@ -23,50 +25,40 @@
|
|||
|
||||
namespace CGAL {
|
||||
|
||||
/*!
|
||||
\file Gps_merge.h
|
||||
\brief This file contains classes that are responsible for merging
|
||||
two sets of polygons in the divide-and-conquer algorithm.
|
||||
The file contains 3 mergers: Join_merge, Intersection_merge and
|
||||
Xor_merge. Join_merge is used when we want to merge the two sets,
|
||||
Intersection_merge is used for intersection, and Xor_merge is used
|
||||
for symmetric difference.
|
||||
*/
|
||||
|
||||
//! Base_merge
|
||||
/*! Base_merge is the base class for all merger classes.
|
||||
All merges used BFS algorithm with a different visitor when discovering
|
||||
a new face.
|
||||
/*! \file Gps_merge.h
|
||||
*
|
||||
* This file contains classes that are responsible for merging two sets of
|
||||
* polygons in the divide-and-conquer algorithm. The file contains 3 mergers:
|
||||
* Join_merge, Intersection_merge and Xor_merge. Join_merge is used when we want
|
||||
* to merge the two sets, Intersection_merge is used for intersection, and
|
||||
* Xor_merge is used for symmetric difference.
|
||||
*/
|
||||
template <class Arrangement_, class Visitor_>
|
||||
class Base_merge
|
||||
{
|
||||
typedef Arrangement_ Arrangement_2;
|
||||
typedef Visitor_ Visitor;
|
||||
typedef typename Arrangement_2::Vertex_handle Vertex_handle;
|
||||
typedef std::pair<Arrangement_2 *,
|
||||
std::vector<Vertex_handle> *> Arr_entry;
|
||||
|
||||
/*! Base_merge
|
||||
* Base_merge is the base class for all merger classes.
|
||||
* All merges used BFS algorithm with a different visitor when discovering
|
||||
* a new face.
|
||||
*/
|
||||
template <typename Arrangement_, typename Visitor_>
|
||||
class Base_merge {
|
||||
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:
|
||||
void operator()(unsigned int i,
|
||||
unsigned int j,
|
||||
unsigned int jump,
|
||||
std::vector<Arr_entry>& arr_vec)
|
||||
{
|
||||
if(i==j)
|
||||
return;
|
||||
void operator()(std::size_t i, std::size_t j, std::size_t jump, std::vector<Arr_entry>& arr_vec) {
|
||||
if (i == j) return;
|
||||
|
||||
const typename Arrangement_2::Geometry_traits_2 * tr =
|
||||
arr_vec[i].first->geometry_traits();
|
||||
Arrangement_2 *res = new Arrangement_2(tr);
|
||||
std::vector<Vertex_handle> *verts = new std::vector<Vertex_handle>;
|
||||
const auto* tr = arr_vec[i].first->geometry_traits();
|
||||
Arrangement_2* res = new Arrangement_2(tr);
|
||||
std::vector<Vertex_handle>* verts = new std::vector<Vertex_handle>;
|
||||
|
||||
Gps_agg_op<Arrangement_2, Visitor>
|
||||
agg_op(*res, *verts, *(res->traits_adaptor()));
|
||||
using Agg_op = Gps_agg_op<Arrangement_2, Visitor, Gps_agg_op_visitor>;
|
||||
Agg_op agg_op(*res, *verts, *(res->traits_adaptor()));
|
||||
agg_op.sweep_arrangements(i, j, jump, arr_vec);
|
||||
|
||||
for(unsigned int count=i; count<=j; count+=jump)
|
||||
{
|
||||
for (std::size_t count = i; count <= j; count += jump) {
|
||||
delete (arr_vec[count].first);
|
||||
delete (arr_vec[count].second);
|
||||
}
|
||||
|
|
@ -74,38 +66,92 @@ public:
|
|||
arr_vec[i].first = res;
|
||||
arr_vec[i].second = verts;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
//! Join_merge
|
||||
/*! Join_merge is used to join two sets of polygons together in the D&C
|
||||
algorithm. It is a base merge with a visitor that joins faces.
|
||||
/*! Base_intercepted_merge
|
||||
* Base_intercepted_merge is the base class for all merger classes that can be
|
||||
* interceted (e.g., when an intersection is detected). All merges used BFS
|
||||
* algorithm with a different visitor when discovering a new face.
|
||||
*/
|
||||
template <class Arrangement_>
|
||||
class Join_merge : public Base_merge<Arrangement_,
|
||||
Gps_bfs_join_visitor<Arrangement_> >
|
||||
{};
|
||||
template <typename Arrangement_, typename Visitor_>
|
||||
class Base_intercepted_merge {
|
||||
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
|
||||
/*! Intersection_merge is used to merge two sets of polygons creating their
|
||||
intersection.
|
||||
*/
|
||||
template <class Arrangement_>
|
||||
class Intersection_merge : public Base_merge<Arrangement_,
|
||||
Gps_bfs_intersection_visitor<Arrangement_> >
|
||||
{};
|
||||
const auto* tr = begin->first->geometry_traits();
|
||||
Arrangement_2* arr = new Arrangement_2(tr);
|
||||
std::vector<Vertex_handle>* verts = new std::vector<Vertex_handle>;
|
||||
|
||||
//! Xor_merge
|
||||
/*! Xor_merge is used to merge two sets of polygons creating their
|
||||
symmetric difference.
|
||||
*/
|
||||
template <class Arrangement_>
|
||||
class Xor_merge : public Base_merge<Arrangement_,
|
||||
Gps_bfs_xor_visitor<Arrangement_> >
|
||||
{
|
||||
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_arrangements2(begin, end);
|
||||
|
||||
begin->first = arr;
|
||||
begin->second = verts;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
bool operator()(std::size_t i, std::size_t j, std::size_t jump, std::vector<Arr_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
|
||||
|
||||
#endif
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -7,11 +7,10 @@
|
|||
// $Id$
|
||||
// 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
|
||||
#define CGAL_BSO_2_GPS_POLYGON_SIMPILFIER_H
|
||||
#ifndef CGAL_GPS_POLYGON_SIMPILFIER_H
|
||||
#define CGAL_GPS_POLYGON_SIMPILFIER_H
|
||||
|
||||
#include <CGAL/license/Boolean_set_operations_2.h>
|
||||
|
||||
|
|
@ -31,34 +30,33 @@ namespace Ss2 = Surface_sweep_2;
|
|||
|
||||
template <typename Arrangement_>
|
||||
class Gps_polygon_simplifier {
|
||||
typedef Arrangement_ Arrangement_2;
|
||||
using Arrangement_2 = Arrangement_;
|
||||
|
||||
typedef typename Arrangement_2::Geometry_traits_2 Geometry_traits_2;
|
||||
typedef typename Arrangement_2::Topology_traits Topology_traits;
|
||||
using Geometry_traits_2 = typename Arrangement_2::Geometry_traits_2;
|
||||
using Topology_traits = typename Arrangement_2::Topology_traits;
|
||||
|
||||
typedef Arrangement_2 Arr;
|
||||
typedef Geometry_traits_2 Gt2;
|
||||
typedef Topology_traits Tt;
|
||||
using Arr = Arrangement_2;
|
||||
using Gt2 = Geometry_traits_2;
|
||||
using Tt = Topology_traits;
|
||||
|
||||
typedef typename Gt2::Curve_const_iterator Curve_const_iterator;
|
||||
typedef typename Gt2::Polygon_2 Polygon_2;
|
||||
typedef typename Gt2::Polygon_with_holes_2 Polygon_with_holes_2;
|
||||
typedef typename Gt2::Construct_curves_2 Construct_curves_2;
|
||||
using Curve_const_iterator = typename Gt2::Curve_const_iterator;
|
||||
using Polygon_2 = typename Gt2::Polygon_2;
|
||||
using Polygon_with_holes_2 = typename Gt2::Polygon_with_holes_2;
|
||||
using Construct_curves_2 = typename Gt2::Construct_curves_2;
|
||||
|
||||
typedef Gps_simplifier_traits<Gt2> Mgt2;
|
||||
typedef typename Mgt2::Curve_data Curve_data;
|
||||
typedef typename Mgt2::X_monotone_curve_2 Meta_X_monotone_curve_2;
|
||||
using Mgt2 = Gps_simplifier_traits<Gt2>;
|
||||
using Curve_data = typename Mgt2::Curve_data;
|
||||
using Meta_X_monotone_curve_2 = typename Mgt2::X_monotone_curve_2;
|
||||
|
||||
typedef typename Arr::Halfedge_handle Halfedge_handle;
|
||||
typedef typename Arr::Halfedge_iterator Halfedge_iterator;
|
||||
typedef typename Arr::Face_handle Face_handle;
|
||||
typedef typename Arr::Face_iterator Face_iterator;
|
||||
typedef typename Arr::Edge_iterator Edge_iterator;
|
||||
typedef typename Arr::Vertex_handle Vertex_handle;
|
||||
typedef typename Arr::Ccb_halfedge_const_circulator
|
||||
Ccb_halfedge_const_circulator;
|
||||
typedef typename Arr::Ccb_halfedge_circulator Ccb_halfedge_circulator;
|
||||
typedef typename Arr::Allocator Allocator;
|
||||
using Halfedge_handle = typename Arr::Halfedge_handle;
|
||||
using Halfedge_iterator = typename Arr::Halfedge_iterator;
|
||||
using Face_handle = typename Arr::Face_handle;
|
||||
using Face_iterator = typename Arr::Face_iterator;
|
||||
using Edge_iterator = typename Arr::Edge_iterator;
|
||||
using Vertex_handle = typename Arr::Vertex_handle;
|
||||
using Ccb_halfedge_const_circulator = typename Arr::Ccb_halfedge_const_circulator;
|
||||
using Ccb_halfedge_circulator = typename Arr::Ccb_halfedge_circulator;
|
||||
using Allocator = typename Arr::Allocator;
|
||||
|
||||
// We obtain a proper helper type from the topology traits of the arrangement.
|
||||
// However, the arrangement is parametrized with the Gt2 geometry traits,
|
||||
|
|
@ -67,22 +65,18 @@ class Gps_polygon_simplifier {
|
|||
// We cannot parameterized the arrangement with the Mgt2 geometry
|
||||
// traits to start with, because it extends the curve type with arrangement
|
||||
// dependent types. (It is parameterized with the arrangement type.)
|
||||
typedef Indexed_event<Mgt2, Arr, Allocator> Event;
|
||||
typedef Arr_construction_subcurve<Mgt2, Event, Allocator>
|
||||
Subcurve;
|
||||
typedef typename Tt::template Construction_helper<Event, Subcurve>
|
||||
Helper_tmp;
|
||||
typedef typename Helper_tmp::template rebind<Mgt2, Arr, Event, Subcurve>::other
|
||||
Helper;
|
||||
typedef Gps_agg_op_base_visitor<Helper, Arr> Visitor;
|
||||
typedef Ss2::Surface_sweep_2<Visitor> Surface_sweep_2;
|
||||
using Event = Indexed_event<Mgt2, Arr, Allocator>;
|
||||
using Subcurve = Arr_construction_subcurve<Mgt2, Event, Allocator>;
|
||||
using Helper_tmp = typename Tt::template Construction_helper<Event, Subcurve>;
|
||||
using Helper = typename Helper_tmp::template rebind<Mgt2, Arr, Event, Subcurve>::other;
|
||||
using Visitor = Gps_agg_op_base_visitor<Helper, Arr>;
|
||||
using Surface_sweep_2 = Ss2::Surface_sweep_2<Visitor>;
|
||||
|
||||
typedef Unique_hash_map<Halfedge_handle, unsigned int>
|
||||
Edges_hash;
|
||||
using Edges_hash = Unique_hash_map<Halfedge_handle, std::size_t>;
|
||||
|
||||
typedef Unique_hash_map<Face_handle, unsigned int> Faces_hash;
|
||||
typedef Gps_bfs_join_visitor<Arr> Bfs_visitor;
|
||||
typedef Gps_bfs_scanner<Arr, Bfs_visitor> Bfs_scanner;
|
||||
using Faces_hash = Unique_hash_map<Face_handle, std::size_t>;
|
||||
using Bfs_visitor = Gps_bfs_join_visitor<Arr>;
|
||||
using Bfs_scanner = Gps_bfs_scanner<Arr, Bfs_visitor>;
|
||||
|
||||
protected:
|
||||
Arr* m_arr;
|
||||
|
|
@ -104,16 +98,14 @@ public:
|
|||
{}
|
||||
|
||||
/*! Destructor. */
|
||||
~Gps_polygon_simplifier()
|
||||
{
|
||||
~Gps_polygon_simplifier() {
|
||||
if (m_own_traits && (m_traits != nullptr)) {
|
||||
delete m_traits;
|
||||
m_traits = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void simplify(const Polygon_2& pgn)
|
||||
{
|
||||
void simplify(const Polygon_2& pgn) {
|
||||
Construct_curves_2 ctr_curves =
|
||||
reinterpret_cast<const Gt2*>(m_traits)->construct_curves_2_object();
|
||||
|
||||
|
|
@ -122,14 +114,13 @@ public:
|
|||
std::pair<Curve_const_iterator, Curve_const_iterator> itr_pair =
|
||||
ctr_curves(pgn);
|
||||
|
||||
unsigned int index = 0;
|
||||
std::size_t index = 0;
|
||||
for (Curve_const_iterator itr = itr_pair.first; itr != itr_pair.second;
|
||||
++itr, ++index)
|
||||
{
|
||||
++itr, ++index) {
|
||||
Curve_data cv_data(1, 0, index);
|
||||
curves_list.push_back(Meta_X_monotone_curve_2(*itr, cv_data));
|
||||
}
|
||||
m_traits->set_polygon_size(static_cast<unsigned int>(curves_list.size()));
|
||||
m_traits->set_polygon_size(curves_list.size());
|
||||
|
||||
m_surface_sweep.sweep(curves_list.begin(), curves_list.end());
|
||||
|
||||
|
|
|
|||
|
|
@ -7,14 +7,13 @@
|
|||
// $Id$
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
||||
//
|
||||
//
|
||||
// Author(s): Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||
// Ron Wein <wein@post.tau.ac.il>
|
||||
// Boris Kozorovitzky <boriskoz@post.tau.ac.il>
|
||||
// Guy Zucker <guyzucke@post.tau.ac.il>
|
||||
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||
// Ron Wein <wein@post.tau.ac.il>
|
||||
// Boris Kozorovitzky <boriskoz@post.tau.ac.il>
|
||||
// Guy Zucker <guyzucke@post.tau.ac.il>
|
||||
|
||||
#ifndef CGAL_BSO_2_GPS_POLYGON_VALIDATION_2_H
|
||||
#define CGAL_BSO_2_GPS_POLYGON_VALIDATION_2_H
|
||||
#ifndef CGAL_GPS_POLYGON_VALIDATION_2_H
|
||||
#define CGAL_GPS_POLYGON_VALIDATION_2_H
|
||||
|
||||
#include <CGAL/license/Boolean_set_operations_2.h>
|
||||
|
||||
|
|
|
|||
|
|
@ -7,9 +7,8 @@
|
|||
// $Id$
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
||||
//
|
||||
//
|
||||
// Author(s): Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||
// Efi Fogel <efifogel@gmail.com>
|
||||
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||
// Efi Fogel <efifogel@gmail.com>
|
||||
|
||||
#ifndef CGAL_GPS_SIMPLIFIER_TRAITS_H
|
||||
#define CGAL_GPS_SIMPLIFIER_TRAITS_H
|
||||
|
|
@ -23,97 +22,94 @@ namespace CGAL {
|
|||
|
||||
class Gps_simplifier_curve_data {
|
||||
protected:
|
||||
unsigned int m_bc;
|
||||
unsigned int m_twin_bc;
|
||||
unsigned int m_index;
|
||||
std::size_t m_bc;
|
||||
std::size_t m_twin_bc;
|
||||
std::size_t m_index;
|
||||
|
||||
public:
|
||||
Gps_simplifier_curve_data() {}
|
||||
|
||||
Gps_simplifier_curve_data(unsigned int bc, unsigned int twin_bc,
|
||||
unsigned int index):
|
||||
Gps_simplifier_curve_data(std::size_t bc, std::size_t twin_bc,
|
||||
std::size_t index):
|
||||
m_bc(bc),
|
||||
m_twin_bc(twin_bc),
|
||||
m_index(index)
|
||||
{}
|
||||
|
||||
unsigned int bc() const { return m_bc; }
|
||||
std::size_t bc() const { return m_bc; }
|
||||
|
||||
unsigned int twin_bc() const { return m_twin_bc; }
|
||||
std::size_t twin_bc() const { return m_twin_bc; }
|
||||
|
||||
unsigned int index() const { return m_index; }
|
||||
std::size_t index() const { return m_index; }
|
||||
|
||||
unsigned int& index() { return m_index; }
|
||||
std::size_t& index() { return m_index; }
|
||||
|
||||
unsigned int& twin_bc() { return m_twin_bc; }
|
||||
std::size_t& twin_bc() { return m_twin_bc; }
|
||||
|
||||
void set_bc(unsigned int bc) { m_bc = bc; }
|
||||
void set_bc(std::size_t bc) { m_bc = bc; }
|
||||
|
||||
void set_twin_bc(unsigned int twin_bc) { m_twin_bc = twin_bc; }
|
||||
void set_twin_bc(std::size_t twin_bc) { m_twin_bc = twin_bc; }
|
||||
|
||||
void set_index(unsigned int index) { m_index = index; }
|
||||
void set_index(std::size_t index) { m_index = index; }
|
||||
};
|
||||
|
||||
struct Gps_simplifier_point_data {
|
||||
protected:
|
||||
unsigned int m_index;
|
||||
std::size_t m_index;
|
||||
|
||||
public:
|
||||
Gps_simplifier_point_data() {}
|
||||
|
||||
Gps_simplifier_point_data(unsigned int index) : m_index(index) {}
|
||||
Gps_simplifier_point_data(std::size_t index) : m_index(index) {}
|
||||
|
||||
unsigned int index() const { return m_index; }
|
||||
std::size_t index() const { return m_index; }
|
||||
|
||||
void set_index(unsigned int index) { m_index = index; }
|
||||
void set_index(std::size_t index) { m_index = index; }
|
||||
};
|
||||
|
||||
template <typename Traits_>
|
||||
class Gps_simplifier_traits :
|
||||
public Gps_traits_decorator<Traits_,
|
||||
Gps_simplifier_curve_data,
|
||||
Gps_simplifier_point_data>
|
||||
{
|
||||
Gps_simplifier_point_data> {
|
||||
public:
|
||||
typedef Traits_ Traits;
|
||||
typedef Gps_traits_decorator<Traits_,
|
||||
Gps_simplifier_curve_data,
|
||||
Gps_simplifier_point_data> Base;
|
||||
typedef Gps_simplifier_traits<Traits> Self;
|
||||
typedef typename Traits::X_monotone_curve_2 Base_x_monotone_curve_2;
|
||||
typedef typename Traits::Point_2 Base_point_2;
|
||||
typedef typename Traits::Construct_min_vertex_2 Base_Construct_min_vertex_2;
|
||||
typedef typename Traits::Construct_max_vertex_2 Base_Construct_max_vertex_2;
|
||||
typedef typename Traits::Compare_endpoints_xy_2 Base_Compare_endpoints_xy_2;
|
||||
typedef typename Traits::Compare_xy_2 Base_Compare_xy_2;
|
||||
typedef typename Traits::Compare_y_at_x_right_2 Base_Compare_y_at_x_right_2;
|
||||
typedef typename Traits::Compare_y_at_x_2 Base_Compare_y_at_x_2;
|
||||
typedef typename Traits::Intersect_2 Base_Intersect_2;
|
||||
typedef typename Traits::Split_2 Base_Split_2;
|
||||
using Traits = Traits_;
|
||||
using Base = Gps_traits_decorator<Traits_, Gps_simplifier_curve_data, Gps_simplifier_point_data>;
|
||||
using Self = Gps_simplifier_traits<Traits>;
|
||||
using Base_x_monotone_curve_2 = typename Traits::X_monotone_curve_2;
|
||||
using Base_point_2 = typename Traits::Point_2;
|
||||
using Base_Construct_min_vertex_2 = typename Traits::Construct_min_vertex_2;
|
||||
using Base_Construct_max_vertex_2 = typename Traits::Construct_max_vertex_2;
|
||||
using Base_Compare_endpoints_xy_2 = typename Traits::Compare_endpoints_xy_2;
|
||||
using Base_Compare_xy_2 = typename Traits::Compare_xy_2;
|
||||
using Base_Compare_y_at_x_right_2 = typename Traits::Compare_y_at_x_right_2;
|
||||
using Base_Compare_y_at_x_2 = typename Traits::Compare_y_at_x_2;
|
||||
using Base_Intersect_2 = typename Traits::Intersect_2;
|
||||
using Base_Split_2 = typename Traits::Split_2;
|
||||
|
||||
protected:
|
||||
mutable unsigned int m_pgn_size;
|
||||
mutable std::size_t m_pgn_size;
|
||||
|
||||
public:
|
||||
typedef typename Base::X_monotone_curve_2 X_monotone_curve_2;
|
||||
typedef typename Base::Point_2 Point_2;
|
||||
typedef typename Base::Multiplicity Multiplicity;
|
||||
using X_monotone_curve_2 = typename Base::X_monotone_curve_2;
|
||||
using Point_2 = typename Base::Point_2;
|
||||
using Multiplicity = typename Base::Multiplicity;
|
||||
|
||||
typedef typename Base::Curve_data Curve_data;
|
||||
typedef typename Base::Point_data Point_data;
|
||||
using Curve_data = typename Base::Curve_data;
|
||||
using Point_data = typename Base::Point_data;
|
||||
|
||||
Gps_simplifier_traits() {}
|
||||
|
||||
Gps_simplifier_traits(const Traits& tr) : Base(tr) {}
|
||||
|
||||
unsigned int polygon_size() const { return m_pgn_size; }
|
||||
std::size_t polygon_size() const { return m_pgn_size; }
|
||||
|
||||
void set_polygon_size(unsigned int pgn_size) const { m_pgn_size = pgn_size; }
|
||||
void set_polygon_size(std::size_t pgn_size) const { m_pgn_size = pgn_size; }
|
||||
|
||||
bool is_valid_index(unsigned int index) const
|
||||
bool is_valid_index(std::size_t index) const
|
||||
{ return (index < m_pgn_size); }
|
||||
|
||||
unsigned int invalid_index() const { return (m_pgn_size); }
|
||||
std::size_t invalid_index() const { return (m_pgn_size); }
|
||||
|
||||
class Intersect_2 {
|
||||
private:
|
||||
|
|
@ -129,12 +125,9 @@ public:
|
|||
template <typename OutputIterator>
|
||||
OutputIterator operator()(const X_monotone_curve_2& cv1,
|
||||
const X_monotone_curve_2& cv2,
|
||||
OutputIterator oi) const
|
||||
{
|
||||
typedef const std::pair<Base_point_2, Multiplicity>
|
||||
Intersection_base_point;
|
||||
typedef std::variant<Intersection_base_point, Base_x_monotone_curve_2>
|
||||
Intersection_base_result;
|
||||
OutputIterator oi) const {
|
||||
using Intersection_base_point = const std::pair<Base_point_2, Multiplicity>;
|
||||
using Intersection_base_result = std::variant<Intersection_base_point, Base_x_monotone_curve_2>;
|
||||
|
||||
const auto* base_traits = m_traits.m_base_traits;
|
||||
auto base_cmp_xy = base_traits->compare_xy_2_object();
|
||||
|
|
@ -146,7 +139,7 @@ public:
|
|||
//if (m_traits.is_valid_index(cv1.data().index()) &&
|
||||
// m_traits.is_valid_index(cv2.data().index()))
|
||||
//{
|
||||
// unsigned int index_diff =
|
||||
// std::size_t index_diff =
|
||||
// (cv1.data().index() > cv2.data().index()) ?
|
||||
// (cv1.data().index() - cv2.data().index()):
|
||||
// (cv2.data().index() - cv1.data().index());
|
||||
|
|
@ -180,8 +173,8 @@ public:
|
|||
std::get_if<Base_x_monotone_curve_2>(&xection);
|
||||
|
||||
CGAL_assertion(overlap_cv != nullptr);
|
||||
unsigned int ov_bc;
|
||||
unsigned int ov_twin_bc;
|
||||
std::size_t ov_bc;
|
||||
std::size_t ov_twin_bc;
|
||||
if (base_cmp_endpoints(cv1) == base_cmp_endpoints(cv2)) {
|
||||
// cv1 and cv2 have the same directions
|
||||
ov_bc = cv1.data().bc() + cv2.data().bc();
|
||||
|
|
@ -207,7 +200,7 @@ public:
|
|||
};
|
||||
|
||||
/*! Obtain an Intersect_2 functor object. */
|
||||
Intersect_2 intersect_2_object () const { return Intersect_2(*this); }
|
||||
Intersect_2 intersect_2_object() const { return Intersect_2(*this); }
|
||||
|
||||
class Split_2 {
|
||||
private:
|
||||
|
|
@ -220,8 +213,7 @@ public:
|
|||
|
||||
public:
|
||||
void operator()(const X_monotone_curve_2& cv, const Point_2 & p,
|
||||
X_monotone_curve_2& c1, X_monotone_curve_2& c2) const
|
||||
{
|
||||
X_monotone_curve_2& c1, X_monotone_curve_2& c2) const {
|
||||
const auto* base_traits = m_traits.m_base_traits;
|
||||
auto base_split = base_traits->split_2_object();
|
||||
base_split(cv.base(), p.base(), c1.base(), c2.base());
|
||||
|
|
@ -250,8 +242,7 @@ public:
|
|||
* \param cv The curve.
|
||||
* \return The left endpoint.
|
||||
*/
|
||||
Point_2 operator()(const X_monotone_curve_2 & cv) const
|
||||
{
|
||||
Point_2 operator()(const X_monotone_curve_2 & cv) const {
|
||||
const auto* base_traits = m_traits.m_base_traits;
|
||||
auto base_ctr_min_vertex = base_traits->construct_min_vertex_2_object();
|
||||
|
||||
|
|
@ -290,8 +281,7 @@ public:
|
|||
* \param cv The curve.
|
||||
* \return The left endpoint.
|
||||
*/
|
||||
Point_2 operator() (const X_monotone_curve_2 & cv) const
|
||||
{
|
||||
Point_2 operator() (const X_monotone_curve_2 & cv) const {
|
||||
const auto* base_traits = m_traits.m_base_traits;
|
||||
auto base_ctr_max_vertex = base_traits->construct_max_vertex_2_object();
|
||||
if (! m_traits.is_valid_index(cv.data().index()))
|
||||
|
|
@ -329,8 +319,7 @@ public:
|
|||
* \param cv The curve.
|
||||
* \return The left endpoint.
|
||||
*/
|
||||
Comparison_result operator()(const Point_2& p1, const Point_2& p2) const
|
||||
{
|
||||
Comparison_result operator()(const Point_2& p1, const Point_2& p2) const {
|
||||
const auto* base_traits = m_traits.m_base_traits;
|
||||
auto base_cmp_xy = base_traits->compare_xy_2_object();
|
||||
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@
|
|||
// Ron Wein <wein@post.tau.ac.il>
|
||||
// Efi Fogel <efifogel@gmail.com>
|
||||
|
||||
#ifndef CGAL_BSO_2_INDEXED_VISITOR_H
|
||||
#define CGAL_BSO_2_INDEXED_VISITOR_H
|
||||
#ifndef CGAL_INDEXED_VISITOR_H
|
||||
#define CGAL_INDEXED_VISITOR_H
|
||||
|
||||
#include <CGAL/license/Boolean_set_operations_2.h>
|
||||
|
||||
|
|
@ -32,17 +32,16 @@ class Indexed_event :
|
|||
Arrangement_,
|
||||
Allocator_>,
|
||||
Allocator_>,
|
||||
Arrangement_>
|
||||
{
|
||||
Arrangement_> {
|
||||
private:
|
||||
unsigned int m_index;
|
||||
std::size_t m_index;
|
||||
|
||||
public:
|
||||
Indexed_event() : m_index (0) {}
|
||||
|
||||
unsigned int index() const { return (m_index); }
|
||||
std::size_t index() const { return (m_index); }
|
||||
|
||||
void set_index(unsigned int index) { m_index = index; }
|
||||
void set_index(std::size_t index) { m_index = index; }
|
||||
};
|
||||
|
||||
} // namespace CGAL
|
||||
|
|
|
|||
|
|
@ -31,9 +31,9 @@ namespace CGAL {
|
|||
// Utility struct
|
||||
template <typename Polygon>
|
||||
struct Gps_polyline_traits {
|
||||
typedef typename Gps_default_traits<Polygon>::Arr_traits Segment_traits;
|
||||
typedef Arr_polyline_traits_2<Segment_traits> Polyline_traits;
|
||||
typedef Gps_traits_2<Polyline_traits> Traits;
|
||||
using Segment_traits = typename Gps_default_traits<Polygon>::Arr_traits;
|
||||
using Polyline_traits = Arr_polyline_traits_2<Segment_traits>;
|
||||
using Traits = Gps_traits_2<Polyline_traits>;
|
||||
};
|
||||
|
||||
// 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>
|
||||
template <typename Kernel, typename Container, typename ArrTraits>
|
||||
General_polygon_2<ArrTraits>
|
||||
convert_polygon(const Polygon_2<Kernel, Container>& polygon,
|
||||
const ArrTraits& traits)
|
||||
{
|
||||
convert_polygon(const Polygon_2<Kernel, Container>& polygon, const ArrTraits& traits) {
|
||||
auto ctr = traits.construct_curve_2_object();
|
||||
if (polygon.is_empty()) return General_polygon_2<ArrTraits>();
|
||||
using Point = typename ArrTraits::Point_2;
|
||||
|
|
@ -99,22 +97,20 @@ convert_polygon(const Polygon_2<Kernel, Container>& polygon,
|
|||
General_polygon_2<ArrTraits> gpgn;
|
||||
auto make_x_mtn = traits.make_x_monotone_2_object();
|
||||
make_x_mtn(cv,
|
||||
boost::make_function_output_iterator
|
||||
([&](const Make_x_monotone_result& obj)
|
||||
{ gpgn.push_back(*(std::get_if<X_monotone_curve>(&obj))); }));
|
||||
boost::make_function_output_iterator([&](const Make_x_monotone_result& obj)
|
||||
{ gpgn.push_back(*(std::get_if<X_monotone_curve>(&obj))); }));
|
||||
return gpgn;
|
||||
}
|
||||
|
||||
// Convert Polygon_with_holes_2 to General_polygon_with_holes_2<Polyline_traits>
|
||||
template <typename Kernel, typename Container, typename ArrTraits>
|
||||
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,
|
||||
const ArrTraits& traits) {
|
||||
typedef General_polygon_2<ArrTraits> General_pgn;
|
||||
typedef Polygon_2<Kernel, Container> Pgn;
|
||||
auto converter = [&](const Pgn& pgn)->General_pgn {
|
||||
return convert_polygon(pgn, traits);
|
||||
};
|
||||
using General_pgn = General_polygon_2<ArrTraits>;
|
||||
using Pgn = Polygon_2<Kernel, Container>;
|
||||
auto converter = [&](const Pgn& pgn)->General_pgn
|
||||
{ return convert_polygon(pgn, traits); };
|
||||
return General_polygon_with_holes_2<General_polygon_2<ArrTraits>>
|
||||
(convert_polygon(pwh.outer_boundary(), traits),
|
||||
boost::make_transform_iterator(pwh.holes().begin(), converter),
|
||||
|
|
@ -137,14 +133,11 @@ convert_polygon_back(const General_polygon_2<ArrTraits>& gpgn) {
|
|||
// Convert General_polygon_with_holes_2<Polyline_traits> to Polygon_with_holes_2
|
||||
template <typename Kernel, typename Container, typename ArrTraits>
|
||||
Polygon_with_holes_2<Kernel, Container>
|
||||
convert_polygon_back(const General_polygon_with_holes_2
|
||||
<General_polygon_2<ArrTraits> >& gpwh)
|
||||
{
|
||||
convert_polygon_back(const General_polygon_with_holes_2<General_polygon_2<ArrTraits>>& gpwh) {
|
||||
using Pgn = Polygon_2<Kernel, Container>;
|
||||
using General_pgn = General_polygon_2<ArrTraits>;
|
||||
auto converter = [](const General_pgn& gpgn)->Pgn {
|
||||
return convert_polygon_back<Kernel, Container>(gpgn);
|
||||
};
|
||||
auto converter = [](const General_pgn& gpgn)->Pgn
|
||||
{ return convert_polygon_back<Kernel, Container>(gpgn); };
|
||||
return Polygon_with_holes_2<Kernel, Container>
|
||||
(convert_polygon_back<Kernel, Container>(gpwh.outer_boundary()),
|
||||
boost::make_transform_iterator(gpwh.holes().begin(), converter),
|
||||
|
|
@ -155,21 +148,17 @@ convert_polygon_back(const General_polygon_with_holes_2
|
|||
// Polygon_2 to General_polygon_2<Polyline_traits>, or
|
||||
// Polygon_with_holes_2 to General_polygon_with_holes_2<Polyline_traits>
|
||||
template <typename InputIterator, typename Traits>
|
||||
boost::transform_iterator
|
||||
<std::function
|
||||
<typename General_polygon_of_polygon<typename std::iterator_traits
|
||||
<InputIterator>::value_type>::type
|
||||
(typename std::iterator_traits<InputIterator>::reference)>,
|
||||
InputIterator>
|
||||
convert_polygon_iterator(InputIterator it, const Traits& traits)
|
||||
{
|
||||
boost::transform_iterator<std::function<
|
||||
typename General_polygon_of_polygon<typename std::iterator_traits<
|
||||
InputIterator>::value_type>::type
|
||||
(typename std::iterator_traits<InputIterator>::reference)>, InputIterator>
|
||||
convert_polygon_iterator(InputIterator it, const Traits& traits) {
|
||||
using Input_type = typename std::iterator_traits<InputIterator>::value_type;
|
||||
using Return_type = typename General_polygon_of_polygon<Input_type>::type;
|
||||
using Function_type = std::function<Return_type(Input_type)>;
|
||||
|
||||
Function_type func =
|
||||
[&traits](const Input_type& p)->Return_type
|
||||
{ return convert_polygon(p, traits); };
|
||||
Function_type func = [&traits](const Input_type& p)->Return_type
|
||||
{ return convert_polygon(p, traits); };
|
||||
|
||||
return boost::transform_iterator<Function_type, InputIterator>(it, func);
|
||||
}
|
||||
|
|
@ -186,8 +175,7 @@ struct Polygon_converter {
|
|||
|
||||
// Convert and export to output iterator.
|
||||
template <typename ArrTraits>
|
||||
void operator()(const General_polygon_with_holes_2
|
||||
<General_polygon_2<ArrTraits> >& gpwh) const
|
||||
void operator()(const General_polygon_with_holes_2<General_polygon_2<ArrTraits>>& gpwh) const
|
||||
{ *m_output++ = convert_polygon_back<Kernel, Container>(gpwh); }
|
||||
};
|
||||
|
||||
|
|
@ -195,9 +183,7 @@ struct Polygon_converter {
|
|||
// OutputIterator
|
||||
template <typename Kernel, typename Container, typename OutputIterator>
|
||||
struct Polygon_converter_output_iterator :
|
||||
boost::function_output_iterator<Polygon_converter
|
||||
<Kernel, Container, OutputIterator> >
|
||||
{
|
||||
boost::function_output_iterator<Polygon_converter<Kernel, Container, OutputIterator>> {
|
||||
using Converter = Polygon_converter<Kernel, Container, OutputIterator>;
|
||||
using Base = boost::function_output_iterator<Converter>;
|
||||
|
||||
|
|
@ -214,11 +200,8 @@ struct Polygon_converter_output_iterator :
|
|||
// (indirection with Polygon_2)
|
||||
template <typename OutputIterator, typename Kernel, typename Container>
|
||||
Polygon_converter_output_iterator<Kernel, Container, OutputIterator>
|
||||
convert_polygon_back(OutputIterator& output,
|
||||
const Polygon_2<Kernel, Container>&)
|
||||
{
|
||||
return Polygon_converter_output_iterator
|
||||
<Kernel, Container, OutputIterator>(output);
|
||||
convert_polygon_back(OutputIterator& output, const Polygon_2<Kernel, Container>&) {
|
||||
return Polygon_converter_output_iterator<Kernel, Container, OutputIterator>(output);
|
||||
}
|
||||
|
||||
// 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>
|
||||
Polygon_converter_output_iterator<Kernel, Container, OutputIterator>
|
||||
convert_polygon_back(OutputIterator& output,
|
||||
const Polygon_with_holes_2<Kernel, Container>&)
|
||||
{
|
||||
return Polygon_converter_output_iterator
|
||||
<Kernel, Container, OutputIterator>(output);
|
||||
const Polygon_with_holes_2<Kernel, Container>&) {
|
||||
return Polygon_converter_output_iterator<Kernel, Container, OutputIterator>(output);
|
||||
}
|
||||
|
||||
template <typename InputIterator>
|
||||
|
|
@ -238,7 +219,6 @@ struct Iterator_to_gps_traits {
|
|||
typedef typename Gps_default_traits<InputPolygon>::Traits Traits;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif // CGAL_BSO_POLYGON_CONVERSIONS_H
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -8,10 +8,10 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
||||
//
|
||||
//
|
||||
// Author(s): Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||
// Ron Wein <wein@post.tau.ac.il>
|
||||
// Efi Fogel <efif@post.tau.ac.il>
|
||||
// Simon Giraudot <simon.giraudot@geometryfactory.com>
|
||||
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||
// Ron Wein <wein@post.tau.ac.il>
|
||||
// Efi Fogel <efif@post.tau.ac.il>
|
||||
// Simon Giraudot <simon.giraudot@geometryfactory.com>
|
||||
|
||||
#ifndef CGAL_BOOLEAN_SET_OPERATIONS_2_DO_INTERSECT_H
|
||||
#define CGAL_BOOLEAN_SET_OPERATIONS_2_DO_INTERSECT_H
|
||||
|
|
@ -33,12 +33,18 @@
|
|||
#include <CGAL/Boolean_set_operations_2/Polygon_conversions.h>
|
||||
#include <CGAL/type_traits/is_iterator.h>
|
||||
|
||||
namespace CGAL
|
||||
{
|
||||
namespace CGAL {
|
||||
|
||||
/// \name do_intersect() functions.
|
||||
//@{
|
||||
|
||||
/*! We do not use polyline for do_intersect), as we rely on the overlay traits
|
||||
* to only intercept intersections between the interiors of segments that
|
||||
* comprise the boundary of polygons. Observe that The intersections between the
|
||||
* interiors of polylines that comprise the boundary of polygons may include an
|
||||
* endpoint of a segment, and we do not want that.
|
||||
*/
|
||||
|
||||
// Polygon_2, Polygon_2 ========================================================
|
||||
// With Traits
|
||||
template <typename Kernel, typename Container, typename Traits>
|
||||
|
|
@ -47,24 +53,24 @@ inline bool do_intersect(const Polygon_2<Kernel, Container>& pgn1,
|
|||
Traits& traits)
|
||||
{ return s_do_intersect(pgn1, pgn2, traits); }
|
||||
|
||||
// With Tag_true
|
||||
// without traits
|
||||
template <typename Kernel, typename Container>
|
||||
inline bool do_intersect(const Polygon_2<Kernel, Container>& pgn1,
|
||||
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_2<Kernel, Container>& pgn1,
|
||||
const Polygon_2<Kernel, Container>& pgn2,
|
||||
Tag_false)
|
||||
{
|
||||
typedef Polygon_2<Kernel, Container> Polygon;
|
||||
const Polygon_2<Kernel, Container>& pgn2) {
|
||||
using Polygon = Polygon_2<Kernel, Container>;
|
||||
typename Gps_default_traits<Polygon>::Traits 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 ==============================================
|
||||
// With Traits
|
||||
template <typename Kernel, typename Container, typename Traits>
|
||||
|
|
@ -73,25 +79,25 @@ inline bool do_intersect(const Polygon_2<Kernel, Container>& pgn1,
|
|||
Traits& traits)
|
||||
{ return s_do_intersect(pgn1, pgn2, traits); }
|
||||
|
||||
// With Tag_true
|
||||
// Without traits
|
||||
template <typename Kernel, typename Container>
|
||||
inline bool do_intersect(const Polygon_2<Kernel, Container>& pgn1,
|
||||
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)
|
||||
{
|
||||
const Polygon_with_holes_2<Kernel, Container>& pgn2) {
|
||||
// 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;
|
||||
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 ==============================================
|
||||
// With 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)
|
||||
{ return s_do_intersect(pgn1, pgn2, traits); }
|
||||
|
||||
// With Tag_true
|
||||
// Without traits
|
||||
template <typename Kernel, typename Container>
|
||||
inline bool do_intersect(const Polygon_with_holes_2<Kernel, Container>& pgn1,
|
||||
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)
|
||||
{
|
||||
const Polygon_2<Kernel, Container>& pgn2) {
|
||||
// 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;
|
||||
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 ====================================
|
||||
// With 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)
|
||||
{ return s_do_intersect(pgn1, pgn2, traits); }
|
||||
|
||||
// With Tag_true
|
||||
// Without traits
|
||||
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_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)
|
||||
{
|
||||
const Polygon_with_holes_2<Kernel, Container>& pgn2) {
|
||||
// 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;
|
||||
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 ========================================
|
||||
// With Traits
|
||||
template <typename ArrTraits, typename GpsTraits>
|
||||
|
|
@ -157,14 +163,22 @@ inline bool do_intersect(const General_polygon_2<ArrTraits>& pgn1,
|
|||
// Without Traits
|
||||
template <typename ArrTraits>
|
||||
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
|
||||
typedef General_polygon_2<ArrTraits> Polygon;
|
||||
using Polygon = General_polygon_2<ArrTraits>;
|
||||
typename Gps_default_traits<Polygon>::Traits 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 =============================
|
||||
// With Traits
|
||||
template <typename ArrTraits, typename GpsTraits>
|
||||
|
|
@ -178,14 +192,23 @@ inline bool do_intersect(const General_polygon_2<ArrTraits>& pgn1,
|
|||
template <typename ArrTraits>
|
||||
inline bool do_intersect(const General_polygon_2<ArrTraits>& pgn1,
|
||||
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
|
||||
typedef General_polygon_2<ArrTraits> Polygon;
|
||||
using Polygon = General_polygon_2<ArrTraits>;
|
||||
typename Gps_default_traits<Polygon>::Traits 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 =============================
|
||||
// With Traits
|
||||
template <typename ArrTraits, typename GpsTraits>
|
||||
|
|
@ -199,15 +222,25 @@ inline bool do_intersect(const General_polygon_with_holes_2
|
|||
template <typename ArrTraits>
|
||||
inline bool do_intersect(const General_polygon_with_holes_2
|
||||
<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
|
||||
typedef General_polygon_2<ArrTraits> Polygon;
|
||||
typedef General_polygon_with_holes_2<Polygon> Polygon_with_holes;
|
||||
using Polygon = General_polygon_2<ArrTraits>;
|
||||
using Polygon_with_holes = General_polygon_with_holes_2<Polygon>;
|
||||
typename Gps_default_traits<Polygon_with_holes>::Traits 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 ==================
|
||||
// With Traits
|
||||
template <typename Polygon_, typename Traits>
|
||||
|
|
@ -219,14 +252,22 @@ inline bool do_intersect(const General_polygon_with_holes_2<Polygon_>& pgn1,
|
|||
// Without Traits
|
||||
template <typename Polygon_>
|
||||
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
|
||||
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;
|
||||
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.
|
||||
|
|
@ -235,26 +276,15 @@ inline bool do_intersect(const General_polygon_with_holes_2<Polygon_>& pgn1,
|
|||
// With Traits
|
||||
template <typename InputIterator, typename 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)
|
||||
{ return r_do_intersect(begin, end, traits, k); }
|
||||
|
||||
// Without Traits
|
||||
// Tag_true => convert to polylines
|
||||
template <typename InputIterator>
|
||||
inline bool do_intersect(InputIterator begin, InputIterator end,
|
||||
Tag_true = Tag_true(), unsigned int k=5,
|
||||
inline bool do_intersect(InputIterator begin, InputIterator end, std::size_t k = 5,
|
||||
std::enable_if_t<CGAL::is_iterator<InputIterator>::value>* = 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)
|
||||
{
|
||||
Enable_if_Polygon_2_iterator<InputIterator>* = 0) {
|
||||
typename Iterator_to_gps_traits<InputIterator>::Traits traits;
|
||||
return r_do_intersect(begin, end, traits, k);
|
||||
}
|
||||
|
|
@ -262,49 +292,57 @@ inline bool do_intersect(InputIterator begin, InputIterator end,
|
|||
// General polygons or polygons with holes
|
||||
template <typename InputIterator>
|
||||
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,
|
||||
Disable_if_Polygon_2_iterator<InputIterator>* = 0)
|
||||
{
|
||||
Disable_if_Polygon_2_iterator<InputIterator>* = 0) {
|
||||
typename Iterator_to_gps_traits<InputIterator>::Traits traits;
|
||||
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
|
||||
template <typename InputIterator1, typename InputIterator2, typename Traits>
|
||||
inline bool do_intersect(InputIterator1 begin1, InputIterator1 end1,
|
||||
InputIterator2 begin2, InputIterator2 end2,
|
||||
Traits& traits, unsigned int k=5)
|
||||
Traits& traits, std::size_t k = 5)
|
||||
{ return r_do_intersect(begin1, end1, begin2, end2, traits, k); }
|
||||
|
||||
// Without Traits
|
||||
// Tag_true => convert to polylines
|
||||
template <typename InputIterator1, typename InputIterator2>
|
||||
inline bool do_intersect (InputIterator1 begin1, InputIterator1 end1,
|
||||
InputIterator2 begin2, InputIterator2 end2,
|
||||
Tag_true = Tag_true(), unsigned int k=5,
|
||||
Enable_if_Polygon_2_iterator<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)
|
||||
inline bool do_intersect(InputIterator1 begin1, InputIterator1 end1,
|
||||
InputIterator2 begin2, InputIterator2 end2,
|
||||
std::size_t k = 5,
|
||||
Enable_if_Polygon_2_iterator<InputIterator1>* = 0)
|
||||
{ return r_do_intersect(begin1, end1, begin2, end2, k); }
|
||||
|
||||
// General polygons or polygons with holes
|
||||
template <typename InputIterator1, typename InputIterator2>
|
||||
inline bool do_intersect (InputIterator1 begin1, InputIterator1 end1,
|
||||
InputIterator2 begin2, InputIterator2 end2,
|
||||
unsigned int k=5,
|
||||
Disable_if_Polygon_2_iterator<InputIterator1>* = 0)
|
||||
{
|
||||
inline bool do_intersect(InputIterator1 begin1, InputIterator1 end1,
|
||||
InputIterator2 begin2, InputIterator2 end2,
|
||||
std::size_t k = 5,
|
||||
Disable_if_Polygon_2_iterator<InputIterator1>* = 0) {
|
||||
typename Iterator_to_gps_traits<InputIterator1>::Traits traits;
|
||||
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
|
||||
|
|
|
|||
|
|
@ -7,11 +7,10 @@
|
|||
// $Id$
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
||||
//
|
||||
//
|
||||
// Author(s): Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||
// Ron Wein <wein@post.tau.ac.il>
|
||||
// Efi Fogel <efif@post.tau.ac.il>
|
||||
// Simon Giraudot <simon.giraudot@geometryfactory.com>
|
||||
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||
// Ron Wein <wein@post.tau.ac.il>
|
||||
// Efi Fogel <efif@post.tau.ac.il>
|
||||
// Simon Giraudot <simon.giraudot@geometryfactory.com>
|
||||
|
||||
#ifndef CGAL_BOOLEAN_SET_OPERATIONS_2_INTERSECTION_H
|
||||
#define CGAL_BOOLEAN_SET_OPERATIONS_2_INTERSECTION_H
|
||||
|
|
@ -33,8 +32,7 @@
|
|||
#include <CGAL/Boolean_set_operations_2/Polygon_conversions.h>
|
||||
#include <CGAL/type_traits/is_iterator.h>
|
||||
|
||||
namespace CGAL
|
||||
{
|
||||
namespace CGAL {
|
||||
|
||||
/// \name intersection() functions.
|
||||
//@{
|
||||
|
|
@ -59,10 +57,9 @@ inline OutputIterator intersection(const Polygon_2<Kernel, Container>& pgn1,
|
|||
template <typename Kernel, typename Container, typename OutputIterator>
|
||||
inline OutputIterator intersection(const Polygon_2<Kernel, Container>& pgn1,
|
||||
const Polygon_2<Kernel, Container>& pgn2,
|
||||
OutputIterator out, Tag_false)
|
||||
{
|
||||
OutputIterator out, Tag_false) {
|
||||
// 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;
|
||||
return s_intersection(pgn1, pgn2, out, traits);
|
||||
}
|
||||
|
|
@ -90,10 +87,9 @@ template <typename Kernel, typename Container, typename OutputIterator>
|
|||
inline OutputIterator
|
||||
intersection(const Polygon_2<Kernel, Container>& pgn1,
|
||||
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
|
||||
typedef Polygon_2<Kernel, Container> Polygon;
|
||||
using Polygon = Polygon_2<Kernel, Container>;
|
||||
typename Gps_default_traits<Polygon>::Traits traits;
|
||||
return s_intersection(pgn1, pgn2, out, traits);
|
||||
}
|
||||
|
|
@ -121,10 +117,9 @@ template <typename Kernel, typename Container, typename OutputIterator>
|
|||
inline OutputIterator
|
||||
intersection(const Polygon_with_holes_2<Kernel, Container>& pgn1,
|
||||
const Polygon_2<Kernel, Container>& pgn2,
|
||||
OutputIterator out, Tag_false)
|
||||
{
|
||||
OutputIterator out, Tag_false) {
|
||||
// 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;
|
||||
return s_intersection(pgn1, pgn2, out, traits);
|
||||
}
|
||||
|
|
@ -152,10 +147,9 @@ template <typename Kernel, typename Container, typename OutputIterator>
|
|||
inline OutputIterator
|
||||
intersection(const Polygon_with_holes_2<Kernel, Container>& pgn1,
|
||||
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
|
||||
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;
|
||||
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>
|
||||
inline OutputIterator intersection(const General_polygon_2<ArrTraits>& pgn1,
|
||||
const General_polygon_2<ArrTraits>& pgn2,
|
||||
OutputIterator out)
|
||||
{
|
||||
OutputIterator out) {
|
||||
// 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;
|
||||
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,
|
||||
const General_polygon_with_holes_2
|
||||
<General_polygon_2<ArrTraits> >& pgn2,
|
||||
OutputIterator out)
|
||||
{
|
||||
OutputIterator out) {
|
||||
// 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;
|
||||
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
|
||||
<General_polygon_2<ArrTraits> >& pgn1,
|
||||
const General_polygon_2<ArrTraits>& pgn2,
|
||||
OutputIterator out)
|
||||
{
|
||||
OutputIterator out) {
|
||||
// Use the first polygon to determine the (default) traits
|
||||
typedef General_polygon_2<ArrTraits> Polygon;
|
||||
typedef General_polygon_with_holes_2<Polygon> Polygon_with_holes;
|
||||
using Polygon = General_polygon_2<ArrTraits>;
|
||||
using Polygon_with_holes = General_polygon_with_holes_2<Polygon>;
|
||||
typename Gps_default_traits<Polygon_with_holes>::Traits traits;
|
||||
return s_intersection(pgn1, pgn2, out, traits);
|
||||
}
|
||||
|
|
@ -239,10 +230,9 @@ template <typename Polygon_, typename OutputIterator>
|
|||
inline OutputIterator
|
||||
intersection(const General_polygon_with_holes_2<Polygon_>& pgn1,
|
||||
const General_polygon_with_holes_2<Polygon_>& pgn2,
|
||||
OutputIterator out)
|
||||
{
|
||||
OutputIterator out) {
|
||||
// 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;
|
||||
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>
|
||||
inline OutputIterator intersection(InputIterator begin, InputIterator end,
|
||||
OutputIterator oi, Traits& traits,
|
||||
unsigned int k=5)
|
||||
std::size_t k = 5)
|
||||
{ return r_intersection(begin, end, oi, traits, k); }
|
||||
|
||||
// Without Traits
|
||||
|
|
@ -265,7 +255,7 @@ template <typename InputIterator, typename OutputIterator>
|
|||
inline OutputIterator
|
||||
intersection(InputIterator begin, InputIterator end,
|
||||
OutputIterator oi, Tag_true = Tag_true(),
|
||||
unsigned int k=5,
|
||||
std::size_t k = 5,
|
||||
Enable_if_Polygon_2_iterator<InputIterator>* = 0)
|
||||
{ return r_intersection(begin, end, oi, k); }
|
||||
|
||||
|
|
@ -273,9 +263,8 @@ intersection(InputIterator begin, InputIterator end,
|
|||
template <typename InputIterator, typename OutputIterator>
|
||||
inline OutputIterator
|
||||
intersection(InputIterator begin, InputIterator end,
|
||||
OutputIterator oi, Tag_false, unsigned int k=5,
|
||||
Enable_if_Polygon_2_iterator<InputIterator>* = 0)
|
||||
{
|
||||
OutputIterator oi, Tag_false, std::size_t k = 5,
|
||||
Enable_if_Polygon_2_iterator<InputIterator>* = 0) {
|
||||
typename Iterator_to_gps_traits<InputIterator>::Traits traits;
|
||||
return r_intersection(begin, end, oi, traits, k);
|
||||
}
|
||||
|
|
@ -284,11 +273,10 @@ intersection(InputIterator begin, InputIterator end,
|
|||
template <typename InputIterator, typename OutputIterator>
|
||||
inline OutputIterator
|
||||
intersection(InputIterator begin, InputIterator end,
|
||||
OutputIterator oi, unsigned int k=5,
|
||||
OutputIterator oi, std::size_t k = 5,
|
||||
// workaround to avoid ambiguous calls with kernel functions
|
||||
std::enable_if_t<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;
|
||||
return r_intersection(begin, end, oi, traits, k);
|
||||
}
|
||||
|
|
@ -300,7 +288,7 @@ template <typename InputIterator1, typename InputIterator2,
|
|||
inline OutputIterator intersection(InputIterator1 begin1, InputIterator1 end1,
|
||||
InputIterator2 begin2, InputIterator2 end2,
|
||||
OutputIterator oi, Traits& traits,
|
||||
unsigned int k=5)
|
||||
std::size_t k = 5)
|
||||
{ return r_intersection(begin1, end1, begin2, end2, oi, traits, k); }
|
||||
|
||||
// Without Traits
|
||||
|
|
@ -310,7 +298,7 @@ template <typename InputIterator1, typename InputIterator2,
|
|||
inline OutputIterator
|
||||
intersection(InputIterator1 begin1, InputIterator1 end1,
|
||||
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)
|
||||
{ return r_intersection(begin1, end1, begin2, end2, oi, k); }
|
||||
|
||||
|
|
@ -320,9 +308,8 @@ template <typename InputIterator1, typename InputIterator2,
|
|||
inline OutputIterator
|
||||
intersection(InputIterator1 begin1, InputIterator1 end1,
|
||||
InputIterator2 begin2, InputIterator2 end2,
|
||||
OutputIterator oi, Tag_false, unsigned int k=5,
|
||||
Enable_if_Polygon_2_iterator<InputIterator1>* = 0)
|
||||
{
|
||||
OutputIterator oi, Tag_false, std::size_t k = 5,
|
||||
Enable_if_Polygon_2_iterator<InputIterator1>* = 0) {
|
||||
typename Iterator_to_gps_traits<InputIterator1>::Traits traits;
|
||||
return r_intersection(begin1, end1, begin2, end2, oi, traits, k);
|
||||
}
|
||||
|
|
@ -333,9 +320,8 @@ template <typename InputIterator1, typename InputIterator2,
|
|||
inline OutputIterator
|
||||
intersection(InputIterator1 begin1, InputIterator1 end1,
|
||||
InputIterator2 begin2, InputIterator2 end2,
|
||||
OutputIterator oi, unsigned int k=5,
|
||||
Disable_if_Polygon_2_iterator<InputIterator1>* = 0)
|
||||
{
|
||||
OutputIterator oi, std::size_t k = 5,
|
||||
Disable_if_Polygon_2_iterator<InputIterator1>* = 0) {
|
||||
typename Iterator_to_gps_traits<InputIterator1>::Traits traits;
|
||||
return r_intersection(begin1, end1, begin2, end2, oi, traits, k);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,11 +7,10 @@
|
|||
// $Id$
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
||||
//
|
||||
//
|
||||
// Author(s): Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||
// Ron Wein <wein@post.tau.ac.il>
|
||||
// Efi Fogel <efif@post.tau.ac.il>
|
||||
// Simon Giraudot <simon.giraudot@geometryfactory.com>
|
||||
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||
// Ron Wein <wein@post.tau.ac.il>
|
||||
// Efi Fogel <efif@post.tau.ac.il>
|
||||
// Simon Giraudot <simon.giraudot@geometryfactory.com>
|
||||
|
||||
#ifndef CGAL_BOOLEAN_SET_OPERATIONS_2_JOIN_H
|
||||
#define CGAL_BOOLEAN_SET_OPERATIONS_2_JOIN_H
|
||||
|
|
@ -33,8 +32,7 @@
|
|||
#include <CGAL/Boolean_set_operations_2/Polygon_conversions.h>
|
||||
#include <CGAL/type_traits/is_iterator.h>
|
||||
|
||||
namespace CGAL
|
||||
{
|
||||
namespace CGAL {
|
||||
|
||||
/// \name join() functions.
|
||||
//@{
|
||||
|
|
@ -60,10 +58,9 @@ template <typename Kernel, typename Container>
|
|||
inline bool join(const Polygon_2<Kernel, Container>& pgn1,
|
||||
const Polygon_2<Kernel, Container>& pgn2,
|
||||
Polygon_with_holes_2<Kernel, Container>& res,
|
||||
Tag_false)
|
||||
{
|
||||
Tag_false) {
|
||||
// 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;
|
||||
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,
|
||||
const Polygon_with_holes_2<Kernel, Container>& pgn2,
|
||||
Polygon_with_holes_2<Kernel, Container>& res,
|
||||
Tag_false)
|
||||
{
|
||||
Tag_false) {
|
||||
// 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;
|
||||
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,
|
||||
const Polygon_2<Kernel, Container>& pgn2,
|
||||
Polygon_with_holes_2<Kernel, Container>& res,
|
||||
Tag_false)
|
||||
{
|
||||
Tag_false) {
|
||||
// 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;
|
||||
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,
|
||||
const Polygon_with_holes_2<Kernel, Container>& pgn2,
|
||||
Polygon_with_holes_2<Kernel, Container>& res,
|
||||
Tag_false)
|
||||
{
|
||||
Tag_false) {
|
||||
// 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;
|
||||
return s_join(pgn1, pgn2, res, traits);
|
||||
}
|
||||
|
|
@ -170,10 +164,9 @@ template <typename ArrTraits>
|
|||
inline bool
|
||||
join(const General_polygon_2<ArrTraits>& pgn1,
|
||||
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
|
||||
typedef General_polygon_2<ArrTraits> Polygon;
|
||||
using Polygon = General_polygon_2<ArrTraits>;
|
||||
typename Gps_default_traits<Polygon>::Traits traits;
|
||||
return s_join(pgn1, pgn2, res, traits);
|
||||
}
|
||||
|
|
@ -193,10 +186,9 @@ template <typename ArrTraits>
|
|||
inline bool
|
||||
join(const General_polygon_2<ArrTraits>& pgn1,
|
||||
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
|
||||
typedef General_polygon_2<ArrTraits> Polygon;
|
||||
using Polygon = General_polygon_2<ArrTraits>;
|
||||
typename Gps_default_traits<Polygon>::Traits traits;
|
||||
return s_join(pgn1, pgn2, res, traits);
|
||||
}
|
||||
|
|
@ -216,11 +208,10 @@ template <typename ArrTraits>
|
|||
inline bool
|
||||
join(const General_polygon_with_holes_2<General_polygon_2<ArrTraits> >& pgn1,
|
||||
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
|
||||
typedef General_polygon_2<ArrTraits> Polygon;
|
||||
typedef General_polygon_with_holes_2<Polygon> Polygon_with_holes;
|
||||
using Polygon = General_polygon_2<ArrTraits>;
|
||||
using Polygon_with_holes = General_polygon_with_holes_2<Polygon>;
|
||||
typename Gps_default_traits<Polygon_with_holes>::Traits 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_>
|
||||
inline bool join(const General_polygon_with_holes_2<Polygon_>& pgn1,
|
||||
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
|
||||
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;
|
||||
return s_join(pgn1, pgn2, res, traits);
|
||||
}
|
||||
|
|
@ -253,7 +243,7 @@ inline bool join(const General_polygon_with_holes_2<Polygon_>& pgn1,
|
|||
// With Traits
|
||||
template <typename InputIterator, typename OutputIterator, typename Traits>
|
||||
inline OutputIterator join(InputIterator begin, InputIterator end,
|
||||
OutputIterator oi, Traits& traits, unsigned int k=5)
|
||||
OutputIterator oi, Traits& traits, std::size_t k = 5)
|
||||
{ return r_join(begin, end, oi, traits, k); }
|
||||
|
||||
// Without Traits
|
||||
|
|
@ -261,16 +251,15 @@ inline OutputIterator join(InputIterator begin, InputIterator end,
|
|||
template <typename InputIterator, typename OutputIterator>
|
||||
inline OutputIterator join(InputIterator begin, InputIterator end,
|
||||
OutputIterator oi, Tag_true = Tag_true(),
|
||||
unsigned int k=5,
|
||||
std::size_t k = 5,
|
||||
Enable_if_Polygon_2_iterator<InputIterator>* = 0)
|
||||
{ return r_join(begin, end, oi, k); }
|
||||
|
||||
// Tag_false => do not convert to polylines
|
||||
template <typename InputIterator, typename OutputIterator>
|
||||
inline OutputIterator join(InputIterator begin, InputIterator end,
|
||||
OutputIterator oi, Tag_false, unsigned int k=5,
|
||||
Enable_if_Polygon_2_iterator<InputIterator>* = 0)
|
||||
{
|
||||
OutputIterator oi, Tag_false, std::size_t k = 5,
|
||||
Enable_if_Polygon_2_iterator<InputIterator>* = 0) {
|
||||
typename Iterator_to_gps_traits<InputIterator>::Traits traits;
|
||||
return r_join(begin, end, oi, traits, k);
|
||||
}
|
||||
|
|
@ -278,9 +267,8 @@ inline OutputIterator join(InputIterator begin, InputIterator end,
|
|||
// General polygons or polygons with holes
|
||||
template <typename InputIterator, typename OutputIterator>
|
||||
inline OutputIterator join(InputIterator begin, InputIterator end,
|
||||
OutputIterator oi, unsigned int k=5,
|
||||
Disable_if_Polygon_2_iterator<InputIterator>* = 0)
|
||||
{
|
||||
OutputIterator oi, std::size_t k = 5,
|
||||
Disable_if_Polygon_2_iterator<InputIterator>* = 0) {
|
||||
typename Iterator_to_gps_traits<InputIterator>::Traits traits;
|
||||
return r_join(begin, end, oi, traits, k);
|
||||
}
|
||||
|
|
@ -291,7 +279,7 @@ template <typename InputIterator1, typename InputIterator2,
|
|||
typename OutputIterator, typename Traits>
|
||||
inline OutputIterator join(InputIterator1 begin1, InputIterator1 end1,
|
||||
InputIterator2 begin2, InputIterator2 end2,
|
||||
OutputIterator oi, Traits& traits, unsigned int k=5)
|
||||
OutputIterator oi, Traits& traits, std::size_t k = 5)
|
||||
{ return r_join(begin1, end1, begin2, end2, oi, traits, k); }
|
||||
|
||||
// Without Traits
|
||||
|
|
@ -301,7 +289,7 @@ template <typename InputIterator1, typename InputIterator2,
|
|||
inline OutputIterator join(InputIterator1 begin1, InputIterator1 end1,
|
||||
InputIterator2 begin2, InputIterator2 end2,
|
||||
OutputIterator oi, Tag_true = Tag_true(),
|
||||
unsigned int k=5,
|
||||
std::size_t k = 5,
|
||||
Enable_if_Polygon_2_iterator<InputIterator1>* = 0)
|
||||
{ return r_join(begin1, end1, begin2, end2, oi, k); }
|
||||
|
||||
|
|
@ -310,9 +298,8 @@ template <typename InputIterator1, typename InputIterator2,
|
|||
typename OutputIterator>
|
||||
inline OutputIterator join(InputIterator1 begin1, InputIterator1 end1,
|
||||
InputIterator2 begin2, InputIterator2 end2,
|
||||
OutputIterator oi, Tag_false, unsigned int k=5,
|
||||
Enable_if_Polygon_2_iterator<InputIterator1>* = 0)
|
||||
{
|
||||
OutputIterator oi, Tag_false, std::size_t k = 5,
|
||||
Enable_if_Polygon_2_iterator<InputIterator1>* = 0) {
|
||||
typename Iterator_to_gps_traits<InputIterator1>::Traits traits;
|
||||
return r_join(begin1, end1, begin2, end2, oi, traits, k);
|
||||
}
|
||||
|
|
@ -322,9 +309,8 @@ template <typename InputIterator1, typename InputIterator2,
|
|||
typename OutputIterator>
|
||||
inline OutputIterator join(InputIterator1 begin1, InputIterator1 end1,
|
||||
InputIterator2 begin2, InputIterator2 end2,
|
||||
OutputIterator oi, unsigned int k=5,
|
||||
Disable_if_Polygon_2_iterator<InputIterator1>* = 0)
|
||||
{
|
||||
OutputIterator oi, std::size_t k = 5,
|
||||
Disable_if_Polygon_2_iterator<InputIterator1>* = 0) {
|
||||
typename Iterator_to_gps_traits<InputIterator1>::Traits traits;
|
||||
return r_join(begin1, end1, begin2, end2, oi, traits, k);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,11 +7,10 @@
|
|||
// $Id$
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
||||
//
|
||||
//
|
||||
// Author(s): Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||
// Ron Wein <wein@post.tau.ac.il>
|
||||
// Efi Fogel <efif@post.tau.ac.il>
|
||||
// Simon Giraudot <simon.giraudot@geometryfactory.com>
|
||||
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||
// Ron Wein <wein@post.tau.ac.il>
|
||||
// Efi Fogel <efif@post.tau.ac.il>
|
||||
// Simon Giraudot <simon.giraudot@geometryfactory.com>
|
||||
|
||||
#ifndef CGAL_BOOLEAN_SET_OPERATIONS_SYMMETRIC_DIFFERENCE_H
|
||||
#define CGAL_BOOLEAN_SET_OPERATIONS_SYMMETRIC_DIFFERENCE_H
|
||||
|
|
@ -33,8 +32,7 @@
|
|||
#include <CGAL/Boolean_set_operations_2/Polygon_conversions.h>
|
||||
#include <CGAL/type_traits/is_iterator.h>
|
||||
|
||||
namespace CGAL
|
||||
{
|
||||
namespace CGAL {
|
||||
|
||||
/// \name symmetric_difference() functions.
|
||||
//@{
|
||||
|
|
@ -62,10 +60,9 @@ template <typename Kernel, typename Container, typename OutputIterator>
|
|||
inline OutputIterator
|
||||
symmetric_difference(const Polygon_2<Kernel, Container>& pgn1,
|
||||
const Polygon_2<Kernel, Container>& pgn2,
|
||||
OutputIterator oi, Tag_false)
|
||||
{
|
||||
OutputIterator oi, Tag_false) {
|
||||
// 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;
|
||||
return s_symmetric_difference(pgn1, pgn2, oi, traits);
|
||||
}
|
||||
|
|
@ -93,10 +90,9 @@ template <typename Kernel, typename Container, typename OutputIterator>
|
|||
inline OutputIterator
|
||||
symmetric_difference(const Polygon_2<Kernel, Container>& pgn1,
|
||||
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
|
||||
typedef Polygon_2<Kernel, Container> Polygon;
|
||||
using Polygon = Polygon_2<Kernel, Container>;
|
||||
typename Gps_default_traits<Polygon>::Traits traits;
|
||||
return s_symmetric_difference(pgn1, pgn2, oi, traits);
|
||||
}
|
||||
|
|
@ -124,10 +120,9 @@ template <typename Kernel, typename Container, typename OutputIterator>
|
|||
inline OutputIterator
|
||||
symmetric_difference(const Polygon_with_holes_2<Kernel, Container>& pgn1,
|
||||
const Polygon_2<Kernel, Container>& pgn2,
|
||||
OutputIterator oi, Tag_false)
|
||||
{
|
||||
OutputIterator oi, Tag_false) {
|
||||
// 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;
|
||||
return s_symmetric_difference(pgn1, pgn2, oi, traits);
|
||||
}
|
||||
|
|
@ -155,10 +150,9 @@ template <typename Kernel, typename Container, typename OutputIterator>
|
|||
inline OutputIterator
|
||||
symmetric_difference(const Polygon_with_holes_2<Kernel, Container>& pgn1,
|
||||
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
|
||||
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;
|
||||
return s_symmetric_difference(pgn1, pgn2, oi, traits);
|
||||
}
|
||||
|
|
@ -176,10 +170,9 @@ template <typename ArrTraits, typename OutputIterator>
|
|||
inline OutputIterator
|
||||
symmetric_difference(const General_polygon_2<ArrTraits>& pgn1,
|
||||
const General_polygon_2<ArrTraits>& pgn2,
|
||||
OutputIterator oi)
|
||||
{
|
||||
OutputIterator oi) {
|
||||
// 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;
|
||||
return s_symmetric_difference(pgn1, pgn2, oi, traits);
|
||||
}
|
||||
|
|
@ -200,10 +193,9 @@ inline OutputIterator
|
|||
symmetric_difference(const General_polygon_2<ArrTraits>& pgn1,
|
||||
const General_polygon_with_holes_2
|
||||
<General_polygon_2<ArrTraits> >& pgn2,
|
||||
OutputIterator oi)
|
||||
{
|
||||
OutputIterator oi) {
|
||||
// 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;
|
||||
return s_symmetric_difference(pgn1, pgn2, oi, traits);
|
||||
}
|
||||
|
|
@ -224,11 +216,10 @@ inline OutputIterator
|
|||
symmetric_difference(const General_polygon_with_holes_2
|
||||
<General_polygon_2<ArrTraits> >& pgn1,
|
||||
const General_polygon_2<ArrTraits>& pgn2,
|
||||
OutputIterator oi)
|
||||
{
|
||||
OutputIterator oi) {
|
||||
// Use the first polygon to determine the (default) traits
|
||||
typedef General_polygon_2<ArrTraits> Polygon;
|
||||
typedef General_polygon_with_holes_2<Polygon> Polygon_with_holes;
|
||||
using Polygon = General_polygon_2<ArrTraits>;
|
||||
using Polygon_with_holes = General_polygon_with_holes_2<Polygon>;
|
||||
typename Gps_default_traits<Polygon_with_holes>::Traits traits;
|
||||
return s_symmetric_difference(pgn1, pgn2, oi, traits);
|
||||
}
|
||||
|
|
@ -247,9 +238,8 @@ template <typename Polygon_, typename OutputIterator>
|
|||
inline OutputIterator
|
||||
symmetric_difference(const General_polygon_with_holes_2<Polygon_>& pgn1,
|
||||
const General_polygon_with_holes_2<Polygon_>& pgn2,
|
||||
OutputIterator oi)
|
||||
{
|
||||
typedef General_polygon_with_holes_2<Polygon_> Polygon_with_holes;
|
||||
OutputIterator oi) {
|
||||
using Polygon_with_holes = General_polygon_with_holes_2<Polygon_>;
|
||||
typename Gps_default_traits<Polygon_with_holes>::Traits traits;
|
||||
return s_symmetric_difference(pgn1, pgn2, oi, traits);
|
||||
}
|
||||
|
|
@ -264,7 +254,7 @@ template <typename InputIterator, typename OutputIterator, typename Traits>
|
|||
inline
|
||||
OutputIterator symmetric_difference(InputIterator begin, InputIterator end,
|
||||
OutputIterator oi, Traits& traits,
|
||||
unsigned int k=5)
|
||||
std::size_t k = 5)
|
||||
{ return r_symmetric_difference(begin, end, oi, traits, k); }
|
||||
|
||||
// Without Traits
|
||||
|
|
@ -272,7 +262,7 @@ OutputIterator symmetric_difference(InputIterator begin, InputIterator end,
|
|||
template <typename InputIterator, typename OutputIterator>
|
||||
inline OutputIterator
|
||||
symmetric_difference(InputIterator begin, InputIterator end,
|
||||
OutputIterator oi, Tag_true = Tag_true(), unsigned int k=5,
|
||||
OutputIterator oi, Tag_true = Tag_true(), std::size_t k = 5,
|
||||
Enable_if_Polygon_2_iterator<InputIterator>* = 0)
|
||||
{ return r_symmetric_difference(begin, end, oi, k); }
|
||||
|
||||
|
|
@ -280,9 +270,8 @@ symmetric_difference(InputIterator begin, InputIterator end,
|
|||
template <typename InputIterator, typename OutputIterator>
|
||||
inline OutputIterator
|
||||
symmetric_difference(InputIterator begin, InputIterator end,
|
||||
OutputIterator oi, Tag_false, unsigned int k=5,
|
||||
Enable_if_Polygon_2_iterator<InputIterator>* = 0)
|
||||
{
|
||||
OutputIterator oi, Tag_false, std::size_t k = 5,
|
||||
Enable_if_Polygon_2_iterator<InputIterator>* = 0) {
|
||||
typename Iterator_to_gps_traits<InputIterator>::Traits traits;
|
||||
return r_symmetric_difference(begin, end, oi, traits, k);
|
||||
}
|
||||
|
|
@ -291,9 +280,8 @@ symmetric_difference(InputIterator begin, InputIterator end,
|
|||
template <typename InputIterator, typename OutputIterator>
|
||||
inline OutputIterator
|
||||
symmetric_difference(InputIterator begin, InputIterator end,
|
||||
OutputIterator oi, unsigned int k=5,
|
||||
Disable_if_Polygon_2_iterator<InputIterator>* = 0)
|
||||
{
|
||||
OutputIterator oi, std::size_t k = 5,
|
||||
Disable_if_Polygon_2_iterator<InputIterator>* = 0) {
|
||||
typename Iterator_to_gps_traits<InputIterator>::Traits traits;
|
||||
return r_symmetric_difference(begin, end, oi, traits, k);
|
||||
}
|
||||
|
|
@ -306,7 +294,7 @@ inline
|
|||
OutputIterator symmetric_difference(InputIterator1 begin1, InputIterator1 end1,
|
||||
InputIterator2 begin2, InputIterator2 end2,
|
||||
OutputIterator oi, Traits& traits,
|
||||
unsigned int k=5)
|
||||
std::size_t k = 5)
|
||||
{ return r_symmetric_difference(begin1, end1, begin2, end2, oi, traits, k); }
|
||||
|
||||
// Without Traits
|
||||
|
|
@ -316,7 +304,7 @@ template <typename InputIterator1, typename InputIterator2,
|
|||
inline OutputIterator
|
||||
symmetric_difference(InputIterator1 begin1, InputIterator1 end1,
|
||||
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)
|
||||
{ return r_symmetric_difference(begin1, end1, begin2, end2, oi, k); }
|
||||
|
||||
|
|
@ -326,9 +314,8 @@ template <typename InputIterator1, typename InputIterator2,
|
|||
inline OutputIterator
|
||||
symmetric_difference(InputIterator1 begin1, InputIterator1 end1,
|
||||
InputIterator2 begin2, InputIterator2 end2,
|
||||
OutputIterator oi, Tag_false, unsigned int k=5,
|
||||
Enable_if_Polygon_2_iterator<InputIterator1>* = 0)
|
||||
{
|
||||
OutputIterator oi, Tag_false, std::size_t k = 5,
|
||||
Enable_if_Polygon_2_iterator<InputIterator1>* = 0) {
|
||||
typename Iterator_to_gps_traits<InputIterator1>::Traits traits;
|
||||
return r_symmetric_difference(begin1, end1, begin2, end2, oi, traits, k);
|
||||
}
|
||||
|
|
@ -339,9 +326,8 @@ template <typename InputIterator1, typename InputIterator2,
|
|||
inline OutputIterator
|
||||
symmetric_difference(InputIterator1 begin1, InputIterator1 end1,
|
||||
InputIterator2 begin2, InputIterator2 end2,
|
||||
OutputIterator oi, unsigned int k=5,
|
||||
Disable_if_Polygon_2_iterator<InputIterator1>* = 0)
|
||||
{
|
||||
OutputIterator oi, std::size_t k = 5,
|
||||
Disable_if_Polygon_2_iterator<InputIterator1>* = 0) {
|
||||
typename Iterator_to_gps_traits<InputIterator1>::Traits traits;
|
||||
return r_symmetric_difference(begin1, end1, begin2, end2, oi, traits, k);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@
|
|||
// $Id$
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
||||
//
|
||||
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||
// Efi Fogel <efif@post.tau.ac.il>
|
||||
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||
// Efi Fogel <efif@post.tau.ac.il>
|
||||
|
||||
#ifndef CGAL_GENERAL_POLYGON_SET_2_H
|
||||
#define CGAL_GENERAL_POLYGON_SET_2_H
|
||||
|
|
@ -27,25 +27,20 @@
|
|||
namespace CGAL {
|
||||
|
||||
// General_polygon_set_2
|
||||
template <class Traits_, class Dcel_ = Gps_default_dcel<Traits_> >
|
||||
class General_polygon_set_2 : public General_polygon_set_on_surface_2
|
||||
<Traits_, typename Default_planar_topology<Traits_, Dcel_>::Traits>
|
||||
{
|
||||
protected:
|
||||
typedef General_polygon_set_2<Traits_, Dcel_> Self;
|
||||
template <typename Traits_, typename Dcel_ = Gps_default_dcel<Traits_>>
|
||||
class General_polygon_set_2 :
|
||||
public General_polygon_set_on_surface_2<
|
||||
Traits_, typename Default_planar_topology<Traits_, Dcel_>::Traits> {
|
||||
|
||||
public:
|
||||
typedef Traits_ Traits_2;
|
||||
typedef Dcel_ Dcel;
|
||||
|
||||
typedef General_polygon_set_on_surface_2 <Traits_2,
|
||||
typename Default_planar_topology<Traits_2, Dcel >::Traits>
|
||||
Base;
|
||||
|
||||
typedef CGAL::Arrangement_2<Traits_2, Dcel> Arrangement_2;
|
||||
|
||||
typedef typename Base::Polygon_2 Polygon_2;
|
||||
typedef typename Base::Polygon_with_holes_2 Polygon_with_holes_2;
|
||||
using Traits_2 = Traits_;
|
||||
using Dcel = Dcel_;
|
||||
using Self = General_polygon_set_2<Traits_2, Dcel>;
|
||||
using Topology_traits = typename Default_planar_topology<Traits_2, Dcel>::Traits;
|
||||
using Base = General_polygon_set_on_surface_2<Traits_2, Topology_traits>;
|
||||
using Arrangement_2 = CGAL::Arrangement_2<Traits_2, Dcel>;
|
||||
using Polygon_2 = typename Base::Polygon_2;
|
||||
using Polygon_with_holes_2 = typename Base::Polygon_with_holes_2;
|
||||
|
||||
// default constructor
|
||||
General_polygon_set_2() : Base() {}
|
||||
|
|
@ -80,19 +75,16 @@ public:
|
|||
using Base::join;
|
||||
using Base::symmetric_difference;
|
||||
|
||||
inline void intersection(const Self& ps1, const Self& ps2)
|
||||
{
|
||||
inline void intersection(const Self& ps1, const Self& ps2) {
|
||||
Base::intersection(static_cast<const Base&>(ps1),
|
||||
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));
|
||||
}
|
||||
|
||||
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),
|
||||
static_cast<const Base&>(ps2));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@
|
|||
// $Id$
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
||||
//
|
||||
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||
// Efi Fogel <efif@post.tau.ac.il>
|
||||
// Author(s): Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||
// Efi Fogel <efif@post.tau.ac.il>
|
||||
// Ophir Setter <ophir.setter@cs.tau.ac.il>
|
||||
|
||||
#ifndef CGAL_GENERAL_POLYGON_SET_ON_SURFACE_2_H
|
||||
|
|
@ -23,54 +23,48 @@
|
|||
|
||||
namespace CGAL {
|
||||
|
||||
namespace Boolean_set_operation_2_internal
|
||||
{
|
||||
struct PreconditionValidationPolicy
|
||||
{
|
||||
/*! is_valid - Checks if a Traits::Polygon_2 OR
|
||||
Traits::Polygon_with_holes_2 are valid.
|
||||
This validation policy checks that polygons are valid in a
|
||||
CGAL_precondition macro. We inherit from Gps_on_surface_base_2
|
||||
and use preconditions to validate the input polygons.
|
||||
namespace Boolean_set_operation_2_internal {
|
||||
|
||||
struct PreconditionValidationPolicy {
|
||||
/*! Checks if a Traits::Polygon_2 or Traits::Polygon_with_holes_2 are valid.
|
||||
* This validation policy checks that polygons are valid in a
|
||||
* CGAL_precondition macro. We inherit from Gps_on_surface_base_2 and use
|
||||
* preconditions to validate the input polygons.
|
||||
*/
|
||||
template <class Polygon, class Traits>
|
||||
inline static void is_valid(const Polygon& p, const Traits& t)
|
||||
{
|
||||
CGAL_precondition(is_valid_unknown_polygon(p, t));
|
||||
CGAL_USE(p); CGAL_USE(t);
|
||||
}
|
||||
};
|
||||
template <typename Polygon, typename Traits>
|
||||
inline static void is_valid(const Polygon& p, const Traits& t) {
|
||||
CGAL_precondition(is_valid_unknown_polygon(p, t));
|
||||
CGAL_USE(p); CGAL_USE(t);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
// General_polygon_set_on_surface_2
|
||||
/*
|
||||
This class is derived from Gps_on_surface_base_2.
|
||||
It enforces the validation conditions for general polygons, and is therefore
|
||||
the basic implementation that should be used by the user
|
||||
*/
|
||||
template <class Traits_, class TopTraits_>
|
||||
class General_polygon_set_on_surface_2 :
|
||||
public Gps_on_surface_base_2<Traits_, TopTraits_,
|
||||
Boolean_set_operation_2_internal::PreconditionValidationPolicy>
|
||||
{
|
||||
/* `General_polygon_set_on_surface_2` class is derived from
|
||||
* `Gps_on_surface_base_2`. It enforces the validation conditions for general
|
||||
* polygons, and is therefore the basic implementation that should be used by
|
||||
* the user
|
||||
*/
|
||||
template <typename Traits_, typename TopTraits_>
|
||||
class General_polygon_set_on_surface_2 :
|
||||
public Gps_on_surface_base_2<
|
||||
Traits_, TopTraits_,
|
||||
Boolean_set_operation_2_internal::PreconditionValidationPolicy> {
|
||||
|
||||
protected:
|
||||
typedef Traits_ Traits_2;
|
||||
typedef General_polygon_set_on_surface_2<Traits_2, TopTraits_> Self;
|
||||
typedef Gps_on_surface_base_2<Traits_2, TopTraits_,
|
||||
Boolean_set_operation_2_internal::PreconditionValidationPolicy> Base;
|
||||
using Traits_2 = Traits_;
|
||||
using Self = General_polygon_set_on_surface_2<Traits_2, TopTraits_>;
|
||||
using Base = Gps_on_surface_base_2<Traits_2, TopTraits_,
|
||||
Boolean_set_operation_2_internal::PreconditionValidationPolicy>;
|
||||
|
||||
public:
|
||||
typedef typename Base::Polygon_2 Polygon_2;
|
||||
typedef typename Base::Polygon_with_holes_2
|
||||
Polygon_with_holes_2;
|
||||
typedef typename Base::Arrangement_on_surface_2
|
||||
Arrangement_on_surface_2;
|
||||
using Polygon_2 = typename Base::Polygon_2;
|
||||
using Polygon_with_holes_2 = typename Base::Polygon_with_holes_2;
|
||||
using Arrangement_on_surface_2 = typename Base::Arrangement_on_surface_2;
|
||||
|
||||
public:
|
||||
|
||||
// default constructor
|
||||
General_polygon_set_on_surface_2() : Base()
|
||||
{}
|
||||
General_polygon_set_on_surface_2() : Base() {}
|
||||
|
||||
// constructor from a traits object
|
||||
General_polygon_set_on_surface_2(const Traits_2& traits) : Base(traits) {}
|
||||
|
|
@ -79,8 +73,7 @@ public:
|
|||
General_polygon_set_on_surface_2(const Self& ps) : Base(ps) {}
|
||||
|
||||
// assignment operator
|
||||
General_polygon_set_on_surface_2& operator=(const Self& ps)
|
||||
{
|
||||
General_polygon_set_on_surface_2& operator=(const Self& ps) {
|
||||
Base::operator=(ps);
|
||||
return (*this);
|
||||
}
|
||||
|
|
@ -90,19 +83,15 @@ public:
|
|||
|
||||
// constructor from a polygon with holes
|
||||
explicit
|
||||
General_polygon_set_on_surface_2(const Polygon_with_holes_2& pwh) :
|
||||
Base(pwh)
|
||||
{}
|
||||
General_polygon_set_on_surface_2(const Polygon_with_holes_2& pwh) : Base(pwh) {}
|
||||
|
||||
// constructor from a polygon and a traits object
|
||||
explicit General_polygon_set_on_surface_2(const Polygon_2& pgn,
|
||||
const Traits_2& traits) :
|
||||
explicit General_polygon_set_on_surface_2(const Polygon_2& pgn, const Traits_2& traits) :
|
||||
Base(pgn, traits) {}
|
||||
|
||||
// constructor from a polygon with holes and a traits object
|
||||
explicit
|
||||
General_polygon_set_on_surface_2(const Polygon_with_holes_2& pwh,
|
||||
const Traits_2& traits) :
|
||||
General_polygon_set_on_surface_2(const Polygon_with_holes_2& pwh, const Traits_2& traits) :
|
||||
Base(pwh, traits)
|
||||
{}
|
||||
|
||||
|
|
@ -142,4 +131,4 @@ private:
|
|||
|
||||
#include <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 <CGAL/Simple_cartesian.h>
|
||||
|
|
@ -13,35 +12,32 @@
|
|||
#include <CGAL/Polygon_set_2.h>
|
||||
|
||||
//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;
|
||||
typedef CGAL::Polygon_set_2<Kernel> Ps;
|
||||
using Traits = CGAL::Gps_segment_traits_2<Kernel>;
|
||||
using Ps = CGAL::Polygon_set_2<Kernel>;
|
||||
|
||||
typedef CGAL::Arr_segment_traits_2<Kernel> Arr_traits;
|
||||
typedef CGAL::Gps_traits_2<Arr_traits> General_traits;
|
||||
typedef CGAL::General_polygon_set_2<General_traits> Gps;
|
||||
using Arr_traits = CGAL::Arr_segment_traits_2<Kernel>;
|
||||
using General_traits = CGAL::Gps_traits_2<Arr_traits>;
|
||||
using Gps = CGAL::General_polygon_set_2<General_traits>;
|
||||
|
||||
typedef CGAL::Arr_non_caching_segment_traits_2<Kernel> Nc_traits;
|
||||
typedef CGAL::Gps_segment_traits_2<Kernel,
|
||||
std::vector<Kernel::Point_2>,
|
||||
Nc_traits> Traits_non_caching;
|
||||
typedef CGAL::General_polygon_set_2<Traits_non_caching> Gps_non_caching;
|
||||
using Nc_traits = CGAL::Arr_non_caching_segment_traits_2<Kernel>;
|
||||
using Traits_non_caching = CGAL::Gps_segment_traits_2<Kernel, std::vector<Kernel::Point_2>, Nc_traits>;
|
||||
using Gps_non_caching = CGAL::General_polygon_set_2<Traits_non_caching>;
|
||||
|
||||
template <class GPS>
|
||||
void test()
|
||||
{
|
||||
typedef typename GPS::Traits_2 Traits;
|
||||
typedef typename Traits::Point_2 Point_2;
|
||||
typedef typename Traits::Polygon_2 Polygon_2;
|
||||
typedef typename Traits::Polygon_with_holes_2 Polygon_with_holes_2;
|
||||
template <typename GPS>
|
||||
void test() {
|
||||
using Traits = typename GPS::Traits_2;
|
||||
using Point_2 = typename Traits::Point_2;
|
||||
using Polygon_2 = typename Traits::Polygon_2;
|
||||
using Polygon_with_holes_2 = typename Traits::Polygon_with_holes_2;
|
||||
|
||||
Polygon_2 pgn1, pgn2;
|
||||
Polygon_with_holes_2 pgn_with_holes1, pgn_with_holes2;
|
||||
std::vector<Polygon_2> polygons;
|
||||
std::vector<Polygon_with_holes_2> polygons_with_holes;
|
||||
Polygon_with_holes_2 pgn_with_holes1, pgn_with_holes2;
|
||||
std::vector<Polygon_2> polygons;
|
||||
std::vector<Polygon_with_holes_2> polygons_with_holes;
|
||||
GPS gps;
|
||||
GPS other;
|
||||
|
||||
|
|
@ -242,8 +238,7 @@ void test()
|
|||
GPS new_gps2 = gps;
|
||||
}
|
||||
|
||||
void test_CGAL_Polygon_variants()
|
||||
{
|
||||
void test_CGAL_Polygon_variants() {
|
||||
typedef CGAL::Polygon_2<Kernel> Polygon_2;
|
||||
typedef CGAL::Polygon_with_holes_2<Kernel> Polygon_with_holes_2;
|
||||
typedef CGAL::Gps_default_traits<Polygon_2>::Traits Traits;
|
||||
|
|
@ -257,45 +252,25 @@ void test_CGAL_Polygon_variants()
|
|||
Traits tr;
|
||||
|
||||
CGAL::do_intersect(pgn1, pgn2);
|
||||
CGAL::do_intersect(pgn1, pgn2, CGAL::Tag_true());
|
||||
CGAL::do_intersect(pgn1, pgn2, CGAL::Tag_false());
|
||||
CGAL::do_intersect(pgn1, pgn2, tr);
|
||||
|
||||
CGAL::do_intersect(pgn1, pgn_with_holes2);
|
||||
CGAL::do_intersect(pgn1, pgn_with_holes2, CGAL::Tag_true());
|
||||
CGAL::do_intersect(pgn1, pgn_with_holes2, CGAL::Tag_false());
|
||||
CGAL::do_intersect(pgn1, pgn_with_holes2, tr);
|
||||
|
||||
CGAL::do_intersect(pgn_with_holes1, pgn2);
|
||||
CGAL::do_intersect(pgn_with_holes1, pgn2, CGAL::Tag_true());
|
||||
CGAL::do_intersect(pgn_with_holes1, pgn2, CGAL::Tag_false());
|
||||
CGAL::do_intersect(pgn_with_holes1, pgn2, tr);
|
||||
|
||||
CGAL::do_intersect(pgn_with_holes1, pgn_with_holes2);
|
||||
CGAL::do_intersect(pgn_with_holes1, pgn_with_holes2, CGAL::Tag_true());
|
||||
CGAL::do_intersect(pgn_with_holes1, pgn_with_holes2, CGAL::Tag_false());
|
||||
CGAL::do_intersect(pgn_with_holes1, pgn_with_holes2, tr);
|
||||
|
||||
CGAL::do_intersect(polygons.begin(), polygons.end());
|
||||
CGAL::do_intersect(polygons.begin(), polygons.end(), CGAL::Tag_true());
|
||||
CGAL::do_intersect(polygons.begin(), polygons.end(), CGAL::Tag_false());
|
||||
CGAL::do_intersect(polygons.begin(), polygons.end(), tr);
|
||||
|
||||
CGAL::do_intersect(polygons_with_holes.begin(), polygons_with_holes.end());
|
||||
CGAL::do_intersect(polygons_with_holes.begin(), polygons_with_holes.end(),
|
||||
CGAL::Tag_true());
|
||||
CGAL::do_intersect(polygons_with_holes.begin(), polygons_with_holes.end(),
|
||||
CGAL::Tag_false());
|
||||
CGAL::do_intersect(polygons_with_holes.begin(), polygons_with_holes.end(), tr);
|
||||
|
||||
CGAL::do_intersect(polygons.begin(), polygons.end(),
|
||||
polygons_with_holes.begin(), polygons_with_holes.end());
|
||||
CGAL::do_intersect(polygons.begin(), polygons.end(),
|
||||
polygons_with_holes.begin(), polygons_with_holes.end(),
|
||||
CGAL::Tag_true());
|
||||
CGAL::do_intersect(polygons.begin(), polygons.end(),
|
||||
polygons_with_holes.begin(), polygons_with_holes.end(),
|
||||
CGAL::Tag_false());
|
||||
CGAL::do_intersect(polygons.begin(), polygons.end(),
|
||||
polygons_with_holes.begin(), polygons_with_holes.end(), tr);
|
||||
|
||||
|
|
@ -519,8 +494,7 @@ void test_CGAL_Polygon_variants()
|
|||
CGAL::complement(pgn_with_holes1, std::back_inserter(result), tr);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int main() {
|
||||
test<Gps>();
|
||||
test<Ps>();
|
||||
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;
|
||||
}
|
||||
|
|
@ -4,7 +4,7 @@ project(Approximate_min_ellipsoid_d_Examples)
|
|||
find_package(CGAL REQUIRED)
|
||||
|
||||
# Use Eigen
|
||||
find_package(Eigen3 3.1.0 QUIET) #(3.1.0 or greater)
|
||||
find_package(Eigen3 QUIET)
|
||||
include(CGAL_Eigen3_support)
|
||||
|
||||
# create a target per cppfile
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ project(Bounding_volumes_Tests)
|
|||
find_package(CGAL REQUIRED COMPONENTS Core)
|
||||
|
||||
# Use Eigen
|
||||
find_package(Eigen3 3.1.0 QUIET) #(3.1.0 or greater)
|
||||
find_package(Eigen3 QUIET)
|
||||
include(CGAL_Eigen3_support)
|
||||
|
||||
# create a target per cppfile
|
||||
|
|
|
|||
|
|
@ -20,8 +20,9 @@ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}")
|
|||
|
||||
find_package(CGAL REQUIRED COMPONENTS Core)
|
||||
|
||||
find_package(Eigen3 3.1.0 QUIET) #(requires 3.1.0 or greater)
|
||||
find_package(Eigen3 QUIET)
|
||||
include(CGAL_Eigen3_support)
|
||||
|
||||
if(NOT TARGET CGAL::Eigen3_support)
|
||||
message("NOTICE: This project requires the Eigen library, and will not be compiled.")
|
||||
return()
|
||||
|
|
|
|||
|
|
@ -23,8 +23,9 @@ if(NOT TARGET CGAL::Boost_iostreams_support)
|
|||
set(Classification_dependencies_met FALSE)
|
||||
endif()
|
||||
|
||||
find_package(Eigen3 3.1.0 QUIET) #(3.1.0 or greater)
|
||||
find_package(Eigen3 QUIET)
|
||||
include(CGAL_Eigen3_support)
|
||||
|
||||
if(NOT TARGET CGAL::Eigen3_support)
|
||||
message("NOTICE: This project requires the Eigen library, and will not be compiled.")
|
||||
set(Classification_dependencies_met FALSE)
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
#include <CGAL/bounding_box.h>
|
||||
#include <CGAL/tags.h>
|
||||
#include <CGAL/IO/read_points.h>
|
||||
#include <CGAL/IO/write_ply_points.h>
|
||||
#include <CGAL/IO/PLY.h>
|
||||
|
||||
#include <CGAL/Real_timer.h>
|
||||
|
||||
|
|
|
|||
|
|
@ -23,8 +23,9 @@ if(NOT TARGET CGAL::Boost_iostreams_support)
|
|||
set(Classification_dependencies_met FALSE)
|
||||
endif()
|
||||
|
||||
find_package(Eigen3 3.1.0 QUIET) #(3.1.0 or greater)
|
||||
find_package(Eigen3 QUIET)
|
||||
include(CGAL_Eigen3_support)
|
||||
|
||||
if(NOT TARGET CGAL::Eigen3_support)
|
||||
message("NOTICE: This project requires the Eigen library, and will not be compiled.")
|
||||
set(Classification_dependencies_met FALSE)
|
||||
|
|
|
|||
|
|
@ -1068,8 +1068,18 @@ If \link GenericMap::are_attributes_automatically_managed `are_attributes_automa
|
|||
template <unsigned int i>
|
||||
size_type remove_cell(Dart_descriptor d);
|
||||
|
||||
/*!
|
||||
\ingroup PkgCombinatorialMapsRefIO
|
||||
Writes `amap` in `os`, using our own internal file format in XML. Writes both the topology of the combinatorial map and its enabled attributes.
|
||||
*/
|
||||
friend std::ostream& operator<< (std::ostream& os, const GenericMap& amap);
|
||||
|
||||
/*!
|
||||
\ingroup PkgCombinatorialMapsRefIO
|
||||
Reads `amap` from `is`, using our own internal file format in XML. Reads both the topology of the combinatorial map and its enabled attributes which are present in `is`. Note that if `amap` is not empty before the reading, the new map is added in the previous one.
|
||||
*/
|
||||
friend std::ifstream& operator>> (std::ifstream& is, GenericMap& amap);
|
||||
|
||||
/// @}
|
||||
|
||||
}; /* end GenericMap */
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,9 @@
|
|||
/// \defgroup PkgCombinatorialMapsClasses Classes
|
||||
/// \ingroup PkgCombinatorialMapsRef
|
||||
|
||||
/// \defgroup PkgCombinatorialMapsRefIO IO Functions for CMap
|
||||
/// \ingroup PkgCombinatorialMapsRef
|
||||
|
||||
/*!
|
||||
\addtogroup PkgCombinatorialMapsRef
|
||||
\cgalPkgDescriptionBegin{Combinatorial Maps,PkgCombinatorialMaps}
|
||||
|
|
@ -36,5 +39,9 @@
|
|||
- `CGAL::Cell_attribute_with_id<CMap,Info_,Tag,OnMerge,OnSplit>`
|
||||
- `CGAL::Generic_map_min_items`
|
||||
|
||||
\cgalCRPSubsection{IO Functions for CMap}
|
||||
- \link PkgCombinatorialMapsRefIO `std::ostream& operator<< (std::ostream& os, const GenericMap& amap)` \endlink
|
||||
- \link PkgCombinatorialMapsRefIO `std::ifstream& operator>> (std::ifstream& is, GenericMap& amap)` \endlink
|
||||
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -255,7 +255,7 @@ namespace CGAL {
|
|||
}
|
||||
}
|
||||
|
||||
// Create an mapping between darts of the two maps (originals->copies).
|
||||
// Creates a mapping between darts of the two maps (originals->copies).
|
||||
// (here we cannot use CGAL::Unique_hash_map because it does not provide
|
||||
// iterators...
|
||||
std::unordered_map<Dart_descriptor_2, Dart_descriptor> local_dartmap;
|
||||
|
|
@ -585,7 +585,7 @@ namespace CGAL {
|
|||
bool copy_perforated_darts=false,
|
||||
size_type mark_perforated=INVALID_MARK)
|
||||
{
|
||||
// Create an mapping between darts of the two maps (originals->copies).
|
||||
// Creates a mapping between darts of the two maps (originals->copies).
|
||||
// (here we cannot use CGAL::Unique_hash_map because it does not provide
|
||||
// iterators...
|
||||
std::unordered_map
|
||||
|
|
@ -661,7 +661,7 @@ namespace CGAL {
|
|||
return is;
|
||||
}
|
||||
|
||||
/** Create a new dart and add it to the map.
|
||||
/** Creates a new dart and add it to the map.
|
||||
* The marks of the darts are initialized with mmask_marks, i.e. the dart
|
||||
* is unmarked for all the marks.
|
||||
* @return a Dart_descriptor on the new dart.
|
||||
|
|
@ -968,7 +968,7 @@ namespace CGAL {
|
|||
size_type number_of_used_marks() const
|
||||
{ return mnb_used_marks; }
|
||||
|
||||
/** Test if a given mark is reserved.
|
||||
/** Tests if a given mark is reserved.
|
||||
* @return true iff the mark is reserved (i.e. in used).
|
||||
*/
|
||||
bool is_reserved(size_type amark) const
|
||||
|
|
@ -997,14 +997,14 @@ namespace CGAL {
|
|||
return number_of_darts() - number_of_marked_darts(amark);
|
||||
}
|
||||
|
||||
/** Test if all the darts are unmarked for a given mark.
|
||||
/** Tests if all the darts are unmarked for a given mark.
|
||||
* @param amark the mark index.
|
||||
* @return true iff all the darts are unmarked for amark.
|
||||
*/
|
||||
bool is_whole_map_unmarked(size_type amark) const
|
||||
{ return number_of_marked_darts(amark) == 0; }
|
||||
|
||||
/** Test if all the darts are marked for a given mark.
|
||||
/** Tests if all the darts are marked for a given mark.
|
||||
* @param amark the mark index.
|
||||
* @return true iff all the darts are marked for amark.
|
||||
*/
|
||||
|
|
@ -1071,7 +1071,7 @@ namespace CGAL {
|
|||
mmask_marks.flip(amark);
|
||||
}
|
||||
|
||||
/** Test if a given dart is marked for a given mark.
|
||||
/** Tests if a given dart is marked for a given mark.
|
||||
* @param adart the dart to test.
|
||||
* @param amark the given mark.
|
||||
* @return true iff adart is marked for the mark amark.
|
||||
|
|
@ -1239,7 +1239,7 @@ namespace CGAL {
|
|||
std::size_t orient(size_type amark) const
|
||||
{ negate_mark(amark); return number_of_darts(); }
|
||||
|
||||
/** Test if this map is without boundary for a given dimension.
|
||||
/** Tests if this map is without boundary for a given dimension.
|
||||
* @param i the dimension.
|
||||
* @return true iff all the darts are not i-free.
|
||||
* @pre 1<=i<=n
|
||||
|
|
@ -1253,7 +1253,7 @@ namespace CGAL {
|
|||
return true;
|
||||
}
|
||||
|
||||
/** Test if this map is without boundary for all the dimensions.
|
||||
/** Tests if this map is without boundary for all the dimensions.
|
||||
* @return true iff all the darts are non free.
|
||||
*/
|
||||
bool is_without_boundary() const
|
||||
|
|
@ -1334,7 +1334,7 @@ namespace CGAL {
|
|||
return res;
|
||||
}
|
||||
|
||||
/** Test if the map is valid.
|
||||
/** Tests if the map is valid.
|
||||
* @return true iff the map is valid.
|
||||
*/
|
||||
bool is_valid(bool show_errors=true) const
|
||||
|
|
@ -1579,7 +1579,7 @@ namespace CGAL {
|
|||
return os;
|
||||
}
|
||||
|
||||
/// Create a new attribute.
|
||||
/// Creates a new attribute.
|
||||
/// @return a descriptor on the new attribute.
|
||||
template<unsigned int i, typename ...Args>
|
||||
typename Attribute_descriptor<i>::type create_attribute(const Args&... args)
|
||||
|
|
@ -1988,7 +1988,7 @@ namespace CGAL {
|
|||
else unlink_beta_for_involution(adart, i);
|
||||
}
|
||||
|
||||
/** Test if it is possible to sew by betai the two given darts
|
||||
/** Tests if it is possible to sew by betai the two given darts
|
||||
* @param adart1 the first dart.
|
||||
* @param adart2 the second dart.
|
||||
* @return true iff \em adart1 can be i-sewn with \em adart2.
|
||||
|
|
@ -3439,7 +3439,7 @@ namespace CGAL {
|
|||
}
|
||||
|
||||
|
||||
/** Test if the connected component of cmap containing dart dh1 is
|
||||
/** Tests if the connected component of cmap containing dart dh1 is
|
||||
* isomorphic to the connected component of map2 containing dart dh2,
|
||||
* starting from dh1 and dh2.
|
||||
* @param dh1 initial dart for this map
|
||||
|
|
@ -3648,7 +3648,7 @@ namespace CGAL {
|
|||
return match;
|
||||
}
|
||||
|
||||
/** Test if this cmap is isomorphic to map2.
|
||||
/** Tests if this cmap is isomorphic to map2.
|
||||
* @pre cmap is connected.
|
||||
* @param map2 the second combinatorial map
|
||||
* @param testDartInfo Boolean to test the equality of dart info (true)
|
||||
|
|
@ -3687,7 +3687,7 @@ namespace CGAL {
|
|||
return false;
|
||||
}
|
||||
|
||||
/** Test if the attributes of this map are automatically updated.
|
||||
/** Tests if the attributes of this map are automatically updated.
|
||||
* @return true iff the boolean automatic_attributes_management is set to true.
|
||||
*/
|
||||
bool are_attributes_automatically_managed() const
|
||||
|
|
@ -3710,13 +3710,13 @@ namespace CGAL {
|
|||
void set_automatic_attributes_management_without_correction(bool newval)
|
||||
{ this->automatic_attributes_management = newval; }
|
||||
|
||||
/** Create a halfedge.
|
||||
* @return a dart of the new halfedge.
|
||||
/** Creates a halfedge.
|
||||
* @return a dart of the new half-edge.
|
||||
*/
|
||||
Dart_descriptor make_half_edge()
|
||||
{ return create_dart(); }
|
||||
|
||||
/** Create an edge.
|
||||
/** Creates an edge.
|
||||
* if closed==true, the edge has no 2-free dart.
|
||||
* (note that for CMap there is no difference between true and false, but
|
||||
* this is not the case for GMap)
|
||||
|
|
@ -3730,7 +3730,7 @@ namespace CGAL {
|
|||
return d1;
|
||||
}
|
||||
|
||||
/** Create an edge given 2 Attribute_descriptor<0>.
|
||||
/** Creates an edge given 2 Attribute_descriptor<0>.
|
||||
* Note that this function can be used only if 0-attributes are non void
|
||||
* @param h0 the first vertex descriptor.
|
||||
* @param h1 the second vertex descriptor.
|
||||
|
|
@ -3751,7 +3751,7 @@ namespace CGAL {
|
|||
return d1;
|
||||
}
|
||||
|
||||
/** Create a combinatorial polygon of length alg
|
||||
/** Creates a combinatorial polygon of length alg
|
||||
* (a cycle of alg darts beta1 links together).
|
||||
* @return a new dart.
|
||||
*/
|
||||
|
|
@ -3772,7 +3772,7 @@ namespace CGAL {
|
|||
return start;
|
||||
}
|
||||
|
||||
/** Test if a face is a combinatorial polygon of length alg
|
||||
/** Tests if a face is a combinatorial polygon of length alg
|
||||
* (a cycle of alg darts beta1 links together).
|
||||
* @param adart an initial dart
|
||||
* @return true iff the face containing adart is a polygon of length alg.
|
||||
|
|
@ -3794,7 +3794,7 @@ namespace CGAL {
|
|||
return (nb==alg);
|
||||
}
|
||||
|
||||
/** Create a triangle given 3 Attribute_descriptor<0>.
|
||||
/** Creates a triangle given 3 Attribute_descriptor<0>.
|
||||
* @param h0 the first descriptor.
|
||||
* @param h1 the second descriptor.
|
||||
* @param h2 the third descriptor.
|
||||
|
|
@ -3814,7 +3814,7 @@ namespace CGAL {
|
|||
return d1;
|
||||
}
|
||||
|
||||
/** Create a quadrangle given 4 Vertex_attribute_descriptor.
|
||||
/** Creates a quadrangle given 4 Vertex_attribute_descriptor.
|
||||
* @param h0 the first vertex descriptor.
|
||||
* @param h1 the second vertex descriptor.
|
||||
* @param h2 the third vertex descriptor.
|
||||
|
|
@ -3837,7 +3837,7 @@ namespace CGAL {
|
|||
return d1;
|
||||
}
|
||||
|
||||
/** Create a combinatorial tetrahedron from 4 triangles.
|
||||
/** Creates a combinatorial tetrahedron from 4 triangles.
|
||||
* @param d1 a dart onto a first triangle.
|
||||
* @param d2 a dart onto a second triangle.
|
||||
* @param d3 a dart onto a third triangle.
|
||||
|
|
@ -3859,9 +3859,9 @@ namespace CGAL {
|
|||
return d1;
|
||||
}
|
||||
|
||||
/** Test if a volume is a combinatorial tetrahedron.
|
||||
* @param adart an initial dart
|
||||
* @return true iff the volume containing adart is a combinatorial tetrahedron.
|
||||
/** Tests if a volume is a combinatorial tetrahedron.
|
||||
* @param d1 an initial dart
|
||||
* @return true iff the volume containing d1 is a combinatorial tetrahedron.
|
||||
*/
|
||||
bool is_volume_combinatorial_tetrahedron(Dart_const_descriptor d1) const
|
||||
{
|
||||
|
|
@ -3892,7 +3892,7 @@ namespace CGAL {
|
|||
return true;
|
||||
}
|
||||
|
||||
/** Create a new combinatorial tetrahedron.
|
||||
/** Creates a new combinatorial tetrahedron.
|
||||
* @return a new dart.
|
||||
*/
|
||||
Dart_descriptor make_combinatorial_tetrahedron()
|
||||
|
|
@ -3905,7 +3905,7 @@ namespace CGAL {
|
|||
return make_combinatorial_tetrahedron(d1, d2, d3, d4);
|
||||
}
|
||||
|
||||
/** Create a combinatorial hexahedron from 6 quadrilaterals.
|
||||
/** Creates a combinatorial hexahedron from 6 quadrilaterals.
|
||||
* @param d1 a dart onto a first quadrilateral.
|
||||
* @param d2 a dart onto a second quadrilateral.
|
||||
* @param d3 a dart onto a third quadrilateral.
|
||||
|
|
@ -3952,9 +3952,9 @@ namespace CGAL {
|
|||
return d1;
|
||||
}
|
||||
|
||||
/** Test if a volume is a combinatorial hexahedron.
|
||||
* @param adart an initial dart
|
||||
* @return true iff the volume containing adart is a combinatorial hexahedron.
|
||||
/** Tests if a volume is a combinatorial hexahedron.
|
||||
* @param d1 an initial dart
|
||||
* @return true iff the volume containing d1 is a combinatorial hexahedron.
|
||||
*/
|
||||
bool is_volume_combinatorial_hexahedron(Dart_const_descriptor d1) const
|
||||
{
|
||||
|
|
@ -4004,7 +4004,7 @@ namespace CGAL {
|
|||
return true;
|
||||
}
|
||||
|
||||
/** Create a new combinatorial hexahedron.
|
||||
/** Creates a new combinatorial hexahedron.
|
||||
* @return a new dart.
|
||||
*/
|
||||
Dart_descriptor make_combinatorial_hexahedron()
|
||||
|
|
@ -4019,7 +4019,362 @@ namespace CGAL {
|
|||
return make_combinatorial_hexahedron(d1, d2, d3, d4, d5, d6);
|
||||
}
|
||||
|
||||
/** Test if an i-cell can be removed.
|
||||
/** Tests if a volume is a combinatorial prism.
|
||||
* @param d1 an initial dart
|
||||
* @return true iff the volume containing d1 is a combinatorial prism.
|
||||
*/
|
||||
bool is_volume_combinatorial_prism(Dart_const_descriptor d1) const
|
||||
{
|
||||
Dart_const_descriptor d2=beta(d1, 2);
|
||||
Dart_const_descriptor d3=beta(d1, 1, 2);
|
||||
Dart_const_descriptor d4=beta(d1, 0, 2);
|
||||
Dart_const_descriptor d5=beta(d2, 1, 1, 2);
|
||||
|
||||
if ( d1==null_dart_descriptor || d2==null_dart_descriptor ||
|
||||
d3==null_dart_descriptor || d4==null_dart_descriptor ||
|
||||
d5==null_dart_descriptor ) { return false; }
|
||||
|
||||
if (!is_face_combinatorial_polygon(d1, 3) ||
|
||||
!is_face_combinatorial_polygon(d2, 4) ||
|
||||
!is_face_combinatorial_polygon(d3, 4) ||
|
||||
!is_face_combinatorial_polygon(d4, 4) ||
|
||||
!is_face_combinatorial_polygon(d5, 3)) { return false; }
|
||||
|
||||
// TODO do better with marks.
|
||||
if (belong_to_same_cell<2,1>(d1, d2) ||
|
||||
belong_to_same_cell<2,1>(d1, d3) ||
|
||||
belong_to_same_cell<2,1>(d1, d4) ||
|
||||
belong_to_same_cell<2,1>(d1, d5) ||
|
||||
belong_to_same_cell<2,1>(d2, d3) ||
|
||||
belong_to_same_cell<2,1>(d2, d4) ||
|
||||
belong_to_same_cell<2,1>(d2, d5) ||
|
||||
belong_to_same_cell<2,1>(d3, d4) ||
|
||||
belong_to_same_cell<2,1>(d3, d5) ||
|
||||
belong_to_same_cell<2,1>(d4, d5))
|
||||
{ return false; }
|
||||
|
||||
if (beta(d2,0,2) !=beta(d3,1) ||
|
||||
beta(d2,1,2) !=beta(d4,0) ||
|
||||
beta(d3,0,2) !=beta(d4,1) ||
|
||||
beta(d3,1,1,2)!=beta(d5,0) ||
|
||||
beta(d4,1,1,2)!=beta(d5,1)) { return false; }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Creates a combinatorial prism from 2 triangles and 3 squares.
|
||||
* @param d1 a dart onto a first triangle.
|
||||
* @param d2 a dart onto a first square.
|
||||
* @param d3 a dart onto a second square.
|
||||
* @param d4 a dart onto a thirth square.
|
||||
* @param d5 a dart onto a second triangle.
|
||||
* @return a new dart.
|
||||
*/
|
||||
Dart_descriptor make_combinatorial_prism(Dart_descriptor d1,
|
||||
Dart_descriptor d2,
|
||||
Dart_descriptor d3,
|
||||
Dart_descriptor d4,
|
||||
Dart_descriptor d5)
|
||||
{
|
||||
// 2-link for first triangle
|
||||
basic_link_beta_for_involution(d1, d2, 2);
|
||||
basic_link_beta_for_involution(beta(d1, 1), d3, 2);
|
||||
basic_link_beta_for_involution(beta(d1, 0), d4, 2);
|
||||
|
||||
// 2-link for quandrangles between them
|
||||
basic_link_beta_for_involution(beta(d2, 0), beta(d3, 1), 2);
|
||||
basic_link_beta_for_involution(beta(d2, 1), beta(d4, 0), 2);
|
||||
basic_link_beta_for_involution(beta(d3, 0), beta(d4, 1), 2);
|
||||
|
||||
// 2-link for second triangle
|
||||
basic_link_beta_for_involution(beta(d2, 1, 1), d5, 2);
|
||||
basic_link_beta_for_involution(beta(d3, 1, 1), beta(d5, 0), 2);
|
||||
basic_link_beta_for_involution(beta(d4, 1, 1), beta(d5, 1), 2);
|
||||
|
||||
return d1;
|
||||
}
|
||||
|
||||
/** Creates a new combinatorial prism.
|
||||
* @return a new dart.
|
||||
*/
|
||||
Dart_descriptor make_combinatorial_prism()
|
||||
{
|
||||
Dart_descriptor d1 = make_combinatorial_polygon(3);
|
||||
Dart_descriptor d2 = make_combinatorial_polygon(4);
|
||||
Dart_descriptor d3 = make_combinatorial_polygon(4);
|
||||
Dart_descriptor d4 = make_combinatorial_polygon(4);
|
||||
Dart_descriptor d5 = make_combinatorial_polygon(3);
|
||||
|
||||
return make_combinatorial_prism( d1, d2, d3, d4, d5);
|
||||
}
|
||||
|
||||
/** Tests if a volume is a combinatorial pyramid.
|
||||
* @param d1 an intial dart
|
||||
* @return true iff the volume containing d1 is a combinatorial pyramid.
|
||||
*/
|
||||
bool is_volume_combinatorial_pyramid(Dart_const_descriptor d1) const
|
||||
{
|
||||
Dart_const_descriptor d2=beta(d1, 2);
|
||||
Dart_const_descriptor d3=beta(d1, 0, 2);
|
||||
Dart_const_descriptor d4=beta(d1, 1, 1, 2);
|
||||
Dart_const_descriptor d5=beta(d1, 1, 2);
|
||||
|
||||
if (d1==null_dart_descriptor || d2==null_dart_descriptor ||
|
||||
d3==null_dart_descriptor || d4==null_dart_descriptor ||
|
||||
d5==null_dart_descriptor) { return false; }
|
||||
|
||||
if (!is_face_combinatorial_polygon(d1, 4) ||
|
||||
!is_face_combinatorial_polygon(d2, 3) ||
|
||||
!is_face_combinatorial_polygon(d3, 3) ||
|
||||
!is_face_combinatorial_polygon(d4, 3) ||
|
||||
!is_face_combinatorial_polygon(d5, 3)) { return false; }
|
||||
|
||||
// TODO do better with marks.
|
||||
if (belong_to_same_cell<2,1>(d1, d2) ||
|
||||
belong_to_same_cell<2,1>(d1, d3) ||
|
||||
belong_to_same_cell<2,1>(d1, d4) ||
|
||||
belong_to_same_cell<2,1>(d1, d5) ||
|
||||
belong_to_same_cell<2,1>(d2, d3) ||
|
||||
belong_to_same_cell<2,1>(d2, d4) ||
|
||||
belong_to_same_cell<2,1>(d2, d5) ||
|
||||
belong_to_same_cell<2,1>(d3, d4) ||
|
||||
belong_to_same_cell<2,1>(d3, d5) ||
|
||||
belong_to_same_cell<2,1>(d4, d5))
|
||||
{ return false; }
|
||||
|
||||
if (beta(d2,1,2)!=beta(d3,0) ||
|
||||
beta(d2,0,2)!=beta(d5,1) ||
|
||||
beta(d5,0,2)!=beta(d4,1) ||
|
||||
beta(d4,0,2)!=beta(d3,1)) { return false; }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Creates a combinatorial pyramid from 1 square and 4 triangles.
|
||||
* @param d1 a dart onto the square.
|
||||
* @param d2 a dart onto a first triangle.
|
||||
* @param d3 a dart onto a second triangle.
|
||||
* @param d4 a dart onto a thirth triangle.
|
||||
* @param d5 a dart onto a fourth triangle.
|
||||
* @return a new dart.
|
||||
*/
|
||||
Dart_descriptor make_combinatorial_pyramid(Dart_descriptor d1,
|
||||
Dart_descriptor d2,
|
||||
Dart_descriptor d3,
|
||||
Dart_descriptor d4,
|
||||
Dart_descriptor d5)
|
||||
{
|
||||
// 2-link for the square
|
||||
basic_link_beta_for_involution(d1, d2, 2);
|
||||
basic_link_beta_for_involution(beta(d1, 1), d5, 2);
|
||||
basic_link_beta_for_involution(beta(d1, 1, 1), d4, 2);
|
||||
basic_link_beta_for_involution(beta(d1, 0), d3, 2);
|
||||
|
||||
// 2-link for first triangle
|
||||
basic_link_beta_for_involution(beta(d2, 1), beta(d3, 0), 2);
|
||||
basic_link_beta_for_involution(beta(d2, 0), beta(d5, 1), 2);
|
||||
|
||||
// 2-link for triangles between them
|
||||
basic_link_beta_for_involution(beta(d5, 0), beta(d4, 1), 2);
|
||||
basic_link_beta_for_involution(beta(d4, 0), beta(d3, 1), 2);
|
||||
|
||||
return d1;
|
||||
}
|
||||
|
||||
/** Creates a new combinatorial pyramid.
|
||||
* @return a new dart.
|
||||
*/
|
||||
Dart_descriptor make_combinatorial_pyramid()
|
||||
{
|
||||
Dart_descriptor d1=make_combinatorial_polygon(4);
|
||||
Dart_descriptor d2=make_combinatorial_polygon(3);
|
||||
Dart_descriptor d3=make_combinatorial_polygon(3);
|
||||
Dart_descriptor d4=make_combinatorial_polygon(3);
|
||||
Dart_descriptor d5=make_combinatorial_polygon(3);
|
||||
|
||||
return make_combinatorial_pyramid(d1, d2, d3, d4, d5);
|
||||
}
|
||||
|
||||
/** Tests if a volume is a combinatorial pentagonal prism.
|
||||
* @param d1 an initial dart
|
||||
* @return true iff the volume containing d1 is a combinatorial pentagonal prism.
|
||||
*/
|
||||
bool is_volume_combinatorial_pentagonal_prism(Dart_const_descriptor d1) const
|
||||
{
|
||||
Dart_const_descriptor d2=beta(d1, 2);
|
||||
Dart_const_descriptor d3=beta(d1, 1, 2);
|
||||
Dart_const_descriptor d4=beta(d1, 1, 1, 2);
|
||||
Dart_const_descriptor d5=beta(d1, 0, 0, 2);
|
||||
Dart_const_descriptor d6=beta(d1, 0, 2);
|
||||
Dart_const_descriptor d7=beta(d2, 1, 1, 2);
|
||||
|
||||
if (d1==null_dart_descriptor || d2==null_dart_descriptor ||
|
||||
d3==null_dart_descriptor || d4==null_dart_descriptor ||
|
||||
d5==null_dart_descriptor || d6==null_dart_descriptor ||
|
||||
d7==null_dart_descriptor)
|
||||
{ return false; }
|
||||
|
||||
if (!is_face_combinatorial_polygon(d1, 5) ||
|
||||
!is_face_combinatorial_polygon(d2, 4) ||
|
||||
!is_face_combinatorial_polygon(d3, 4) ||
|
||||
!is_face_combinatorial_polygon(d4, 4) ||
|
||||
!is_face_combinatorial_polygon(d5, 4) ||
|
||||
!is_face_combinatorial_polygon(d6, 4) ||
|
||||
!is_face_combinatorial_polygon(d7, 5)) { return false; }
|
||||
|
||||
// TODO do better with marks.
|
||||
if (belong_to_same_cell<2,1>(d1, d2) ||
|
||||
belong_to_same_cell<2,1>(d1, d3) ||
|
||||
belong_to_same_cell<2,1>(d1, d4) ||
|
||||
belong_to_same_cell<2,1>(d1, d5) ||
|
||||
belong_to_same_cell<2,1>(d1, d6) ||
|
||||
belong_to_same_cell<2,1>(d1, d7) ||
|
||||
belong_to_same_cell<2,1>(d2, d3) ||
|
||||
belong_to_same_cell<2,1>(d2, d4) ||
|
||||
belong_to_same_cell<2,1>(d2, d5) ||
|
||||
belong_to_same_cell<2,1>(d2, d6) ||
|
||||
belong_to_same_cell<2,1>(d2, d7) ||
|
||||
belong_to_same_cell<2,1>(d3, d4) ||
|
||||
belong_to_same_cell<2,1>(d3, d5) ||
|
||||
belong_to_same_cell<2,1>(d3, d6) ||
|
||||
belong_to_same_cell<2,1>(d3, d7) ||
|
||||
belong_to_same_cell<2,1>(d4, d5) ||
|
||||
belong_to_same_cell<2,1>(d4, d6) ||
|
||||
belong_to_same_cell<2,1>(d4, d7) ||
|
||||
belong_to_same_cell<2,1>(d5, d6) ||
|
||||
belong_to_same_cell<2,1>(d5, d7) ||
|
||||
belong_to_same_cell<2,1>(d6, d7))
|
||||
{ return false; }
|
||||
|
||||
if (beta(d2,0,2) !=beta(d3,1) ||
|
||||
beta(d3,0,2) !=beta(d4,1) ||
|
||||
beta(d4,0,2) !=beta(d5,1) ||
|
||||
beta(d5,0,2) !=beta(d6,1) ||
|
||||
beta(d6,0,2) !=beta(d2,1) ||
|
||||
beta(d3,1,1,2)!=beta(d7,0) ||
|
||||
beta(d4,1,1,2)!=beta(d7,0,0) ||
|
||||
beta(d5,1,1,2)!=beta(d7,1,1) ||
|
||||
beta(d6,1,1,2)!=beta(d7,1)) { return false; }
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
/** Tests if a volume is a combinatorial hexagonal prism.
|
||||
* @param d1 an initial dart
|
||||
* @return true iff the volume containing d1 is a combinatorial hexagonal prism.
|
||||
*/
|
||||
bool is_volume_combinatorial_hexagonal_prism(Dart_const_descriptor d1) const
|
||||
{
|
||||
Dart_const_descriptor d2=beta(d1, 2);
|
||||
Dart_const_descriptor d3=beta(d1, 1, 2);
|
||||
Dart_const_descriptor d4=beta(d1, 1, 1, 2);
|
||||
Dart_const_descriptor d5=beta(d1, 1, 1, 1, 2);
|
||||
Dart_const_descriptor d6=beta(d1, 0, 0, 2);
|
||||
Dart_const_descriptor d7=beta(d1, 0, 2);
|
||||
Dart_const_descriptor d8=beta(d2, 1, 1, 2);
|
||||
|
||||
if (d1==null_dart_descriptor || d2==null_dart_descriptor ||
|
||||
d3==null_dart_descriptor || d4==null_dart_descriptor ||
|
||||
d5==null_dart_descriptor || d6==null_dart_descriptor ||
|
||||
d7==null_dart_descriptor || d8==null_dart_descriptor)
|
||||
{ return false; }
|
||||
|
||||
if (!is_face_combinatorial_polygon(d1, 6) ||
|
||||
!is_face_combinatorial_polygon(d2, 4) ||
|
||||
!is_face_combinatorial_polygon(d3, 4) ||
|
||||
!is_face_combinatorial_polygon(d4, 4) ||
|
||||
!is_face_combinatorial_polygon(d5, 4) ||
|
||||
!is_face_combinatorial_polygon(d6, 4) ||
|
||||
!is_face_combinatorial_polygon(d7, 4) ||
|
||||
!is_face_combinatorial_polygon(d8, 6)) { return false; }
|
||||
|
||||
// TODO do better with marks.
|
||||
if (belong_to_same_cell<2,1>(d1, d2) ||
|
||||
belong_to_same_cell<2,1>(d1, d3) ||
|
||||
belong_to_same_cell<2,1>(d1, d4) ||
|
||||
belong_to_same_cell<2,1>(d1, d5) ||
|
||||
belong_to_same_cell<2,1>(d1, d6) ||
|
||||
belong_to_same_cell<2,1>(d1, d7) ||
|
||||
belong_to_same_cell<2,1>(d1, d8) ||
|
||||
belong_to_same_cell<2,1>(d2, d3) ||
|
||||
belong_to_same_cell<2,1>(d2, d4) ||
|
||||
belong_to_same_cell<2,1>(d2, d5) ||
|
||||
belong_to_same_cell<2,1>(d2, d6) ||
|
||||
belong_to_same_cell<2,1>(d2, d7) ||
|
||||
belong_to_same_cell<2,1>(d2, d8) ||
|
||||
belong_to_same_cell<2,1>(d3, d4) ||
|
||||
belong_to_same_cell<2,1>(d3, d5) ||
|
||||
belong_to_same_cell<2,1>(d3, d6) ||
|
||||
belong_to_same_cell<2,1>(d3, d7) ||
|
||||
belong_to_same_cell<2,1>(d3, d8) ||
|
||||
belong_to_same_cell<2,1>(d4, d5) ||
|
||||
belong_to_same_cell<2,1>(d4, d6) ||
|
||||
belong_to_same_cell<2,1>(d4, d7) ||
|
||||
belong_to_same_cell<2,1>(d4, d8) ||
|
||||
belong_to_same_cell<2,1>(d5, d6) ||
|
||||
belong_to_same_cell<2,1>(d5, d7) ||
|
||||
belong_to_same_cell<2,1>(d5, d8) ||
|
||||
belong_to_same_cell<2,1>(d6, d7) ||
|
||||
belong_to_same_cell<2,1>(d6, d8) ||
|
||||
belong_to_same_cell<2,1>(d7, d8))
|
||||
{ return false; }
|
||||
|
||||
if (beta(d2,0,2) !=beta(d3,1) ||
|
||||
beta(d3,0,2) !=beta(d4,1) ||
|
||||
beta(d4,0,2) !=beta(d5,1) ||
|
||||
beta(d5,0,2) !=beta(d6,1) ||
|
||||
beta(d6,0,2) !=beta(d7,1) ||
|
||||
beta(d7,0,2) !=beta(d2,1) ||
|
||||
beta(d3,1,1,2)!=beta(d8,0) ||
|
||||
beta(d4,1,1,2)!=beta(d8,0,0) ||
|
||||
beta(d5,1,1,2)!=beta(d8,0,0,0) ||
|
||||
beta(d6,1,1,2)!=beta(d8,1,1) ||
|
||||
beta(d7,1,1,2)!=beta(d8,1)) { return false; }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Tests if a volume is a combinatorial tetrahedron10.
|
||||
* @param d1 an initial dart
|
||||
* @return true iff the volume containing d1 is a combinatorial tetrahedron10.
|
||||
*/
|
||||
bool is_volume_combinatorial_tetrahedron10(Dart_const_descriptor d1) const
|
||||
{
|
||||
Dart_const_descriptor d2=beta(d1, 2,0);
|
||||
Dart_const_descriptor d3=beta(d2, 0,2);
|
||||
Dart_const_descriptor d4=beta(d2, 1,1,1,2);
|
||||
|
||||
if(d1==null_dart_descriptor || d2==null_dart_descriptor ||
|
||||
d3==null_dart_descriptor || d4==null_dart_descriptor)
|
||||
{ return false; }
|
||||
|
||||
if(!is_face_combinatorial_polygon(d1, 6) ||
|
||||
!is_face_combinatorial_polygon(d2, 6) ||
|
||||
!is_face_combinatorial_polygon(d3, 6) ||
|
||||
!is_face_combinatorial_polygon(d4, 6)) { return false; }
|
||||
|
||||
if(beta(d1, 1,2)!=beta(d1, 2,0) ||
|
||||
beta(d2, 1,2)!=beta(d2, 2,0) ||
|
||||
beta(d3, 1,2)!=beta(d3, 2,0) ||
|
||||
beta(d4, 1,2)!=beta(d4, 2,0)) { return false; }
|
||||
|
||||
// TODO do better with marks (?).
|
||||
if(belong_to_same_cell<2,1>(d1, d2) ||
|
||||
belong_to_same_cell<2,1>(d1, d3) ||
|
||||
belong_to_same_cell<2,1>(d1, d4) ||
|
||||
belong_to_same_cell<2,1>(d2, d3) ||
|
||||
belong_to_same_cell<2,1>(d2, d4) ||
|
||||
belong_to_same_cell<2,1>(d3, d4)) { return false; }
|
||||
|
||||
if(beta(d1,1,1,2)!=beta(d3,0) ||
|
||||
beta(d1,0,2)!=beta(d4,1,1) ||
|
||||
beta(d4,0,2)!=beta(d3,1,1)) { return false; }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Tests if an i-cell can be removed.
|
||||
* An i-cell can be removed if i==dimension or i==dimension-1,
|
||||
* or if there are at most two (i+1)-cell incident to it.
|
||||
* @param adart a dart of the i-cell.
|
||||
|
|
@ -4041,7 +4396,7 @@ namespace CGAL {
|
|||
run(*this,adart,update_attributes);
|
||||
}
|
||||
|
||||
/** Test if an i-cell can be contracted.
|
||||
/** Tests if an i-cell can be contracted.
|
||||
* An i-cell can be contracted if i==1
|
||||
* or if there are at most two (i-1)-cell incident to it.
|
||||
* @param adart a dart of the i-cell.
|
||||
|
|
@ -4407,7 +4762,7 @@ namespace CGAL {
|
|||
return this->template beta<0>(adart1);
|
||||
}
|
||||
|
||||
/** Test if an edge can be inserted onto a 2-cell between two given darts.
|
||||
/** Tests if an edge can be inserted onto a 2-cell between two given darts.
|
||||
* @param adart1 a first dart.
|
||||
* @param adart2 a second dart.
|
||||
* @return true iff an edge can be inserted between adart1 and adart2.
|
||||
|
|
@ -4443,7 +4798,7 @@ namespace CGAL {
|
|||
return generic_insert_cell_1(adart1, adart2, false, update_attributes);
|
||||
}
|
||||
|
||||
/** Test if an edge can be inserted between two different 2-cells
|
||||
/** Tests if an edge can be inserted between two different 2-cells
|
||||
* between two given darts.
|
||||
* @param adart1 a first dart.
|
||||
* @param adart2 a second dart.
|
||||
|
|
@ -4627,7 +4982,7 @@ namespace CGAL {
|
|||
return this->template beta<0>(adart1);
|
||||
}
|
||||
|
||||
/** Test if a 2-cell can be inserted onto a given 3-cell along
|
||||
/** Tests if a 2-cell can be inserted onto a given 3-cell along
|
||||
* a path of edges.
|
||||
* @param afirst iterator on the beginning of the path.
|
||||
* @param alast iterator on the end of the path.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,208 @@
|
|||
// Copyright (c) 2025 CNRS and LIRIS' Establishments (France).
|
||||
// All rights reserved.
|
||||
//
|
||||
// This file is part of CGAL (www.cgal.org)
|
||||
//
|
||||
// $URL$
|
||||
// $Id$
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||
//
|
||||
// Author(s) : Guillaume Damiand <guillaume.damiand@liris.cnrs.fr>
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef CMAP_ELEMENT_TOPO_H
|
||||
#define CMAP_ELEMENT_TOPO_H
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace CGAL {
|
||||
namespace CMap {
|
||||
namespace Element_topo {
|
||||
|
||||
enum cell_topo
|
||||
{
|
||||
SQUARE=0,
|
||||
TRIANGLE=1,
|
||||
HEXAHEDRON=2,
|
||||
TETRAHEDRON=3,
|
||||
PRISM=4,
|
||||
PYRAMID=5,
|
||||
GENERIC_2D=6,
|
||||
GENERIC_3D=7,
|
||||
EDGE=8,
|
||||
TETRAHEDRON10=9,
|
||||
PENTAGONAL_PRISM=10,
|
||||
HEXAGONAL_PRISM=11,
|
||||
NO_TYPE=-1
|
||||
};
|
||||
|
||||
inline
|
||||
std::string topo_name(cell_topo t)
|
||||
{
|
||||
switch(t)
|
||||
{
|
||||
case SQUARE: return "SQUARE";
|
||||
case TRIANGLE: return "TRIANGLE";
|
||||
case HEXAHEDRON: return "HEXAHEDRON";
|
||||
case TETRAHEDRON: return "TETRAHEDRON";
|
||||
case PRISM: return "PRISM";
|
||||
case PYRAMID: return "PYRAMID";
|
||||
case GENERIC_2D: return "GENERIC_2D";
|
||||
case GENERIC_3D: return "GENERIC_3D";
|
||||
case EDGE: return "EDGE";
|
||||
case TETRAHEDRON10: return "TETRAHEDRON10";
|
||||
case PENTAGONAL_PRISM: return "PENTAGONAL_PRISM";
|
||||
case HEXAGONAL_PRISM: return "HEXAGONAL_PRISM";
|
||||
case NO_TYPE: return "NO_TYPE";
|
||||
}
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
inline
|
||||
cell_topo topo_from_name(const std::string& t)
|
||||
{
|
||||
if (t=="SQUARE") return SQUARE;
|
||||
if (t=="TRIANGLE") return TRIANGLE;
|
||||
if (t=="HEXAHEDRON") return HEXAHEDRON;
|
||||
if (t=="TETRAHEDRON") return TETRAHEDRON;
|
||||
if (t=="PRISM") return PRISM;
|
||||
if (t=="PYRAMID") return PYRAMID;
|
||||
if (t=="GENERIC_2D") return GENERIC_2D;
|
||||
if (t=="GENERIC_3D") return GENERIC_3D;
|
||||
if (t=="EDGE") return EDGE;
|
||||
if (t=="TETRAHEDRON10") return TETRAHEDRON10;
|
||||
if (t=="PENTAGONAL_PRISM") return PENTAGONAL_PRISM;
|
||||
if (t=="HEXAGONAL_PRISM") return HEXAGONAL_PRISM;
|
||||
if (t=="NO_TYPE") return NO_TYPE;
|
||||
return NO_TYPE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief To get the type of `dimD` cell of the `CMap` of `cmapdim` dimension.
|
||||
*/
|
||||
template<typename CMap, unsigned int dimcell,
|
||||
unsigned int cmapdim=CMap::dimension>
|
||||
struct Get_cell_topo
|
||||
{
|
||||
static cell_topo run(CMap&, typename CMap::Dart_descriptor dh,
|
||||
typename CMap::Dart_descriptor& starting_dart)
|
||||
{
|
||||
starting_dart=dh;
|
||||
return NO_TYPE;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief To get the type associated of an edge. For now only one type.
|
||||
*/
|
||||
template<typename CMap, unsigned int cmapdim>
|
||||
struct Get_cell_topo<CMap, 1, cmapdim>
|
||||
{
|
||||
static cell_topo run(CMap&, typename CMap::Dart_descriptor it,
|
||||
typename CMap::Dart_descriptor& starting_dart)
|
||||
{
|
||||
starting_dart=it;
|
||||
return EDGE;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief To get the type of 2D cell of the CMap of cmapdim dimension.
|
||||
*/
|
||||
template<typename CMap, unsigned int cmapdim>
|
||||
struct Get_cell_topo<CMap, 2, cmapdim>
|
||||
{
|
||||
static cell_topo run(CMap& cmap, typename CMap::Dart_descriptor it,
|
||||
typename CMap::Dart_descriptor& starting_dart)
|
||||
{
|
||||
starting_dart=it;
|
||||
|
||||
if (cmap.is_face_combinatorial_polygon(it, 3))
|
||||
{ return TRIANGLE; }
|
||||
|
||||
else if (cmap.is_face_combinatorial_polygon(it, 4))
|
||||
{ return SQUARE; }
|
||||
|
||||
return GENERIC_2D;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief To get the type of 3D cell of the CMap of dimension 3.
|
||||
*/
|
||||
template<typename CMap>
|
||||
struct Get_cell_topo<CMap, 3, 3>
|
||||
{
|
||||
static cell_topo run(CMap& cmap, typename CMap::Dart_descriptor it,
|
||||
typename CMap::Dart_descriptor& starting_dart)
|
||||
{
|
||||
starting_dart=it;
|
||||
|
||||
if (cmap.is_volume_combinatorial_tetrahedron(it))
|
||||
{ return TETRAHEDRON; }
|
||||
|
||||
else if (cmap.is_volume_combinatorial_hexahedron(it))
|
||||
{ return HEXAHEDRON; }
|
||||
|
||||
else if(cmap.is_volume_combinatorial_tetrahedron10(it))
|
||||
{ return TETRAHEDRON10; }
|
||||
|
||||
// For non symetric object, we need to test all darts
|
||||
for (auto itv=cmap.template darts_of_cell<3>(it).begin(),
|
||||
itvend=cmap.template darts_of_cell<3>(it).end(); itv!=itvend; ++itv)
|
||||
{
|
||||
starting_dart=itv;
|
||||
|
||||
if (cmap.is_volume_combinatorial_prism(itv))
|
||||
{ return PRISM; }
|
||||
|
||||
else if (cmap.is_volume_combinatorial_pentagonal_prism(itv))
|
||||
{ return PENTAGONAL_PRISM; }
|
||||
|
||||
else if (cmap.is_volume_combinatorial_pyramid(itv))
|
||||
{ return PYRAMID; }
|
||||
|
||||
else if (cmap.is_volume_combinatorial_hexagonal_prism(itv))
|
||||
{ return HEXAGONAL_PRISM; }
|
||||
|
||||
}
|
||||
|
||||
return GENERIC_3D;
|
||||
}
|
||||
};
|
||||
|
||||
template<unsigned int dimcell, typename CMap>
|
||||
cell_topo get_cell_topo(CMap& cmap, typename CMap::Dart_descriptor it,
|
||||
typename CMap::Dart_descriptor& starting_dart)
|
||||
{ return Get_cell_topo<CMap, dimcell>::run(cmap, it, starting_dart); }
|
||||
|
||||
template<unsigned int dimcell, typename CMap>
|
||||
cell_topo get_cell_topo(CMap& cmap, typename CMap::Dart_descriptor it)
|
||||
{
|
||||
typename CMap::Dart_descriptor dummy;
|
||||
return get_cell_topo<dimcell, CMap>(cmap, it, dummy);
|
||||
}
|
||||
|
||||
template<unsigned int dimcell, typename CMap>
|
||||
cell_topo get_cell_topo(const CMap& cmap, typename CMap::Dart_const_descriptor it,
|
||||
typename CMap::Dart_const_descriptor& starting_dart)
|
||||
{
|
||||
typename CMap::Dart_descriptor it2=const_cast<CMap&>(cmap).dart_descriptor
|
||||
(cmap.darts().index(it));
|
||||
typename CMap::Dart_descriptor sd2;
|
||||
cell_topo res=Get_cell_topo<CMap, dimcell>::run(const_cast<CMap&>(cmap),
|
||||
it2, sd2);
|
||||
starting_dart=sd2;
|
||||
return res;
|
||||
}
|
||||
|
||||
template<unsigned int dimcell, typename CMap>
|
||||
cell_topo get_cell_topo(const CMap& cmap, typename CMap::Dart_const_descriptor it)
|
||||
{
|
||||
typename CMap::Dart_descriptor it2=it;
|
||||
return Get_cell_topo<CMap, dimcell>::run(const_cast<CMap&>(cmap), it2);
|
||||
}
|
||||
|
||||
} } } // namespace CGAL::CMap::Element_topo
|
||||
|
||||
#endif // CMAP_ELEMENT_TOPO_H
|
||||
|
|
@ -5,6 +5,7 @@
|
|||
#include <CGAL/make_conforming_constrained_Delaunay_triangulation_3.h>
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
using K = CGAL::Exact_predicates_inexact_constructions_kernel;
|
||||
|
||||
|
|
@ -29,6 +30,18 @@ int main(int argc, char* argv[])
|
|||
<< "Number of constrained facets in the CDT: "
|
||||
<< ccdt.number_of_constrained_facets() << '\n';
|
||||
|
||||
// Collect constrained facets per polygon
|
||||
std::vector<std::size_t> constrained_facets(polygons.size());
|
||||
for(auto facet : ccdt.constrained_facets())
|
||||
{
|
||||
int i = ccdt.face_constraint_index(facet);
|
||||
++constrained_facets[i];
|
||||
}
|
||||
auto it = std::max_element(constrained_facets.begin(), constrained_facets.end());
|
||||
|
||||
std::cout << "The polygon with the most constrained facets has index "
|
||||
<< (it - constrained_facets.begin()) << " and " << *it << " facets.\n";
|
||||
|
||||
std::ofstream ofs(argc > 2 ? argv[2] : "out.mesh");
|
||||
ofs.precision(17);
|
||||
CGAL::IO::write_MEDIT(ofs, ccdt);
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@
|
|||
#include <ostream>
|
||||
#include <sstream>
|
||||
#include <stack>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
|
@ -72,6 +73,7 @@ namespace CDT_3 {
|
|||
struct Debug_options {
|
||||
enum class Flags {
|
||||
Steiner_points = 0,
|
||||
Steiner_points_construction,
|
||||
conforming,
|
||||
input_faces,
|
||||
missing_region,
|
||||
|
|
@ -93,6 +95,8 @@ struct Debug_options {
|
|||
use_epeck_for_Steiner_points,
|
||||
nb_of_flags
|
||||
};
|
||||
bool Steiner_points_construction() const { return flags[static_cast<int>(Flags::Steiner_points_construction)]; }
|
||||
void Steiner_points_construction(bool b) { flags.set(static_cast<int>(Flags::Steiner_points_construction), b); }
|
||||
|
||||
bool Steiner_points() const { return flags[static_cast<int>(Flags::Steiner_points)]; }
|
||||
void Steiner_points(bool b) { flags.set(static_cast<int>(Flags::Steiner_points), b); }
|
||||
|
|
@ -791,11 +795,29 @@ protected:
|
|||
Locate_type lt;
|
||||
int li, lj;
|
||||
const Cell_handle c = tr().locate(steiner_pt, lt, li, lj, hint);
|
||||
if(lt == T_3::VERTEX) {
|
||||
auto other_v = c->vertex(li);
|
||||
const auto [c_va, c_vb] = constraint_extremities(constraint);
|
||||
std::stringstream ss;
|
||||
ss.precision(std::cerr.precision());
|
||||
ss << "insert_Steiner_point_on_subconstraint: Steiner point coincides with an existing vertex\n";
|
||||
ss << " -> Steiner point: " << steiner_pt << '\n';
|
||||
ss << " on constraint: " << display_vert(c_va) << " - " << display_vert(c_vb) << '\n';
|
||||
ss << " -> existing vertex: " << IO::oformat(other_v, with_point_and_info) << '\n';
|
||||
if(other_v->ccdt_3_data().number_of_incident_constraints() > 0) {
|
||||
const auto c_id = other_v->ccdt_3_data().constrained_polyline_id(*this);
|
||||
const auto [c_va, c_vb] = constraint_extremities(c_id);
|
||||
ss << " which is on constraint: " << display_vert(c_va) << " - " << display_vert(c_vb) << '\n';
|
||||
ss << " Possible cause: two input segments are too close to each other\n";
|
||||
} else if(other_v->ccdt_3_data().vertex_type() == CDT_3_vertex_type::INPUT_VERTEX) {
|
||||
ss << " which is an input vertex.\n";
|
||||
ss << " Possible cause: an input segment is too close to an input vertex\n";
|
||||
}
|
||||
throw std::runtime_error(std::move(ss).str());
|
||||
}
|
||||
const Vertex_handle v = visitor.insert_in_triangulation(steiner_pt, lt, c, li, lj);
|
||||
v->ccdt_3_data().set_vertex_type(CDT_3_vertex_type::STEINER_ON_EDGE);
|
||||
if(lt != T_3::VERTEX) {
|
||||
v->ccdt_3_data().set_on_constraint(constraint);
|
||||
}
|
||||
v->ccdt_3_data().set_on_constraint(constraint);
|
||||
constraint_hierarchy.add_Steiner(va, vb, v);
|
||||
visitor.insert_Steiner_point_on_constraint(constraint, va, vb, v);
|
||||
add_to_subconstraints_to_conform(va, v, constraint);
|
||||
|
|
@ -1126,7 +1148,7 @@ protected:
|
|||
return {exact(midpoint_functor(pa, pb)), va->cell(), va};
|
||||
}
|
||||
|
||||
if(debug().encroaching_vertices()) {
|
||||
if(debug().Steiner_points_construction()) {
|
||||
std::cerr << "construct_Steiner_point( " << display_vert(va) << " , "
|
||||
<< display_vert(vb) << " )\n";
|
||||
}
|
||||
|
|
@ -1142,10 +1164,10 @@ protected:
|
|||
pa, this->tr().point(v2), pb) == SMALLER;
|
||||
});
|
||||
CGAL_assertion(reference_vertex_it != vector_of_encroaching_vertices.end());
|
||||
#if CGAL_CDT_3_DEBUG_CONFORMING
|
||||
std::cerr << " -> reference point: " << display_vert(*reference_vertex_it)
|
||||
<< '\n';
|
||||
#endif // CGAL_CDT_3_DEBUG_CONFORMING
|
||||
if(debug().Steiner_points_construction()) {
|
||||
std::cerr << " -> reference point: " << display_vert(*reference_vertex_it)
|
||||
<< '\n';
|
||||
}
|
||||
const auto reference_vertex = *reference_vertex_it;
|
||||
const auto& reference_point = tr().point(reference_vertex);
|
||||
|
||||
|
|
@ -1155,36 +1177,41 @@ protected:
|
|||
CGAL_assertion(reference_vertex->ccdt_3_data().number_of_incident_constraints() == 1);
|
||||
const auto ref_constrained_polyline_id = reference_vertex->ccdt_3_data().constrained_polyline_id(*this);
|
||||
const auto [ref_va, ref_vb] = constraint_extremities(ref_constrained_polyline_id);
|
||||
#if CGAL_CDT_3_DEBUG_CONFORMING
|
||||
std::cerr << " reference point is on constraint: " << display_vert(ref_va)
|
||||
if(debug().Steiner_points_construction()) {
|
||||
std::cerr << " reference point is on constraint: " << display_vert(ref_va)
|
||||
<< " " << display_vert(ref_vb) << '\n'
|
||||
<< " original constraint: " << display_vert(orig_va)
|
||||
<< " " << display_vert(orig_vb) << '\n';
|
||||
#endif // CGAL_CDT_3_DEBUG_CONFORMING
|
||||
}
|
||||
const auto vector_orig_ab = vector_functor(orig_pa, orig_pb);
|
||||
const auto length_ab = CGAL::approximate_sqrt(sq_length_functor(vector_ab));
|
||||
auto return_orig_result_point = [&](auto lambda_val, Point orig_pa_param,
|
||||
Point orig_pb_param) -> Construct_Steiner_point_return_type {
|
||||
// Compute projected point with distance-based ratio threshold check
|
||||
const auto result_point = compute_projected_point_with_threshold(
|
||||
orig_pa_param, orig_pb_param, // Projection segment
|
||||
pa, pb, // Midpoint segment
|
||||
orig_pa_param, orig_pb_param, // Projection segment
|
||||
pa, pb, // Midpoint segment
|
||||
[lambda_val](auto&&, auto&&) { return lambda_val; }, // Lambda computer
|
||||
[&](auto, const std::optional<Point>& projected_pt) { // Threshold check based on distance ratio
|
||||
[&](auto, const std::optional<Point>& projected_pt) { // Threshold check based on distance ratio
|
||||
// If projected_pt is not computed yet (std::nullopt), can't check, so return false
|
||||
if(!projected_pt) return false;
|
||||
if(!projected_pt)
|
||||
return false;
|
||||
|
||||
const auto dist_a_result = CGAL::approximate_sqrt(sq_length_functor(vector_functor(pa, *projected_pt)));
|
||||
const auto ratio = dist_a_result / length_ab;
|
||||
#if CGAL_CDT_3_DEBUG_CONFORMING
|
||||
std::cerr << " ref ratio = " << ratio << '\n';
|
||||
#endif
|
||||
return ratio < 0.2 || ratio > 0.8;
|
||||
bool use_midpoint = ratio < 0.2 || ratio > 0.8;
|
||||
if(debug().Steiner_points_construction()) {
|
||||
std::cerr << " ref ratio = " << ratio << '\n';
|
||||
if(use_midpoint) {
|
||||
std::cerr << " -> using midpoint instead of projection\n";
|
||||
}
|
||||
}
|
||||
return use_midpoint;
|
||||
});
|
||||
|
||||
#if CGAL_CDT_3_DEBUG_CONFORMING
|
||||
std::cerr << " -> Steiner point: " << result_point << '\n';
|
||||
#endif // CGAL_CDT_3_DEBUG_CONFORMING
|
||||
if(debug().Steiner_points_construction()) {
|
||||
std::cerr << " -> Steiner point: " << result_point << '\n';
|
||||
}
|
||||
return {exact(result_point), reference_vertex->cell(), reference_vertex};
|
||||
};
|
||||
|
||||
|
|
@ -1231,12 +1258,12 @@ protected:
|
|||
return result;
|
||||
});
|
||||
|
||||
#if CGAL_CDT_3_DEBUG_CONFORMING
|
||||
const auto vector_a_ref = vector_functor(pa, reference_point);
|
||||
const auto lambda = sc_product_functor(vector_a_ref, vector_ab) / sq_length_functor(vector_ab);
|
||||
std::cerr << " lambda = " << lambda << '\n';
|
||||
std::cerr << " -> Steiner point: " << result_point << '\n';
|
||||
#endif // CGAL_CDT_3_DEBUG_CONFORMING
|
||||
if(debug().Steiner_points_construction()) {
|
||||
const auto vector_a_ref = vector_functor(pa, reference_point);
|
||||
const auto lambda = gt.compute_scalar_product_3_object()(vector_a_ref, vector_ab) / sq_length_functor(vector_ab);
|
||||
std::cerr << " lambda = " << lambda << '\n';
|
||||
std::cerr << " -> Steiner point: " << result_point << '\n';
|
||||
}
|
||||
return {exact(result_point), reference_vertex->cell(), reference_vertex};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
#ifndef CGAL_CONFORMING_CONSTRAINED_DELAUNAY_TRIANGULATION_3_H
|
||||
#define CGAL_CONFORMING_CONSTRAINED_DELAUNAY_TRIANGULATION_3_H
|
||||
|
||||
#include <CGAL/IO/Color_ostream.h>
|
||||
#include <CGAL/license/Constrained_triangulation_3.h>
|
||||
|
||||
#include <CGAL/Conforming_constrained_Delaunay_triangulation_3_fwd.h>
|
||||
|
|
@ -39,9 +40,12 @@
|
|||
#include <CGAL/Dynamic_property_map.h>
|
||||
#include <CGAL/enum.h>
|
||||
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
||||
#include <CGAL/Exception_ostream.h>
|
||||
#include <CGAL/exceptions.h>
|
||||
#include <CGAL/intersection_3.h>
|
||||
#include <CGAL/IO/Color_ostream.h>
|
||||
#include <CGAL/IO/Color.h>
|
||||
#include <CGAL/IO/Indenting_ostream.h>
|
||||
#include <CGAL/IO/io.h>
|
||||
#include <CGAL/Iterator_range.h>
|
||||
#include <CGAL/iterator.h>
|
||||
|
|
@ -195,6 +199,26 @@ does_first_triangle_intersect_second_triangle_interior(const typename K::Triangl
|
|||
const typename K::Triangle_3& t2,
|
||||
const K& k)
|
||||
{
|
||||
// if(do_intersect(t1, t2) == false)
|
||||
// return false;
|
||||
|
||||
// using Point_3 = typename K::Point_3;
|
||||
|
||||
// std::array<Point_3,3> tr1_points{ t1.vertex(0), t1.vertex(1), t1.vertex(2) };
|
||||
// std::array<Point_3,3> tr2_points{ t2.vertex(0), t2.vertex(1), t2.vertex(2) };
|
||||
// std::sort(tr1_points.begin(), tr1_points.end());
|
||||
// std::sort(tr2_points.begin(), tr2_points.end());
|
||||
// std::size_t nb_of_common_vertices = 0;
|
||||
// std::set_intersection(
|
||||
// tr1_points.begin(), tr1_points.end(),
|
||||
// tr2_points.begin(), tr2_points.end(),
|
||||
// CGAL::Counting_output_iterator(&nb_of_common_vertices));
|
||||
// if(nb_of_common_vertices >= 2)
|
||||
// return false;
|
||||
|
||||
// return true;
|
||||
|
||||
|
||||
typedef typename K::Point_3 Point_3;
|
||||
|
||||
CGAL_kernel_precondition(!k.is_degenerate_3_object() (t1) );
|
||||
|
|
@ -239,11 +263,13 @@ does_first_triangle_intersect_second_triangle_interior(const typename K::Triangl
|
|||
|
||||
auto comp = k.compare_xyz_3_object();
|
||||
auto sort_ptrs = [&comp](const Point_3* p1, const Point_3* p2) { return comp(*p1, *p2) == SMALLER; };
|
||||
auto intersection_is_a_vertex_or_a_common_edge = [&]() {
|
||||
CGAL_assume(nb_of_t1_vertices_in_the_line >= 0 && nb_of_t1_vertices_in_the_line <= 3);
|
||||
auto intersection_is_a_common_edge = [&]() {
|
||||
if(nb_of_t1_vertices_in_the_line < 2) return false;
|
||||
CGAL_assume(nb_of_t1_vertices_in_the_line <= 3);
|
||||
if(nb_of_t2_vertices_in_the_line < 2) return false;
|
||||
CGAL_assume(nb_of_t2_vertices_in_the_line <= 3);
|
||||
std::sort(t1_vertices_in_the_line.data(), t1_vertices_in_the_line.data() + nb_of_t1_vertices_in_the_line,
|
||||
sort_ptrs);
|
||||
CGAL_assume(nb_of_t2_vertices_in_the_line >= 0 && nb_of_t2_vertices_in_the_line <= 3);
|
||||
std::sort(t2_vertices_in_the_line.data(), t2_vertices_in_the_line.data() + nb_of_t2_vertices_in_the_line,
|
||||
sort_ptrs);
|
||||
std::size_t nb_of_common_vertices = 0;
|
||||
|
|
@ -251,7 +277,7 @@ does_first_triangle_intersect_second_triangle_interior(const typename K::Triangl
|
|||
t1_vertices_in_the_line.data(), t1_vertices_in_the_line.data() + nb_of_t1_vertices_in_the_line,
|
||||
t2_vertices_in_the_line.data(), t2_vertices_in_the_line.data() + nb_of_t2_vertices_in_the_line,
|
||||
CGAL::Counting_output_iterator(&nb_of_common_vertices), sort_ptrs);
|
||||
return nb_of_common_vertices == 1 || nb_of_common_vertices == 2;
|
||||
return nb_of_common_vertices == 2;
|
||||
};
|
||||
|
||||
switch(dp)
|
||||
|
|
@ -351,7 +377,7 @@ does_first_triangle_intersect_second_triangle_interior(const typename K::Triangl
|
|||
push_to_t2_vertices_in_the_line(&a);
|
||||
push_to_t2_vertices_in_the_line(&b);
|
||||
push_to_t2_vertices_in_the_line(&c);
|
||||
if(intersection_is_a_vertex_or_a_common_edge()) return false;
|
||||
if(intersection_is_a_common_edge()) return false;
|
||||
return CGAL::Intersections::internal::do_intersect_coplanar(t1,t2,k);
|
||||
}
|
||||
default: // should not happen.
|
||||
|
|
@ -385,7 +411,7 @@ does_first_triangle_intersect_second_triangle_interior(const typename K::Triangl
|
|||
if(db == COPLANAR) push_to_t2_vertices_in_the_line(&b);
|
||||
if(dc == COPLANAR) push_to_t2_vertices_in_the_line(&c);
|
||||
|
||||
if(intersection_is_a_vertex_or_a_common_edge()) return false;
|
||||
if(intersection_is_a_common_edge()) return false;
|
||||
|
||||
switch(da)
|
||||
{
|
||||
|
|
@ -1075,7 +1101,7 @@ public:
|
|||
*/
|
||||
CDT_3_signed_index face_constraint_index(typename Triangulation::Cell_handle ch, int i) const
|
||||
{
|
||||
return ch->face_id[static_cast<unsigned>(i)];
|
||||
return ch->ccdt_3_data().face_constraint_index(i);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
@ -1827,6 +1853,9 @@ public:
|
|||
auto& border = borders.emplace_back();
|
||||
border.reserve(std::size(vertex_handles));
|
||||
const auto polygon_constraint_id = face_index.value_or(this->face_data.size() - 1);
|
||||
if(this->debug().input_faces()) {
|
||||
std::cerr << "insert_constrained_face: new polygon_constraint_id: " << polygon_constraint_id << '\n';
|
||||
}
|
||||
do {
|
||||
const auto va = *circ;
|
||||
++circ;
|
||||
|
|
@ -1845,6 +1874,10 @@ public:
|
|||
} while(circ != circ_end);
|
||||
|
||||
if(this->debug().input_faces()) {
|
||||
for(auto [c_id, is_reversed] : border) {
|
||||
std::cerr << " - edge on constraint c_id #" << c_id.index()
|
||||
<< (is_reversed ? " (reversed)" : "") << '\n';
|
||||
}
|
||||
std::vector<std::vector<Vertex_handle>> single_polygon{std::vector(vertex_handles.begin(), vertex_handles.end())};
|
||||
dump_face_polygons(single_polygon, polygon_constraint_id,
|
||||
"dump-input-face-" + std::to_string(polygon_constraint_id) + "_polygon_" +
|
||||
|
|
@ -1855,9 +1888,6 @@ public:
|
|||
// Face_data already created above with emplace_back
|
||||
face_constraint_misses_subfaces.resize(face_data.size());
|
||||
}
|
||||
if(this->debug().input_faces()) {
|
||||
std::cerr << "insert_constrained_face return the polygon_constraint_id: " << polygon_constraint_id << '\n';
|
||||
}
|
||||
return polygon_constraint_id;
|
||||
}
|
||||
|
||||
|
|
@ -2218,6 +2248,11 @@ private:
|
|||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
std::cerr << "ERROR: edge between "
|
||||
<< tr().point(va) << " and "
|
||||
<< tr().point(vb)
|
||||
<< " is not a known constraint of the CDT_3.\n";
|
||||
}
|
||||
|
||||
auto vh_2d = it == end ? first_2d : insert_vertex_in_cdt_2(vb);
|
||||
|
|
@ -2403,8 +2438,9 @@ private:
|
|||
};
|
||||
|
||||
template <typename Fh_region>
|
||||
int does_edge_interior_intersect_region(Cell_handle cell, int index_vc, int index_vd,
|
||||
const CDT_2& cdt_2, const Fh_region& fh_region)
|
||||
std::pair<int, std::array<Vertex_handle, 3>>
|
||||
does_edge_interior_intersect_region(Cell_handle cell, int index_vc, int index_vd,
|
||||
const CDT_2& cdt_2, const Fh_region& fh_region)
|
||||
{
|
||||
auto orientation = tr().geom_traits().orientation_3_object();
|
||||
const auto vc = cell->vertex(index_vd);
|
||||
|
|
@ -2432,16 +2468,17 @@ private:
|
|||
orientation(pc, pd, t1, t2) != opc &&
|
||||
orientation(pc, pd, t2, t0) != opc)
|
||||
{
|
||||
return static_cast<int>(opc);
|
||||
return {static_cast<int>(opc), {v0, v1, v2}};
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return {0, {}};
|
||||
}
|
||||
|
||||
struct Search_first_intersection_result_type {
|
||||
Edge intersecting_edge;
|
||||
Edge border_edge;
|
||||
std::array<Vertex_handle, 3> triangle_vertices;
|
||||
};
|
||||
|
||||
// Given a region and a border edge of it, returns an edge in the link of the
|
||||
|
|
@ -2472,12 +2509,13 @@ private:
|
|||
|
||||
if(is_marked(cell_circ->vertex(index_vc), Vertex_marker::REGION_BORDER)) continue;
|
||||
if(is_marked(cell_circ->vertex(index_vd), Vertex_marker::REGION_BORDER)) continue;
|
||||
int cd_intersects_region = does_edge_interior_intersect_region(cell_circ, index_vc, index_vd, cdt_2, fh_region);
|
||||
auto [cd_intersects_region, triangle_vertices] =
|
||||
does_edge_interior_intersect_region(cell_circ, index_vc, index_vd, cdt_2, fh_region);
|
||||
if(cd_intersects_region == 1) {
|
||||
return Search_first_intersection_result_type{ Edge{cell_circ, index_vc, index_vd}, border_edge };
|
||||
return Search_first_intersection_result_type{ Edge{cell_circ, index_vc, index_vd}, border_edge, triangle_vertices };
|
||||
}
|
||||
if(cd_intersects_region == -1) {
|
||||
return Search_first_intersection_result_type{ Edge{cell_circ, index_vd, index_vc}, border_edge };
|
||||
return Search_first_intersection_result_type{ Edge{cell_circ, index_vd, index_vc}, border_edge, triangle_vertices };
|
||||
}
|
||||
} while(++cell_circ != end);
|
||||
}
|
||||
|
|
@ -2591,26 +2629,27 @@ private:
|
|||
int region_index,
|
||||
const CDT_2& cdt_2,
|
||||
const Fh_region& fh_region,
|
||||
const Vertices_container& region_border_vertices,
|
||||
const Vertices_container& region_vertices,
|
||||
Edge first_intersecting_edge,
|
||||
const std::array<Vertex_handle, 3>& first_intersected_triangle_vertices,
|
||||
Edges_container border_edges)
|
||||
{
|
||||
// outputs
|
||||
struct Outputs
|
||||
{
|
||||
std::vector<Edge> intersecting_edges;
|
||||
std::set<Cell_handle> intersecting_cells;
|
||||
std::vector<std::array<Vertex_handle, 3>> intersected_triangles;
|
||||
std::vector<Cell_handle> intersecting_cells;
|
||||
std::vector<Vertex_handle> vertices_of_upper_cavity;
|
||||
std::vector<Vertex_handle> vertices_of_lower_cavity;
|
||||
std::vector<Facet> facets_of_upper_cavity;
|
||||
std::vector<Facet> facets_of_lower_cavity;
|
||||
} outputs{
|
||||
{}, {}, {region_vertices.begin(), region_vertices.end()}, {region_vertices.begin(), region_vertices.end()},
|
||||
{}, {}, {}, {region_vertices.begin(), region_vertices.end()}, {region_vertices.begin(), region_vertices.end()},
|
||||
{}, {}};
|
||||
|
||||
auto& [intersecting_edges, intersecting_cells, vertices_of_upper_cavity, vertices_of_lower_cavity,
|
||||
facets_of_upper_cavity, facets_of_lower_cavity] = outputs;
|
||||
auto& [intersecting_edges, intersected_triangles, intersecting_cells, vertices_of_upper_cavity,
|
||||
vertices_of_lower_cavity, facets_of_upper_cavity, facets_of_lower_cavity] = outputs;
|
||||
|
||||
// to avoid "warning: captured structured bindings are a C++20 extension [-Wc++20-extensions]""
|
||||
auto& vertices_of_upper_cavity_ = vertices_of_upper_cavity;
|
||||
|
|
@ -2619,15 +2658,18 @@ private:
|
|||
|
||||
std::set<std::pair<Vertex_handle, Vertex_handle>> non_intersecting_edges_set;
|
||||
|
||||
if constexpr (cdt_3_can_use_cxx20_format()) if(this->debug().regions()) {
|
||||
expensive_debug_dump_tetrahedra_intersect_region(face_index, region_index, cdt_2, fh_region);
|
||||
}
|
||||
detect_edges_and_cells_intersecting_region(face_index, region_index, cdt_2, fh_region, first_intersecting_edge,
|
||||
first_intersected_triangle_vertices, intersecting_edges,
|
||||
intersected_triangles, intersecting_cells, non_intersecting_edges_set);
|
||||
const std::set<Cell_handle> cr_intersecting_cells_set{cr_intersecting_cells.begin(), cr_intersecting_cells.end()};
|
||||
// if constexpr(cdt_3_can_use_cxx20_format())
|
||||
// if(this->debug().regions()) {
|
||||
// expensive_debug_dump_tetrahedra_intersect_region(face_index, region_index, cdt_2, fh_region,
|
||||
// cr_intersecting_cells_set);
|
||||
// }
|
||||
|
||||
detect_edges_and_cells_intersecting_region(face_index, region_index, cdt_2, fh_region, region_border_vertices,
|
||||
first_intersecting_edge, intersecting_edges, intersecting_cells,
|
||||
non_intersecting_edges_set);
|
||||
if(this->use_older_cavity_algorithm()) {
|
||||
process_older_cavity_algorithm(intersecting_edges, cr_intersecting_cells, vertices_of_upper_cavity,
|
||||
process_older_cavity_algorithm(intersecting_edges, cr_intersecting_cells_set, vertices_of_upper_cavity,
|
||||
vertices_of_lower_cavity, facets_of_upper_cavity, facets_of_lower_cavity);
|
||||
} // older algorithm
|
||||
|
||||
|
|
@ -2638,7 +2680,7 @@ private:
|
|||
for(auto c : cr_intersecting_cells) {
|
||||
for(int i = 0; i < 4; ++i) {
|
||||
auto n = c->neighbor(i);
|
||||
if(cr_intersecting_cells.count(n) == 0) {
|
||||
if(cr_intersecting_cells_set.count(n) == 0) {
|
||||
facets_of_border.emplace(n, n->index(c));
|
||||
}
|
||||
}
|
||||
|
|
@ -2757,8 +2799,8 @@ private:
|
|||
const auto facet = stack.top();
|
||||
stack.pop();
|
||||
const auto [cell, facet_index] = facet; // border facet seen from the outside of the cavity
|
||||
CGAL_assertion(cr_intersecting_cells.count(cell) == 0); //REMOVE
|
||||
CGAL_assertion(cr_intersecting_cells.count(cell->neighbor(facet_index)) > 0); //REMOVE
|
||||
CGAL_assertion(cr_intersecting_cells_set.count(cell) == 0); //REMOVE
|
||||
CGAL_assertion(cr_intersecting_cells_set.count(cell->neighbor(facet_index)) > 0); //REMOVE
|
||||
const auto vertices = tr().vertices(facet);
|
||||
for(auto v : vertices) {
|
||||
if(is_marked(v, Vertex_marker::CAVITY)) {
|
||||
|
|
@ -2781,14 +2823,14 @@ private:
|
|||
auto previous_cell = cell;
|
||||
auto other_cell = cell->neighbor(facet_index);
|
||||
do {
|
||||
CGAL_assertion(cr_intersecting_cells.count(other_cell) >= 0); // REMOVE
|
||||
CGAL_assertion(cr_intersecting_cells_set.count(other_cell) >= 0); // REMOVE
|
||||
auto index_va = other_cell->index(va);
|
||||
auto index_vb = other_cell->index(vb);
|
||||
auto other_facet_index = tr().next_around_edge(index_vb, index_va);
|
||||
previous_cell = other_cell;
|
||||
other_cell = previous_cell->neighbor(other_facet_index);
|
||||
|
||||
} while(cr_intersecting_cells.count(other_cell) > 0);
|
||||
} while(cr_intersecting_cells_set.count(other_cell) > 0);
|
||||
const Facet neighbor_facet{other_cell, other_cell->index(previous_cell)};
|
||||
CGAL_assertion(facets_of_border.count(neighbor_facet) > 0);
|
||||
if(remaining_facets_of_border.erase(neighbor_facet) > 0) {
|
||||
|
|
@ -2945,8 +2987,11 @@ private:
|
|||
CDT_2& non_const_cdt_2, Fh_region& non_const_fh_region)
|
||||
{
|
||||
if(this->debug().regions()) {
|
||||
auto guard_color = CGAL::IO::make_color_guards(CGAL::IO::Ansi_color::Yellow, std::cerr);
|
||||
std::cerr << "restore_subface_region face index: " << face_index << ", region #" << region_index << "\n";
|
||||
}
|
||||
auto guard_indenting = CGAL::IO::make_indenting_guards(2, std::cerr, std::cout);
|
||||
|
||||
const auto& cdt_2 = non_const_cdt_2;
|
||||
const auto& fh_region = non_const_fh_region;
|
||||
const auto border_edges = brute_force_border_3_of_region(face_index, region_index, cdt_2, fh_region);
|
||||
|
|
@ -3134,11 +3179,12 @@ private:
|
|||
clear_marks(region_vertices, Vertex_marker::REGION_INSIDE);
|
||||
}};
|
||||
|
||||
const auto [first_intersecting_edge, _] = *found_edge_opt;
|
||||
const auto [intersecting_edges, original_intersecting_cells, original_vertices_of_upper_cavity,
|
||||
original_vertices_of_lower_cavity, original_facets_of_upper_cavity, original_facets_of_lower_cavity] =
|
||||
construct_cavities(face_index, region_index, cdt_2, fh_region, region_border_vertices, region_vertices,
|
||||
first_intersecting_edge, border_edges);
|
||||
const auto [first_intersecting_edge, _, triangle_vertices] = *found_edge_opt;
|
||||
const auto [intersecting_edges, intersected_triangles, original_intersecting_cells,
|
||||
original_vertices_of_upper_cavity, original_vertices_of_lower_cavity, original_facets_of_upper_cavity,
|
||||
original_facets_of_lower_cavity] =
|
||||
construct_cavities(face_index, region_index, cdt_2, fh_region, region_vertices,
|
||||
first_intersecting_edge, triangle_vertices, border_edges);
|
||||
|
||||
const std::set<Point_3> polygon_points = std::invoke([&](){
|
||||
std::set<Point_3> polygon_points;
|
||||
|
|
@ -3448,6 +3494,9 @@ private:
|
|||
int i;
|
||||
typename CDT_2::Locate_type lt;
|
||||
const auto fh = cdt_2.locate(p, lt, i, hint);
|
||||
if(lt != CDT_2::VERTEX) {
|
||||
exception_ostream() << cdt_3_format("vertex_of_cdt_2_functor: point {} lt = {}\n", IO::oformat(p), int(lt));
|
||||
}
|
||||
CGAL_assume(lt == CDT_2::VERTEX);
|
||||
hint = fh;
|
||||
return fh->vertex(i);
|
||||
|
|
@ -3955,7 +4004,7 @@ public:
|
|||
std::cerr << "ratio (non-squared): "
|
||||
<< CGAL::sqrt(CGAL::to_double(from_exact(exact_sq_distance / exact_sq_circumradius))) << '\n';
|
||||
}
|
||||
result = false;
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3974,7 +4023,7 @@ public:
|
|||
if(verbose)
|
||||
std::cerr << "non-empty circle " << std::endl;
|
||||
|
||||
result = false;
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4218,16 +4267,17 @@ public:
|
|||
};
|
||||
};
|
||||
|
||||
template <typename Fh_region, typename Vertices_container>
|
||||
template <typename Fh_region>
|
||||
void detect_edges_and_cells_intersecting_region(
|
||||
CDT_3_signed_index face_index,
|
||||
int region_index,
|
||||
[[maybe_unused]] CDT_3_signed_index face_index,
|
||||
[[maybe_unused]] int region_index,
|
||||
const CDT_2& cdt_2,
|
||||
const Fh_region& fh_region,
|
||||
const Vertices_container& region_border_vertices,
|
||||
Edge first_intersecting_edge,
|
||||
const std::array<Vertex_handle, 3>& first_intersected_triangle_vertices,
|
||||
std::vector<Edge>& intersecting_edges,
|
||||
std::set<Cell_handle>& intersecting_cells,
|
||||
std::vector<std::array<Vertex_handle, 3>>& intersected_triangles,
|
||||
std::vector<Cell_handle>& intersecting_cells,
|
||||
std::set<std::pair<Vertex_handle, Vertex_handle>>& non_intersecting_edges_set)
|
||||
{
|
||||
// Create visitor functors
|
||||
|
|
@ -4239,135 +4289,85 @@ public:
|
|||
};
|
||||
|
||||
intersecting_edges.push_back(first_intersecting_edge);
|
||||
const auto [v0, v1] = tr().vertices(first_intersecting_edge);
|
||||
(void)new_edge(v0, v1, true);
|
||||
intersecting_cells.push_back(first_intersecting_edge.first);
|
||||
intersected_triangles.push_back(first_intersected_triangle_vertices);
|
||||
(void)new_cell(first_intersecting_edge.first);
|
||||
|
||||
for(std::size_t i = 0; i < intersecting_edges.size(); ++i) {
|
||||
const auto intersecting_edge = intersecting_edges[i];
|
||||
const auto [v_above, v_below] = tr().vertices(intersecting_edge);
|
||||
if constexpr (cdt_3_can_use_cxx20_format()) if(this->debug().regions()) {
|
||||
debug_dump_edge_region_intersection(face_index, region_index, fh_region, i, v_above, v_below, intersecting_edge);
|
||||
}
|
||||
|
||||
auto test_edge = [&](Cell_handle cell, Vertex_handle v0, int index_v0, Vertex_handle v1, int index_v1,
|
||||
int expected)
|
||||
{
|
||||
auto value_returned = [this, v0, v1](bool b, bool not_visited) {
|
||||
if constexpr (cdt_3_can_use_cxx20_format()) if(this->debug().regions()) {
|
||||
std::cerr << cdt_3_format(" test_edge {} {} return {} {}\n",
|
||||
IO::oformat(v0, with_point_and_info),
|
||||
IO::oformat(v1, with_point_and_info),
|
||||
b,
|
||||
not_visited ? "(new)" : "(cached)");
|
||||
auto test_edge = [&](Cell_handle cell, Vertex_handle v0, int index_v0, Vertex_handle v1, int index_v1)
|
||||
{
|
||||
auto value_returned = [this, v0, v1](bool b, bool not_visited, std::array<Vertex_handle, 3> triangle_vertices = {}) {
|
||||
if constexpr (cdt_3_can_use_cxx20_format()) if(this->debug().regions()) {
|
||||
std::cerr << cdt_3_format("test_edge {} {} return {} {}\n",
|
||||
IO::oformat(v0, with_point_and_info),
|
||||
IO::oformat(v1, with_point_and_info),
|
||||
b,
|
||||
not_visited ? "(new)" : "(cached)");
|
||||
if(not_visited && b) {
|
||||
std::cerr << " triangle " << IO::oformat(triangle_vertices[0], with_point_and_info) << "\n"
|
||||
<< " " << IO::oformat(triangle_vertices[1], with_point_and_info) << "\n"
|
||||
<< " " << IO::oformat(triangle_vertices[2], with_point_and_info) << "\n";
|
||||
}
|
||||
CGAL_USE(this, v0, v1, b, not_visited);
|
||||
return b;
|
||||
};
|
||||
auto [cached_value_it, not_visited] = new_edge(v0, v1, false);
|
||||
if(!not_visited) return value_returned(cached_value_it->second, not_visited);
|
||||
int v0v1_intersects_region =
|
||||
(is_marked(v0, Vertex_marker::REGION_INSIDE) || is_marked(v1, Vertex_marker::REGION_INSIDE))
|
||||
? expected
|
||||
: does_edge_interior_intersect_region(cell, index_v0, index_v1, cdt_2, fh_region);
|
||||
}
|
||||
CGAL_USE(this, v0, v1, b, not_visited);
|
||||
return b;
|
||||
};
|
||||
auto [cached_value_it, not_visited] = new_edge(v0, v1, false);
|
||||
if(!not_visited) return value_returned(cached_value_it->second, not_visited);
|
||||
if(!is_marked(v0, Vertex_marker::REGION_INSIDE) && !is_marked(v1, Vertex_marker::REGION_INSIDE)) {
|
||||
auto [v0v1_intersects_region, triangle_vertices] =
|
||||
does_edge_interior_intersect_region(cell, index_v0, index_v1, cdt_2, fh_region);
|
||||
if(v0v1_intersects_region != 0) {
|
||||
if(this->use_older_cavity_algorithm()) {
|
||||
if(v0v1_intersects_region != expected) {
|
||||
throw PLC_error{"PLC error: v0v1_intersects_region != expected" ,
|
||||
__FILE__, __LINE__, face_index, region_index};
|
||||
}
|
||||
}
|
||||
// report the edge with first vertex above the region
|
||||
if(v0v1_intersects_region < 0) {
|
||||
std::swap(index_v0, index_v1);
|
||||
}
|
||||
intersecting_edges.emplace_back(cell, index_v0, index_v1);
|
||||
intersected_triangles.push_back(triangle_vertices);
|
||||
cached_value_it->second = true;
|
||||
return value_returned(true, not_visited);
|
||||
} else {
|
||||
non_intersecting_edges_set.insert(make_sorted_pair(v0, v1));
|
||||
cached_value_it->second = false;
|
||||
return value_returned(false, not_visited);
|
||||
return value_returned(true, not_visited, triangle_vertices);
|
||||
}
|
||||
};
|
||||
}
|
||||
non_intersecting_edges_set.insert(make_sorted_pair(v0, v1));
|
||||
cached_value_it->second = false;
|
||||
return value_returned(false, not_visited);
|
||||
};
|
||||
|
||||
auto facet_circ = this->incident_facets(intersecting_edge);
|
||||
const auto facet_circ_end = facet_circ;
|
||||
do { // loop facets around [v_above, v_below]
|
||||
CGAL_assertion(false == this->is_infinite(*facet_circ));
|
||||
const auto cell = facet_circ->first;
|
||||
const auto facet_index = facet_circ->second;
|
||||
if(cell->ccdt_3_data().is_facet_constrained(facet_index)) {
|
||||
CGAL_error_msg(std::invoke([&]() {
|
||||
if(this->debug().regions()) this->dump_triangulation_to_off();
|
||||
return std::string("intersecting polygons!");
|
||||
}).c_str());
|
||||
auto test_cell = [&](Cell_handle cell) {
|
||||
if constexpr(cdt_3_can_use_cxx20_format()) if(this->debug().regions()) {
|
||||
std::cerr << cdt_3_format("test_cell #{}\n {}\n {}\n {}\n {}\n",
|
||||
IO::oformat(cell, with_offset),
|
||||
IO::oformat(cell->vertex(0), with_point_and_info),
|
||||
IO::oformat(cell->vertex(1), with_point_and_info),
|
||||
IO::oformat(cell->vertex(2), with_point_and_info),
|
||||
IO::oformat(cell->vertex(3), with_point_and_info));
|
||||
}
|
||||
auto indent_guard = CGAL::IO::make_indenting_guards("| ", std::cerr, std::cout, std::clog);
|
||||
bool does_intersect = false;
|
||||
for(int i = 0; i < 4; ++i) {
|
||||
const auto v0 = cell->vertex(i);
|
||||
for(int j = i + 1; j < 4; ++j) {
|
||||
const auto v1 = cell->vertex(j);
|
||||
if(test_edge(cell, v0, i, v1, j) != 0) {
|
||||
does_intersect = true;
|
||||
}
|
||||
}
|
||||
if(new_cell(cell)) {
|
||||
intersecting_cells.insert(cell);
|
||||
}
|
||||
const auto index_v_above = cell->index(v_above);
|
||||
const auto index_v_below = cell->index(v_below);
|
||||
const auto index_vc = 6 - index_v_above - index_v_below - facet_index;
|
||||
const auto vc = cell->vertex(index_vc);
|
||||
if(region_border_vertices.count(vc) > 0) continue; // intersecting edges cannot touch the border
|
||||
}
|
||||
if constexpr(cdt_3_can_use_cxx20_format()) if(this->debug().regions()) {
|
||||
std::cerr << cdt_3_format(" -> test_cell return {}\n", does_intersect);
|
||||
}
|
||||
return does_intersect;
|
||||
};
|
||||
|
||||
if(!test_edge(cell, v_above, index_v_above, vc, index_vc, 1) &&
|
||||
!test_edge(cell, v_below, index_v_below, vc, index_vc, -1) &&
|
||||
this->use_older_cavity_algorithm())
|
||||
{
|
||||
if(this->debug().regions()) {
|
||||
dump_triangulation();
|
||||
dump_region(face_index, region_index, cdt_2);
|
||||
std::ofstream out(std::string("dump_two_edges_") + std::to_string(face_index) + ".polylines.txt");
|
||||
out.precision(17);
|
||||
write_segment(out, Edge{cell, index_v_above, index_vc});
|
||||
write_segment(out, Edge{cell, index_v_below, index_vc});
|
||||
}
|
||||
throw PLC_error{"PLC error: !test_edge(v_above..) && !test_edge(v_below..)" ,
|
||||
__FILE__, __LINE__, face_index, region_index};
|
||||
for(std::size_t i = 0; i < intersecting_cells.size(); ++i) {
|
||||
const auto cell = intersecting_cells[i];
|
||||
test_cell(cell);
|
||||
for(int other_i = 0; other_i < 4; ++other_i) {
|
||||
auto neighbor = cell->neighbor(other_i);
|
||||
if(new_cell(neighbor) && !tr().is_infinite(neighbor) && test_cell(neighbor)) {
|
||||
intersecting_cells.push_back(neighbor);
|
||||
}
|
||||
} while(++facet_circ != facet_circ_end);
|
||||
if(this->use_newer_cavity_algorithm() && i + 1 == intersecting_edges.size()) {
|
||||
for(auto ch: intersecting_cells) {
|
||||
if(this->debug().regions()) {
|
||||
std::cerr << "tetrahedron #" << ch->time_stamp() << " intersects the region\n";
|
||||
}
|
||||
for(int i = 0; i < 4; ++i) {
|
||||
for(int j = i + 1; j < 4; ++j) {
|
||||
test_edge(ch, ch->vertex(i), i, ch->vertex(j), j, 1);
|
||||
}
|
||||
}
|
||||
for(int i = 0; i < 4; ++i) {
|
||||
auto n_ch = ch->neighbor(i);
|
||||
if(tr().is_infinite(n_ch))
|
||||
continue;
|
||||
if(new_cell(n_ch)) {
|
||||
const auto tetrahedron = tr().tetrahedron(n_ch);
|
||||
const auto tet_bbox = tetrahedron.bbox();
|
||||
if(std::any_of(fh_region.begin(), fh_region.end(), [&](auto fh) {
|
||||
const auto triangle = cdt_2.triangle(fh);
|
||||
const auto tri_bbox = triangle.bbox();
|
||||
return CGAL::do_overlap(tet_bbox, tri_bbox) &&
|
||||
does_tetrahedron_intersect_triangle_interior(tetrahedron, triangle, tr().geom_traits());
|
||||
}))
|
||||
{
|
||||
intersecting_cells.insert(n_ch);
|
||||
if(this->debug().regions()) {
|
||||
std::cerr << "new tetrahedron #" << n_ch->time_stamp() << " intersects the region\n";
|
||||
}
|
||||
} else if(this->debug().regions()) {
|
||||
std::cerr << "NO, new tetrahedron #" << n_ch->time_stamp() << " does not intersect the region\n";
|
||||
}
|
||||
for(int i = 0; i < 4; ++i) {
|
||||
for(int j = i + 1; j < 4; ++j) {
|
||||
test_edge(n_ch, n_ch->vertex(i), i, n_ch->vertex(j), j, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // last intersecting edge, and new algorithm
|
||||
} // end loop on intersecting_edges
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void debug_dump_cavity_outputs(CDT_3_signed_index face_index,
|
||||
|
|
@ -4428,16 +4428,28 @@ public:
|
|||
std::size_t edge_index,
|
||||
Vertex_handle v_above,
|
||||
Vertex_handle v_below,
|
||||
Edge intersecting_edge)
|
||||
Edge intersecting_edge,
|
||||
const std::array<Vertex_handle, 3>& first_intersected_triangle_vertices)
|
||||
{
|
||||
using EK = CGAL::Exact_predicates_exact_constructions_kernel;
|
||||
const auto to_exact = CGAL::Cartesian_converter<Geom_traits, EK>();
|
||||
const auto& cdt_2 = this->face_cdt_2(face_index);
|
||||
|
||||
std::cerr << cdt_3_format("restore_subface_region face index: {}, region #{}, intersecting edge #{}: ({} {})\n",
|
||||
face_index, region_index, edge_index,
|
||||
IO::oformat(v_above, with_point_and_info),
|
||||
IO::oformat(v_below, with_point_and_info));
|
||||
auto of = [](auto&&... args) {
|
||||
return IO::oformat(std::forward<decltype(args)>(args)..., with_point_and_info);
|
||||
};
|
||||
|
||||
std::cerr << cdt_3_format("restore_subface_region face index: {}, region #{}\n",
|
||||
face_index, region_index);
|
||||
auto indent_guard = CGAL::IO::make_indenting_guards("| ", std::cerr, std::cout, std::clog);
|
||||
std::cerr << cdt_3_format("intersecting edge #{}: ( {} {} )\n"
|
||||
"intersected triangle vertices: {}\n"
|
||||
" {}\n"
|
||||
" {}\n",
|
||||
edge_index, of(v_above), of(v_below),
|
||||
of(first_intersected_triangle_vertices[0]),
|
||||
of(first_intersected_triangle_vertices[1]),
|
||||
of(first_intersected_triangle_vertices[2]));
|
||||
dump_region(face_index, region_index, cdt_2);
|
||||
|
||||
const auto p_above = this->point(v_above);
|
||||
|
|
@ -4467,12 +4479,8 @@ public:
|
|||
for(const auto& ch: make_prevent_deref_range(cells_around_intersecting_edge)) {
|
||||
CGAL_assertion(!ch->has_vertex(tr().infinite_vertex()));
|
||||
auto tetrahedron = tr().tetrahedron(ch.current_circulator());
|
||||
std::cerr << cdt_3_format("Test tetrahedron (#{}):\n {}\n {}\n {}\n {}\n",
|
||||
ch->time_stamp(),
|
||||
IO::oformat(ch->vertex(0), with_point_and_info),
|
||||
IO::oformat(ch->vertex(1), with_point_and_info),
|
||||
IO::oformat(ch->vertex(2), with_point_and_info),
|
||||
IO::oformat(ch->vertex(3), with_point_and_info));
|
||||
std::cerr << cdt_3_format("Test tetrahedron (#{}):\n {}\n {}\n {}\n {}\n", ch->time_stamp(),
|
||||
of(ch->vertex(0)), of(ch->vertex(1)), of(ch->vertex(2)), of(ch->vertex(3)));
|
||||
if(!std::any_of(fh_region.begin(), fh_region.end(), [&](const auto fh) {
|
||||
auto triangle = cdt_2.triangle(fh);
|
||||
bool b = does_tetrahedron_intersect_triangle_interior(tetrahedron, triangle, tr().geom_traits());
|
||||
|
|
@ -4482,11 +4490,14 @@ public:
|
|||
return b;
|
||||
}))
|
||||
{
|
||||
std::cerr << cdt_3_format(
|
||||
"ERROR: The following tetrahedron (#{}) does not intersect the region:\n {}\n {}\n {}\n {}\n",
|
||||
ch->time_stamp(),
|
||||
IO::oformat(ch->vertex(0), with_point_and_info), IO::oformat(ch->vertex(1), with_point_and_info),
|
||||
IO::oformat(ch->vertex(2), with_point_and_info), IO::oformat(ch->vertex(3), with_point_and_info));
|
||||
auto triangle = typename Geom_traits::Triangle_3{tr().point(first_intersected_triangle_vertices[0]),
|
||||
tr().point(first_intersected_triangle_vertices[1]),
|
||||
tr().point(first_intersected_triangle_vertices[2])};
|
||||
exception_ostream()
|
||||
<< cdt_3_format(
|
||||
"ERROR: The following tetrahedron (#{}) does not intersect the region:\n {}\n {}\n {}\n {}",
|
||||
ch->time_stamp(), of(ch->vertex(0)), of(ch->vertex(1)), of(ch->vertex(2)), of(ch->vertex(3)))
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4495,7 +4506,8 @@ public:
|
|||
void expensive_debug_dump_tetrahedra_intersect_region(CDT_3_signed_index face_index,
|
||||
int region_index,
|
||||
const CDT_2& cdt_2,
|
||||
const Fh_region& fh_region)
|
||||
const Fh_region& fh_region,
|
||||
const std::set<Cell_handle>& intersecting_cells_to_check)
|
||||
{
|
||||
using Mesh = Surface_mesh<Point_3>;
|
||||
using Face_index = typename Mesh::Face_index;
|
||||
|
|
@ -4507,18 +4519,24 @@ public:
|
|||
auto [color_vpmap, _] = tets_intersect_region_mesh.template add_property_map<Face_index, int>("f:patch_id");
|
||||
|
||||
for(auto ch : tr().finite_cell_handles()) {
|
||||
const bool is_in_set = intersecting_cells_to_check.find(ch) != intersecting_cells_to_check.end();
|
||||
auto tetrahedron = tr().tetrahedron(ch);
|
||||
if(!std::any_of(fh_region.begin(), fh_region.end(), [&](auto fh) {
|
||||
const auto triangle = cdt_2.triangle(fh);
|
||||
return does_tetrahedron_intersect_triangle_interior(tetrahedron, triangle, tr().geom_traits());
|
||||
}))
|
||||
{
|
||||
if(is_in_set) {
|
||||
exception_ostream() << cdt_3_format(
|
||||
"ERROR: tetrahedron #{} is in the intersecting_cells_to_check set but it does not intersect the region",
|
||||
ch->time_stamp()) << std::endl;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
bool intersects = false;
|
||||
for(int i = 0; i < 4; ++i) {
|
||||
for(int j = i + 1; j < 4; ++j) {
|
||||
int intersects_region = does_edge_interior_intersect_region(ch, i, j, cdt_2, fh_region);
|
||||
int intersects_region = does_edge_interior_intersect_region(ch, i, j, cdt_2, fh_region).first;
|
||||
if(intersects_region != 0) {
|
||||
intersects = true;
|
||||
}
|
||||
|
|
@ -4527,6 +4545,13 @@ public:
|
|||
if(!intersects) {
|
||||
std::cerr << "ERROR: tetrahedron #" << ch->time_stamp() << " has no edge intersecting the region\n";
|
||||
}
|
||||
if(is_in_set != intersects) {
|
||||
exception_ostream() << cdt_3_format(
|
||||
"ERROR: tetrahedron #{} is {} in the intersecting_cells_to_check set but it {}intersects the region\n",
|
||||
ch->time_stamp(),
|
||||
is_in_set ? "" : "not",
|
||||
intersects ? "" : "does not ")<< std::endl;
|
||||
}
|
||||
std::ofstream dump_tetrahedron(
|
||||
cdt_3_format("dump_intersecting_{}_{}_tetrahedron_{}.off", face_index, region_index, ch->time_stamp()));
|
||||
dump_tetrahedron.precision(17);
|
||||
|
|
|
|||
|
|
@ -14,10 +14,17 @@
|
|||
|
||||
#include <CGAL/license/Constrained_triangulation_3.h>
|
||||
|
||||
#include <CGAL/Triangulation_simplex_base_with_time_stamp.h>
|
||||
#include <CGAL/Conforming_constrained_Delaunay_triangulation_cell_data_3.h>
|
||||
#include <CGAL/Triangulation_cell_base_3.h>
|
||||
#include <CGAL/IO/io.h>
|
||||
#include <CGAL/SMDS_3/io_signature.h>
|
||||
#include <CGAL/Triangulation_cell_base_3.h>
|
||||
#include <CGAL/Triangulation_simplex_base_with_time_stamp.h>
|
||||
|
||||
#include <istream>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
|
|
@ -98,7 +105,7 @@ public:
|
|||
CGAL::read(is, i);
|
||||
}
|
||||
if(!is) return is;
|
||||
c.face_id[li] = i;
|
||||
c->ccdt_3_data().set_face_constraint_index(li, i);
|
||||
}
|
||||
return is;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ cgal_add_test(test_CDT_3_insert_constrained_edge_from_OFF_file)
|
|||
function(CGAL_add_cdt3_from_off_test_aux data_name data_dir)
|
||||
set(options ONLY_MERGE_FACETS)
|
||||
set(oneValueArgs DATA_FILENAME TIMEOUT)
|
||||
set(multiValueArgs LABELS)
|
||||
set(multiValueArgs LABELS OPTIONS)
|
||||
cmake_parse_arguments(PARSE_ARGV 2 "MY" "${options}" "${oneValueArgs}"
|
||||
"${multiValueArgs}")
|
||||
if(NOT MY_DATA_FILENAME)
|
||||
|
|
@ -58,7 +58,7 @@ function(CGAL_add_cdt3_from_off_test_aux data_name data_dir)
|
|||
cgal_setup_test_properties("execution of cdt_3_from_off ${data_name}" cdt_3_from_off)
|
||||
add_test(NAME "execution of cdt_3_from_off --merge-facets ${data_name}"
|
||||
COMMAND cdt_3_from_off
|
||||
--merge-facets --segment-vertex-epsilon 0 --vertex-vertex-epsilon 0
|
||||
--merge-facets --segment-vertex-epsilon 0 --vertex-vertex-epsilon 0 ${MY_OPTIONS}
|
||||
${data_dir}/${data_filename}
|
||||
${CMAKE_CURRENT_BINARY_DIR}/dump_output_${data_name}--merge-facets.off)
|
||||
cgal_setup_test_properties("execution of cdt_3_from_off --merge-facets ${data_name}" cdt_3_from_off)
|
||||
|
|
@ -100,6 +100,8 @@ CGAL_add_cdt3_from_local_off_test(cheese28)
|
|||
CGAL_add_cdt3_from_local_off_test(cheese31)
|
||||
CGAL_add_cdt3_from_local_off_test(cheese36-bis)
|
||||
CGAL_add_cdt3_from_local_off_test(cheese36)
|
||||
CGAL_add_cdt3_from_local_off_test(cheese-min1-no-merge-facets-read-mesh-with-operator OPTIONS --read-mesh-with-operator --debug-regions)
|
||||
CGAL_add_cdt3_from_local_off_test(cheese-min2)
|
||||
CGAL_add_cdt3_from_local_off_test(cheese6-PLCerrorWithFace0)
|
||||
CGAL_add_cdt3_from_local_off_test(HexiCosPot-11)
|
||||
CGAL_add_cdt3_from_local_off_test(HexiCosPot-1)
|
||||
|
|
@ -129,6 +131,8 @@ if (CGAL_CDT_TEST_USE_THINGI)
|
|||
CGAL_add_cdt3_from_local_off_test(285604-min8)
|
||||
CGAL_add_cdt3_from_local_off_test(40985-min3)
|
||||
CGAL_add_cdt3_from_local_off_test(505036-min1)
|
||||
CGAL_add_cdt3_from_local_off_test(57811-min)
|
||||
CGAL_add_cdt3_from_local_off_test(734961-min3)
|
||||
CGAL_add_cdt3_from_local_off_test(error_mesh-p_not_equal_0-min2)
|
||||
CGAL_add_cdt3_from_local_off_test(thingi-1036467-selection3)
|
||||
|
||||
|
|
|
|||
|
|
@ -111,6 +111,9 @@ Usage: cdt_3_from_off [options] input.off output.off
|
|||
--read-mesh-with-operator: read the mesh with operator>>
|
||||
--reject-self-intersections: reject self-intersecting polygon soups
|
||||
--no-is-valid: do not call is_valid checks
|
||||
|
||||
--debug-Steiner-points: debug Steiner point insertion
|
||||
--debug-Steiner-points-construction: debug Steiner point construction
|
||||
--debug-input-faces: debug input faces
|
||||
--debug-missing-regions: debug missing regions
|
||||
--debug-regions: debug regions
|
||||
|
|
@ -124,6 +127,7 @@ Usage: cdt_3_from_off [options] input.off output.off
|
|||
--debug-constraint-hierarchy: debug constraint hierarchy operations
|
||||
--debug-geometric-errors: debug geometric error handling
|
||||
--debug-polygon-insertion: debug polygon insertion process
|
||||
|
||||
--use-finite-edges-map: use a hash map for finite edges (default: false)
|
||||
--use-epeck-for-normals/--no-use-epeck-for-normals: use exact kernel for normal computations (default: false)
|
||||
--use-epeck-for-Steiner-points/--no-use-epeck-for-Steiner-points: use exact kernel for Steiner point computations (default: false)
|
||||
|
|
@ -150,6 +154,8 @@ struct CDT_options
|
|||
bool reject_self_intersections = false;
|
||||
bool repair_mesh = true;
|
||||
bool read_mesh_with_operator = false;
|
||||
bool debug_Steiner_points = false;
|
||||
bool debug_Steiner_points_construction = false;
|
||||
bool debug_input_faces = false;
|
||||
bool debug_missing_regions = false;
|
||||
bool debug_regions = false;
|
||||
|
|
@ -235,6 +241,10 @@ CDT_options::CDT_options(int argc, char* argv[]) {
|
|||
quiet = true;
|
||||
} else if(arg == "--no-is-valid"sv) {
|
||||
call_is_valid = false;
|
||||
} else if(arg == "--debug-Steiner-points"sv) {
|
||||
debug_Steiner_points = true;
|
||||
} else if(arg == "--debug-Steiner-points-construction"sv) {
|
||||
debug_Steiner_points_construction = true;
|
||||
} else if(arg == "--debug-input-faces"sv) {
|
||||
debug_input_faces = true;
|
||||
} else if(arg == "--debug-missing-regions"sv) {
|
||||
|
|
@ -296,7 +306,8 @@ CDT_options::CDT_options(int argc, char* argv[]) {
|
|||
|
||||
CGAL::CDT_3::Debug_options cdt_debug_options(const CDT_options& options) {
|
||||
CGAL::CDT_3::Debug_options cdt_debug;
|
||||
cdt_debug.Steiner_points(options.verbose_level > 0);
|
||||
cdt_debug.Steiner_points(options.debug_Steiner_points || options.verbose_level > 0);
|
||||
cdt_debug.Steiner_points_construction(options.debug_Steiner_points_construction);
|
||||
cdt_debug.input_faces(options.debug_input_faces);
|
||||
cdt_debug.missing_region(options.verbose_level > 1 || options.debug_missing_regions);
|
||||
cdt_debug.regions(options.debug_regions);
|
||||
|
|
@ -737,6 +748,14 @@ int bisect_errors(Mesh mesh, CDT_options options) {
|
|||
CGAL::Euler::remove_face(halfedge(*it, m), m);
|
||||
}
|
||||
|
||||
std::stringstream ss;
|
||||
ss.precision(17);
|
||||
ss << m;
|
||||
ss.seekg(0);
|
||||
Mesh simplified_mesh;
|
||||
ss >> simplified_mesh;
|
||||
m = std::move(simplified_mesh);
|
||||
|
||||
return m.is_valid(true);
|
||||
return true;
|
||||
};
|
||||
|
|
@ -748,7 +767,16 @@ int bisect_errors(Mesh mesh, CDT_options options) {
|
|||
|
||||
// Lambda to save the mesh to a file
|
||||
auto save_mesh = [](const Mesh& m, const std::string& prefix) {
|
||||
std::ofstream out(prefix + "_mesh.off");
|
||||
static int count = 0;
|
||||
auto filename = prefix + "_mesh";
|
||||
if(prefix == "bad") {
|
||||
++count;
|
||||
filename += "_";
|
||||
filename += std::to_string(count) + ".off";
|
||||
} else {
|
||||
filename += ".off";
|
||||
}
|
||||
std::ofstream out(filename);
|
||||
out.precision(17);
|
||||
out << m;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -0,0 +1,75 @@
|
|||
OFF
|
||||
47 24 0
|
||||
|
||||
0 38.899999999999999 0
|
||||
2.4425500000000002 38.8232 0
|
||||
0 38.899999999999999 17.899999999999999
|
||||
2.1000000000000001 38.834000000000003 20
|
||||
1.99722 38.837200000000003 20.648900000000001
|
||||
0 38.899999999999999 37.600000000000001
|
||||
1.6989399999999999 38.846600000000002 21.234300000000001
|
||||
1.2343500000000001 38.861199999999997 21.698899999999998
|
||||
0.64893599999999996 38.879600000000003 21.997199999999999
|
||||
0 38.899999999999999 22.100000000000001
|
||||
4.76372e-15 38.899999999999999 37.600000000000001
|
||||
-0.64893599999999996 38.879600000000003 21.997199999999999
|
||||
-16.562799999999999 35.197800000000001 39.777900000000002
|
||||
-16.562799999999999 35.197800000000001 23.228899999999999
|
||||
-15.2951 35.746400000000001 40.479900000000001
|
||||
-14.32 36.168300000000002 33.152900000000002
|
||||
-14.32 36.168300000000002 41.5396
|
||||
-14.5837 36.054200000000002 32.595100000000002
|
||||
-14.8108 35.956000000000003 31.050000000000001
|
||||
-12.020799999999999 36.996099999999998 70
|
||||
5.5228999999999999 38.490699999999997 33.170099999999998
|
||||
6.1012300000000002 38.399099999999997 51.211100000000002
|
||||
7.1997900000000001 38.225099999999998 50.104900000000001
|
||||
0.64893599999999996 31 21.997199999999999
|
||||
0 31 22.100000000000001
|
||||
-0.64893599999999996 31 21.997199999999999
|
||||
1.2343500000000001 31 21.698899999999998
|
||||
1.6989399999999999 31 21.234300000000001
|
||||
1.99722 31 20.648900000000001
|
||||
2.1000000000000001 31 20
|
||||
-11.787800000000001 24.674299999999999 31.050000000000001
|
||||
-13.9178 36.313099999999999 33.988900000000001
|
||||
-10.9046 25.067499999999999 33.988900000000001
|
||||
-14.2759 36.184199999999997 41.586100000000002
|
||||
-12.9948 36.645400000000002 57.620100000000001
|
||||
-12.321199999999999 36.887900000000002 59.0139
|
||||
-12.020799999999999 36.996099999999998 52.819400000000002
|
||||
-12.8734 36.689100000000003 35.095100000000002
|
||||
-9.9471100000000003 25.472999999999999 40.479900000000001
|
||||
-11.2333 24.9252 39.7697
|
||||
-10.068199999999999 25.429400000000001 40.414900000000003
|
||||
-16.577100000000002 35.1905 39.7697
|
||||
-18.740200000000002 34.088299999999997 24.370999999999999
|
||||
-18.740200000000002 34.088299999999997 39.6648
|
||||
-18.0885 34.420400000000001 24.255299999999998
|
||||
-17.953800000000001 34.488999999999997 39.524999999999999
|
||||
-16.844899999999999 35.054000000000002 23.545100000000001
|
||||
3 0 2 1
|
||||
3 4 5 3
|
||||
3 6 5 4
|
||||
3 7 5 6
|
||||
3 8 9 5
|
||||
3 8 5 7
|
||||
3 3 5 10
|
||||
3 22 20 21
|
||||
3 8 23 9
|
||||
3 11 24 25
|
||||
3 7 26 8
|
||||
3 6 27 7
|
||||
3 4 28 6
|
||||
3 3 29 4
|
||||
3 30 18 17
|
||||
3 15 31 32
|
||||
3 31 36 37
|
||||
3 34 19 35
|
||||
3 16 38 33
|
||||
3 14 40 38
|
||||
3 39 12 41
|
||||
3 42 43 44
|
||||
3 44 45 41
|
||||
3 46 12 13
|
||||
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
OFF
|
||||
54 35 0
|
||||
|
||||
-42.555007934570312 -19.583858489990234 23.548229217529297
|
||||
-42.555007934570312 19.583858489990234 23.548229217529297
|
||||
-42.931419372558594 -19.638389587402344 23.76545524597168
|
||||
-42.931419372558594 19.638389587402344 23.76545524597168
|
||||
-43.321365356445312 -19.682565689086914 23.840118408203125
|
||||
-43.58544921875 19.706684112548828 23.819894790649414
|
||||
-43.839744567871094 -19.725315093994141 23.744318008422852
|
||||
-43.839744567871094 19.725315093994141 23.744318008422852
|
||||
-44.072181701660156 19.737567901611328 23.616901397705078
|
||||
-44.272682189941406 -19.742908477783203 23.443172454833984
|
||||
-44.272682189941406 19.742908477783203 23.443172454833984
|
||||
-35.752426147460938 23.839736938476562 18.138641357421875
|
||||
-36.507049560546875 -23.322196960449219 18.498517990112305
|
||||
-31.488866806030273 33.198989868164062 0.79087954759597778
|
||||
-45.971839904785156 21.947345733642578 0.36052587628364563
|
||||
-46.772842407226562 20.331201553344727 0.35106539726257324
|
||||
-48.338508605957031 16.342769622802734 0.33569896221160889
|
||||
-48.963981628417969 14.277647018432617 0.33057129383087158
|
||||
-50.32745361328125 7.5033769607543945 0.32097962498664856
|
||||
-50.589942932128906 5.1325240135192871 0.31935694813728333
|
||||
-35.191650390625 8.0233678817749023 16.466701507568359
|
||||
-34.508567810058594 12.283490180969238 16.345012664794922
|
||||
-34.134033203125 13.834349632263184 16.330089569091797
|
||||
-33.933021545410156 14.552207946777344 16.331699371337891
|
||||
-31.360790252685547 21.144365310668945 16.357900619506836
|
||||
-16.018253326416016 31.838802337646484 19.413871765136719
|
||||
-14.776437759399414 31.928308486938477 20.053590774536133
|
||||
-35.535102844238281 3.7208642959594727 16.577224731445312
|
||||
-35.398593902587891 5.877772331237793 16.529092788696289
|
||||
43.764686584472656 34.414215087890625 86.751472473144531
|
||||
44.172019958496094 34 87.843376159667969
|
||||
43.496627807617188 34 86.922248840332031
|
||||
-35.911941528320312 3.7682209014892578 18.193878173828125
|
||||
-35.808559417724609 5.9533171653747559 18.156938552856445
|
||||
-55.324134826660156 12.75 8.3038663864135742
|
||||
-50.570335388183594 12.75 3.8708794116973877
|
||||
-55.324134826660156 19.25 8.3038663864135742
|
||||
-50.570335388183594 19.25 3.8708794116973877
|
||||
-41.743515014648438 12.75 22.867301940917969
|
||||
-36.779350280761719 12.75 18.701873779296875
|
||||
-36.757293701171875 12.75 18.683547973632812
|
||||
-36.757293701171875 19.25 18.683547973632812
|
||||
-36.779350280761719 19.25 18.701873779296875
|
||||
-41.743515014648438 19.25 22.867301940917969
|
||||
-36.757297515869141 11.250000953674316 18.683549880981445
|
||||
-36.779350280761719 11.25 18.701873779296875
|
||||
-36.757297515869141 4.7500004768371582 18.683549880981445
|
||||
-36.779350280761719 4.7500004768371582 18.701873779296875
|
||||
-41.743515014648438 11.250000953674316 22.867301940917969
|
||||
-41.743515014648438 4.7500004768371582 22.867301940917969
|
||||
-55.324134826660156 4.7500004768371582 8.3038663864135742
|
||||
-50.570335388183594 4.7500004768371582 3.8708794116973877
|
||||
-55.324134826660156 11.250000953674316 8.3038663864135742
|
||||
-50.570335388183594 11.250000953674316 3.8708794116973877
|
||||
3 2 3 4
|
||||
3 6 5 7
|
||||
3 9 8 10
|
||||
3 17 22 21
|
||||
3 17 16 22
|
||||
3 16 23 22
|
||||
3 13 26 25
|
||||
3 27 19 28
|
||||
3 28 18 20
|
||||
3 15 14 24
|
||||
3 30 29 31
|
||||
3 34 38 35
|
||||
3 35 38 39
|
||||
3 41 37 40
|
||||
3 37 35 40
|
||||
3 36 42 43
|
||||
3 38 34 43
|
||||
3 34 36 43
|
||||
3 11 32 33
|
||||
3 39 45 44
|
||||
3 12 44 46
|
||||
3 39 38 45
|
||||
3 38 48 45
|
||||
3 38 0 48
|
||||
3 1 38 43
|
||||
3 1 0 38
|
||||
3 0 49 48
|
||||
3 51 49 47
|
||||
3 51 47 46
|
||||
3 44 53 46
|
||||
3 53 51 46
|
||||
3 52 44 45
|
||||
3 52 45 48
|
||||
3 49 50 48
|
||||
3 50 52 48
|
||||
|
||||
|
|
@ -0,0 +1,527 @@
|
|||
OFF
|
||||
360 163 0
|
||||
|
||||
-0.050000000699999998 -0.017913000700000001 -0.015625
|
||||
-0.043749999300000002 -0.0125000002 -0.018750000700000002
|
||||
-0.041919000400000003 0.033080998799999997 -0.041919000400000003
|
||||
-0.043719999500000002 -0.018719999099999999 -0.0131130004
|
||||
-0.050000000699999998 -0.0062500000999999999 -0.0125000002
|
||||
-0.041919000400000003 -0.0080810003000000002 -0.016919000100000001
|
||||
0.050000000699999998 0.043620001499999998 0.036230001599999999
|
||||
0.050000000699999998 0.043561998800000001 0.014023000399999999
|
||||
-0.050000000699999998 -0.018536999799999999 -0.014117999900000001
|
||||
-0.043274000299999997 0.031725998999999998 -0.0398919992
|
||||
-0.041919000400000003 -0.016919000100000001 -0.016919000100000001
|
||||
-0.050000000699999998 -0.018750000700000002 -0.0125000002
|
||||
-0.043719999500000002 -0.0131130004 -0.018719999099999999
|
||||
-0.050000000699999998 -0.014117999900000001 -0.018536999799999999
|
||||
0.050000000699999998 0.043102998300000001 0.034729998599999999
|
||||
0.050000000699999998 0.043007999700000001 0.015453999899999999
|
||||
-0.050000000699999998 0.043749999300000002 -0.037500001499999998
|
||||
-0.043719999500000002 -0.0118869999 -0.018719999099999999
|
||||
-0.043719999500000002 -0.0062799999000000004 -0.0131130004
|
||||
-0.042697001200000001 0.040972001899999999 -0.042697001200000001
|
||||
-0.042697001200000001 0.034028001099999997 -0.042697001200000001
|
||||
-0.042697001200000001 0.0323030017 -0.040972001899999999
|
||||
0.050000000699999998 0.042224999499999999 0.0334089994
|
||||
-0.050000000699999998 0.043536998299999997 -0.035881999900000003
|
||||
-0.050000000699999998 0.041919000400000003 -0.041919000400000003
|
||||
-0.038113001700000003 0.0312799998 -0.018719999099999999
|
||||
-0.038113001700000003 0.0312799998 -0.0312799998
|
||||
-0.043274000299999997 -0.0148919998 -0.018273999900000001
|
||||
-0.042697001200000001 -0.0073029999999999996 -0.015971999600000002
|
||||
-0.042697001200000001 -0.0090279998000000004 -0.017697000899999999
|
||||
-0.042697001200000001 -0.015971999600000002 -0.017697000899999999
|
||||
-0.050000000699999998 0.040624998500000002 -0.042913000999999999
|
||||
-0.050000000699999998 0.039117999399999999 -0.043536998299999997
|
||||
-0.050000000699999998 -0.015625 -0.017913000700000001
|
||||
-0.050000000699999998 0.037500001499999998 -0.03125
|
||||
0.050000000699999998 0.040624998500000002 -0.032086998200000001
|
||||
-0.050000000699999998 0.037500001499999998 -0.043749999300000002
|
||||
-0.042697001200000001 -0.017697000899999999 -0.015971999600000002
|
||||
-0.050000000699999998 0.035881999900000003 -0.031463000900000003
|
||||
-0.050000000699999998 0.035881999900000003 -0.043536998299999997
|
||||
-0.038718998400000003 0.031369999099999997 -0.018629999800000002
|
||||
-0.038718998400000003 0.031369999099999997 -0.031369999099999997
|
||||
-0.050000000699999998 0.034375000699999998 -0.042913000999999999
|
||||
0.050000000699999998 0.039117999399999999 -0.031463000900000003
|
||||
-0.050000000699999998 0.033080998799999997 -0.041919000400000003
|
||||
-0.050000000699999998 0.032086998200000001 -0.040624998500000002
|
||||
-0.043719999500000002 0.0118869999 -0.018719999099999999
|
||||
-0.050000000699999998 -0.0125000002 -0.018750000700000002
|
||||
-0.050000000699999998 0.031463000900000003 -0.039117999399999999
|
||||
-0.043719999500000002 0.036887001199999998 -0.043719999500000002
|
||||
0.050000000699999998 0.037833999799999997 -0.027458000900000001
|
||||
0.050000000699999998 0.037500001499999998 -0.03125
|
||||
-0.043719999500000002 0.036887001199999998 -0.0312799998
|
||||
-0.043719999500000002 0.038113001700000003 -0.043719999500000002
|
||||
0.050000000699999998 0.0370969996 -0.0292380005
|
||||
-0.050000000699999998 0.0125000002 -0.018750000700000002
|
||||
-0.050000000699999998 -0.016919000100000001 -0.016919000100000001
|
||||
-0.050000000699999998 0.010882000399999999 -0.018536999799999999
|
||||
-0.043274000299999997 -0.018273999900000001 -0.0148919998
|
||||
-0.043274000299999997 -0.0101079997 -0.018273999900000001
|
||||
-0.043274000299999997 0.0398919992 -0.043274000299999997
|
||||
-0.050000000699999998 -0.010882000399999999 -0.018536999799999999
|
||||
-0.043719999500000002 0.043719999500000002 -0.036887001199999998
|
||||
0.015971999600000002 0.017697000899999999 -0.0323030017
|
||||
0.015971999600000002 0.0323030017 -0.0323030017
|
||||
0.016797000499999999 -0.025195000700000001 -0.025546999599999998
|
||||
0.016797000499999999 -0.025195000700000001 -0.019218999899999999
|
||||
0.016797000499999999 -0.025112999600000002 -0.0181159992
|
||||
0.016797000499999999 -0.0249439999 -0.027458000900000001
|
||||
0.016797000499999999 -0.0248659998 -0.0170389991
|
||||
0.016797000499999999 -0.024205999400000001 -0.0292380005
|
||||
0.016797000499999999 -0.023033000500000001 -0.0307669993
|
||||
0.016797000499999999 -0.0215039998 -0.031941000400000003
|
||||
0.016797000499999999 -0.019723000000000001 -0.0326780006
|
||||
0.050000000699999998 0.0307030007 -0.032930001600000001
|
||||
0.016797000499999999 -0.017812000599999999 -0.032930001600000001
|
||||
0.016797000499999999 -0.0170389991 -0.032930001600000001
|
||||
0.016797000499999999 -0.0170389991 -0.0170389991
|
||||
0.016797000499999999 -0.0079610002999999999 -0.032930001600000001
|
||||
0.016797000499999999 -0.0079610002999999999 -0.0170389991
|
||||
0.016797000499999999 0.0079610002999999999 -0.032930001600000001
|
||||
0.016797000499999999 0.0079610002999999999 -0.0170389991
|
||||
0.016797000499999999 0.0170389991 -0.032930001600000001
|
||||
0.016797000499999999 0.0170389991 -0.0170389991
|
||||
0.016797000499999999 0.0307030007 -0.032930001600000001
|
||||
0.016797000499999999 0.031846001700000001 -0.032841000699999998
|
||||
0.016797000499999999 0.032960999800000002 -0.032575998500000002
|
||||
0.016797000499999999 0.032960999800000002 -0.0170389991
|
||||
0.016919000100000001 0.016919000100000001 -0.050000000699999998
|
||||
0.016919000100000001 0.016919000100000001 -0.033080998799999997
|
||||
0.016919000100000001 0.033080998799999997 -0.033080998799999997
|
||||
0.016919000100000001 0.041919000400000003 -0.033080998799999997
|
||||
0.016919000100000001 0.041919000400000003 -0.016919000100000001
|
||||
0.0170699991 -0.0082369995999999994 -0.032930001600000001
|
||||
0.0170699991 0.0082369995999999994 -0.032930001600000001
|
||||
0.0170699991 0.016762999800000001 -0.032930001600000001
|
||||
0.017508000100000001 -0.0245670006 -0.0162390005
|
||||
0.017550000900000001 0.041182000199999999 0.0074499999000000004
|
||||
0.017563000299999999 0.033835999700000001 -0.032232001400000002
|
||||
0.017613999500000001 0.041092999300000002 -0.017613999500000001
|
||||
0.017697000899999999 0.0323030017 -0.034028001099999997
|
||||
0.050000000699999998 0.014401000000000001 0.0184540004
|
||||
0.017697000899999999 0.034028001099999997 -0.0323030017
|
||||
0.017697000899999999 0.040972001899999999 -0.0323030017
|
||||
0.050000000699999998 0.0137449997 0.0313749984
|
||||
0.017913000700000001 0.015625 -0.050000000699999998
|
||||
0.018043000300000001 -0.024124000199999999 -0.0153879998
|
||||
0.050000000699999998 0.012891000099999999 0.018737999700000001
|
||||
0.018060000600000001 0.040355000600000003 0.0069400002000000001
|
||||
0.018123999200000001 0.034775000100000002 -0.031706001599999999
|
||||
-0.0398919992 0.031725998999999998 -0.018273999900000001
|
||||
0.018155999499999999 0.040160000299999998 -0.018155999499999999
|
||||
0.018273999900000001 0.035108 -0.031725998999999998
|
||||
0.018273999900000001 0.0398919992 -0.031725998999999998
|
||||
0.018420999899999999 -0.023491000799999998 -0.014500999800000001
|
||||
0.0184349995 0.039459999699999998 0.0065649999000000001
|
||||
0.018492000200000001 0.0357219987 -0.030960999400000001
|
||||
0.018528999800000001 0.039147999099999997 -0.018528999800000001
|
||||
0.018536999799999999 0.014117999900000001 -0.050000000699999998
|
||||
0.018629999800000002 -0.022735999900000001 -0.0137179997
|
||||
-0.043749999300000002 0.037500001499999998 -0.043749999300000002
|
||||
0.018629999800000002 0.036281000799999998 -0.031369999099999997
|
||||
0.018629999800000002 0.038718998400000003 -0.031369999099999997
|
||||
0.018666999399999998 0.038516998300000001 0.0063330000000000001
|
||||
0.0186730009 0.036520998899999997 -0.030092999299999999
|
||||
0.018719999099999999 -0.018719999099999999 -0.011892000200000001
|
||||
0.018719999099999999 0.036887001199999998 -0.0312799998
|
||||
0.018719999099999999 0.038113001700000003 -0.0312799998
|
||||
0.018721999600000001 0.038086000799999999 -0.025546999599999998
|
||||
0.050000000699999998 0.0082369995999999994 -0.032930001600000001
|
||||
0.018721999600000001 0.038086000799999999 -0.018721999600000001
|
||||
0.018726000600000001 -0.021869 -0.0130500002
|
||||
0.0187309999 0.037987999600000003 -0.026743000400000001
|
||||
0.018737999700000001 -0.019819999099999999 -0.0121139996
|
||||
-0.037500001499999998 0.03125 -0.018750000700000002
|
||||
0.018742000700000001 0.037188000999999998 -0.029075000399999999
|
||||
0.018747 0.037686999899999997 -0.0279399995
|
||||
0.018750000700000002 -0.020883999800000001 -0.0125050005
|
||||
0.018750000700000002 0.037500001499999998 -0.03125
|
||||
0.022630000500000001 0.040805000799999998 0.0071959998000000001
|
||||
0.023674000099999998 0.0412780009 0.0075210002
|
||||
-0.050000000699999998 -0.0093750003999999998 -0.017913000700000001
|
||||
0.03125 0.043749999300000002 0.0125000002
|
||||
-0.050000000699999998 -0.0064630000999999996 -0.014117999900000001
|
||||
0.03125 0.050000000699999998 0.0125000002
|
||||
0.031252000500000002 0.037645999300000003 -0.028056999700000002
|
||||
0.031252998900000002 -0.020402999599999999 -0.012306000100000001
|
||||
0.031263001300000003 0.037099000100000001 -0.029234999800000001
|
||||
0.031268000599999998 0.037978000900000003 -0.026802999899999999
|
||||
0.031277999299999998 0.038086000799999999 -0.025546999599999998
|
||||
0.031277999299999998 0.038086000799999999 -0.0062779997999999997
|
||||
0.031277999299999998 0.038086000799999999 0.0062779997999999997
|
||||
0.031279001399999999 -0.0219470002 -0.013101999600000001
|
||||
0.0312799998 -0.018719999099999999 -0.011892000200000001
|
||||
0.0312799998 0.043719999500000002 0.0118869999
|
||||
0.0312799998 0.043719999500000002 0.0131130004
|
||||
0.031351000099999998 -0.022621000200000001 -0.0136160003
|
||||
0.0313530006 0.036370001700000001 -0.030277999100000001
|
||||
-0.050000000699999998 -0.0080810003000000002 -0.016919000100000001
|
||||
0.031369999099999997 0.043630000199999998 0.011281000500000001
|
||||
0.031463000900000003 0.014117999900000001 -0.050000000699999998
|
||||
0.031463000900000003 0.050000000699999998 0.010882000399999999
|
||||
0.031463000900000003 0.050000000699999998 0.014117999900000001
|
||||
0.031470999100000001 0.039147999099999997 -0.0064710000999999998
|
||||
0.031470999100000001 0.039147999099999997 0.0064710000999999998
|
||||
0.031482998300000002 -0.023217000099999999 -0.014189000199999999
|
||||
0.031578999000000003 0.035498999099999998 -0.031160000699999999
|
||||
0.031706001599999999 -0.023758999999999999 -0.0148440003
|
||||
0.050000000699999998 -0.0082369995999999994 -0.032930001600000001
|
||||
0.031844001300000001 0.040160000299999998 -0.0068440000000000003
|
||||
0.031844001300000001 0.040160000299999998 0.0068440000000000003
|
||||
0.032024998200000002 0.034485999500000003 -0.031886998600000001
|
||||
0.032037001099999997 -0.024211000699999999 -0.015535999999999999
|
||||
0.032086998200000001 0.015625 -0.050000000699999998
|
||||
0.0323030017 -0.015971999600000002 -0.0073029999999999996
|
||||
0.0323030017 -0.015971999600000002 0.0073029999999999996
|
||||
0.0323860012 0.041092999300000002 -0.0073859998999999997
|
||||
0.0323860012 0.041092999300000002 0.0073859998999999997
|
||||
0.032460000400000001 -0.0245479997 -0.016196999699999999
|
||||
0.032680001100000002 0.0335219987 -0.032370001099999997
|
||||
0.032930001600000001 -0.016762999800000001 -0.032930001600000001
|
||||
0.032930001600000001 -0.0082369995999999994 -0.032930001600000001
|
||||
0.032930001600000001 0.0082369995999999994 -0.032930001600000001
|
||||
0.032930001600000001 0.016762999800000001 -0.032930001600000001
|
||||
0.032972000500000001 -0.024791000399999999 -0.0168079995
|
||||
0.033080998799999997 -0.016919000100000001 -0.0080810003000000002
|
||||
0.033080998799999997 -0.016919000100000001 0.0080810003000000002
|
||||
-0.043630000199999998 -0.018629999800000002 -0.013718999900000001
|
||||
0.033080998799999997 0.016919000100000001 -0.050000000699999998
|
||||
0.033080998799999997 0.041919000400000003 -0.0080810003000000002
|
||||
0.033080998799999997 0.041919000400000003 0.0080810003000000002
|
||||
0.033080998799999997 0.050000000699999998 0.0080810003000000002
|
||||
0.033236999099999998 -0.017812000599999999 -0.032930001600000001
|
||||
0.033236999099999998 -0.0170699991 -0.032930001600000001
|
||||
0.033236999099999998 -0.0079300003000000001 -0.032930001600000001
|
||||
0.033236999099999998 0.0079300003000000001 -0.032930001600000001
|
||||
0.050000000699999998 -0.016762999800000001 -0.032930001600000001
|
||||
0.033236999099999998 0.0307030007 -0.032930001600000001
|
||||
0.033578999300000002 -0.024958999799999999 -0.017366999800000001
|
||||
0.050000000699999998 -0.0177040007 -0.0090380003999999993
|
||||
0.034028001099999997 -0.017697000899999999 -0.0073029999999999996
|
||||
0.050000000699999998 -0.017812000599999999 -0.032930001600000001
|
||||
0.034028001099999997 -0.017697000899999999 0.0073029999999999996
|
||||
0.034028001099999997 0.042697001200000001 -0.0073029999999999996
|
||||
0.034028001099999997 0.042697001200000001 0.0073029999999999996
|
||||
0.034269999699999998 -0.025066999699999998 -0.017851000700000001
|
||||
0.034375000699999998 0.050000000699999998 0.0070870001999999996
|
||||
0.050000000699999998 -0.0183879994 -0.0104019996
|
||||
0.035027999400000003 -0.02513 -0.018239999199999999
|
||||
0.035108 -0.018273999900000001 -0.0067260000000000002
|
||||
0.035108 -0.018273999900000001 0.0067260000000000002
|
||||
-0.043630000199999998 -0.013718999900000001 -0.018629999800000002
|
||||
0.035108 0.043274000299999997 -0.0067260000000000002
|
||||
0.035108 0.043274000299999997 0.0067260000000000002
|
||||
0.035108 0.043274000299999997 0.018273999900000001
|
||||
0.050000000699999998 -0.018719999099999999 -0.011892000200000001
|
||||
0.035833999499999998 -0.0251630004 -0.018524000400000001
|
||||
0.035881999900000003 0.050000000699999998 0.0064630000999999996
|
||||
0.035881999900000003 0.050000000699999998 0.018536999799999999
|
||||
0.050000000699999998 -0.0204450004 -0.012321
|
||||
0.036281000799999998 -0.018629999800000002 -0.0063700001000000003
|
||||
0.050000000699999998 -0.022016000000000001 -0.01315
|
||||
0.036281000799999998 -0.018629999800000002 0.0063700001000000003
|
||||
0.050000000699999998 -0.023344999200000001 -0.0143299997
|
||||
0.036281000799999998 0.043630000199999998 -0.0063700001000000003
|
||||
0.050000000699999998 -0.024351999199999998 -0.0157929994
|
||||
0.036281000799999998 0.043630000199999998 0.0063700001000000003
|
||||
0.050000000699999998 -0.024981999800000002 -0.0174550004
|
||||
0.050000000699999998 -0.025195000700000001 -0.019218999899999999
|
||||
0.050000000699999998 -0.025195000700000001 -0.025546999599999998
|
||||
0.036281000799999998 0.043630000199999998 0.018629999800000002
|
||||
0.036665998399999997 -0.025177000099999999 -0.018694000299999999
|
||||
0.050000000699999998 -0.03125 -0.0125000002
|
||||
0.036887001199999998 -0.018719999099999999 -0.0062799999000000004
|
||||
0.036887001199999998 -0.018719999099999999 0.0062799999000000004
|
||||
0.050000000699999998 -0.031463000900000003 0.035881999900000003
|
||||
0.036887001199999998 0.043719999500000002 -0.0062799999000000004
|
||||
0.036887001199999998 0.043719999500000002 0.0062799999000000004
|
||||
0.050000000699999998 -0.031463000900000003 -0.010882000399999999
|
||||
0.050000000699999998 -0.031463000900000003 -0.014117999900000001
|
||||
0.036887001199999998 0.043719999500000002 0.018719999099999999
|
||||
0.037500001499999998 -0.025180000800000001 -0.018750000700000002
|
||||
0.037500001499999998 -0.018750000700000002 -0.0062500000999999999
|
||||
0.050000000699999998 -0.032086998200000001 0.034375000699999998
|
||||
0.037500001499999998 -0.018750000700000002 0.0062500000999999999
|
||||
0.037500001499999998 0.043749999300000002 -0.0062500000999999999
|
||||
0.050000000699999998 -0.032086998200000001 -0.015625
|
||||
0.038113001700000003 -0.018719999099999999 0.0062799999000000004
|
||||
0.050000000699999998 -0.033080998799999997 0.033080998799999997
|
||||
0.038113001700000003 0.043719999500000002 -0.0062799999000000004
|
||||
0.038334000899999998 -0.025177000099999999 -0.018694000299999999
|
||||
0.050000000699999998 -0.033080998799999997 -0.016919000100000001
|
||||
0.050000000699999998 -0.034375000699999998 0.032086998200000001
|
||||
0.039165999700000002 -0.0251630004 -0.018524000400000001
|
||||
0.0398919992 -0.018273999900000001 -0.0067260000000000002
|
||||
0.050000000699999998 -0.034375000699999998 -0.017913000700000001
|
||||
0.0398919992 -0.018273999900000001 0.0067260000000000002
|
||||
0.039971999799999998 -0.02513 -0.018239999199999999
|
||||
0.050000000699999998 -0.035881999900000003 0.031463000900000003
|
||||
-0.050000000699999998 -0.0070870001999999996 -0.015625
|
||||
0.040729999500000003 -0.025066999699999998 -0.017851000700000001
|
||||
0.050000000699999998 -0.035881999900000003 -0.018536999799999999
|
||||
0.050000000699999998 -0.035881999900000003 -0.031463000900000003
|
||||
0.040972001899999999 -0.017697000899999999 -0.0073029999999999996
|
||||
0.040972001899999999 -0.017697000899999999 0.0073029999999999996
|
||||
0.050000000699999998 -0.037500001499999998 0.03125
|
||||
0.041420999899999998 -0.024958999799999999 -0.017366999800000001
|
||||
0.041763000199999997 -0.017812000599999999 -0.032930001600000001
|
||||
0.050000000699999998 -0.037500001499999998 -0.018750000700000002
|
||||
0.050000000699999998 -0.037500001499999998 -0.03125
|
||||
0.041763000199999997 -0.0079300003000000001 -0.032930001600000001
|
||||
0.050000000699999998 -0.039103001399999997 -0.018541000799999999
|
||||
0.041763000199999997 0.0079300003000000001 -0.032930001600000001
|
||||
0.050000000699999998 -0.039117999399999999 0.031463000900000003
|
||||
0.041763000199999997 0.0170699991 -0.032930001600000001
|
||||
0.041763000199999997 0.0307030007 -0.032930001600000001
|
||||
0.050000000699999998 -0.039117999399999999 -0.031463000900000003
|
||||
0.041919000400000003 -0.041919000400000003 0.033080998799999997
|
||||
0.041919000400000003 -0.033080998799999997 0.033080998799999997
|
||||
0.041919000400000003 -0.016919000100000001 -0.0080810003000000002
|
||||
0.050000000699999998 -0.040624998500000002 0.032086998200000001
|
||||
0.041919000400000003 -0.016919000100000001 0.0080810003000000002
|
||||
0.042027998699999999 -0.024791000399999999 -0.0168079995
|
||||
0.042070001400000001 -0.016762999800000001 -0.032930001600000001
|
||||
0.042070001400000001 -0.0082369995999999994 -0.032930001600000001
|
||||
0.042070001400000001 0.0082369995999999994 -0.032930001600000001
|
||||
0.050000000699999998 -0.041919000400000003 0.033080998799999997
|
||||
0.042070001400000001 0.016762999800000001 -0.032930001600000001
|
||||
0.042539998900000001 -0.0245479997 -0.016196999699999999
|
||||
0.042697001200000001 -0.042697001200000001 0.034028001099999997
|
||||
0.042697001200000001 -0.040972001899999999 0.0323030017
|
||||
0.042697001200000001 -0.034028001099999997 0.0323030017
|
||||
0.042697001200000001 -0.0323030017 0.034028001099999997
|
||||
0.050000000699999998 -0.042913000999999999 0.034375000699999998
|
||||
0.042697001200000001 -0.015971999600000002 -0.0073029999999999996
|
||||
0.042697001200000001 -0.015971999600000002 0.0073029999999999996
|
||||
0.042697001200000001 -0.0073029999999999996 -0.034028001099999997
|
||||
0.042697001200000001 0.0073029999999999996 -0.034028001099999997
|
||||
-0.043274000299999997 0.035108 -0.043274000299999997
|
||||
0.042962998199999998 -0.024211000699999999 -0.015535999999999999
|
||||
0.050000000699999998 -0.043536998299999997 0.035881999900000003
|
||||
0.043274000299999997 -0.043274000299999997 0.035108
|
||||
0.043274000299999997 -0.0398919992 0.031725998999999998
|
||||
0.043274000299999997 -0.035108 0.031725998999999998
|
||||
0.043274000299999997 -0.031725998999999998 0.035108
|
||||
0.043274000299999997 -0.0067260000000000002 -0.035108
|
||||
0.043274000299999997 0.0067260000000000002 -0.035108
|
||||
-0.043630000199999998 0.036281000799999998 -0.043630000199999998
|
||||
0.043294001399999997 -0.023758999999999999 -0.0148440003
|
||||
0.043517001 -0.023217000099999999 -0.014189000199999999
|
||||
0.0435290001 0.039147999099999997 -0.018528999800000001
|
||||
0.043630000199999998 -0.038718998400000003 0.031369999099999997
|
||||
0.043630000199999998 -0.036281000799999998 0.031369999099999997
|
||||
0.043630000199999998 -0.0063700001000000003 -0.036281000799999998
|
||||
0.043630000199999998 0.0063700001000000003 -0.036281000799999998
|
||||
0.043630000199999998 0.038718998400000003 -0.031369999099999997
|
||||
0.043648999199999997 -0.022621000200000001 -0.0136160003
|
||||
0.043719999500000002 -0.038113001700000003 0.0312799998
|
||||
0.043719999500000002 -0.036887001199999998 0.0312799998
|
||||
-0.043630000199999998 0.038718998400000003 -0.043630000199999998
|
||||
0.043719999500000002 0.038113001700000003 -0.0312799998
|
||||
0.043721999999999997 0.038086000799999999 -0.025546999599999998
|
||||
0.043721999999999997 0.038086000799999999 -0.018721999600000001
|
||||
0.043749999300000002 -0.037500001499999998 0.03125
|
||||
-0.037500001499999998 0.03125 -0.03125
|
||||
-0.038113001700000003 0.0312799998 -0.018719999099999999
|
||||
-0.042697001200000001 -0.0090279998000000004 -0.017697000899999999
|
||||
-0.038718998400000003 0.031369999099999997 -0.018629999800000002
|
||||
0.050000000699999998 0.039117999399999999 -0.031463000900000003
|
||||
0.016919000100000001 0.033080998799999997 -0.033080998799999997
|
||||
0.016919000100000001 0.033080998799999997 -0.033080998799999997
|
||||
0.017563000299999999 0.033835999700000001 -0.032232001400000002
|
||||
0.017613999500000001 0.041092999300000002 -0.017613999500000001
|
||||
0.017697000899999999 0.034028001099999997 -0.0323030017
|
||||
0.018123999200000001 0.034775000100000002 -0.031706001599999999
|
||||
0.018155999499999999 0.040160000299999998 -0.018155999499999999
|
||||
0.018273999900000001 0.035108 -0.031725998999999998
|
||||
0.018492000200000001 0.0357219987 -0.030960999400000001
|
||||
0.018528999800000001 0.039147999099999997 -0.018528999800000001
|
||||
0.018629999800000002 0.036281000799999998 -0.031369999099999997
|
||||
0.0186730009 0.036520998899999997 -0.030092999299999999
|
||||
0.018719999099999999 0.036887001199999998 -0.0312799998
|
||||
-0.050000000699999998 -0.0080810003000000002 -0.016919000100000001
|
||||
0.031725998999999998 0.043274000299999997 0.0101079997
|
||||
0.031844001300000001 0.040160000299999998 -0.0068440000000000003
|
||||
0.032086998200000001 0.015625 -0.050000000699999998
|
||||
0.0323860012 0.041092999300000002 -0.0073859998999999997
|
||||
0.033080998799999997 -0.016919000100000001 0.0080810003000000002
|
||||
0.033080998799999997 0.041919000400000003 -0.0080810003000000002
|
||||
0.033080998799999997 0.041919000400000003 0.0080810003000000002
|
||||
0.034028001099999997 0.042697001200000001 -0.0073029999999999996
|
||||
0.034028001099999997 0.042697001200000001 0.0073029999999999996
|
||||
0.035108 0.043274000299999997 -0.0067260000000000002
|
||||
0.036887001199999998 0.043719999500000002 -0.0062799999000000004
|
||||
0.037500001499999998 0.043749999300000002 0.0062500000999999999
|
||||
0.050000000699999998 -0.035881999900000003 -0.018536999799999999
|
||||
0.050000000699999998 -0.037500001499999998 -0.018750000700000002
|
||||
0.043274000299999997 -0.0067260000000000002 -0.035108
|
||||
0.043630000199999998 -0.0063700001000000003 -0.036281000799999998
|
||||
0.043719999500000002 -0.0062799999000000004 -0.036887001199999998
|
||||
3 217 226 237
|
||||
3 213 226 217
|
||||
3 206 191 204
|
||||
3 191 190 204
|
||||
3 159 343 161
|
||||
3 159 161 154
|
||||
3 155 142 144
|
||||
3 155 144 162
|
||||
3 214 218 230
|
||||
3 218 240 230
|
||||
3 55 57 46
|
||||
3 22 15 14
|
||||
3 76 65 68
|
||||
3 70 76 68
|
||||
3 75 72 73
|
||||
3 67 77 69
|
||||
3 76 71 75
|
||||
3 81 79 78
|
||||
3 43 35 50
|
||||
3 51 328 54
|
||||
3 182 94 80
|
||||
3 194 195 80
|
||||
3 78 93 181
|
||||
3 180 192 193
|
||||
3 283 267 201
|
||||
3 196 283 201
|
||||
3 275 274 287
|
||||
3 74 275 287
|
||||
3 197 84 183
|
||||
3 84 82 95
|
||||
3 359 313 314
|
||||
3 7 6 14
|
||||
3 321 315 320
|
||||
3 310 315 322
|
||||
3 87 84 85
|
||||
3 84 83 82
|
||||
3 132 149 128
|
||||
3 132 136 148
|
||||
3 136 135 145
|
||||
3 135 124 147
|
||||
3 124 116 157
|
||||
3 116 109 166
|
||||
3 109 98 171
|
||||
3 98 86 179
|
||||
3 168 270 284
|
||||
3 272 129 285
|
||||
3 67 69 198
|
||||
3 205 208 67
|
||||
3 67 208 216
|
||||
3 231 241 66
|
||||
3 241 250 228
|
||||
3 228 250 253
|
||||
3 257 228 253
|
||||
3 227 260 266
|
||||
3 282 225 227
|
||||
3 225 288 299
|
||||
3 308 223 225
|
||||
3 308 309 223
|
||||
3 303 312 258
|
||||
3 303 252 291
|
||||
3 248 278 291
|
||||
3 292 278 248
|
||||
3 243 235 304
|
||||
3 221 223 316
|
||||
3 114 119 165
|
||||
3 119 131 156
|
||||
3 131 137 152
|
||||
3 137 133 146
|
||||
3 133 125 153
|
||||
3 172 106 167
|
||||
3 178 96 172
|
||||
3 178 184 96
|
||||
3 66 241 228
|
||||
3 358 305 306
|
||||
3 357 296 297
|
||||
3 164 151 150
|
||||
3 163 169 164
|
||||
3 344 176 170
|
||||
3 346 189 177
|
||||
3 348 203 349
|
||||
3 350 212 351
|
||||
3 352 224 213
|
||||
3 213 224 226
|
||||
3 224 236 237
|
||||
3 353 245 354
|
||||
3 354 245 249
|
||||
3 301 300 293
|
||||
3 286 277 289
|
||||
3 290 280 302
|
||||
3 317 311 273
|
||||
3 317 265 323
|
||||
3 258 318 265
|
||||
3 45 48 9
|
||||
3 21 2 44
|
||||
3 44 2 20
|
||||
3 298 39 42
|
||||
3 298 307 39
|
||||
3 120 36 49
|
||||
3 281 263 264
|
||||
3 264 254 256
|
||||
3 247 242 244
|
||||
3 234 244 233
|
||||
3 234 220 222
|
||||
3 186 202 200
|
||||
3 175 347 185
|
||||
3 175 185 174
|
||||
3 53 319 32
|
||||
3 19 31 60
|
||||
3 19 24 31
|
||||
3 34 52 38
|
||||
3 16 62 23
|
||||
3 130 122 128
|
||||
3 132 128 127
|
||||
3 138 136 127
|
||||
3 209 202 210
|
||||
3 220 209 222
|
||||
3 279 295 294
|
||||
3 138 126 135
|
||||
3 341 121 340
|
||||
3 339 112 337
|
||||
3 336 102 334
|
||||
3 333 90 331
|
||||
3 271 276 268
|
||||
3 86 64 87
|
||||
3 130 117 122
|
||||
3 338 111 113
|
||||
3 335 99 103
|
||||
3 332 92 91
|
||||
3 356 269 261
|
||||
3 229 355 262
|
||||
3 255 229 228
|
||||
3 251 228 246
|
||||
3 239 227 225
|
||||
3 246 227 239
|
||||
3 238 223 221
|
||||
3 158 28 259
|
||||
3 143 18 4
|
||||
3 232 223 238
|
||||
3 215 207 219
|
||||
3 207 199 219
|
||||
3 11 3 8
|
||||
3 5 342 29
|
||||
3 326 141 59
|
||||
3 47 17 61
|
||||
3 1 47 12
|
||||
3 27 211 13
|
||||
3 27 13 33
|
||||
3 56 10 30
|
||||
3 37 10 56
|
||||
3 0 8 58
|
||||
3 3 187 8
|
||||
3 140 97 139
|
||||
3 118 173 160
|
||||
3 108 115 139
|
||||
3 115 123 139
|
||||
3 107 101 104
|
||||
3 88 345 105
|
||||
3 88 188 345
|
||||
3 25 134 324
|
||||
3 40 325 26
|
||||
3 110 327 41
|
||||
3 64 329 63
|
||||
3 330 100 89
|
||||
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
OFF
|
||||
24 8 0
|
||||
|
||||
-0.038718998400000003 0.031369999099999997 -0.018629999800000002
|
||||
-0.038718998400000003 0.031369999099999997 -0.031369999099999997
|
||||
0.015971999600000002 0.017697000899999999 -0.0323030017
|
||||
0.015971999600000002 0.0323030017 -0.0323030017
|
||||
0.016797000499999999 0.0170389991 -0.032930001600000001
|
||||
0.016797000499999999 0.0170389991 -0.0170389991
|
||||
0.016797000499999999 0.0307030007 -0.032930001600000001
|
||||
0.016797000499999999 0.031846001700000001 -0.032841000699999998
|
||||
0.016797000499999999 0.032960999800000002 -0.032575998500000002
|
||||
0.016919000100000001 0.016919000100000001 -0.033080998799999997
|
||||
0.016919000100000001 0.033080998799999997 -0.033080998799999997
|
||||
0.0170699991 0.016762999800000001 -0.032930001600000001
|
||||
0.017697000899999999 0.017697000899999999 -0.034028001099999997
|
||||
0.017697000899999999 0.0323030017 -0.034028001099999997
|
||||
-0.0398919992 0.031725998999999998 -0.018273999900000001
|
||||
0.0323030017 0.017697000899999999 -0.034028001099999997
|
||||
0.032680001100000002 0.0335219987 -0.032370001099999997
|
||||
0.032930001600000001 0.016762999800000001 -0.032930001600000001
|
||||
0.033309001499999998 0.031690999900000003 -0.032862998499999997
|
||||
0.016797000499999999 0.0307030007 -0.032930001600000001
|
||||
0.016797000499999999 0.0307030007 -0.032930001600000001
|
||||
0.016919000100000001 0.016919000100000001 -0.033080998799999997
|
||||
0.016919000100000001 0.033080998799999997 -0.033080998799999997
|
||||
0.017563000299999999 0.033835999700000001 -0.032232001400000002
|
||||
3 17 6 11
|
||||
3 20 5 4
|
||||
3 23 8 16
|
||||
3 7 19 18
|
||||
3 12 15 9
|
||||
3 14 0 1
|
||||
3 3 10 2
|
||||
3 22 13 21
|
||||
|
||||
|
|
@ -117,14 +117,14 @@ Qt is a cross-platform application and UI framework.
|
|||
The component `CGAL_Qt6` is essential to run the \cgal demos and basic viewers.
|
||||
It requires \qt6 installed on your system.
|
||||
In case \qt is not yet installed on your system, you can download
|
||||
it from <A HREF="https://www.qt-project.org/">`https://www.qt-project.org/`</A>.
|
||||
it from <A HREF="https://contribute.qt-project.org/">`https://contribute.qt-project.org/`</A>.
|
||||
|
||||
The exhaustive list of \qt6 components used in demos is:
|
||||
`Core`, `Gui`, `Help`, `OpenGL`, `OpenGLWidgets`, `Qml`, `Svg`, `Widgets`,
|
||||
`WebSockets`, `Network`, and `qcollectiongenerator` (with `sqlite` driver plugin).
|
||||
|
||||
\subsection thirdpartyEigen Eigen
|
||||
<b>Version 3.3.7 or later</b>
|
||||
<b>Version 3.3.7 or later (including Eigen3 5.0.0)</b>
|
||||
|
||||
\eigen is a `C++` template library for linear algebra. \eigen supports all
|
||||
matrix sizes, various matrix decomposition methods and sparse linear solvers.
|
||||
|
|
@ -138,7 +138,7 @@ Overview</a> page. In order to use Eigen in \cgal programs, the
|
|||
executables should be linked with the CMake imported target
|
||||
`CGAL::Eigen3_support` provided in `CGAL_Eigen3_support.cmake`.
|
||||
|
||||
The \eigen web site is <A HREF="https://eigen.tuxfamily.org/index.php?title=Main_Page">`https://eigen.tuxfamily.org`</A>.
|
||||
The \eigen web site is <A HREF="https://libeigen.gitlab.io/">`https://libeigen.gitlab.io/`</A>.
|
||||
|
||||
\subsection thirdpartyOpenGR OpenGR
|
||||
|
||||
|
|
@ -167,17 +167,6 @@ Alternatively, version 1.3.1 of \libpointmatcher is supported with version 3.3.7
|
|||
`https://github.com/ethz-asl/libpointmatcher/blob/master/doc/Compilation.md`:`NABO_INCLUDE_DIR` becomes `libnabo_INCLUDE_DIRS`
|
||||
and `NABO_LIBRARY` becomes `libnabo_LIBRARIES` in the "Build libpointmatcher" section.
|
||||
|
||||
\subsection thirdpartyLeda LEDA
|
||||
<b>Version 6.2 or later</b>
|
||||
|
||||
\leda is a library of efficient data structures and
|
||||
algorithms. Like \core, \leda offers a real number data type.
|
||||
|
||||
In \cgal this library is optional, and its number types can
|
||||
be used as an alternative to \gmp, \mpfr, and \core.
|
||||
|
||||
Free and commercial editions of \leda are available from <A HREF="https://www.algorithmic-solutions.com">`https://www.algorithmic-solutions.com`</A>.
|
||||
|
||||
\subsection thirdpartyMPFI Multiple Precision Floating-point Interval (MPFI)
|
||||
<b>Version 1.4 or later</b>
|
||||
|
||||
|
|
@ -265,7 +254,7 @@ vcpkg install suitesparse
|
|||
\subsection thirdpartyMETIS METIS
|
||||
<b>Version 5.1 or later</b>
|
||||
|
||||
\metis is a library developed by the <A HREF="http://glaros.dtc.umn.edu/gkhome/">Karypis Lab</A>
|
||||
\metis is a library developed by the <A HREF="https://github.com/KarypisLab/">Karypis Lab</A>
|
||||
and designed to partition graphs and produce fill-reducing matrix orderings.
|
||||
|
||||
\cgal offers wrappers around some of the methods of the \metis library
|
||||
|
|
@ -274,7 +263,7 @@ to allow the partitioning of graphs that are models of the concepts of the
|
|||
and, by extension, of surface meshes (see Section \ref BGLPartitioning of the package \ref PkgBGL).
|
||||
|
||||
More information is available on the METIS library
|
||||
at <A HREF="http://glaros.dtc.umn.edu/gkhome/metis/metis/overview">`http://glaros.dtc.umn.edu/gkhome/metis/metis/overview`</A>.
|
||||
at <A HREF="https://github.com/KarypisLab/METIS">`https://github.com/KarypisLab/METIS`</A>.
|
||||
|
||||
\subsection thirdpartyzlib zlib
|
||||
|
||||
|
|
|
|||
|
|
@ -83,12 +83,12 @@ a newline character and each coordinate separated by a white
|
|||
space. Other formats available are 'OFF', 'PLY' and 'LAS'. \cgal
|
||||
provides functions to read such formats:
|
||||
|
||||
- `read_XYZ()`
|
||||
- `read_OFF()`
|
||||
- `read_PLY()`
|
||||
- `read_PLY_with_properties()` to read additional PLY properties
|
||||
- `read_LAS()`
|
||||
- `read_LAS_with_properties()` to read additional LAS properties
|
||||
- `CGAL::IO::read_XYZ()`
|
||||
- `CGAL::IO::read_OFF()`
|
||||
- `CGAL::IO::read_PLY()`
|
||||
- `CGAL::IO::read_PLY_with_properties()` to read additional PLY properties
|
||||
- `CGAL::IO::read_LAS()`
|
||||
- `CGAL::IO::read_LAS_with_properties()` to read additional LAS properties
|
||||
|
||||
\cgal also provides a dedicated container `CGAL::Point_set_3` to
|
||||
handle point sets with additional properties such as normal
|
||||
|
|
|
|||
|
|
@ -123,11 +123,11 @@ In the example below, we can see a query where:
|
|||
</center>
|
||||
|
||||
|
||||
\subsection subsecFrechetDistanceImageCredits Image Credits
|
||||
\section subsecFrechetDistanceImageCredits Image Credits
|
||||
|
||||
The character image is a visualization of two data points from the <a href="https://archive.ics.uci.edu/dataset/175/character+trajectories">Character Trajectories</a> data set.
|
||||
|
||||
\subsection subsecFrechetDistanceImplementation Implementation History
|
||||
\section subsecFrechetDistanceImplementation Implementation History
|
||||
|
||||
An initial version using floating point arithmetic was developed by the authors
|
||||
while working at the Max-Planck Institute for Informatics in Saarbrücken, Germany.
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ project( Frechet_distance_Examples )
|
|||
find_package(CGAL REQUIRED QUIET OPTIONAL_COMPONENTS Core )
|
||||
|
||||
|
||||
find_package(Eigen3 3.1.0 QUIET) #(requires 3.1.0 or greater)
|
||||
find_package(Eigen3 QUIET)
|
||||
include(CGAL_Eigen3_support)
|
||||
|
||||
create_single_source_cgal_program( "Frechet_distance_2.cpp" )
|
||||
|
|
|
|||
|
|
@ -6,11 +6,12 @@ project( Frechet_distance_Tests )
|
|||
|
||||
find_package(CGAL REQUIRED)
|
||||
|
||||
find_package(Eigen3 QUIET)
|
||||
|
||||
include(CGAL_Eigen3_support)
|
||||
|
||||
create_single_source_cgal_program( "Frechet-IssueOct25.cpp" )
|
||||
|
||||
find_package(Eigen3 3.1.0 QUIET) #(3.1.0 or greater)
|
||||
include(CGAL_Eigen3_support)
|
||||
if(TARGET CGAL::Eigen3_support)
|
||||
create_single_source_cgal_program( "Frechet_distance_test.cpp" )
|
||||
target_link_libraries(Frechet_distance_test PRIVATE CGAL::Eigen3_support)
|
||||
|
|
|
|||
|
|
@ -6,8 +6,7 @@ project( classical_Frechet_distance )
|
|||
|
||||
find_package(CGAL REQUIRED)
|
||||
|
||||
|
||||
find_package(Eigen3 3.1.0 QUIET) #(requires 3.1.0 or greater)
|
||||
find_package(Eigen3 QUIET)
|
||||
include(CGAL_Eigen3_support)
|
||||
|
||||
create_single_source_cgal_program("Compute_classical_Frechet_distance_3.cpp")
|
||||
|
|
|
|||
|
|
@ -28,8 +28,9 @@ create_single_source_cgal_program("random_segments1.cpp")
|
|||
create_single_source_cgal_program("random_segments2.cpp")
|
||||
create_single_source_cgal_program("sphere_d.cpp")
|
||||
|
||||
find_package(Eigen3 3.1.0 QUIET) #(3.1.0 or greater)
|
||||
find_package(Eigen3 QUIET)
|
||||
include(CGAL_Eigen3_support)
|
||||
|
||||
if(TARGET CGAL::Eigen3_support)
|
||||
create_single_source_cgal_program("random_points_in_tetrahedral_mesh_3.cpp")
|
||||
target_link_libraries(random_points_in_tetrahedral_mesh_3 PRIVATE CGAL::Eigen3_support)
|
||||
|
|
|
|||
|
|
@ -15,8 +15,9 @@ create_single_source_cgal_program("test_tetrahedron_3.cpp")
|
|||
create_single_source_cgal_program("test_triangle_2.cpp")
|
||||
create_single_source_cgal_program("test_triangle_3.cpp")
|
||||
|
||||
find_package(Eigen3 3.1.0 QUIET) #(3.1.0 or greater)
|
||||
find_package(Eigen3 QUIET)
|
||||
include(CGAL_Eigen3_support)
|
||||
|
||||
if(TARGET CGAL::Eigen3_support)
|
||||
create_single_source_cgal_program("generic_random_test.cpp")
|
||||
target_link_libraries(generic_random_test PRIVATE CGAL::Eigen3_support)
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ find_package(CGAL REQUIRED OPTIONAL_COMPONENTS Qt6)
|
|||
|
||||
find_package(Qt6 QUIET COMPONENTS Widgets)
|
||||
|
||||
find_package(Eigen3 3.1.91 QUIET) #(requires 3.1.91 or greater)
|
||||
find_package(Eigen3 QUIET)
|
||||
include(CGAL_Eigen3_support)
|
||||
|
||||
if(NOT TARGET CGAL::Eigen3_support)
|
||||
|
|
|
|||
|
|
@ -6,8 +6,9 @@ project(Polygon_Demo)
|
|||
|
||||
find_package(CGAL REQUIRED OPTIONAL_COMPONENTS Qt6 Core)
|
||||
|
||||
find_package(Eigen3 3.1.0 QUIET) #(requires 3.1.0 or greater)
|
||||
find_package(Eigen3 QUIET)
|
||||
include(CGAL_Eigen3_support)
|
||||
|
||||
if(NOT TARGET CGAL::Eigen3_support)
|
||||
message("NOTICE: This demo requires the Eigen library, and will not be compiled.")
|
||||
return()
|
||||
|
|
|
|||
|
|
@ -13,12 +13,12 @@
|
|||
\cgalPkgPicture{detail.png}
|
||||
\cgalPkgSummaryBegin
|
||||
\cgalPkgAuthors{Andreas Fabri and Laurent Rineau}
|
||||
\cgalPkgDesc{This package provides classes for displaying \cgal objects and data structures in the <A HREF="https://doc.qt.io/qt-6/graphicsview.html">Qt 5 Graphics View Framework</A>.}
|
||||
\cgalPkgDesc{This package provides classes for displaying \cgal objects and data structures in the <A HREF="https://doc.qt.io/qt-6/graphicsview.html">Qt 6 Graphics View Framework</A>.}
|
||||
\cgalPkgManuals{Chapter_CGAL_and_the_Qt_Graphics_View_Framework,PkgGraphicsViewRef}
|
||||
\cgalPkgSummaryEnd
|
||||
\cgalPkgShortInfoBegin
|
||||
\cgalPkgSince{3.4}
|
||||
\cgalPkgDependsOn{\qt 5}
|
||||
\cgalPkgDependsOn{\qt 6}
|
||||
\cgalPkgBib{cgal:fr-cqgvf}
|
||||
\cgalPkgLicense{\ref licensesGPL "GPL"}
|
||||
\cgalPkgShortInfoEnd
|
||||
|
|
|
|||
|
|
@ -221,7 +221,10 @@ void
|
|||
DemosMainWindow::popupAboutBox(QString title, QString html_resource_name)
|
||||
{
|
||||
QFile about_CGAL(html_resource_name);
|
||||
about_CGAL.open(QIODevice::ReadOnly);
|
||||
if (!about_CGAL.open(QIODevice::ReadOnly)) {
|
||||
QMessageBox::warning(this, tr("Error"), tr("Could not open resource file: %1").arg(html_resource_name));
|
||||
return;
|
||||
}
|
||||
QString about_CGAL_txt = QTextStream(&about_CGAL).readAll();
|
||||
#ifdef CGAL_VERSION_STR
|
||||
QString cgal_version(CGAL_VERSION_STR);
|
||||
|
|
|
|||
|
|
@ -7,8 +7,9 @@ project(Heat_method_3_Examples)
|
|||
# CGAL and its components
|
||||
find_package(CGAL REQUIRED)
|
||||
|
||||
find_package(Eigen3 3.3.0 QUIET)
|
||||
find_package(Eigen3 QUIET)
|
||||
include(CGAL_Eigen3_support)
|
||||
|
||||
if(NOT TARGET CGAL::Eigen3_support)
|
||||
message("NOTICE: These examples require the Eigen library (3.3 or greater), and will not be compiled.")
|
||||
return()
|
||||
|
|
|
|||
|
|
@ -7,8 +7,9 @@ project(Heat_method_3_Tests)
|
|||
# CGAL and its components
|
||||
find_package(CGAL REQUIRED)
|
||||
|
||||
find_package(Eigen3 3.3.0 QUIET)
|
||||
find_package(Eigen3 QUIET)
|
||||
include(CGAL_Eigen3_support)
|
||||
|
||||
if(NOT TARGET CGAL::Eigen3_support)
|
||||
message("NOTICE: These tests require the Eigen library (3.3 or greater), and will not be compiled.")
|
||||
return()
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -3,5 +3,5 @@ if(CERES_FOUND AND NOT TARGET CGAL::Ceres_support)
|
|||
set_target_properties(CGAL::Ceres_support PROPERTIES
|
||||
INTERFACE_COMPILE_DEFINITIONS "CGAL_PMP_USE_CERES_SOLVER"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${CERES_INCLUDE_DIRS}"
|
||||
INTERFACE_LINK_LIBRARIES "ceres")
|
||||
INTERFACE_LINK_LIBRARIES "Ceres::ceres")
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -1,3 +1,10 @@
|
|||
if((EIGEN3_FOUND OR Eigen3_FOUND) AND NOT TARGET CGAL::Eigen3_support)
|
||||
if ("${Eigen3_VERSION}" VERSION_LESS "3.3.7")
|
||||
set (EIGEN3_FOUND 0)
|
||||
find_package(Eigen3 3.3.7 QUIET) # (3.3.7 or greater)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if((EIGEN3_FOUND OR Eigen3_FOUND) AND NOT TARGET CGAL::Eigen3_support)
|
||||
if(NOT TARGET Threads::Threads)
|
||||
find_package(Threads REQUIRED)
|
||||
|
|
|
|||
|
|
@ -554,6 +554,11 @@ namespace cpp11{
|
|||
/// @}
|
||||
#include <CGAL/license/lgpl.h>
|
||||
|
||||
#ifdef __STDC_LIB_EXT1__
|
||||
# define __STDC_WANT_LIB_EXT1__ 1
|
||||
# include <stdlib.h> // for getenv_s
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------//
|
||||
// Function to define data directory
|
||||
//----------------------------------------------------------------------//
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ project( Isosurfacing_3_benchmark )
|
|||
|
||||
find_package(CGAL REQUIRED)
|
||||
|
||||
find_package(Eigen3 3.1.0 QUIET) #(3.1.0 or greater)
|
||||
find_package(Eigen3 QUIET)
|
||||
include(CGAL_Eigen3_support)
|
||||
|
||||
find_package(TBB)
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ project( Isosurfacing_3_Examples )
|
|||
|
||||
find_package(CGAL REQUIRED COMPONENTS ImageIO)
|
||||
|
||||
find_package(Eigen3 3.1.0 QUIET) #(3.1.0 or greater)
|
||||
find_package(Eigen3 QUIET)
|
||||
include(CGAL_Eigen3_support)
|
||||
|
||||
find_package(TBB QUIET)
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ project(Isosurfacing_3_Tests)
|
|||
|
||||
find_package(CGAL REQUIRED)
|
||||
|
||||
find_package(Eigen3 3.1.0 QUIET) #(3.1.0 or greater)
|
||||
find_package(Eigen3 QUIET)
|
||||
include(CGAL_Eigen3_support)
|
||||
|
||||
find_package(TBB QUIET)
|
||||
|
|
|
|||
|
|
@ -7,8 +7,9 @@ project(Jet_fitting_3_Examples)
|
|||
find_package(CGAL REQUIRED)
|
||||
|
||||
# use Eigen
|
||||
find_package(Eigen3 3.1.0 QUIET) #(requires 3.1.0 or greater)
|
||||
find_package(Eigen3 QUIET)
|
||||
include(CGAL_Eigen3_support)
|
||||
|
||||
if(TARGET CGAL::Eigen3_support)
|
||||
|
||||
# Link with Boost.ProgramOptions (optional)
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue