mirror of https://github.com/CGAL/cgal
Compare commits
176 Commits
5ecfbaa008
...
e11bdb9756
| Author | SHA1 | Date |
|---|---|---|
|
|
e11bdb9756 | |
|
|
26a5fc70e4 | |
|
|
39dd7c5028 | |
|
|
def6c38d76 | |
|
|
f503ce9359 | |
|
|
be305f320f | |
|
|
b8db056348 | |
|
|
18ee149f2e | |
|
|
15d96571a1 | |
|
|
06996f077f | |
|
|
5f8a8fe359 | |
|
|
543d424f58 | |
|
|
8e3a59a27b | |
|
|
40ac746be7 | |
|
|
9d28892e5f | |
|
|
dbcace69e6 | |
|
|
bac686d05b | |
|
|
30f63794c3 | |
|
|
92a896abb9 | |
|
|
1b3556184a | |
|
|
d14619c335 | |
|
|
50a187db38 | |
|
|
95a315335f | |
|
|
ff5166fbee | |
|
|
9f2fcb5e28 | |
|
|
85ef57ffa1 | |
|
|
aefbc23955 | |
|
|
fdf06fe969 | |
|
|
c8099415d4 | |
|
|
da0f634cb2 | |
|
|
7bf5687d5d | |
|
|
a0c32277d0 | |
|
|
1069678f36 | |
|
|
cda931ec46 | |
|
|
884e9fc4ee | |
|
|
cee9effe09 | |
|
|
eb14bf2a17 | |
|
|
e98fa21cc9 | |
|
|
e0a720452d | |
|
|
c856e40662 | |
|
|
ef6f9d8c3c | |
|
|
18e5836373 | |
|
|
3e1a8c110d | |
|
|
970f16913b | |
|
|
3ccdc134fe | |
|
|
1602be1348 | |
|
|
5812c1d6b5 | |
|
|
48262b8068 | |
|
|
24d3cd4bec | |
|
|
c751ee6bc9 | |
|
|
76552ccca1 | |
|
|
546d0b2871 | |
|
|
828d57a419 | |
|
|
6f2c3d819e | |
|
|
459fcf3c3f | |
|
|
1c1245d5c0 | |
|
|
d1c66eaa0f | |
|
|
7e1f685ea3 | |
|
|
f92b41ae0a | |
|
|
e4469c043e | |
|
|
25844edf50 | |
|
|
2a5351cc0a | |
|
|
f508d6fe1d | |
|
|
6bd5ec4f8b | |
|
|
eaa25c500b | |
|
|
64e33bd6cb | |
|
|
f28e643ed0 | |
|
|
7f4703e248 | |
|
|
e13da7cbd4 | |
|
|
5cc8ec7d71 | |
|
|
2d39ab4dd8 | |
|
|
2fb9a2d832 | |
|
|
7c3b2302b5 | |
|
|
8b4e81ab5c | |
|
|
44306e981a | |
|
|
25060734a0 | |
|
|
e70e2109f4 | |
|
|
fb748f6442 | |
|
|
b5c3b5f895 | |
|
|
ab9e0ebc8a | |
|
|
6706e0468e | |
|
|
fd21dfb67d | |
|
|
bc42fb4a40 | |
|
|
07e0ea785d | |
|
|
edbc32959d | |
|
|
b068e62ffb | |
|
|
b85035ff87 | |
|
|
c48b4cb6c2 | |
|
|
d34201ed38 | |
|
|
15a155ec30 | |
|
|
e02c1495bf | |
|
|
28d6ac5e49 | |
|
|
f766834601 | |
|
|
5e26465b2c | |
|
|
67220b911b | |
|
|
37b6a7214d | |
|
|
592b8824ec | |
|
|
7c9b9d1592 | |
|
|
6d011a62ae | |
|
|
7fe0100855 | |
|
|
e7ab5002a3 | |
|
|
940ac3d6e4 | |
|
|
8746a29fa9 | |
|
|
bc770242a5 | |
|
|
61013d5053 | |
|
|
d7faad95dd | |
|
|
bac2c06026 | |
|
|
75c2ac5a68 | |
|
|
b11e42c4a7 | |
|
|
7d9dbdafcd | |
|
|
21df7dad86 | |
|
|
f6425d7773 | |
|
|
4d3d2f4f03 | |
|
|
626675ea08 | |
|
|
71c2425b6e | |
|
|
2ca338068b | |
|
|
e1ec2fd1d2 | |
|
|
ce1c890cb0 | |
|
|
8c84316796 | |
|
|
ed6eb76670 | |
|
|
66bb36e336 | |
|
|
cd248c2638 | |
|
|
1a03f8c6e1 | |
|
|
c26c013b5a | |
|
|
89393e1b7c | |
|
|
ba10efcbe4 | |
|
|
2a815ff510 | |
|
|
8c150b865c | |
|
|
d309bc89ce | |
|
|
f4aa383177 | |
|
|
93d3356dd9 | |
|
|
9b3132a2cd | |
|
|
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 |
|
|
@ -1,35 +1,63 @@
|
|||
---
|
||||
# CGAL clang-format configuration
|
||||
# This file defines the code formatting style for C++ files in the CGAL project.
|
||||
|
||||
Language: Cpp
|
||||
BasedOnStyle: LLVM
|
||||
AccessModifierOffset: -2
|
||||
AllowShortFunctionsOnASingleLine: true
|
||||
BinPackParameters: false
|
||||
BreakConstructorInitializers: BeforeComma
|
||||
|
||||
# Indentation
|
||||
AccessModifierOffset: -2 # Indent public:/private:/protected: 2 spaces to the left
|
||||
|
||||
# Function formatting
|
||||
AllowShortFunctionsOnASingleLine: Inline # Allow short inline/member functions on one line, but not free functions
|
||||
AlwaysBreakAfterReturnType: None # Don't force return type on separate line
|
||||
|
||||
# Parameter and argument formatting
|
||||
BinPackParameters: false # Put each parameter on its own line for better readability
|
||||
|
||||
# Constructor formatting
|
||||
BreakConstructorInitializers: BeforeComma # Put comma before each initializer: `MyClass() \n , member1(val1) \n , member2(val2)`
|
||||
|
||||
# Brace wrapping configuration
|
||||
BreakBeforeBraces: Custom
|
||||
BraceWrapping:
|
||||
AfterCaseLabel: false
|
||||
AfterClass: true
|
||||
AfterControlStatement: MultiLine
|
||||
AfterEnum: false
|
||||
AfterFunction: false
|
||||
AfterNamespace: false
|
||||
AfterObjCDeclaration: false
|
||||
AfterStruct: true
|
||||
AfterUnion: false
|
||||
AfterExternBlock: false
|
||||
BeforeCatch: false
|
||||
BeforeElse: false
|
||||
BeforeLambdaBody: false
|
||||
BeforeWhile: false
|
||||
IndentBraces: false
|
||||
SplitEmptyFunction: false
|
||||
SplitEmptyRecord: false
|
||||
SplitEmptyNamespace: false
|
||||
ColumnLimit: 120
|
||||
# Force pointers to the type for C++.
|
||||
AfterCaseLabel: false # Don't put brace on new line after case labels
|
||||
AfterClass: true # Put opening brace on new line after class definition
|
||||
AfterControlStatement: MultiLine # Only break before braces if the control statement spans multiple lines
|
||||
AfterEnum: false # Don't break after enum
|
||||
AfterFunction: false # Don't break after function declaration (keep on same line)
|
||||
AfterNamespace: false # Don't break after namespace
|
||||
AfterObjCDeclaration: false # Objective-C related (not used in CGAL)
|
||||
AfterStruct: true # Put opening brace on new line after struct definition
|
||||
AfterUnion: false # Don't break after union
|
||||
AfterExternBlock: false # Don't break after extern "C" blocks
|
||||
BeforeCatch: false # Don't put catch on new line
|
||||
BeforeElse: false # Don't put else on new line
|
||||
BeforeLambdaBody: false # Don't break before lambda body
|
||||
BeforeWhile: false # Don't put while on new line (do-while loops)
|
||||
IndentBraces: false # Don't indent the braces themselves
|
||||
SplitEmptyFunction: false # Don't split empty functions across lines
|
||||
SplitEmptyRecord: false # Don't split empty classes/structs across lines
|
||||
SplitEmptyNamespace: false # Don't split empty namespaces across lines
|
||||
|
||||
# Line length
|
||||
ColumnLimit: 120 # Maximum line length of 120 characters
|
||||
|
||||
# Pointer and reference alignment
|
||||
# Force pointers and references to align with the type (e.g., `int* ptr` not `int *ptr`)
|
||||
DerivePointerAlignment: false
|
||||
PointerAlignment: Left
|
||||
# Control the spaces around conditionals
|
||||
SpacesInConditionalStatement: false
|
||||
SpaceBeforeParens: false
|
||||
|
||||
# Spacing in control statements
|
||||
SpacesInConditionalStatement: false # No extra spaces inside conditionals: `if(condition)` not `if( condition )`
|
||||
SpaceBeforeParens: false # No space before parentheses: `if(` not `if (`
|
||||
|
||||
# Include directive handling
|
||||
SortIncludes: Never # Preserve the original order of #include statements (don't sort them)
|
||||
|
||||
# Preprocessor directive formatting
|
||||
IndentPPDirectives: None # Don't indent preprocessor directives (#ifdef, #include, etc.)
|
||||
|
||||
# Blank line handling
|
||||
MaxEmptyLinesToKeep: 2 # Keep up to 2 consecutive blank lines
|
||||
...
|
||||
|
|
|
|||
|
|
@ -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.");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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>
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
\cgalConcept
|
||||
|
||||
The concept `ConformingConstrainedDelaunayTriangulationCellBase_3` refines the concept
|
||||
`TriangulationCellBase_3` and and describes the requirements for a base cell class of
|
||||
`TriangulationCellBase_3` and describes the requirements for a base cell class of
|
||||
the `CGAL::Conforming_constrained_Delaunay_triangulation_3` class.
|
||||
|
||||
\cgalRefines{TriangulationCellBase_3, BaseWithTimeStamp}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
#include <CGAL/Constrained_triangulation_3/internal/config.h>
|
||||
|
||||
#include <CGAL/Conforming_constrained_Delaunay_triangulation_vertex_data_3.h>
|
||||
#include <CGAL/Real_timer.h>
|
||||
#include <CGAL/Triangulation_2/internal/Polyline_constraint_hierarchy_2.h>
|
||||
#include <CGAL/Triangulation_segment_traverser_3.h>
|
||||
#include <CGAL/unordered_flat_set.h>
|
||||
|
|
@ -34,8 +35,209 @@
|
|||
|
||||
#ifndef DOXYGEN_RUNNING
|
||||
|
||||
#if CGAL_USE_ITT
|
||||
# include <ittnotify.h>
|
||||
#endif
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
namespace CDT_3 {
|
||||
|
||||
struct Debug_options {
|
||||
enum class Flags {
|
||||
Steiner_points = 0,
|
||||
conforming,
|
||||
input_faces,
|
||||
missing_region,
|
||||
regions,
|
||||
copy_triangulation_into_hole,
|
||||
validity,
|
||||
use_older_cavity_algorithm,
|
||||
debug_finite_edges_map,
|
||||
use_finite_edges_map,
|
||||
debug_subconstraints_to_conform,
|
||||
verbose_special_cases,
|
||||
debug_encroaching_vertices,
|
||||
debug_conforming_validation,
|
||||
debug_constraint_hierarchy,
|
||||
debug_geometric_errors,
|
||||
debug_polygon_insertion,
|
||||
display_statistics,
|
||||
nb_of_flags
|
||||
};
|
||||
|
||||
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); }
|
||||
|
||||
bool input_faces() const { return flags[static_cast<int>(Flags::input_faces)]; }
|
||||
void input_faces(bool b) { flags.set(static_cast<int>(Flags::input_faces), b); }
|
||||
|
||||
bool missing_region() const { return flags[static_cast<int>(Flags::missing_region)]; }
|
||||
void missing_region(bool b) { flags.set(static_cast<int>(Flags::missing_region), b); }
|
||||
|
||||
bool regions() const { return flags[static_cast<int>(Flags::regions)]; }
|
||||
void regions(bool b) { flags.set(static_cast<int>(Flags::regions), b); }
|
||||
|
||||
bool copy_triangulation_into_hole() const { return flags[static_cast<int>(Flags::copy_triangulation_into_hole)]; }
|
||||
void copy_triangulation_into_hole(bool b) { flags.set(static_cast<int>(Flags::copy_triangulation_into_hole), b); }
|
||||
|
||||
bool validity() const { return flags[static_cast<int>(Flags::validity)]; }
|
||||
void validity(bool b) { flags.set(static_cast<int>(Flags::validity), b); }
|
||||
|
||||
bool use_older_cavity_algorithm() const { return flags[static_cast<int>(Flags::use_older_cavity_algorithm)]; }
|
||||
bool use_newer_cavity_algorithm() const { return !flags[static_cast<int>(Flags::use_older_cavity_algorithm)]; }
|
||||
void use_older_cavity_algorithm(bool b) { flags.set(static_cast<int>(Flags::use_older_cavity_algorithm), b); }
|
||||
|
||||
bool finite_edges_map() const { return flags[static_cast<int>(Flags::debug_finite_edges_map)]; }
|
||||
void finite_edges_map(bool b) { flags.set(static_cast<int>(Flags::debug_finite_edges_map), b); }
|
||||
|
||||
bool subconstraints_to_conform() const { return flags[static_cast<int>(Flags::debug_subconstraints_to_conform)]; }
|
||||
void subconstraints_to_conform(bool b) { flags.set(static_cast<int>(Flags::debug_subconstraints_to_conform), b); }
|
||||
|
||||
bool use_finite_edges_map_flag() const { return flags[static_cast<int>(Flags::use_finite_edges_map)]; }
|
||||
void use_finite_edges_map(bool b) { flags.set(static_cast<int>(Flags::use_finite_edges_map), b); }
|
||||
|
||||
bool verbose_special_cases() const { return flags[static_cast<int>(Flags::verbose_special_cases)]; }
|
||||
void verbose_special_cases(bool b) { flags.set(static_cast<int>(Flags::verbose_special_cases), b); }
|
||||
|
||||
bool encroaching_vertices() const { return flags[static_cast<int>(Flags::debug_encroaching_vertices)]; }
|
||||
void encroaching_vertices(bool b) { flags.set(static_cast<int>(Flags::debug_encroaching_vertices), b); }
|
||||
|
||||
bool conforming_validation() const { return flags[static_cast<int>(Flags::debug_conforming_validation)]; }
|
||||
void conforming_validation(bool b) { flags.set(static_cast<int>(Flags::debug_conforming_validation), b); }
|
||||
|
||||
bool constraint_hierarchy() const { return flags[static_cast<int>(Flags::debug_constraint_hierarchy)]; }
|
||||
void constraint_hierarchy(bool b) { flags.set(static_cast<int>(Flags::debug_constraint_hierarchy), b); }
|
||||
|
||||
bool geometric_errors() const { return flags[static_cast<int>(Flags::debug_geometric_errors)]; }
|
||||
void geometric_errors(bool b) { flags.set(static_cast<int>(Flags::debug_geometric_errors), b); }
|
||||
|
||||
bool polygon_insertion() const { return flags[static_cast<int>(Flags::debug_polygon_insertion)]; }
|
||||
void polygon_insertion(bool b) { flags.set(static_cast<int>(Flags::debug_polygon_insertion), b); }
|
||||
|
||||
bool display_statistics() const { return flags[static_cast<int>(Flags::display_statistics)]; }
|
||||
void display_statistics(bool b) { flags.set(static_cast<int>(Flags::display_statistics), b); }
|
||||
|
||||
double segment_vertex_epsilon() const { return segment_vertex_epsilon_; }
|
||||
void set_segment_vertex_epsilon(double eps) { segment_vertex_epsilon_ = eps; }
|
||||
|
||||
double vertex_vertex_epsilon() const { return vertex_vertex_epsilon_; }
|
||||
void set_vertex_vertex_epsilon(double eps) { vertex_vertex_epsilon_ = eps; }
|
||||
|
||||
private:
|
||||
std::bitset<static_cast<int>(Flags::nb_of_flags)> flags{};
|
||||
double segment_vertex_epsilon_ = 0.0;
|
||||
double vertex_vertex_epsilon_ = 0.0;
|
||||
}; // end struct Debug_options
|
||||
|
||||
namespace internal {
|
||||
|
||||
auto& tasks_manager() {
|
||||
struct Tasks_manager {
|
||||
enum {
|
||||
READ_INPUT = 0,
|
||||
MERGE_FACETS,
|
||||
INSERT_VERTICES,
|
||||
COMPUTE_DISTANCES,
|
||||
CONFORMING,
|
||||
CDT,
|
||||
OUTPUT,
|
||||
VALIDATION,
|
||||
NB_TASKS
|
||||
};
|
||||
|
||||
#if CGAL_USE_ITT
|
||||
__itt_domain* cdt_3_domain = __itt_domain_create("org.cgal.CDT_3");
|
||||
const std::array<__itt_string_handle*, NB_TASKS> task_handles = {
|
||||
__itt_string_handle_create("CDT_3: read input file"),
|
||||
__itt_string_handle_create("CDT_3: merge facets"),
|
||||
__itt_string_handle_create("CDT_3: insert vertices"),
|
||||
__itt_string_handle_create("CDT_3: compute distances"),
|
||||
__itt_string_handle_create("CDT_3: conforming"),
|
||||
__itt_string_handle_create("CDT_3: cdt"),
|
||||
__itt_string_handle_create("CDT_3: outputs"),
|
||||
__itt_string_handle_create("CDT_3: validation")
|
||||
};
|
||||
#endif
|
||||
std::array<CGAL::Real_timer, NB_TASKS> timers{};
|
||||
struct Scope_guard {
|
||||
Tasks_manager *instance = nullptr;
|
||||
int task_id;
|
||||
Scope_guard(Tasks_manager *instance, int task_id) : instance(instance), task_id(task_id) {
|
||||
instance->timers[task_id].start();
|
||||
#if CGAL_USE_ITT
|
||||
__itt_task_begin(instance->cdt_3_domain, __itt_null, __itt_null, instance->task_handles[task_id]);
|
||||
#endif
|
||||
}
|
||||
auto time() const {
|
||||
return instance->timers[task_id].time();
|
||||
}
|
||||
auto time_ms() const {
|
||||
return instance->timers[task_id].time() / 1000.;
|
||||
}
|
||||
~Scope_guard() {
|
||||
instance->timers[task_id].stop();
|
||||
#if CGAL_USE_ITT
|
||||
__itt_task_end(instance->cdt_3_domain);
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
Scope_guard make_task_scope_guard(int task_id) {
|
||||
return Scope_guard(this, task_id);
|
||||
}
|
||||
|
||||
Scope_guard READ_INPUT_TASK_guard() { return make_task_scope_guard(READ_INPUT); }
|
||||
Scope_guard MERGE_FACETS_TASK_guard() { return make_task_scope_guard(MERGE_FACETS); }
|
||||
Scope_guard INSERT_VERTICES_TASK_guard() { return make_task_scope_guard(INSERT_VERTICES); }
|
||||
Scope_guard COMPUTE_DISTANCES_TASK_guard() { return make_task_scope_guard(COMPUTE_DISTANCES); }
|
||||
Scope_guard CONFORMING_TASK_guard() { return make_task_scope_guard(CONFORMING); }
|
||||
Scope_guard CDT_TASK_guard() { return make_task_scope_guard(CDT); }
|
||||
Scope_guard OUTPUT_TASK_guard() { return make_task_scope_guard(OUTPUT); }
|
||||
Scope_guard VALIDATION_TASK_guard() { return make_task_scope_guard(VALIDATION); }
|
||||
|
||||
}; // end struct Intel_OneAPI_ITT_API
|
||||
|
||||
static Tasks_manager instance;
|
||||
return instance;
|
||||
} // end auto& tasks_manager()
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
} // end namespace CDT_3
|
||||
|
||||
inline auto CDT_3_READ_INPUT_TASK_guard() {
|
||||
return CDT_3::internal::tasks_manager().READ_INPUT_TASK_guard();
|
||||
}
|
||||
|
||||
inline auto CDT_3_MERGE_FACETS_TASK_guard() {
|
||||
return CDT_3::internal::tasks_manager().MERGE_FACETS_TASK_guard();
|
||||
}
|
||||
|
||||
inline auto CDT_3_INSERT_VERTICES_TASK_guard() {
|
||||
return CDT_3::internal::tasks_manager().INSERT_VERTICES_TASK_guard();
|
||||
}
|
||||
|
||||
inline auto CDT_3_COMPUTE_DISTANCES_TASK_guard() {
|
||||
return CDT_3::internal::tasks_manager().COMPUTE_DISTANCES_TASK_guard();
|
||||
}
|
||||
|
||||
inline auto CDT_3_CONFORMING_TASK_guard() {
|
||||
return CDT_3::internal::tasks_manager().CONFORMING_TASK_guard();
|
||||
}
|
||||
|
||||
inline auto CDT_3_CDT_TASK_guard() {
|
||||
return CDT_3::internal::tasks_manager().CDT_TASK_guard();
|
||||
}
|
||||
|
||||
inline auto CDT_3_OUTPUT_TASK_guard() {
|
||||
return CDT_3::internal::tasks_manager().OUTPUT_TASK_guard();
|
||||
}
|
||||
|
||||
inline auto CDT_3_VALIDATION_TASK_guard() {
|
||||
return CDT_3::internal::tasks_manager().VALIDATION_TASK_guard();
|
||||
}
|
||||
|
||||
template <typename T_3>
|
||||
class Conforming_Delaunay_triangulation_3 : public T_3 {
|
||||
public:
|
||||
|
|
@ -50,9 +252,9 @@ public:
|
|||
using Line = typename T_3::Geom_traits::Line_3;
|
||||
using Locate_type = typename T_3::Locate_type;
|
||||
|
||||
inline static With_offset_tag with_offset{};
|
||||
inline static With_point_tag with_point{};
|
||||
inline static With_point_and_info_tag with_point_and_info{};
|
||||
inline static With_offset_tag with_offset{ -1 };
|
||||
inline static With_point_tag with_point{ {-1} };
|
||||
inline static With_point_and_info_tag with_point_and_info{ { {-1} } };
|
||||
|
||||
Conforming_Delaunay_triangulation_3(const Geom_traits& gt = Geom_traits())
|
||||
: T_3(gt)
|
||||
|
|
@ -110,7 +312,7 @@ protected:
|
|||
if(v1 > v2) std::swap(v1, v2);
|
||||
auto v1_index = v1->time_stamp();
|
||||
[[maybe_unused]] auto nb_erased = self->all_finite_edges[v1_index].erase(v2);
|
||||
if constexpr (cdt_3_can_use_cxx20_format()) if(self->debug_finite_edges_map() && nb_erased > 0) {
|
||||
if constexpr (cdt_3_can_use_cxx20_format()) if(self->debug().finite_edges_map() && nb_erased > 0) {
|
||||
std::cerr << cdt_3_format("erasing edge {} {}\n", self->display_vert((std::min)(v1, v2)),
|
||||
self->display_vert((std::max)(v1, v2)));
|
||||
}
|
||||
|
|
@ -169,18 +371,17 @@ protected:
|
|||
void add_to_subconstraints_to_conform(Vertex_handle va, Vertex_handle vb,
|
||||
Constrained_polyline_id id) {
|
||||
const auto pair = make_subconstraint(va, vb);
|
||||
#if CGAL_DEBUG_CDT_3 & 32
|
||||
std::cerr << "tr().subconstraints_to_conform.push("
|
||||
<< display_subcstr(pair) << ")\n";
|
||||
#endif // CGAL_DEBUG_CDT_3
|
||||
if(debug().subconstraints_to_conform()) {
|
||||
std::cerr << "tr().subconstraints_to_conform.push("
|
||||
<< display_subcstr(pair) << ")\n";
|
||||
}
|
||||
subconstraints_to_conform.push({pair, id});
|
||||
}
|
||||
|
||||
template <typename Visitor>
|
||||
Constrained_polyline_id insert_constrained_edge_impl(Vertex_handle va, Vertex_handle vb,
|
||||
Visitor&) {
|
||||
Constrained_polyline_id insert_constrained_edge_impl(Vertex_handle va, Vertex_handle vb, Visitor&) {
|
||||
if(va != vb) {
|
||||
if(segment_vertex_epsilon != 0.) {
|
||||
if(debug().segment_vertex_epsilon() != 0.) {
|
||||
auto [min_dist, min_vertex] = min_distance_and_vertex_between_constraint_and_encroaching_vertex(va, vb);
|
||||
check_segment_vertex_distance_or_throw(va, vb, min_vertex, CGAL::to_double(min_dist),
|
||||
Check_distance::NON_SQUARED_DISTANCE);
|
||||
|
|
@ -217,7 +418,7 @@ protected:
|
|||
if(tr().is_infinite(v1) || tr().is_infinite(v2))
|
||||
return;
|
||||
[[maybe_unused]] auto [_, inserted] = all_finite_edges[v1->time_stamp()].insert(v2);
|
||||
if constexpr (cdt_3_can_use_cxx20_format()) if (debug_finite_edges_map() && inserted) {
|
||||
if constexpr (cdt_3_can_use_cxx20_format()) if (debug().finite_edges_map() && inserted) {
|
||||
if(v2 < v1) std::swap(v1, v2);
|
||||
std::cerr << cdt_3_format("new_edge({}, {})\n", display_vert(v1), display_vert(v2));
|
||||
}
|
||||
|
|
@ -268,7 +469,7 @@ protected:
|
|||
if(use_finite_edges_map()) {
|
||||
new_vertex(v);
|
||||
all_finite_edges.clear();
|
||||
if (debug_finite_edges_map()) std::cerr << "all_finite_edges.clear()\n";
|
||||
if (debug().finite_edges_map()) std::cerr << "all_finite_edges.clear()\n";
|
||||
for(auto e: tr().all_edges()) {
|
||||
new_edge(e);
|
||||
}
|
||||
|
|
@ -304,7 +505,7 @@ protected:
|
|||
}
|
||||
}
|
||||
|
||||
void update_max_bbox_edge_length() {
|
||||
void update_max_bbox_edge_length() const {
|
||||
double d_x = bbox.xmax() - bbox.xmin();
|
||||
double d_y = bbox.ymax() - bbox.ymin();
|
||||
double d_z = bbox.zmax() - bbox.zmin();
|
||||
|
|
@ -313,85 +514,15 @@ protected:
|
|||
}
|
||||
|
||||
public:
|
||||
void set_segment_vertex_epsilon(double epsilon) {
|
||||
segment_vertex_epsilon = epsilon;
|
||||
}
|
||||
CDT_3::Debug_options& debug() { return debug_options_; }
|
||||
const CDT_3::Debug_options& debug() const { return debug_options_; }
|
||||
|
||||
bool debug_Steiner_points() const {
|
||||
return debug_flags[static_cast<int>(Debug_flags::Steiner_points)];
|
||||
}
|
||||
|
||||
void debug_Steiner_points(bool b) {
|
||||
debug_flags.set(static_cast<int>(Debug_flags::Steiner_points), b);
|
||||
}
|
||||
|
||||
bool debug_input_faces() const {
|
||||
return debug_flags[static_cast<int>(Debug_flags::input_faces)];
|
||||
}
|
||||
|
||||
void debug_input_faces(bool b) {
|
||||
debug_flags.set(static_cast<int>(Debug_flags::input_faces), b);
|
||||
}
|
||||
|
||||
bool debug_missing_region() const {
|
||||
return debug_flags[static_cast<int>(Debug_flags::missing_region)];
|
||||
}
|
||||
|
||||
void debug_missing_region(bool b) {
|
||||
debug_flags.set(static_cast<int>(Debug_flags::missing_region), b);
|
||||
}
|
||||
|
||||
bool debug_regions() const {
|
||||
return debug_flags[static_cast<int>(Debug_flags::regions)];
|
||||
}
|
||||
|
||||
void debug_regions(bool b) {
|
||||
debug_flags.set(static_cast<int>(Debug_flags::regions), b);
|
||||
}
|
||||
|
||||
bool debug_copy_triangulation_into_hole() const {
|
||||
return debug_flags[static_cast<int>(Debug_flags::copy_triangulation_into_hole)];
|
||||
}
|
||||
|
||||
void debug_copy_triangulation_into_hole(bool b) {
|
||||
debug_flags.set(static_cast<int>(Debug_flags::copy_triangulation_into_hole), b);
|
||||
}
|
||||
|
||||
bool debug_validity() const {
|
||||
return debug_flags[static_cast<int>(Debug_flags::validity)];
|
||||
}
|
||||
|
||||
void debug_validity(bool b) {
|
||||
debug_flags.set(static_cast<int>(Debug_flags::validity), b);
|
||||
}
|
||||
|
||||
bool use_older_cavity_algorithm() const {
|
||||
return debug_flags[static_cast<int>(Debug_flags::use_older_cavity_algorithm)];
|
||||
}
|
||||
|
||||
bool use_newer_cavity_algorithm() const {
|
||||
return !debug_flags[static_cast<int>(Debug_flags::use_older_cavity_algorithm)];
|
||||
}
|
||||
|
||||
void use_older_cavity_algorithm(bool b) {
|
||||
debug_flags.set(static_cast<int>(Debug_flags::use_older_cavity_algorithm), b);
|
||||
}
|
||||
|
||||
bool debug_finite_edges_map() const {
|
||||
return debug_flags[static_cast<int>(Debug_flags::debug_finite_edges_map)];
|
||||
}
|
||||
|
||||
void debug_finite_edges_map(bool b) {
|
||||
debug_flags.set(static_cast<int>(Debug_flags::debug_finite_edges_map), b);
|
||||
}
|
||||
|
||||
bool use_finite_edges_map() const {
|
||||
return update_all_finite_edges_ && debug_flags[static_cast<int>(Debug_flags::use_finite_edges_map)];
|
||||
}
|
||||
|
||||
void use_finite_edges_map(bool b) {
|
||||
debug_flags.set(static_cast<int>(Debug_flags::use_finite_edges_map), b);
|
||||
}
|
||||
// Backward compatibility wrappers (deprecated, use debug().method() instead)
|
||||
bool use_older_cavity_algorithm() const { return debug_options_.use_older_cavity_algorithm(); }
|
||||
bool use_newer_cavity_algorithm() const { return debug_options_.use_newer_cavity_algorithm(); }
|
||||
void use_older_cavity_algorithm(bool b) { debug_options_.use_older_cavity_algorithm(b); }
|
||||
bool use_finite_edges_map() const { return update_all_finite_edges_ && debug_options_.use_finite_edges_map_flag(); }
|
||||
void use_finite_edges_map(bool b) { debug_options_.use_finite_edges_map(b); }
|
||||
|
||||
Vertex_handle insert(const Point &p, Locate_type lt, Cell_handle c,
|
||||
int li, int lj)
|
||||
|
|
@ -419,14 +550,14 @@ public:
|
|||
|
||||
bool is_edge(Vertex_handle va, Vertex_handle vb) const {
|
||||
const bool is_edge_v1 =
|
||||
((debug_finite_edges_map() && use_finite_edges_map()) || !use_finite_edges_map()) && tr().tds().is_edge(va, vb);
|
||||
((debug().finite_edges_map() && use_finite_edges_map()) || !use_finite_edges_map()) && tr().tds().is_edge(va, vb);
|
||||
|
||||
if(use_finite_edges_map() && va > vb) std::swap(va, vb);
|
||||
const auto va_index = va->time_stamp();
|
||||
const bool is_edge_v2 =
|
||||
use_finite_edges_map() && all_finite_edges[va_index].find(vb) != all_finite_edges[va_index].end();
|
||||
|
||||
if(debug_finite_edges_map() && use_finite_edges_map() && is_edge_v1 != is_edge_v2) {
|
||||
if(debug().finite_edges_map() && use_finite_edges_map() && is_edge_v1 != is_edge_v2) {
|
||||
std::cerr << "!! Inconsistent edge status\n";
|
||||
std::cerr << " -> constraint " << display_vert(va) << " " << display_vert(vb) << '\n';
|
||||
std::cerr << " -> edge " << (is_edge_v1 ? "is" : "is not") << " in the triangulation\n";
|
||||
|
|
@ -446,12 +577,12 @@ public:
|
|||
[this](const auto &sc) {
|
||||
const auto [va, vb] = sc;
|
||||
const auto is_edge = this->is_edge(va, vb);
|
||||
#if CGAL_DEBUG_CDT_3 & 128 && CGAL_CAN_USE_CXX20_FORMAT
|
||||
std::cerr << cdt_3_format("is_conforming>> Edge is 3D: {} ({} , {})\n",
|
||||
is_edge,
|
||||
CGAL::IO::oformat(va, with_point_and_info),
|
||||
CGAL::IO::oformat(vb, with_point_and_info));
|
||||
#endif // CGAL_DEBUG_CDT_3
|
||||
if constexpr (cdt_3_can_use_cxx20_format()) if(debug().conforming_validation()) {
|
||||
std::cerr << cdt_3_format("is_conforming>> Edge is 3D: {} ({} , {})\n",
|
||||
is_edge,
|
||||
CGAL::IO::oformat(va, with_point_and_info),
|
||||
CGAL::IO::oformat(vb, with_point_and_info));
|
||||
}
|
||||
return is_edge;
|
||||
});
|
||||
}
|
||||
|
|
@ -462,14 +593,15 @@ public:
|
|||
Vertex_handle vb,
|
||||
Vertex_handle min_vertex,
|
||||
double min_dist,
|
||||
Check_distance option)
|
||||
Check_distance distance_type = Check_distance::NON_SQUARED_DISTANCE) const
|
||||
{
|
||||
if(!max_bbox_edge_length) {
|
||||
update_max_bbox_edge_length();
|
||||
}
|
||||
if((option == Check_distance::NON_SQUARED_DISTANCE && min_dist < segment_vertex_epsilon * *max_bbox_edge_length) ||
|
||||
(option == Check_distance::SQUARED_DISTANCE &&
|
||||
min_dist < CGAL::square(segment_vertex_epsilon * *max_bbox_edge_length)))
|
||||
if((distance_type == Check_distance::NON_SQUARED_DISTANCE &&
|
||||
min_dist < debug().segment_vertex_epsilon() * *max_bbox_edge_length) ||
|
||||
(distance_type == Check_distance::SQUARED_DISTANCE &&
|
||||
min_dist < CGAL::square(debug().segment_vertex_epsilon() * *max_bbox_edge_length)))
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss.precision(std::cerr.precision());
|
||||
|
|
@ -482,6 +614,26 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
void check_vertex_vertex_distance_or_throw(Vertex_handle va,
|
||||
Vertex_handle vb,
|
||||
double min_dist) const
|
||||
{
|
||||
if(!max_bbox_edge_length) {
|
||||
update_max_bbox_edge_length();
|
||||
}
|
||||
if(min_dist < debug_options_.vertex_vertex_epsilon() * *max_bbox_edge_length)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss.precision(std::cerr.precision());
|
||||
ss << "Two vertices are too close to each other.\n";
|
||||
ss << " -> vertex " << display_vert(va) << '\n';
|
||||
ss << " -> vertex " << display_vert(vb) << '\n';
|
||||
ss << " -> distance = " << min_dist << '\n';
|
||||
ss << " -> max_bbox_edge_length = " << *max_bbox_edge_length << '\n';
|
||||
CGAL_error_msg(ss.str().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
auto ancestors_of_Steiner_vertex_on_edge(Vertex_handle v) const {
|
||||
std::pair<Vertex_handle, Vertex_handle> result;
|
||||
CGAL_precondition(v->ccdt_3_data().is_Steiner_vertex_on_edge());
|
||||
|
|
@ -587,10 +739,10 @@ protected:
|
|||
if(!constraint_hierarchy.is_subconstraint(va, vb)) {
|
||||
continue;
|
||||
}
|
||||
#if CGAL_DEBUG_CDT_3 & 32
|
||||
std::cerr << "tr().subconstraints_to_conform.pop()="
|
||||
<< display_subcstr(subconstraint) << "\n";
|
||||
#endif // CGAL_DEBUG_CDT_3
|
||||
if(debug().subconstraints_to_conform()) {
|
||||
std::cerr << "tr().subconstraints_to_conform.pop()="
|
||||
<< display_subcstr(subconstraint) << "\n";
|
||||
}
|
||||
conform_subconstraint(subconstraint, constrained_polyline_id, visitor);
|
||||
}
|
||||
}
|
||||
|
|
@ -633,7 +785,7 @@ protected:
|
|||
const auto& [steiner_pt, hint, ref_vertex] = construct_Steiner_point(constraint, subconstraint);
|
||||
[[maybe_unused]] const auto v =
|
||||
insert_Steiner_point_on_subconstraint(steiner_pt, hint, subconstraint, constraint, visitor);
|
||||
if(debug_Steiner_points()) {
|
||||
if(debug().Steiner_points()) {
|
||||
const auto [c_start, c_end] = constraint_extremities(constraint);
|
||||
std::cerr << "(" << IO::oformat(va, with_offset) << ", " << IO::oformat(vb, with_offset) << ")";
|
||||
std::cerr << ": [ " << display_vert(c_start) << " - " << display_vert(c_end) << " ] ";
|
||||
|
|
@ -669,10 +821,10 @@ protected:
|
|||
this->constraint_hierarchy.constraints_end(), c_id) != this->constraint_hierarchy.constraints_end());
|
||||
CGAL_assertion(this->constraint_hierarchy.vertices_in_constraint_begin(c_id) !=
|
||||
this->constraint_hierarchy.vertices_in_constraint_end(c_id));
|
||||
#if CGAL_DEBUG_CDT_3 & 8
|
||||
std::cerr << "constraint " << (void*) c_id.vl_ptr() << " has "
|
||||
<< c_id.vl_ptr()->skip_size() << " vertices\n";
|
||||
#endif // CGAL_DEBUG_CDT_3
|
||||
if(debug().constraint_hierarchy()) {
|
||||
std::cerr << "constraint " << static_cast<void*>(c_id.vl_ptr()) << " has "
|
||||
<< c_id.vl_ptr()->skip_size() << " vertices\n";
|
||||
}
|
||||
const auto begin = this->constraint_hierarchy.vertices_in_constraint_begin(c_id);
|
||||
const auto end = this->constraint_hierarchy.vertices_in_constraint_end(c_id);
|
||||
const auto c_va = *begin;
|
||||
|
|
@ -730,9 +882,9 @@ protected:
|
|||
encroaching_vertices.insert(v);
|
||||
};
|
||||
auto fill_encroaching_vertices = [&](const auto simplex) {
|
||||
#if CGAL_DEBUG_CDT_3 & 0x10
|
||||
std::cerr << " - " << IO::oformat(simplex, With_point_tag{}) << '\n';
|
||||
#endif // CGAL_DEBUG_CDT_3
|
||||
if(debug().encroaching_vertices()) {
|
||||
std::cerr << " - " << IO::oformat(simplex, With_point_tag{}) << '\n';
|
||||
}
|
||||
auto visit_cell = [&](Cell_handle cell) {
|
||||
for(int i = 0, end = this->tr().dimension() + 1; i < end; ++i) {
|
||||
const auto v = cell->vertex(i);
|
||||
|
|
@ -776,9 +928,9 @@ protected:
|
|||
std::cerr << "!! The constraint passes through a vertex!\n";
|
||||
std::cerr << " -> constraint " << display_vert(va) << " " << display_vert(vb) << '\n';
|
||||
std::cerr << " -> vertex " << display_vert(v) << '\n';
|
||||
#if CGAL_DEBUG_CDT_3
|
||||
debug_dump("bug-through-vertex");
|
||||
#endif
|
||||
if(debug().geometric_errors()) {
|
||||
debug_dump("bug-through-vertex");
|
||||
}
|
||||
CGAL_error();
|
||||
}
|
||||
} break;
|
||||
|
|
@ -788,14 +940,14 @@ protected:
|
|||
std::for_each(tr().segment_traverser_simplices_begin(va, vb), tr().segment_traverser_simplices_end(),
|
||||
fill_encroaching_vertices);
|
||||
auto vector_of_encroaching_vertices = encroaching_vertices.extract_sequence();
|
||||
#if CGAL_DEBUG_CDT_3 & 0x10
|
||||
std::cerr << " -> vector_of_encroaching_vertices (before filter):\n";
|
||||
std::for_each(vector_of_encroaching_vertices.begin(),
|
||||
vector_of_encroaching_vertices.end(),
|
||||
[this](Vertex_handle v){
|
||||
std::cerr << " " << this->display_vert(v) << '\n';
|
||||
});
|
||||
#endif // CGAL_DEBUG_CDT_3
|
||||
if(debug().encroaching_vertices()) {
|
||||
std::cerr << " -> vector_of_encroaching_vertices (before filter):\n";
|
||||
std::for_each(vector_of_encroaching_vertices.begin(),
|
||||
vector_of_encroaching_vertices.end(),
|
||||
[this](Vertex_handle v){
|
||||
std::cerr << " " << this->display_vert(v) << '\n';
|
||||
});
|
||||
}
|
||||
auto end = std::remove_if(vector_of_encroaching_vertices.begin(),
|
||||
vector_of_encroaching_vertices.end(),
|
||||
[va, vb, pa, pb, &angle_functor, this](Vertex_handle v) {
|
||||
|
|
@ -804,13 +956,13 @@ protected:
|
|||
this->tr().point(v),
|
||||
pb) == ACUTE;
|
||||
});
|
||||
#if CGAL_DEBUG_CDT_3 & 0x10
|
||||
std::cerr << " -> vector_of_encroaching_vertices (after filter):\n";
|
||||
std::for_each(vector_of_encroaching_vertices.begin(), end, [&](Vertex_handle v) {
|
||||
std::cerr << " " << this->display_vert(v) << " angle " << approximate_angle(pa, this->tr().point(v), pb)
|
||||
<< '\n';
|
||||
});
|
||||
#endif // CGAL_DEBUG_CDT_3
|
||||
if(debug().encroaching_vertices()) {
|
||||
std::cerr << " -> vector_of_encroaching_vertices (after filter):\n";
|
||||
std::for_each(vector_of_encroaching_vertices.begin(), end, [&](Vertex_handle v) {
|
||||
std::cerr << " " << this->display_vert(v) << " angle " << approximate_angle(pa, this->tr().point(v), pb)
|
||||
<< '\n';
|
||||
});
|
||||
}
|
||||
vector_of_encroaching_vertices.erase(end, vector_of_encroaching_vertices.end());
|
||||
return vector_of_encroaching_vertices;
|
||||
}
|
||||
|
|
@ -840,10 +992,10 @@ protected:
|
|||
return {midpoint_functor(pa, pb), va->cell(), va};
|
||||
}
|
||||
|
||||
#if CGAL_DEBUG_CDT_3 & 0x10
|
||||
std::cerr << "construct_Steiner_point( " << display_vert(va) << " , "
|
||||
<< display_vert(vb) << " )\n";
|
||||
#endif // CGAL_DEBUG_CDT_3
|
||||
if(debug().encroaching_vertices()) {
|
||||
std::cerr << "construct_Steiner_point( " << display_vert(va) << " , "
|
||||
<< display_vert(vb) << " )\n";
|
||||
}
|
||||
|
||||
const auto vector_of_encroaching_vertices = encroaching_vertices(va, vb);
|
||||
CGAL_assertion(vector_of_encroaching_vertices.size() > 0);
|
||||
|
|
@ -909,7 +1061,7 @@ protected:
|
|||
return return_orig_result_point(lambda, orig_pb, orig_pa);
|
||||
}
|
||||
} else {
|
||||
if(segment_vertex_epsilon > 0) {
|
||||
if(debug().segment_vertex_epsilon() > 0) {
|
||||
if(!max_bbox_edge_length) {
|
||||
update_max_bbox_edge_length();
|
||||
}
|
||||
|
|
@ -940,8 +1092,7 @@ protected:
|
|||
Constraint_hierarchy constraint_hierarchy = {comp};
|
||||
static_assert(CGAL::cdt_3_msvc_2019_or_older() || CGAL::is_nothrow_movable_v<Constraint_hierarchy>);
|
||||
Bbox_3 bbox{};
|
||||
double segment_vertex_epsilon = 1e-8;
|
||||
std::optional<double> max_bbox_edge_length;
|
||||
mutable std::optional<double> max_bbox_edge_length;
|
||||
using Pair_of_vertex_handles = std::pair<Vertex_handle, Vertex_handle>;
|
||||
boost::container::map<Pair_of_vertex_handles, Constrained_polyline_id> pair_of_vertices_to_cid;
|
||||
Insert_in_conflict_visitor insert_in_conflict_visitor = {this};
|
||||
|
|
@ -973,20 +1124,7 @@ protected:
|
|||
}
|
||||
}
|
||||
|
||||
enum class Debug_flags {
|
||||
Steiner_points = 0,
|
||||
conforming,
|
||||
input_faces,
|
||||
missing_region,
|
||||
regions,
|
||||
copy_triangulation_into_hole,
|
||||
validity,
|
||||
use_older_cavity_algorithm,
|
||||
debug_finite_edges_map,
|
||||
use_finite_edges_map,
|
||||
nb_of_flags
|
||||
};
|
||||
std::bitset<static_cast<int>(Debug_flags::nb_of_flags)> debug_flags{};
|
||||
CDT_3::Debug_options debug_options_{};
|
||||
bool is_Delaunay = true;
|
||||
};
|
||||
|
||||
|
|
@ -994,6 +1132,5 @@ protected:
|
|||
|
||||
#endif // not DOXYGEN_RUNNING
|
||||
|
||||
#
|
||||
|
||||
#endif // CGAL_CONFORMING_DELAUNAY_TRIANGULATION_3_H
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -98,7 +98,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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,31 +52,33 @@ class Conforming_constrained_Delaunay_triangulation_cell_data_3 {
|
|||
void clear_mark(CDT_3_cell_marker m) { markers.reset(static_cast<unsigned>(m)); }
|
||||
void clear_marks() { markers.reset(); }
|
||||
|
||||
static unsigned int uint(int i) { return static_cast<unsigned int>(i); }
|
||||
|
||||
template <typename Facet_handle>
|
||||
void set_facet_constraint(int i, CDT_3_signed_index face_id,
|
||||
Facet_handle facet_2d)
|
||||
{
|
||||
this->face_id[unsigned(i)] = face_id;
|
||||
this->facet_2d[unsigned(i)] = static_cast<void*>(facet_2d == Facet_handle{} ? nullptr : std::addressof(*facet_2d));
|
||||
this->face_id[uint(i)] = face_id;
|
||||
this->facet_2d[uint(i)] = static_cast<void*>(facet_2d == Facet_handle{} ? nullptr : std::addressof(*facet_2d));
|
||||
}
|
||||
|
||||
template <typename CDT_2>
|
||||
auto face_2 (const CDT_2& cdt, int i) const {
|
||||
using Face = typename CDT_2::Face;
|
||||
auto ptr = static_cast<Face*>(facet_2d[unsigned(i)]);
|
||||
auto ptr = static_cast<Face*>(facet_2d[uint(i)]);
|
||||
return cdt.tds().faces().iterator_to(*ptr);
|
||||
}
|
||||
public:
|
||||
/// @{
|
||||
// @cond SKIP_IN_MANUAL
|
||||
bool is_facet_constrained(int i) const { return face_id[unsigned(i)] >= 0; }
|
||||
bool is_facet_constrained(int i) const { return face_id[uint(i)] >= 0; }
|
||||
|
||||
CDT_3_signed_index face_constraint_index(int i) const {
|
||||
return face_id[unsigned(i)];
|
||||
return face_id[uint(i)];
|
||||
}
|
||||
|
||||
void set_face_constraint_index(int i, CDT_3_signed_index index) {
|
||||
face_id[unsigned(i)] = index;
|
||||
face_id[uint(i)] = index;
|
||||
}
|
||||
/// @endcond
|
||||
};
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include <CGAL/assertions.h>
|
||||
#include <CGAL/Constrained_triangulation_3/internal/config.h>
|
||||
#include <CGAL/Constrained_triangulation_3_types.h>
|
||||
|
||||
#include <bitset>
|
||||
|
||||
|
|
@ -34,7 +35,7 @@ namespace CGAL {
|
|||
struct Conforming_constrained_Delaunay_triangulation_vertex_data_3 {};
|
||||
#else // DOXYGEN_RUNNING
|
||||
|
||||
enum class CDT_3_vertex_type { FREE, CORNER, STEINER_ON_EDGE, STEINER_IN_FACE };
|
||||
enum class CDT_3_vertex_type { FREE, CORNER, INPUT_VERTEX = CORNER, STEINER_ON_EDGE, STEINER_IN_FACE };
|
||||
|
||||
enum class CDT_3_vertex_marker {
|
||||
CLEAR = 0,
|
||||
|
|
@ -91,6 +92,8 @@ public:
|
|||
}
|
||||
|
||||
int number_of_incident_constraints() const {
|
||||
if(vertex_type() == CDT_3_vertex_type::STEINER_IN_FACE)
|
||||
return 0;
|
||||
CGAL_assertion(u.on_edge.nb_of_incident_constraints >= 0);
|
||||
return u.on_edge.nb_of_incident_constraints;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,13 +26,6 @@ create_single_source_cgal_program( "cdt_3_from_off_with_Epeck.cpp")
|
|||
target_link_libraries(cdt_3_from_off_with_Epeck PRIVATE CDT_3_dependencies)
|
||||
create_single_source_cgal_program( "snap_and_cdt3.cpp")
|
||||
|
||||
if(cxx_std_20 IN_LIST CMAKE_CXX_COMPILE_FEATURES)
|
||||
add_executable(cdt_3_from_off_CGAL_DEBUG_CDT_3 cdt_3_from_off)
|
||||
target_compile_definitions(cdt_3_from_off_CGAL_DEBUG_CDT_3 PRIVATE CGAL_DEBUG_CDT_3=255)
|
||||
target_link_libraries(cdt_3_from_off_CGAL_DEBUG_CDT_3 PRIVATE CDT_3_dependencies)
|
||||
cgal_add_test(cdt_3_from_off_CGAL_DEBUG_CDT_3)
|
||||
endif()
|
||||
|
||||
add_executable(test_CDT_3_insert_constrained_edge_from_EDG_file cdt_test_insert_constrained_edge_from_EDG_file.cpp)
|
||||
target_link_libraries(test_CDT_3_insert_constrained_edge_from_EDG_file PRIVATE CDT_3_dependencies)
|
||||
target_compile_definitions(test_CDT_3_insert_constrained_edge_from_EDG_file PUBLIC CGAL_TEST_CDT_3_USE_CDT)
|
||||
|
|
@ -85,7 +78,7 @@ function(CGAL_add_cdt3_from_off_test_aux data_name data_dir)
|
|||
endfunction()
|
||||
|
||||
function(CGAL_add_cdt3_from_off_test data_name)
|
||||
CGAL_add_cdt3_from_off_test_aux(${data_name} ${CGAL_DATA_DIR}/meshes)
|
||||
CGAL_add_cdt3_from_off_test_aux(${data_name} ${CGAL_DATA_DIR}/meshes ${ARGN})
|
||||
endfunction()
|
||||
|
||||
CGAL_add_cdt3_from_off_test("cube")
|
||||
|
|
@ -95,9 +88,10 @@ CGAL_add_cdt3_from_off_test("mpi")
|
|||
CGAL_add_cdt3_from_off_test("3torus")
|
||||
CGAL_add_cdt3_from_off_test("cheese-selection")
|
||||
CGAL_add_cdt3_from_off_test("cheese-selection-2")
|
||||
CGAL_add_cdt3_from_off_test("non_manifold_face_graph")
|
||||
|
||||
function(CGAL_add_cdt3_from_local_off_test data_name)
|
||||
CGAL_add_cdt3_from_off_test_aux(${data_name} ${CMAKE_CURRENT_SOURCE_DIR}/data)
|
||||
CGAL_add_cdt3_from_off_test_aux(${data_name} ${CMAKE_CURRENT_SOURCE_DIR}/data ${ARGN})
|
||||
endfunction()
|
||||
|
||||
CGAL_add_cdt3_from_local_off_test(cheese18)
|
||||
|
|
@ -130,17 +124,15 @@ if (CGAL_CDT_TEST_USE_THINGI)
|
|||
CGAL_add_cdt3_from_local_off_test(1514904-min8)
|
||||
CGAL_add_cdt3_from_local_off_test(1147177-min1)
|
||||
CGAL_add_cdt3_from_local_off_test(1452672-min1)
|
||||
CGAL_add_cdt3_from_local_off_test(135777-min3)
|
||||
CGAL_add_cdt3_from_local_off_test(196123-min3)
|
||||
CGAL_add_cdt3_from_local_off_test(200695-min3)
|
||||
CGAL_add_cdt3_from_local_off_test(285604-min8)
|
||||
CGAL_add_cdt3_from_local_off_test(error_mesh-p_not_equal_0-min2)
|
||||
|
||||
include(./Thingi10k-CDT.cmake)
|
||||
endif()
|
||||
|
||||
if(cxx_std_20 IN_LIST CMAKE_CXX_COMPILE_FEATURES)
|
||||
add_test(NAME "execution of cdt_3_from_off_CGAL_DEBUG_CDT_3 3torus" COMMAND cdt_3_from_off_CGAL_DEBUG_CDT_3 ${CGAL_DATA_DIR}/meshes/3torus.off)
|
||||
cgal_add_compilation_test(cdt_3_from_off_CGAL_DEBUG_CDT_3)
|
||||
cgal_setup_test_properties("execution of cdt_3_from_off_CGAL_DEBUG_CDT_3 3torus" cdt_3_from_off_CGAL_DEBUG_CDT_3)
|
||||
endif()
|
||||
|
||||
get_directory_property(all_tests TESTS)
|
||||
foreach(test ${all_tests})
|
||||
if(test MATCHES cdt|CDT)
|
||||
|
|
|
|||
|
|
@ -109,6 +109,152 @@ set(thingi10k_FAILED_WITH_MERGE_FACETS_CTest_20240222_2201
|
|||
1514904.stl
|
||||
)
|
||||
|
||||
set(thingi10k_FAILED_WITH_SEGFAULT_CTest_20251002
|
||||
1439534.stl
|
||||
196123.stl
|
||||
200695.stl
|
||||
135777.stl
|
||||
285604.stl
|
||||
822697.stl
|
||||
)
|
||||
|
||||
set(thingi10k_FAILED_CTest_20251002
|
||||
100606.stl
|
||||
100644.stl
|
||||
101955.stl
|
||||
109130.stl
|
||||
116873.stl
|
||||
116876.stl
|
||||
135777.stl
|
||||
139737.stl
|
||||
1439534.stl
|
||||
145329.stl
|
||||
145330.stl
|
||||
1505036.stl
|
||||
1514900.stl
|
||||
196121.stl
|
||||
196122.stl
|
||||
196123.stl
|
||||
196126.stl
|
||||
196127.stl
|
||||
199814.stl
|
||||
199818.stl
|
||||
200695.stl
|
||||
215991.stl
|
||||
230152.stl
|
||||
230153.stl
|
||||
239188.stl
|
||||
276937.stl
|
||||
285604.stl
|
||||
285605.stl
|
||||
288352.stl
|
||||
288353.stl
|
||||
288354.stl
|
||||
288355.stl
|
||||
39182.stl
|
||||
39245.stl
|
||||
472050.stl
|
||||
55278.stl
|
||||
61418.stl
|
||||
622000.stl
|
||||
669962.stl
|
||||
67817.stl
|
||||
702204.stl
|
||||
723893.stl
|
||||
822697.stl
|
||||
904476.stl
|
||||
91474.stl
|
||||
95796.stl
|
||||
95797.stl
|
||||
97515.stl
|
||||
)
|
||||
|
||||
set(thingi10k_FAILED_WITH_MERGE_FACETS_CTest_20251028
|
||||
139765.stl
|
||||
1452677.stl
|
||||
1452678.stl
|
||||
1452679.stl
|
||||
145329.stl
|
||||
145330.stl
|
||||
145331.stl
|
||||
1505036.stl
|
||||
1514900.stl
|
||||
153100.stl
|
||||
1652975.stl
|
||||
1652976.stl
|
||||
1706457.stl
|
||||
186546.stl
|
||||
196121.stl
|
||||
196122.stl
|
||||
196123.stl
|
||||
196126.stl
|
||||
196127.stl
|
||||
196194.stl
|
||||
199814.stl
|
||||
199818.stl
|
||||
206318.stl
|
||||
215991.stl
|
||||
230152.stl
|
||||
230153.stl
|
||||
237632.stl
|
||||
239188.stl
|
||||
255657.stl
|
||||
255658.stl
|
||||
276937.stl
|
||||
285603.stl
|
||||
286161.stl
|
||||
288352.stl
|
||||
288446.stl
|
||||
360073.stl
|
||||
362398.stl
|
||||
37743.stl
|
||||
383022.stl
|
||||
39182.stl
|
||||
39245.stl
|
||||
39495.stl
|
||||
39499.stl
|
||||
40841.stl
|
||||
41521.stl
|
||||
42040.stl
|
||||
44025.stl
|
||||
44064.stl
|
||||
44901.stl
|
||||
472050.stl
|
||||
50659.stl
|
||||
51797.stl
|
||||
57811.stl
|
||||
61418.stl
|
||||
61431.stl
|
||||
622000.stl
|
||||
62592.stl
|
||||
62593.stl
|
||||
65144.stl
|
||||
65395.stl
|
||||
65402.stl
|
||||
669962.stl
|
||||
68255.stl
|
||||
702204.stl
|
||||
70381.stl
|
||||
71461.stl
|
||||
723893.stl
|
||||
72419.stl
|
||||
726665.stl
|
||||
77343.stl
|
||||
84624.stl
|
||||
90225.stl
|
||||
906183.stl
|
||||
91147.stl
|
||||
91474.stl
|
||||
93702.stl
|
||||
93703.stl
|
||||
95796.stl
|
||||
95797.stl
|
||||
97515.stl
|
||||
97590.stl
|
||||
97593.stl
|
||||
99895.stl
|
||||
)
|
||||
|
||||
function(CGAL_add_cdt3_test_from_Thingi10k data_name data_filename)
|
||||
set(options "ONLY_MERGE_FACETS")
|
||||
set(oneValueArgs TIMEOUT)
|
||||
|
|
@ -145,6 +291,15 @@ foreach(thingi_file_name ${thingi10k_max_10k_solid})
|
|||
if(thingi_file_name IN_LIST thingi10k_FAILED_WITH_MERGE_FACETS_CTest_20240222_2201)
|
||||
list(APPEND LABELS "CTest_20240222_2201_failed_merge_facets")
|
||||
endif()
|
||||
if(thingi_file_name IN_LIST thingi10k_FAILED_CTest_20251002)
|
||||
list(APPEND LABELS "CTest_20251002_failed")
|
||||
endif()
|
||||
if(thingi_file_name IN_LIST thingi10k_FAILED_WITH_SEGFAULT_CTest_20251002)
|
||||
list(APPEND LABELS "CTest_20251002_failed_segfault")
|
||||
endif()
|
||||
if(thingi_file_name IN_LIST thingi10k_FAILED_WITH_MERGE_FACETS_CTest_20251028)
|
||||
list(APPEND LABELS "CTest_20251028_failed_merge_facets")
|
||||
endif()
|
||||
get_filename_component(thingi_ID "${thingi_file_name}" NAME_WE)
|
||||
CGAL_add_cdt3_test_from_Thingi10k(Thingi10K_${thingi_ID} ${thingi_file_name}
|
||||
TIMEOUT 600 LABELS ${LABELS} ${MY_ONLY_MERGE_FACETS})
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,6 +1,3 @@
|
|||
#if __has_include(<format>)
|
||||
#define CGAL_DEBUG_CDT_3 1
|
||||
#endif
|
||||
#define CGAL_TRIANGULATION_CHECK_EXPENSIVE 1
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include <CGAL/Delaunay_triangulation_3.h>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,3 @@
|
|||
#if __has_include(<format>)
|
||||
#define CGAL_DEBUG_CDT_3 1
|
||||
#endif
|
||||
#define CGAL_TRIANGULATION_CHECK_EXPENSIVE 1
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include <CGAL/Delaunay_triangulation_3.h>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,69 @@
|
|||
OFF
|
||||
42 23 0
|
||||
|
||||
9.4220000000000006 6.265949 1.2926169999999999
|
||||
9.4220000000000006 6.4378760000000002 0.4304
|
||||
9.4299999999999997 6.3669419999999999 1.3120000000000001
|
||||
9.4220000000000006 6.522742 1.2616000000000001
|
||||
9.4299999999999997 1.737943 2.867
|
||||
9.4299999999999997 1.310943 1.46
|
||||
9.4299999999999997 1.167238 0
|
||||
9.4299999999999997 5.7969429999999997 6.9269999999999996
|
||||
9.4299999999999997 16.167649999999998 0
|
||||
9.4299999999999997 4.499943 6.2329999999999997
|
||||
9.4299999999999997 3.3639420000000002 5.3010000000000002
|
||||
9.4299999999999997 2.4309430000000001 4.1639999999999997
|
||||
12.430999999999999 1.167238 0
|
||||
12.430999999999999 1.310943 1.46
|
||||
-7.2230889999999999 -5.1901419999999998 1.2724260000000001
|
||||
-7.2389999999999999 -5.1100570000000003 1.3959999999999999
|
||||
3.7330000000000001 -6.7590570000000003 0.79200000000000004
|
||||
-7.255185 -4.6623049999999999 0.88247529999999996
|
||||
-7.2552779999999997 -4.6682399999999999 0.88692839999999995
|
||||
3.7330000000000001 -6.2710569999999999 0.42699999999999999
|
||||
-7.262251 -4.5335140000000003 0.78721229999999998
|
||||
-7.7199999999999998 -4.2110570000000003 1.929
|
||||
-7.6440000000000001 -4.1590579999999999 1.6100000000000001
|
||||
-7.5739999999999998 -4.3940570000000001 1.726
|
||||
-7.5469999999999997 -3.6850580000000002 1.224
|
||||
-7.5369999999999999 -3.8630580000000001 1.3169999999999999
|
||||
-7.4050000000000002 -4.4780569999999997 1.4410000000000001
|
||||
-7.3220000000000001 -4.3380580000000002 1.022
|
||||
-7.4009999999999998 -4.689057 1.677
|
||||
-7.2534720000000004 -4.6835990000000001 0.89814380000000005
|
||||
9.4299999999999997 10.06494 1.929
|
||||
-7.2789999999999999 -4.0440569999999996 0.34699999999999998
|
||||
9.4299999999999997 6.3669419999999999 1.3120000000000001
|
||||
-7.2230889999999999 -5.1901419999999998 1.2724260000000001
|
||||
3.68716 -6.0934090000000003 0
|
||||
3.7330000000000001 -6.2710569999999999 0.42699999999999999
|
||||
3.7330000000000001 -6.2710569999999999 0.42699999999999999
|
||||
-7.262251 -4.5335140000000003 0.78721229999999998
|
||||
-7.6029999999999998 -4.5610569999999999 2.0139999999999998
|
||||
-7.4050000000000002 -4.4780569999999997 1.4410000000000001
|
||||
-7.3220000000000001 -4.3380580000000002 1.022
|
||||
-7.2599 -4.5207920000000001 0.75421059999999995
|
||||
3 0 1 2
|
||||
3 1 3 2
|
||||
3 4 32 5
|
||||
3 6 5 32
|
||||
3 8 32 30
|
||||
3 9 7 32
|
||||
3 32 7 30
|
||||
3 10 32 11
|
||||
3 4 11 32
|
||||
3 10 9 32
|
||||
3 6 32 8
|
||||
3 13 5 12
|
||||
3 38 23 21
|
||||
3 26 25 22
|
||||
3 24 25 26
|
||||
3 27 39 28
|
||||
3 16 19 14
|
||||
3 35 34 20
|
||||
3 18 29 36
|
||||
3 18 28 29
|
||||
3 15 33 29
|
||||
3 31 40 41
|
||||
3 40 17 37
|
||||
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
OFF
|
||||
37 34 0
|
||||
|
||||
172.45960998535156 327.00732421875 10.000033378601074
|
||||
173.35765075683594 327.18472290039062 10.000033378601074
|
||||
172.45960998535156 327.00732421875 10
|
||||
174.25531005859375 327.36398315429688 10.000033378601074
|
||||
175.282470703125 327.571533203125 10
|
||||
170.58482360839844 325.87066650390625 10
|
||||
170.58482360839844 325.87066650390625 10.000033378601074
|
||||
170.58476257324219 326.1373291015625 10
|
||||
170.58476257324219 326.1373291015625 10.000033378601074
|
||||
170.58488464355469 326.67068481445312 10.000033378601074
|
||||
170.58488464355469 326.67068481445312 10
|
||||
170.58477783203125 326.40402221679688 10.000033378601074
|
||||
170.58477783203125 326.40402221679688 10
|
||||
171.21096801757812 326.77630615234375 10
|
||||
171.21096801757812 326.77630615234375 10.000033378601074
|
||||
171.83589172363281 326.88851928710938 10.000033378601074
|
||||
171.83589172363281 326.88851928710938 10
|
||||
198.59626770019531 331.45306396484375 10
|
||||
171.3594970703125 325.91452026367188 10
|
||||
171.3594970703125 325.91452026367188 10.000033378601074
|
||||
171.10134887695312 325.89859008789062 10
|
||||
171.10134887695312 325.89859008789062 10.000033378601074
|
||||
170.84312438964844 325.88397216796875 10.000033378601074
|
||||
170.84312438964844 325.88397216796875 10
|
||||
173.88740539550781 326.08248901367188 10.000033378601074
|
||||
174.88548278808594 326.13330078125 10
|
||||
173.12164306640625 326.03756713867188 10
|
||||
172.62298583984375 326.00552368164062 10.000033378601074
|
||||
176.65058898925781 326.20169067382812 10
|
||||
179.54045104980469 326.31793212890625 10
|
||||
182.43142700195312 326.40179443359375 10
|
||||
192.267333984375 331.10971069335938 10
|
||||
197.96424865722656 332.17782592773438 10
|
||||
175.15260314941406 328.56558227539062 10.000033378601074
|
||||
175.15260314941406 325.1444091796875 10.000033378601074
|
||||
161.37049865722656 320.09548950195312 10.000033378601074
|
||||
161.37049865722656 332.70773315429688 10.000033378601074
|
||||
3 1 3 2
|
||||
3 2 3 4
|
||||
3 18 26 27
|
||||
3 27 26 24
|
||||
3 4 30 2
|
||||
3 31 32 17
|
||||
3 30 29 2
|
||||
3 2 29 16
|
||||
3 25 10 28
|
||||
3 10 25 12
|
||||
3 18 7 26
|
||||
3 18 20 7
|
||||
3 20 23 7
|
||||
3 23 5 7
|
||||
3 7 12 26
|
||||
3 26 12 25
|
||||
3 10 13 28
|
||||
3 13 16 28
|
||||
3 21 19 34
|
||||
3 21 34 22
|
||||
3 19 27 34
|
||||
3 36 11 35
|
||||
3 3 1 33
|
||||
3 1 0 33
|
||||
3 0 15 33
|
||||
3 15 14 33
|
||||
3 14 9 33
|
||||
3 33 9 36
|
||||
3 11 8 35
|
||||
3 8 6 35
|
||||
3 35 6 34
|
||||
3 6 22 34
|
||||
3 34 27 24
|
||||
3 11 36 9
|
||||
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
OFF
|
||||
25 17 0
|
||||
|
||||
137.05000305175781 47.498001098632812 132.02400207519531
|
||||
137.05000305175781 42.498001098632812 132.65000915527344
|
||||
137.05000305175781 20 131.40000915527344
|
||||
137.05000305175781 14.998001098632812 90.316001892089844
|
||||
137.05000305175781 0 133.90000915527344
|
||||
137.05000305175781 5 131.40000915527344
|
||||
120.80000305175781 0 133.90000915527344
|
||||
134.05000305175781 2.9980001449584961 133.90000915527344
|
||||
136.67401123046875 15.874000549316406 133.90000915527344
|
||||
137.12800598144531 5 132.33399963378906
|
||||
137.12800598144531 20 132.33399963378906
|
||||
137.36601257324219 5 133.24000549316406
|
||||
137.36601257324219 20 133.24000549316406
|
||||
137.75401306152344 5 134.09400939941406
|
||||
137.05000305175781 31.248001098632812 90.316001892089844
|
||||
137.05000305175781 16.248001098632812 133.90000915527344
|
||||
118.55000305175781 2.25 133.90000915527344
|
||||
104.55000305175781 0 133.90000915527344
|
||||
137.05000305175781 32.498001098632812 133.90000915527344
|
||||
55.800003051757812 0 133.90000915527344
|
||||
54.674003601074219 1.124000072479248 133.90000915527344
|
||||
55.050003051757812 0.74800002574920654 133.90000915527344
|
||||
136.30000305175781 31.750001907348633 133.90000915527344
|
||||
39.550003051757812 0 133.90000915527344
|
||||
137.05000305175781 20 118.12000274658203
|
||||
3 0 1 2
|
||||
3 4 5 2
|
||||
3 7 4 8
|
||||
3 10 9 11
|
||||
3 10 11 12
|
||||
3 12 11 13
|
||||
3 14 24 3
|
||||
3 2 15 4
|
||||
3 15 8 4
|
||||
3 17 7 16
|
||||
3 18 2 1
|
||||
3 7 17 6
|
||||
3 2 18 15
|
||||
3 7 8 22
|
||||
3 15 22 8
|
||||
3 20 23 21
|
||||
3 19 21 23
|
||||
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
OFF
|
||||
67 48 0
|
||||
|
||||
25.003999710083008 4.125999927520752 5.3249998092651367
|
||||
24.648000717163086 4.1110000610351562 5.3020000457763672
|
||||
27.875 4.124000072479248 5.3159999847412109
|
||||
28.104999542236328 4.0980000495910645 5.3020000457763672
|
||||
27.547000885009766 -0.76599997282028198 5.3020000457763672
|
||||
24.26300048828125 4.1999998092651367 5.3020000457763672
|
||||
24.350000381469727 -1.2070000171661377 5.3020000457763672
|
||||
22.61199951171875 -1.2680000066757202 5.3020000457763672
|
||||
18.076999664306641 -0.76700001955032349 5.3020000457763672
|
||||
20.534172058105469 6.6471333503723145 5.3020000457763672
|
||||
21.565000534057617 6.2769999504089355 5.3020000457763672
|
||||
21.576999664306641 6.2220001220703125 5.3020000457763672
|
||||
24.184999465942383 4.2010002136230469 5.3020000457763672
|
||||
24.132999420166016 4.2109999656677246 5.3020000457763672
|
||||
23.76099967956543 4.3359999656677246 5.3020000457763672
|
||||
23.552000045776367 4.3480663299560547 5.3020000457763672
|
||||
23.822000503540039 4.2779998779296875 5.3020000457763672
|
||||
23.259000778198242 4.4369997978210449 5.3029999732971191
|
||||
22.599832534790039 5.119999885559082 5.3020000457763672
|
||||
21.814010620117188 5.7782330513000488 5.3020000457763672
|
||||
22.527999877929688 4.9455761909484863 5.3020000457763672
|
||||
21.797874450683594 5.8303966522216797 5.3020968437194824
|
||||
22.527999877929688 4.6591053009033203 5.3020000457763672
|
||||
21.822000503540039 5.8159999847412109 6.0100002288818359
|
||||
21.772134780883789 5.687347412109375 5.3039073944091797
|
||||
21.657405853271484 5.9652857780456543 5.3020000457763672
|
||||
21.655532836914062 5.9393019676208496 5.3023014068603516
|
||||
21.794061660766602 5.8427157402038574 5.3020000457763672
|
||||
21.660037994384766 5.9280643463134766 5.3023800849914551
|
||||
21.660087585449219 5.9279398918151855 5.3023805618286133
|
||||
21.820028305053711 5.6319999694824219 5.3020000457763672
|
||||
21.659999847412109 5.9279999732971191 5.3020000457763672
|
||||
19.494876861572266 4.9111647605895996 5.3020000457763672
|
||||
21.641000747680664 5.9800000190734863 5.3020000457763672
|
||||
21.624000549316406 6.0019998550415039 5.309999942779541
|
||||
-2.1689999103546143 -0.46799999475479126 5.3020000457763672
|
||||
20.37629508972168 6.2305684089660645 5.3020000457763672
|
||||
-2.2790000438690186 -1.3259999752044678 6.0859999656677246
|
||||
-2.1040000915527344 0.082999996840953827 5.320000171661377
|
||||
22.329999923706055 5.0479998588562012 5.3020000457763672
|
||||
19.238409042358398 4.5272407531738281 5.3020000457763672
|
||||
-1.9989999532699585 0.26600000262260437 6.7109999656677246
|
||||
18.052036285400391 3.3704285621643066 5.3020000457763672
|
||||
20.326999664306641 6.2470002174377441 5.0159997940063477
|
||||
19.670000076293945 6.4640002250671387 3.7780001163482666
|
||||
18.603000640869141 4.8670001029968262 3.7780001163482666
|
||||
-0.6029999852180481 6.8179998397827148 2.6359999179840088
|
||||
0.33100000023841858 3.0639998912811279 5.0159997940063477
|
||||
-1.143372654914856 4.4346461296081543 5.3020000457763672
|
||||
-1.1940000057220459 4.5510001182556152 5.0159997940063477
|
||||
0.83399999141693115 3.4670000076293945 3.7780001163482666
|
||||
-3.2599999904632568 10 5.0159997940063477
|
||||
-2.5490000247955322 10 3.7780001163482666
|
||||
-2.3269999027252197 8.1979999542236328 3.7780001163482666
|
||||
-1.6699999570846558 6.4640002250671387 3.7780001163482666
|
||||
-2.1198277473449707 5.846644401550293 5.3020000457763672
|
||||
-3.0250000953674316 8.0860004425048828 5.0159997940063477
|
||||
-1.9939999580383301 3.0099999904632568 5.3020000457763672
|
||||
-1.2384099960327148 4.5272407531738281 5.3020000457763672
|
||||
-2.2780001163482666 3.7369999885559082 5.3020000457763672
|
||||
-2.0220000743865967 0.74299997091293335 6.0689997673034668
|
||||
-1.9220000505447388 1.1330000162124634 5.3020000457763672
|
||||
-1.9739999771118164 0.92799997329711914 5.314000129699707
|
||||
-2.1050000190734863 -0.041999999433755875 6.1490001678466797
|
||||
-2.3269999027252197 6.2470002174377441 5.0159997940063477
|
||||
-0.6029999852180481 4.8670001029968262 3.7780001163482666
|
||||
21.659999847412109 5.9279999732971191 5.3020000457763672
|
||||
3 2 3 0
|
||||
3 5 1 6
|
||||
3 3 4 1
|
||||
3 4 6 1
|
||||
3 12 5 6
|
||||
3 13 12 7
|
||||
3 25 19 30
|
||||
3 19 25 27
|
||||
3 24 29 23
|
||||
3 31 32 25
|
||||
3 25 30 31
|
||||
3 34 66 26
|
||||
3 33 25 32
|
||||
3 66 34 28
|
||||
3 10 11 36
|
||||
3 11 33 36
|
||||
3 27 18 19
|
||||
3 17 18 21
|
||||
3 39 22 32
|
||||
3 20 19 18
|
||||
3 40 32 22
|
||||
3 8 40 22
|
||||
3 16 8 14
|
||||
3 6 7 12
|
||||
3 15 14 8
|
||||
3 8 16 7
|
||||
3 36 9 10
|
||||
3 30 39 32
|
||||
3 31 30 32
|
||||
3 36 33 32
|
||||
3 43 45 44
|
||||
3 22 15 8
|
||||
3 8 42 40
|
||||
3 16 13 7
|
||||
3 49 58 55
|
||||
3 57 59 48
|
||||
3 51 52 56
|
||||
3 64 56 53
|
||||
3 65 54 46
|
||||
3 65 49 54
|
||||
3 49 64 54
|
||||
3 47 65 50
|
||||
3 47 49 65
|
||||
3 38 62 35
|
||||
3 62 61 35
|
||||
3 38 37 63
|
||||
3 41 60 63
|
||||
3 63 37 41
|
||||
|
||||
|
|
@ -40,7 +40,7 @@ int main(int argc, char* argv[])
|
|||
auto cdt = CGAL::make_conforming_constrained_Delaunay_triangulation_3<CDT>(mesh);
|
||||
static_assert(std::is_same_v<decltype(cdt), CDT>);
|
||||
CDT cdt2(mesh);
|
||||
const auto nb_cstr_facets = cdt2.number_of_constrained_facets();
|
||||
[[maybe_unused]] const auto nb_cstr_facets = cdt2.number_of_constrained_facets();
|
||||
|
||||
assert(cdt.triangulation().number_of_vertices() == cdt2.triangulation().number_of_vertices());
|
||||
assert(cdt.number_of_constrained_facets() == cdt2.number_of_constrained_facets());
|
||||
|
|
|
|||
|
|
@ -0,0 +1,39 @@
|
|||
OFF
|
||||
24 11 0
|
||||
|
||||
1.5 0.5 1
|
||||
0.5 0.5 0
|
||||
0.5 0.5 1
|
||||
0 0 0
|
||||
0 0.5 0
|
||||
0.5 0.5 0
|
||||
0.5 1 0
|
||||
0 1 0
|
||||
0.5 0 0
|
||||
1 0 0
|
||||
1 0.5 0
|
||||
1 1 0
|
||||
1.5 1.5 1
|
||||
2.5 1.5 1
|
||||
2.5 0.5 1
|
||||
-0.5 -0.5 1
|
||||
2.5 -0.5 1
|
||||
0.5 1.5 1
|
||||
-0.5 0.5 1
|
||||
1.5 0.5 1
|
||||
1.5 -0.5 1
|
||||
-0.5 1.5 1
|
||||
0.5 0.5 1
|
||||
0.5 -0.5 1
|
||||
3 2 1 0
|
||||
4 4 3 8 5
|
||||
4 7 4 5 6
|
||||
4 5 8 9 10
|
||||
4 6 5 10 11
|
||||
4 12 19 14 13
|
||||
4 19 20 16 14
|
||||
4 17 22 19 12
|
||||
4 22 23 20 19
|
||||
4 21 18 22 17
|
||||
4 18 15 23 22
|
||||
|
||||
|
|
@ -118600,7 +118600,7 @@ both for rendering and for modeling. Contains C code."
|
|||
|
||||
@article{ph-ddocs-92
|
||||
, author = "J. P. Pratt and V. P. Heuring"
|
||||
, title = "Designing digital optical computing systems: power and and crosstalk"
|
||||
, title = "Designing digital optical computing systems: power and crosstalk"
|
||||
, journal = "Appl. Optics"
|
||||
, volume = 31
|
||||
, number = 23
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -462,10 +462,6 @@ namespace CGAL {
|
|||
} // end of the temporary compatibility with CGAL-4.14
|
||||
#endif // CGAL_NO_DEPRECATED_CODE
|
||||
|
||||
#if __has_include(<version>)
|
||||
# include <version>
|
||||
#endif
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
// Typedef for the type of nullptr.
|
||||
|
|
|
|||
|
|
@ -14,15 +14,15 @@
|
|||
|
||||
namespace CGAL { namespace internal {
|
||||
|
||||
template < typename T > inline
|
||||
void use(const T&) {}
|
||||
template <typename ...T> inline
|
||||
void use(T&&...) {}
|
||||
|
||||
template<typename> void use_type() {}
|
||||
|
||||
} }
|
||||
|
||||
/// CGAL_USE() is a macro which aims at removing "variable is unused" warnings.
|
||||
#define CGAL_USE(x) ::CGAL::internal::use(x)
|
||||
#define CGAL_USE(...) ::CGAL::internal::use(__VA_ARGS__)
|
||||
|
||||
/// CGAL_USE_TYPE() is a macro which aims at removing "typedef locally
|
||||
/// defined but not used" warnings.
|
||||
|
|
|
|||
|
|
@ -177,7 +177,7 @@ class Interval_for_container : public Interval_
|
|||
|
||||
|
||||
// remove markers for Interval I starting at left, the left endpoint
|
||||
// of I, and and stopping at the right endpoint of I.
|
||||
// of I, and stopping at the right endpoint of I.
|
||||
Interval_handle removeMarkers(IntervalSLnode<Interval>* left,
|
||||
const Interval& I);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2019
|
||||
// Copyright (c) 2019,2025
|
||||
// GeometryFactory (France)
|
||||
//
|
||||
// This file is part of CGAL (www.cgal.org)
|
||||
|
|
@ -9,6 +9,8 @@
|
|||
//
|
||||
//
|
||||
// Author(s) : Simon Giraudot
|
||||
//
|
||||
// Test file: test/Kernel_23/test_hash_functions.cpp
|
||||
|
||||
#ifndef CGAL_KERNEL_HASH_FUNCTIONS_H
|
||||
#define CGAL_KERNEL_HASH_FUNCTIONS_H
|
||||
|
|
@ -16,18 +18,73 @@
|
|||
#include <boost/functional/hash.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
#include <CGAL/representation_tags.h>
|
||||
#include <CGAL/Aff_transformation_2.h>
|
||||
#include <CGAL/Aff_transformation_3.h>
|
||||
#include <CGAL/Bbox_2.h>
|
||||
#include <CGAL/Bbox_3.h>
|
||||
#include <CGAL/Circle_2.h>
|
||||
#include <CGAL/Iso_rectangle_2.h>
|
||||
#include <CGAL/Iso_cuboid_3.h>
|
||||
#include <CGAL/Point_2.h>
|
||||
#include <CGAL/Point_3.h>
|
||||
#include <CGAL/Segment_2.h>
|
||||
#include <CGAL/Segment_3.h>
|
||||
#include <CGAL/Sphere_3.h>
|
||||
#include <CGAL/Vector_2.h>
|
||||
#include <CGAL/Vector_3.h>
|
||||
#include <CGAL/Weighted_point_2.h>
|
||||
#include <CGAL/Weighted_point_3.h>
|
||||
|
||||
|
||||
namespace CGAL
|
||||
{
|
||||
|
||||
using boost::hash_value;
|
||||
|
||||
template <typename K, typename = void>
|
||||
inline constexpr bool has_rep_tag_v = false;
|
||||
|
||||
template <typename K>
|
||||
inline std::enable_if_t<std::is_same<typename K::Rep_tag, Cartesian_tag>::value, std::size_t>
|
||||
inline constexpr bool has_rep_tag_v<K, std::void_t<typename K::Rep_tag>> = true;
|
||||
|
||||
template <typename K, typename = void>
|
||||
struct Rep_tag {
|
||||
using type = void;
|
||||
};
|
||||
|
||||
template <typename K>
|
||||
struct Rep_tag<K, std::enable_if_t<has_rep_tag_v<K>>> {
|
||||
using type = typename K::Rep_tag;
|
||||
};
|
||||
|
||||
template <typename K>
|
||||
using Rep_tag_t = typename Rep_tag<K>::type;
|
||||
|
||||
template <typename K>
|
||||
inline constexpr bool is_Cartesian_v = std::is_same<Rep_tag_t<K>, Cartesian_tag>::value;
|
||||
|
||||
template <typename K, typename = void>
|
||||
struct Is_kernel_hashable : public std::false_type {};
|
||||
|
||||
template <typename K>
|
||||
struct Is_kernel_hashable<K, std::void_t<decltype(hash_value(std::declval<typename K::FT>()))>> : public std::true_type {};
|
||||
|
||||
template <typename K>
|
||||
inline constexpr bool is_kernel_hashable_v = Is_kernel_hashable<K>::value;
|
||||
|
||||
template <typename K, typename T>
|
||||
using enable_if_Cartesian_and_hashable_t =
|
||||
std::enable_if_t<is_Cartesian_v<K> && is_kernel_hashable_v<K>, T>;
|
||||
|
||||
template <typename K>
|
||||
inline enable_if_Cartesian_and_hashable_t<K, std::size_t>
|
||||
hash_value (const Aff_transformation_2<K>& transform)
|
||||
{
|
||||
std::size_t result = hash_value(transform.cartesian(0,0));
|
||||
for(int i=0; i < 3; ++i)
|
||||
for(int j = 0; j < 3; ++j)
|
||||
for(int j=0; j < 3; ++j)
|
||||
// Skip (0,0) as it was already used to initialize the hash
|
||||
if (!(i == 0 && j == 0))
|
||||
boost::hash_combine(result, hash_value(transform.cartesian(i,j)));
|
||||
return result;
|
||||
|
|
@ -44,7 +101,7 @@ hash_value (const Bbox_2& bbox)
|
|||
}
|
||||
|
||||
template <typename K>
|
||||
inline std::enable_if_t<std::is_same<typename K::Rep_tag, Cartesian_tag>::value, std::size_t>
|
||||
inline enable_if_Cartesian_and_hashable_t<K, std::size_t>
|
||||
hash_value (const Circle_2<K>& circle)
|
||||
{
|
||||
std::size_t result = hash_value(circle.center());
|
||||
|
|
@ -54,7 +111,7 @@ hash_value (const Circle_2<K>& circle)
|
|||
}
|
||||
|
||||
template <typename K>
|
||||
inline std::enable_if_t<std::is_same<typename K::Rep_tag, Cartesian_tag>::value, std::size_t>
|
||||
inline enable_if_Cartesian_and_hashable_t<K, std::size_t>
|
||||
hash_value (const Iso_rectangle_2<K>& iso_rectangle)
|
||||
{
|
||||
std::size_t result = hash_value((iso_rectangle.min)());
|
||||
|
|
@ -63,7 +120,7 @@ hash_value (const Iso_rectangle_2<K>& iso_rectangle)
|
|||
}
|
||||
|
||||
template <typename K>
|
||||
inline std::enable_if_t<std::is_same<typename K::Rep_tag, Cartesian_tag>::value, std::size_t>
|
||||
inline enable_if_Cartesian_and_hashable_t<K, std::size_t>
|
||||
hash_value (const Point_2<K>& point)
|
||||
{
|
||||
std::size_t result = hash_value(point.x());
|
||||
|
|
@ -72,7 +129,7 @@ hash_value (const Point_2<K>& point)
|
|||
}
|
||||
|
||||
template <typename K>
|
||||
inline std::enable_if_t<std::is_same<typename K::Rep_tag, Cartesian_tag>::value, std::size_t>
|
||||
inline enable_if_Cartesian_and_hashable_t<K, std::size_t>
|
||||
hash_value (const Segment_2<K>& segment)
|
||||
{
|
||||
std::size_t result = hash_value(segment.source());
|
||||
|
|
@ -81,7 +138,7 @@ hash_value (const Segment_2<K>& segment)
|
|||
}
|
||||
|
||||
template <typename K>
|
||||
inline std::enable_if_t<std::is_same<typename K::Rep_tag, Cartesian_tag>::value, std::size_t>
|
||||
inline enable_if_Cartesian_and_hashable_t<K, std::size_t>
|
||||
hash_value (const Vector_2<K>& vector)
|
||||
{
|
||||
std::size_t result = hash_value(vector.x());
|
||||
|
|
@ -90,7 +147,7 @@ hash_value (const Vector_2<K>& vector)
|
|||
}
|
||||
|
||||
template <typename K>
|
||||
inline std::enable_if_t<std::is_same<typename K::Rep_tag, Cartesian_tag>::value, std::size_t>
|
||||
inline enable_if_Cartesian_and_hashable_t<K, std::size_t>
|
||||
hash_value (const Weighted_point_2<K>& weighed_point)
|
||||
{
|
||||
std::size_t result = hash_value(weighed_point.point());
|
||||
|
|
@ -99,14 +156,13 @@ hash_value (const Weighted_point_2<K>& weighed_point)
|
|||
}
|
||||
|
||||
template <typename K>
|
||||
inline std::enable_if_t<std::is_same<typename K::Rep_tag, Cartesian_tag>::value, std::size_t>
|
||||
inline enable_if_Cartesian_and_hashable_t<K, std::size_t>
|
||||
hash_value (const Aff_transformation_3<K>& transform)
|
||||
{
|
||||
std::size_t result = hash_value(transform.cartesian(0,0));
|
||||
for(int i = 0; i < 3; ++i)
|
||||
for(int j = 0; j < 4; ++j)
|
||||
if (!(i == 0 && j == 0))
|
||||
boost::hash_combine(result, hash_value(transform.cartesian(i,j)));
|
||||
for(int j = (i == 0 ? 1 : 0); j < 4; ++j)
|
||||
boost::hash_combine(result, hash_value(transform.cartesian(i,j)));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -123,7 +179,7 @@ hash_value (const Bbox_3& bbox)
|
|||
}
|
||||
|
||||
template <typename K>
|
||||
inline std::enable_if_t<std::is_same<typename K::Rep_tag, Cartesian_tag>::value, std::size_t>
|
||||
inline enable_if_Cartesian_and_hashable_t<K, std::size_t>
|
||||
hash_value (const Iso_cuboid_3<K>& iso_cuboid)
|
||||
{
|
||||
std::size_t result = hash_value((iso_cuboid.min)());
|
||||
|
|
@ -132,7 +188,7 @@ hash_value (const Iso_cuboid_3<K>& iso_cuboid)
|
|||
}
|
||||
|
||||
template <typename K>
|
||||
inline std::enable_if_t<std::is_same<typename K::Rep_tag, Cartesian_tag>::value, std::size_t>
|
||||
inline enable_if_Cartesian_and_hashable_t<K, std::size_t>
|
||||
hash_value (const Point_3<K>& point)
|
||||
{
|
||||
std::size_t result = hash_value(point.x());
|
||||
|
|
@ -142,7 +198,7 @@ hash_value (const Point_3<K>& point)
|
|||
}
|
||||
|
||||
template <typename K>
|
||||
inline std::enable_if_t<std::is_same<typename K::Rep_tag, Cartesian_tag>::value, std::size_t>
|
||||
inline enable_if_Cartesian_and_hashable_t<K, std::size_t>
|
||||
hash_value (const Segment_3<K>& segment)
|
||||
{
|
||||
std::size_t result = hash_value(segment.source());
|
||||
|
|
@ -151,7 +207,7 @@ hash_value (const Segment_3<K>& segment)
|
|||
}
|
||||
|
||||
template <typename K>
|
||||
inline std::enable_if_t<std::is_same<typename K::Rep_tag, Cartesian_tag>::value, std::size_t>
|
||||
inline enable_if_Cartesian_and_hashable_t<K, std::size_t>
|
||||
hash_value (const Sphere_3<K>& sphere)
|
||||
{
|
||||
std::size_t result = hash_value(sphere.center());
|
||||
|
|
@ -161,7 +217,7 @@ hash_value (const Sphere_3<K>& sphere)
|
|||
}
|
||||
|
||||
template <typename K>
|
||||
inline std::enable_if_t<std::is_same<typename K::Rep_tag, Cartesian_tag>::value, std::size_t>
|
||||
inline enable_if_Cartesian_and_hashable_t<K, std::size_t>
|
||||
hash_value (const Vector_3<K>& vector)
|
||||
{
|
||||
std::size_t result = hash_value(vector.x());
|
||||
|
|
@ -171,7 +227,7 @@ hash_value (const Vector_3<K>& vector)
|
|||
}
|
||||
|
||||
template <typename K>
|
||||
inline std::enable_if_t<std::is_same<typename K::Rep_tag, Cartesian_tag>::value, std::size_t>
|
||||
inline enable_if_Cartesian_and_hashable_t<K, std::size_t>
|
||||
hash_value (const Weighted_point_3<K>& weighed_point)
|
||||
{
|
||||
std::size_t result = hash_value(weighed_point.point());
|
||||
|
|
@ -179,93 +235,46 @@ hash_value (const Weighted_point_3<K>& weighed_point)
|
|||
return result;
|
||||
}
|
||||
|
||||
struct Forward_to_hash_value {
|
||||
template <typename T>
|
||||
std::size_t operator()(T&& t) const {
|
||||
using boost::hash_value;
|
||||
return hash_value(std::forward<T>(t));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename K, typename = void>
|
||||
struct Maybe_forward_to_hash_value {
|
||||
Maybe_forward_to_hash_value() = delete;
|
||||
Maybe_forward_to_hash_value(const Maybe_forward_to_hash_value&) = delete;
|
||||
};
|
||||
|
||||
template <typename K>
|
||||
struct Maybe_forward_to_hash_value<K, std::enable_if_t<is_kernel_hashable_v<K>>>
|
||||
: public Forward_to_hash_value {};
|
||||
|
||||
|
||||
} //namespace CGAL
|
||||
|
||||
// overloads of std::hash used for using std::unordered_[set/map] on CGAL Kernel objects
|
||||
namespace std
|
||||
{
|
||||
namespace std {
|
||||
template <typename K> struct hash<CGAL::Aff_transformation_2<K>> : CGAL::Maybe_forward_to_hash_value<K> {};
|
||||
template <typename K> struct hash<CGAL::Circle_2<K>> : CGAL::Maybe_forward_to_hash_value<K> {};
|
||||
template <typename K> struct hash<CGAL::Iso_rectangle_2<K>> : CGAL::Maybe_forward_to_hash_value<K> {};
|
||||
template <typename K> struct hash<CGAL::Point_2<K>> : CGAL::Maybe_forward_to_hash_value<K> {};
|
||||
template <typename K> struct hash<CGAL::Segment_2<K>> : CGAL::Maybe_forward_to_hash_value<K> {};
|
||||
template <typename K> struct hash<CGAL::Vector_2<K>> : CGAL::Maybe_forward_to_hash_value<K> {};
|
||||
template <typename K> struct hash<CGAL::Weighted_point_2<K>> : CGAL::Maybe_forward_to_hash_value<K> {};
|
||||
template <> struct hash<CGAL::Bbox_2> : CGAL::Forward_to_hash_value {};
|
||||
template <typename K> struct hash<CGAL::Aff_transformation_3<K>> : CGAL::Maybe_forward_to_hash_value<K> {};
|
||||
template <typename K> struct hash<CGAL::Iso_cuboid_3<K>> : CGAL::Maybe_forward_to_hash_value<K> {};
|
||||
template <typename K> struct hash<CGAL::Point_3<K>> : CGAL::Maybe_forward_to_hash_value<K> {};
|
||||
template <typename K> struct hash<CGAL::Segment_3<K>> : CGAL::Maybe_forward_to_hash_value<K> {};
|
||||
template <typename K> struct hash<CGAL::Sphere_3<K>> : CGAL::Maybe_forward_to_hash_value<K> {};
|
||||
template <typename K> struct hash<CGAL::Vector_3<K>> : CGAL::Maybe_forward_to_hash_value<K> {};
|
||||
template <typename K> struct hash<CGAL::Weighted_point_3<K>> : CGAL::Maybe_forward_to_hash_value<K> {};
|
||||
template <> struct hash<CGAL::Bbox_3> : CGAL::Forward_to_hash_value {};
|
||||
} // namespace std
|
||||
|
||||
template <typename K> struct hash<CGAL::Aff_transformation_2<K> > {
|
||||
std::size_t operator() (const CGAL::Aff_transformation_2<K>& transform) const {
|
||||
return CGAL::hash_value<K> (transform);
|
||||
}
|
||||
};
|
||||
template <> struct hash<CGAL::Bbox_2> {
|
||||
std::size_t operator() (const CGAL::Bbox_2& bbox) const {
|
||||
return CGAL::hash_value (bbox);
|
||||
}
|
||||
};
|
||||
template <typename K> struct hash<CGAL::Circle_2<K> > {
|
||||
std::size_t operator() (const CGAL::Circle_2<K>& circle) const {
|
||||
return CGAL::hash_value<K> (circle);
|
||||
}
|
||||
};
|
||||
template <typename K> struct hash<CGAL::Iso_rectangle_2<K> > {
|
||||
std::size_t operator() (const CGAL::Iso_rectangle_2<K>& iso_rectangle) const {
|
||||
return CGAL::hash_value<K> (iso_rectangle);
|
||||
}
|
||||
};
|
||||
template <typename K> struct hash<CGAL::Point_2<K> > {
|
||||
std::size_t operator() (const CGAL::Point_2<K>& point) const {
|
||||
return CGAL::hash_value<K> (point);
|
||||
}
|
||||
};
|
||||
template <typename K> struct hash<CGAL::Segment_2<K> > {
|
||||
std::size_t operator() (const CGAL::Segment_2<K>& segment) const {
|
||||
return CGAL::hash_value<K> (segment);
|
||||
}
|
||||
};
|
||||
template <typename K> struct hash<CGAL::Vector_2<K> > {
|
||||
std::size_t operator() (const CGAL::Vector_2<K>& vector) const {
|
||||
return CGAL::hash_value<K> (vector);
|
||||
}
|
||||
};
|
||||
template <typename K> struct hash<CGAL::Weighted_point_2<K> > {
|
||||
std::size_t operator() (const CGAL::Weighted_point_2<K>& weighted_point) const {
|
||||
return CGAL::hash_value<K> (weighted_point);
|
||||
}
|
||||
};
|
||||
template <typename K> struct hash<CGAL::Aff_transformation_3<K> > {
|
||||
std::size_t operator() (const CGAL::Aff_transformation_3<K>& transform) const {
|
||||
return CGAL::hash_value<K> (transform);
|
||||
}
|
||||
};
|
||||
template <> struct hash<CGAL::Bbox_3> {
|
||||
std::size_t operator() (const CGAL::Bbox_3& bbox) const {
|
||||
return CGAL::hash_value (bbox);
|
||||
}
|
||||
};
|
||||
template <typename K> struct hash<CGAL::Iso_cuboid_3<K> > {
|
||||
std::size_t operator() (const CGAL::Iso_cuboid_3<K>& iso_cuboid) const {
|
||||
return CGAL::hash_value<K> (iso_cuboid);
|
||||
}
|
||||
};
|
||||
template <typename K> struct hash<CGAL::Point_3<K> > {
|
||||
std::size_t operator() (const CGAL::Point_3<K>& point) const {
|
||||
return CGAL::hash_value<K> (point);
|
||||
}
|
||||
};
|
||||
template <typename K> struct hash<CGAL::Segment_3<K> > {
|
||||
std::size_t operator() (const CGAL::Segment_3<K>& segment) const {
|
||||
return CGAL::hash_value<K> (segment);
|
||||
}
|
||||
};
|
||||
template <typename K> struct hash<CGAL::Sphere_3<K> > {
|
||||
std::size_t operator() (const CGAL::Sphere_3<K>& sphere) const {
|
||||
return CGAL::hash_value<K> (sphere);
|
||||
}
|
||||
};
|
||||
template <typename K> struct hash<CGAL::Vector_3<K> > {
|
||||
std::size_t operator() (const CGAL::Vector_3<K>& vector) const {
|
||||
return CGAL::hash_value<K> (vector);
|
||||
}
|
||||
};
|
||||
template <typename K> struct hash<CGAL::Weighted_point_3<K> > {
|
||||
std::size_t operator() (const CGAL::Weighted_point_3<K>& weighted_point) const {
|
||||
return CGAL::hash_value<K> (weighted_point);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // CGAL_KERNEL_HASH_FUNCTIONS_H
|
||||
|
|
|
|||
|
|
@ -1,13 +1,18 @@
|
|||
// test partially generated by Github Copilot
|
||||
|
||||
#include <unordered_set>
|
||||
|
||||
#include <CGAL/Simple_cartesian.h>
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
|
||||
#include <CGAL/Bbox_2.h>
|
||||
#include <CGAL/Bbox_3.h>
|
||||
|
||||
typedef CGAL::Simple_cartesian<double> SC;
|
||||
typedef CGAL::Exact_predicates_inexact_constructions_kernel Epick;
|
||||
|
||||
static_assert(CGAL::is_kernel_hashable_v<SC>);
|
||||
static_assert(CGAL::is_kernel_hashable_v<Epick>);
|
||||
|
||||
template <typename Object>
|
||||
void test (const Object& obj)
|
||||
{
|
||||
|
|
@ -67,5 +72,3 @@ int main()
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@ Modular_arithmetic
|
|||
Number_types
|
||||
Orthtree
|
||||
Point_set_3
|
||||
Point_set_processing_3
|
||||
Polygon
|
||||
Polygon_mesh_processing
|
||||
Principal_component_analysis
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@ Modular_arithmetic
|
|||
Number_types
|
||||
Orthtree
|
||||
Point_set_3
|
||||
Point_set_processing_3
|
||||
Polygon
|
||||
Polygon_mesh_processing
|
||||
Principal_component_analysis
|
||||
|
|
|
|||
|
|
@ -1795,8 +1795,8 @@ bool MainWindow::loadScript(QFileInfo info)
|
|||
QString program;
|
||||
QString filename = info.absoluteFilePath();
|
||||
QFile script_file(filename);
|
||||
script_file.open(QIODevice::ReadOnly);
|
||||
if(!script_file.isReadable()) {
|
||||
bool success = script_file.open(QIODevice::ReadOnly);
|
||||
if((! success) || (!script_file.isReadable())) {
|
||||
throw std::ios_base::failure(script_file.errorString().toStdString());
|
||||
}
|
||||
program = script_file.readAll();
|
||||
|
|
@ -2747,9 +2747,9 @@ void MainWindow::exportStatistics()
|
|||
if(filename.isEmpty())
|
||||
return;
|
||||
QFile output(filename);
|
||||
output.open(QIODevice::WriteOnly | QIODevice::Text);
|
||||
bool success = output.open(QIODevice::WriteOnly | QIODevice::Text);
|
||||
|
||||
if(!output.isOpen()){
|
||||
if((! success) || (!output.isOpen())){
|
||||
qDebug() << "- Error, unable to open" << "outputFilename" << "for output";
|
||||
}
|
||||
QTextStream outStream(&output);
|
||||
|
|
|
|||
|
|
@ -93,18 +93,20 @@ bool Camera_positions_list::save(QString filename) {
|
|||
if(m_model->rowCount() <1)
|
||||
return false;
|
||||
QFile file(filename);
|
||||
file.open(QIODevice::WriteOnly);
|
||||
QTextStream out(&file);
|
||||
for(int i = 0; i < m_model->rowCount(); ++i)
|
||||
{
|
||||
QStandardItem* item = m_model->item(i);
|
||||
out << item->data(Qt::DisplayRole).toString()
|
||||
<< "\n"
|
||||
<< item->data(Qt::UserRole).toString()
|
||||
<< "\n";
|
||||
if(file.open(QIODevice::WriteOnly)){
|
||||
QTextStream out(&file);
|
||||
for(int i = 0; i < m_model->rowCount(); ++i)
|
||||
{
|
||||
QStandardItem* item = m_model->item(i);
|
||||
out << item->data(Qt::DisplayRole).toString()
|
||||
<< "\n"
|
||||
<< item->data(Qt::UserRole).toString()
|
||||
<< "\n";
|
||||
}
|
||||
file.close();
|
||||
return true;
|
||||
}
|
||||
file.close();
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void Camera_positions_list::on_saveButton_pressed()
|
||||
|
|
@ -129,19 +131,24 @@ void Camera_positions_list::on_openButton_pressed()
|
|||
|
||||
void Camera_positions_list::load(QString filename) {
|
||||
QFile file(filename);
|
||||
std::clog << "Loading camera positions " << qPrintable(filename) << std::endl;
|
||||
file.open(QIODevice::ReadOnly);
|
||||
QTextStream input(&file);
|
||||
while(!input.atEnd()) {
|
||||
QString text = input.readLine(1000);
|
||||
QString coord = input.readLine(1000);
|
||||
if(text.isNull() || coord.isNull()) return;
|
||||
CGAL::qglviewer::Frame frame;
|
||||
if(Three::activeViewer()->readFrame(coord, frame))
|
||||
{
|
||||
addItem(text,
|
||||
Three::activeViewer()->dumpFrame(frame));
|
||||
|
||||
if(file.open(QIODevice::ReadOnly)){
|
||||
std::clog << "Loading camera positions " << qPrintable(filename) << std::endl;
|
||||
|
||||
QTextStream input(&file);
|
||||
while(!input.atEnd()) {
|
||||
QString text = input.readLine(1000);
|
||||
QString coord = input.readLine(1000);
|
||||
if(text.isNull() || coord.isNull()) return;
|
||||
CGAL::qglviewer::Frame frame;
|
||||
if(Three::activeViewer()->readFrame(coord, frame))
|
||||
{
|
||||
addItem(text,
|
||||
Three::activeViewer()->dumpFrame(frame));
|
||||
}
|
||||
}
|
||||
}else {
|
||||
std::clog << "Loading camera positions " << qPrintable(filename) << " failed" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,68 @@
|
|||
namespace CGAL {
|
||||
namespace IO {
|
||||
|
||||
/** \file VTK.h
|
||||
* Functions to import/export 3D Linear_cell_complex from/to VTK legacy ASCII
|
||||
* format.
|
||||
*
|
||||
* Only supports:
|
||||
* - `CGAL::Linear_cell_complex_for_combinatorial_map<3,3>`
|
||||
* - VTK legacy ASCII format (.vtk files)
|
||||
* - Optional scalar fields for vertices and volumes
|
||||
*
|
||||
* Supported VTK cell types:
|
||||
* - VTK_TETRA (10): Tetrahedron
|
||||
* - VTK_VOXEL (11): Voxel (special hexahedron ordering)
|
||||
* - VTK_HEXAHEDRON (12): Hexahedron
|
||||
* - VTK_WEDGE (13): Prism/Wedge
|
||||
* - VTK_PYRAMID (14): Pyramid
|
||||
* - VTK_PENTAGONAL_PRISM (15): Pentagonal prism
|
||||
* - VTK_HEXAGONAL_PRISM (16): Hexagonal prism
|
||||
* - VTK_POLYHEDRON (42): Generic polyhedron
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief Reads a VTK legacy ASCII file and load it into a 3D
|
||||
* linear cell complex.
|
||||
* \ingroup PkgLinearCellComplexRefIOVTK
|
||||
*
|
||||
* \tparam LCC must be a `CGAL::Linear_cell_complex_for_combinatorial_map<3,3>`
|
||||
* \tparam VertexScalarType Type for vertex scalar data (default: float)
|
||||
* \tparam VolumeScalarType Type for volume scalar data (default: float)
|
||||
* \param filename Path to the VTK file
|
||||
* \param alcc The linear cell complex to populate (will be cleared first)
|
||||
* \param vertex_scalars Optional output vector to store per-vertex scalar values.
|
||||
* If provided, will be resized to match number of vertices.
|
||||
* \param volume_scalars Optional output vector to store per-volume scalar values.
|
||||
* If provided, will be resized to match number of volumes.
|
||||
* \return `true` if loading was successful, `false` otherwise
|
||||
*/
|
||||
template <typename LCC, typename VertexScalarType, typename VolumeScalarType>
|
||||
bool read_VTK(const char* filename,
|
||||
LCC& alcc,
|
||||
std::vector<VertexScalarType>* vertex_scalars=nullptr,
|
||||
std::vector<VolumeScalarType>* volume_scalars=nullptr);
|
||||
|
||||
/**
|
||||
* \brief Writes a 3D Linear_cell_complex to a VTK legacy ASCII file.
|
||||
* \ingroup PkgLinearCellComplexRefIOVTK
|
||||
*
|
||||
* \tparam LCC must be a `CGAL::Linear_cell_complex_for_combinatorial_map<3,3>`
|
||||
* \tparam VertexScalarType Type for vertex scalar data (default: float)
|
||||
* \tparam VolumeScalarType Type for volume scalar data (default: float)
|
||||
* \param filename Path to the output VTK file
|
||||
* \param alcc The linear cell complex to export
|
||||
* \param vertex_scalars Optional per-vertex scalar data. If provided, must have
|
||||
* same size as number of vertex attributes in the LCC.
|
||||
* \param volume_scalars Optional per-volume scalar data. If provided, must have
|
||||
* same size as number of 3-cells in the LCC.
|
||||
* \return `true` if writing was successful, `false` otherwise
|
||||
*/
|
||||
template <typename LCC, typename VertexScalarType, typename VolumeScalarType>
|
||||
bool write_VTK(const char* filename,
|
||||
const LCC& alcc,
|
||||
const std::vector<VertexScalarType>* vertex_scalars=nullptr,
|
||||
const std::vector<VolumeScalarType>* volume_scalars=nullptr);
|
||||
|
||||
} // namespace IO
|
||||
} // namespace CGAL
|
||||
|
|
@ -289,6 +289,18 @@ The following example shows the use of \link GenericMap::insert_cell_1_between_t
|
|||
Result of the run of the linear_cell_complex_3_insert program. A window shows the 3D cube where one face has a hole.
|
||||
\cgalFigureEnd
|
||||
|
||||
\subsection Linear_cell_complexWriteVTK Writing a Linear Cell Complex to a VTK File
|
||||
\anchor ssecLCCWriteVtK
|
||||
|
||||
This example loads a 3D linear cell complex from a `.3map` file (using the `operator>>`). It computes for each 3-cell (volume) the number of incident vertices (0-cells), stores these values in a `std::vector<std::size_t>`, and writes the result to a `.vtk` file using `CGAL::IO::write_VTK()`, with the computed values as scalars for each volume.
|
||||
|
||||
\cgalExample{Linear_cell_complex/linear_cell_complex_3_vtk_io.cpp}
|
||||
|
||||
\cgalFigureBegin{fig_lcc_export_vtk,lcc-export-vtk.png}
|
||||
Visualization of the VTK file generated by the `linear_cell_complex_3_vtk_io` program, using Paraview. Each volume is colored depending on its number of vertices.
|
||||
\cgalFigureEnd
|
||||
|
||||
|
||||
\section Linear_cell_complexDesign Design and Implementation History
|
||||
|
||||
This package was developed by Guillaume Damiand, with the help of Andreas Fabri, Sébastien Loriot and Laurent Rineau. Monique Teillaud and Bernd Gärtner contributed to the manual.
|
||||
|
|
|
|||
|
|
@ -23,6 +23,14 @@
|
|||
/// \defgroup PkgDrawLinearCellComplex Draw a Linear Cell Complex
|
||||
/// \ingroup PkgLinearCellComplexRef
|
||||
|
||||
/// \defgroup PkgLinearCellComplexRefIO IO Functions for LCC
|
||||
/// \ingroup PkgLinearCellComplexRef
|
||||
|
||||
/*! High-level operations.
|
||||
\cgalInclude{CGAL/Linear_cell_complex/IO/VTK.h}
|
||||
*/
|
||||
/// \defgroup PkgLinearCellComplexRefIOVTK VTK IO Functions for LCC
|
||||
/// \ingroup PkgLinearCellComplexRefIO
|
||||
|
||||
/*!
|
||||
\addtogroup PkgLinearCellComplexRef
|
||||
|
|
@ -74,4 +82,10 @@
|
|||
- \link PkgDrawLinearCellComplex CGAL::draw<LCC>() \endlink
|
||||
- \link PkgDrawLinearCellComplex CGAL::add_in_graphics_scene<LCC, BufferType, DrawingFunctor>() \endlink
|
||||
|
||||
\cgalCRPSubsection{IO Functions for LCC}
|
||||
- \link PkgCombinatorialMapsRefIO `std::ostream& operator<< (std::ostream& os, const GenericMap& amap)` \endlink
|
||||
- \link PkgCombinatorialMapsRefIO `std::ifstream& operator>> (std::ifstream& is, GenericMap& amap)` \endlink
|
||||
- \link PkgLinearCellComplexRefIOVTK `CGAL::IO::Read_VTK<LCC>()` \endlink
|
||||
- \link PkgLinearCellComplexRefIOVTK `CGAL::IO::Write_VTK<LCC>()` \endlink
|
||||
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -6,4 +6,5 @@
|
|||
\example Linear_cell_complex/linear_cell_complex_3_incremental_builder.cpp
|
||||
\example Linear_cell_complex/draw_linear_cell_complex.cpp
|
||||
\example Linear_cell_complex/linear_cell_complex_3_insert.cpp
|
||||
\example Linear_cell_complex/linear_cell_complex_3_vtk_io.cpp
|
||||
*/
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 89 KiB |
|
|
@ -27,6 +27,7 @@ create_single_source_cgal_program("linear_cell_complex_4.cpp")
|
|||
create_single_source_cgal_program("read_plane_graph_in_lcc_2.cpp")
|
||||
create_single_source_cgal_program("voronoi_2.cpp")
|
||||
create_single_source_cgal_program("voronoi_3.cpp")
|
||||
create_single_source_cgal_program("linear_cell_complex_3_vtk_io.cpp")
|
||||
|
||||
create_single_source_cgal_program("draw_linear_cell_complex.cpp")
|
||||
if(CGAL_Qt6_FOUND)
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,34 @@
|
|||
#include <CGAL/Linear_cell_complex_for_combinatorial_map.h>
|
||||
#include <CGAL/Linear_cell_complex/IO/VTK.h>
|
||||
#include <vector>
|
||||
#include <cstdlib>
|
||||
|
||||
int main()
|
||||
{
|
||||
CGAL::Linear_cell_complex_for_combinatorial_map<3> lcc;
|
||||
std::ifstream is("data/beam-with-mixed-cells.3map");
|
||||
if(!is)
|
||||
{
|
||||
std::cout<<"Error opening data/beam-with-mixed-cells.3map."<<std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
is>>lcc;
|
||||
// Compute per-volume vertex count
|
||||
std::vector<std::size_t> volume_scalars;
|
||||
for(auto it=lcc.template one_dart_per_cell<3>().begin(),
|
||||
itend=lcc.template one_dart_per_cell<3>().end(); it!=itend; ++it)
|
||||
{
|
||||
std::size_t nbv=lcc.template one_dart_per_incident_cell<0,3>(it).size();
|
||||
volume_scalars.push_back(nbv);
|
||||
}
|
||||
|
||||
if(!CGAL::IO::write_VTK("beam-with-mixed-cells.vtk", lcc, nullptr,
|
||||
&volume_scalars))
|
||||
{
|
||||
std::cout<<"Error for write_VTK."<<std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
@ -0,0 +1,719 @@
|
|||
// 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 CGAL_LCC_IO_VTK_H
|
||||
#define CGAL_LCC_IO_VTK_H
|
||||
|
||||
#include <CGAL/Linear_cell_complex_incremental_builder_3.h>
|
||||
#include <CGAL/assertions.h>
|
||||
#include <CGAL/Element_topo.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
||||
namespace CGAL {
|
||||
namespace IO {
|
||||
|
||||
/*
|
||||
* Functions to import/export 3D Linear_cell_complex from/to VTK legacy ASCII
|
||||
* format.
|
||||
*
|
||||
* Only supports:
|
||||
* - Linear_cell_complex_for_combinatorial_map<3,3>
|
||||
* - VTK legacy ASCII format (.vtk files)
|
||||
* - Optional scalar fields for vertices and volumes
|
||||
*
|
||||
* Supported VTK cell types:
|
||||
* - VTK_TETRA (10): Tetrahedron
|
||||
* - VTK_VOXEL (11): Voxel (special hexahedron ordering)
|
||||
* - VTK_HEXAHEDRON (12): Hexahedron
|
||||
* - VTK_WEDGE (13): Prism/Wedge
|
||||
* - VTK_PYRAMID (14): Pyramid
|
||||
* - VTK_PENTAGONAL_PRISM (15): Pentagonal prism
|
||||
* - VTK_HEXAGONAL_PRISM (16): Hexagonal prism
|
||||
* - VTK_POLYHEDRON (42): Generic polyhedron
|
||||
*/
|
||||
|
||||
// ============================================================================
|
||||
// Declarations
|
||||
// ============================================================================
|
||||
|
||||
/*
|
||||
* Read a VTK legacy ASCII file and load it into a 3D Linear_cell_complex.
|
||||
*
|
||||
* \tparam LCC must be a Linear_cell_complex_for_combinatorial_map<3,3>
|
||||
* \tparam VertexScalarType Type for vertex scalar data (default: float)
|
||||
* \tparam VolumeScalarType Type for volume scalar data (default: float)
|
||||
* \param alcc The Linear_cell_complex to populate (will be cleared first)
|
||||
* \param filename Path to the VTK file
|
||||
* \param vertex_scalars Optional output vector to store per-vertex scalar values.
|
||||
* If provided, will be resized to match number of vertices.
|
||||
* \param volume_scalars Optional output vector to store per-volume scalar values.
|
||||
* If provided, will be resized to match number of volumes.
|
||||
* \return `true` if loading was successful, `false` otherwise
|
||||
*/
|
||||
template <typename LCC, typename VertexScalarType,
|
||||
typename VolumeScalarType>
|
||||
bool read_VTK(const char* filename,
|
||||
LCC& alcc,
|
||||
std::vector<VertexScalarType>* vertex_scalars,
|
||||
std::vector<VolumeScalarType>* volume_scalars);
|
||||
|
||||
/*
|
||||
* Write a 3D Linear_cell_complex to a VTK legacy ASCII file.
|
||||
*
|
||||
* \tparam LCC must be a Linear_cell_complex_for_combinatorial_map<3,3>
|
||||
* \tparam VertexScalarType Type for vertex scalar data (default: float)
|
||||
* \tparam VolumeScalarType Type for volume scalar data (default: float)
|
||||
* \param alcc The Linear_cell_complex to export
|
||||
* \param filename Path to the output VTK file
|
||||
* \param vertex_scalars Optional per-vertex scalar data. If provided, must have
|
||||
* same size as number of vertex attributes in the LCC.
|
||||
* \param volume_scalars Optional per-volume scalar data. If provided, must have
|
||||
* same size as number of 3-cells in the LCC.
|
||||
* \return `true` if writing was successful, `false` otherwise
|
||||
*/
|
||||
template <typename LCC, typename VertexScalarType,
|
||||
typename VolumeScalarType>
|
||||
bool write_VTK(const char* filename,
|
||||
const LCC& alcc,
|
||||
const std::vector<VertexScalarType>* vertex_scalars,
|
||||
const std::vector<VolumeScalarType>* volume_scalars);
|
||||
|
||||
// "Advanced" versions with functors
|
||||
template <typename LCC, typename PointFunctor, typename CellFunctor>
|
||||
bool write_VTK_with_fct(const char* filename, const LCC& alcc,
|
||||
PointFunctor ptval, CellFunctor cellval);
|
||||
|
||||
// ============================================================================
|
||||
// Implementation details
|
||||
// ============================================================================
|
||||
|
||||
namespace internal
|
||||
{
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// VTK type name mapping
|
||||
// bit, unsigned_char, char, unsigned_short, short, unsigned_int, int,
|
||||
// unsigned_long, long, float, double.
|
||||
template<typename T>
|
||||
struct gettype
|
||||
{ static std::string name() { return "unknown"; }};
|
||||
template<>
|
||||
struct gettype<bool>
|
||||
{ static std::string name() { return "bit"; }};
|
||||
template<>
|
||||
struct gettype<unsigned char>
|
||||
{ static std::string name() { return "unsigned_char"; }};
|
||||
template<>
|
||||
struct gettype<char>
|
||||
{ static std::string name() { return "char"; }};
|
||||
template<>
|
||||
struct gettype<unsigned short int>
|
||||
{ static std::string name() { return "unsigned_short"; }};
|
||||
template<>
|
||||
struct gettype<short int>
|
||||
{ static std::string name() { return "short"; }};
|
||||
template<>
|
||||
struct gettype<unsigned int>
|
||||
{ static std::string name() { return "unsigned_int"; }};
|
||||
template<>
|
||||
struct gettype<int>
|
||||
{ static std::string name() { return "int"; }};
|
||||
template<>
|
||||
struct gettype<unsigned long int>
|
||||
{ static std::string name() { return "unsigned_long"; }};
|
||||
template<>
|
||||
struct gettype<long int>
|
||||
{ static std::string name() { return "long"; }};
|
||||
template<>
|
||||
struct gettype<float>
|
||||
{ static std::string name() { return "float"; }};
|
||||
template<>
|
||||
struct gettype<double>
|
||||
{ static std::string name() { return "double"; }};
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// VTK cell type constants
|
||||
enum VTK_Cell_Type
|
||||
{
|
||||
VTK_TETRA = 10,
|
||||
VTK_VOXEL = 11,
|
||||
VTK_HEXAHEDRON = 12,
|
||||
VTK_WEDGE = 13, // Prism
|
||||
VTK_PYRAMID = 14,
|
||||
VTK_PENTAGONAL_PRISM = 15,
|
||||
VTK_HEXAGONAL_PRISM = 16,
|
||||
VTK_POLYHEDRON = 42 // Generic cell
|
||||
};
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
/// Write cell_data.
|
||||
template<typename FCT>
|
||||
struct Write_cell_data
|
||||
{
|
||||
/// nb is the number of cells,
|
||||
/// fct is a function having 3 parameters: a lcc, a dart_descriptor,
|
||||
/// an the index of the cell.
|
||||
template<typename LCC>
|
||||
static void run(std::ofstream& fo, LCC& lcc, std::size_t nb, FCT fct)
|
||||
{
|
||||
fo<<"CELL_DATA "<<nb<<std::endl;
|
||||
fo<<"SCALARS cell_scalars "
|
||||
<<gettype<decltype(fct(lcc, lcc.null_dart_descriptor, 0))>::name()
|
||||
<<" 1"<<std::endl;
|
||||
fo<<"LOOKUP_TABLE default"<<std::endl;
|
||||
std::size_t i=0;
|
||||
for(auto itvol=lcc.template one_dart_per_cell<3>().begin(),
|
||||
itvolend=lcc.template one_dart_per_cell<3>().end();
|
||||
itvol!=itvolend; ++itvol, ++i)
|
||||
{ fo<<fct(lcc, itvol, i)<<std::endl; }
|
||||
fo<<std::endl;
|
||||
}
|
||||
};
|
||||
template<>
|
||||
struct Write_cell_data<std::nullptr_t>
|
||||
{
|
||||
template<typename LCC>
|
||||
static void run(std::ofstream&, LCC&, std::size_t, std::nullptr_t)
|
||||
{}
|
||||
};
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
/// Write point_data.
|
||||
template<typename FCT>
|
||||
struct Write_point_data
|
||||
{
|
||||
/// nb is the number of cells,
|
||||
/// fct is a function having 3 parameters: a lcc, a dart_descriptor,
|
||||
/// an the index of the cell.
|
||||
template<typename LCC>
|
||||
static void run(std::ofstream& fo, LCC& lcc, std::size_t nb, FCT fct)
|
||||
{
|
||||
fo<<"POINT_DATA "<<nb<<std::endl;
|
||||
fo<<"SCALARS point_scalars "
|
||||
<<gettype<decltype(fct(lcc, lcc.null_dart_descriptor, 0))>::name()
|
||||
<<" 1"<<std::endl;
|
||||
fo<<"LOOKUP_TABLE default"<<std::endl;
|
||||
std::size_t i=0;
|
||||
for(auto itv=lcc.vertex_attributes().begin(),
|
||||
itvend=lcc.vertex_attributes().end(); itv!=itvend; ++itv, ++i)
|
||||
{ fo<<fct(lcc, lcc.template dart_of_attribute<0>(itv), i)<<std::endl; }
|
||||
fo<<std::endl;
|
||||
}
|
||||
};
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
template<>
|
||||
struct Write_point_data<std::nullptr_t>
|
||||
{
|
||||
template<typename LCC>
|
||||
static void run(std::ofstream&, LCC&, std::size_t, std::nullptr_t)
|
||||
{}
|
||||
};
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Read data, stored values as T.
|
||||
template<typename T>
|
||||
bool read_data(std::istream& fi, std::string& line, std::vector<T>& data)
|
||||
{
|
||||
std::string txt, data_type;
|
||||
std::size_t nb;
|
||||
std::istringstream inputline(line);
|
||||
inputline>>txt>>nb; // "CELL_DATA xxx"
|
||||
fi>>txt>>txt; // "SCALARS cell_scalars "
|
||||
fi>>data_type>>txt; // type for data
|
||||
fi>>txt>>txt; // "LOOKUP_TABLE default"
|
||||
if(!fi.good())
|
||||
{ return false; }
|
||||
data.clear();
|
||||
data.reserve(nb);
|
||||
for(std::size_t i=0; i<nb; ++i)
|
||||
{
|
||||
if(!(fi>>txt))
|
||||
{ return false; }
|
||||
|
||||
std::stringstream ss{txt};
|
||||
T t;
|
||||
ss>>t;
|
||||
|
||||
data.push_back(t);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Helper: detect VTK cell type from a 3-cell
|
||||
template<typename LCC>
|
||||
VTK_Cell_Type get_vtk_cell_type(const LCC& lcc,
|
||||
typename LCC::Dart_const_descriptor itvol,
|
||||
typename LCC::Dart_const_descriptor& sd)
|
||||
{
|
||||
using namespace CGAL::CMap::Element_topo;
|
||||
cell_topo vol_type=get_cell_topo<3>(lcc, itvol, sd);
|
||||
switch(vol_type)
|
||||
{
|
||||
case TETRAHEDRON: return VTK_TETRA;
|
||||
case PYRAMID: return VTK_PYRAMID;
|
||||
case PRISM: return VTK_WEDGE;
|
||||
case HEXAHEDRON: return VTK_HEXAHEDRON;
|
||||
// case PENTAGONAL_PRISM: return VTK_PENTAGONAL_PRISM;
|
||||
// case HEXAGONAL_PRISM: return VTK_HEXAGONAL_PRISM;
|
||||
// 24 QUADRATIC_TETRA
|
||||
// 25 QUADRATIC_HEXAHEDRON
|
||||
// 26 QUADRATIC_WEDGE
|
||||
// 27 QUADRATIC_PYRAMID
|
||||
default: break;
|
||||
}
|
||||
return VTK_POLYHEDRON;
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
template <typename LCC, typename VertexScalarType=float,
|
||||
typename CellScalarType=float>
|
||||
bool read_lcc_from_vtk_ascii(std::istream& is, LCC& alcc,
|
||||
std::vector<VertexScalarType>* vertex_scalars=nullptr,
|
||||
std::vector<CellScalarType>* cell_scalars=nullptr)
|
||||
{
|
||||
static_assert(LCC::dimension==3 && LCC::ambient_dimension==3,
|
||||
"read_VTK() only supports 3D Linear_cell_complexes (3,3)");
|
||||
|
||||
using Point=typename LCC::Point;
|
||||
using FT=typename LCC::FT;
|
||||
|
||||
Linear_cell_complex_incremental_builder_3<LCC> ib(alcc);
|
||||
|
||||
std::string line, tmp;
|
||||
std::size_t npoints, ncells;
|
||||
|
||||
// Skip to POINTS section
|
||||
while(std::getline(is, line) && line.find("POINTS")==std::string::npos)
|
||||
{}
|
||||
if(is.eof())
|
||||
{
|
||||
std::cerr<<"[ERROR] read_VTK: POINTS section not found"<<std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::stringstream ss(line);
|
||||
std::getline(ss, tmp, ' '); // skip "POINTS"
|
||||
ss>>npoints;
|
||||
|
||||
// Read points
|
||||
std::vector<typename LCC::Vertex_attribute_descriptor> points(npoints);
|
||||
for(std::size_t i=0; i<npoints; ++i)
|
||||
{
|
||||
FT x, y, z;
|
||||
if(!(is>>x>>y>>z))
|
||||
{
|
||||
std::cerr<<"[ERROR] read_VTK: failed to read point "<<i<<std::endl;
|
||||
return false;
|
||||
}
|
||||
points[i]=ib.add_vertex(Point(x, y, z));
|
||||
}
|
||||
|
||||
// Skip to CELLS section
|
||||
while(std::getline(is, line) && line.find("CELLS")==std::string::npos)
|
||||
{}
|
||||
if(is.eof())
|
||||
{
|
||||
std::cerr<<"[ERROR] read_VTK: CELLS section not found"<<std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
ss=std::stringstream(line);
|
||||
std::getline(ss, tmp, ' '); // skip "CELLS"
|
||||
ss>>ncells;
|
||||
|
||||
// Read connectivity
|
||||
std::vector<std::vector<std::size_t>> faces(ncells);
|
||||
std::size_t points_per_cell;
|
||||
for(std::size_t i=0; i<ncells; ++i)
|
||||
{
|
||||
if(!(is>>points_per_cell))
|
||||
{
|
||||
std::cerr<<"[ERROR] read_VTK: failed to read cell "<<i<<std::endl;
|
||||
return false;
|
||||
}
|
||||
faces[i].resize(points_per_cell);
|
||||
for(std::size_t j=0; j<points_per_cell; ++j)
|
||||
{
|
||||
if(!(is>>faces[i][j]))
|
||||
{
|
||||
std::cerr<<"[ERROR] read_VTK: failed to read cell "<<i<<" vertex "<<j<< std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Skip to CELL_TYPES section
|
||||
while(std::getline(is, line) && line.find("CELL_TYPES")==std::string::npos)
|
||||
{}
|
||||
if(is.eof())
|
||||
{
|
||||
std::cerr<<"[ERROR] read_VTK: CELL_TYPES section not found"<<std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create cells based on types
|
||||
std::size_t cell_type;
|
||||
std::set<std::size_t> error_types;
|
||||
for(std::size_t i = 0; i<ncells; ++i)
|
||||
{
|
||||
if(!(is>>cell_type))
|
||||
{
|
||||
std::cerr<<"[ERROR] read_VTK: failed to read cell type "<<i<< std::endl;
|
||||
return false;
|
||||
}
|
||||
const auto& v=faces[i];
|
||||
switch(cell_type)
|
||||
{
|
||||
case VTK_TETRA:
|
||||
if(v.size()==4)
|
||||
{ make_tetrahedron_with_builder(ib, v[0], v[1], v[2], v[3]); }
|
||||
break;
|
||||
case VTK_VOXEL:
|
||||
if(v.size()==8)
|
||||
{ make_hexahedron_with_builder(ib, v[0], v[1], v[3], v[2], v[4], v[5],
|
||||
v[7], v[6]); }
|
||||
break;
|
||||
case VTK_HEXAHEDRON:
|
||||
if(v.size()==8)
|
||||
{ make_hexahedron_with_builder(ib, v[0], v[1], v[2], v[3], v[4], v[5],
|
||||
v[6], v[7]); }
|
||||
break;
|
||||
case VTK_WEDGE: // PRISM
|
||||
if(v.size()==6)
|
||||
{ make_prism_with_builder(ib, v[0], v[1], v[2], v[3], v[4], v[5]); }
|
||||
break;
|
||||
case VTK_PYRAMID:
|
||||
if(v.size()==5)
|
||||
{ make_pyramid_with_builder(ib, v[0], v[1], v[2], v[3], v[4]); }
|
||||
break;
|
||||
case VTK_PENTAGONAL_PRISM:
|
||||
if(v.size()==10)
|
||||
{ make_pentagonal_prism_with_builder(ib, v[0], v[1], v[2], v[3], v[4],
|
||||
v[5], v[6], v[7], v[8], v[9]); }
|
||||
break;
|
||||
case VTK_HEXAGONAL_PRISM:
|
||||
if(v.size()==12)
|
||||
{ make_hexagonal_prism_with_builder(ib, v[0], v[1], v[2], v[3], v[4],
|
||||
v[5], v[6], v[7], v[8], v[9],
|
||||
v[10], v[11]); }
|
||||
break;
|
||||
case VTK_POLYHEDRON: // GENERIC CELL
|
||||
make_generic_cell_with_builder(ib, v);
|
||||
break;
|
||||
default:
|
||||
if(error_types.count(cell_type)==0)
|
||||
{
|
||||
std::cerr<<"[ERROR] read_VTK: type "<<cell_type<<" unknown."<<std::endl;
|
||||
error_types.insert(cell_type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clean up unused vertex attributes
|
||||
for(auto itv=alcc.vertex_attributes().begin();
|
||||
itv!=alcc.vertex_attributes().end(); ++itv)
|
||||
{
|
||||
if(alcc.template dart_of_attribute<0>(itv)==alcc.null_descriptor)
|
||||
{ alcc.erase_vertex_attribute(itv); }
|
||||
}
|
||||
|
||||
if(vertex_scalars!=nullptr)
|
||||
{ vertex_scalars->clear(); }
|
||||
if(cell_scalars!=nullptr)
|
||||
{ cell_scalars->clear(); }
|
||||
|
||||
while(std::getline(is, line))
|
||||
{
|
||||
// Read POINT_DATA scalars if present
|
||||
if(vertex_scalars!=nullptr && line.find("POINT_DATA")!=std::string::npos)
|
||||
{
|
||||
if(!read_data(is, line, *vertex_scalars))
|
||||
{
|
||||
std::cerr<<"[ERROR] read_VTK: error when reading POINT_DATA."
|
||||
<<std::endl;
|
||||
}
|
||||
}
|
||||
// Read CELL_DATA scalars if present
|
||||
else if(cell_scalars!=nullptr && line.find("CELL_DATA")!=std::string::npos)
|
||||
{
|
||||
if(!read_data(is, line, *cell_scalars))
|
||||
{
|
||||
std::cerr<<"[ERROR] read_VTK: error when reading CELL_DATA."
|
||||
<<std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
template<class LCC>
|
||||
bool write_lcc_topo_to_vtk_ascii(std::ostream& os, const LCC& alcc,
|
||||
std::size_t& nbpts, std::size_t& nbcells)
|
||||
{
|
||||
static_assert(LCC::dimension==3 && LCC::ambient_dimension==3,
|
||||
"write_VTK() only supports 3D Linear_cell_complexes (3,3)");
|
||||
|
||||
// Write VTK header
|
||||
os<<"# vtk DataFile Version 2.0\n";
|
||||
os<<"CGAL Linear_cell_complex\n";
|
||||
os<<"ASCII\n";
|
||||
os<<"DATASET UNSTRUCTURED_GRID\n\n";
|
||||
|
||||
// Build vertex index map and write points
|
||||
std::unordered_map<typename LCC::Vertex_attribute_const_descriptor, std::size_t>
|
||||
index;
|
||||
nbpts=0;
|
||||
os<<"POINTS "<<alcc.vertex_attributes().size()<<" double"<<std::endl;
|
||||
for(auto itv=alcc.vertex_attributes().begin(),
|
||||
itvend=alcc.vertex_attributes().end(); itv!=itvend; ++itv)
|
||||
{
|
||||
os<<" "<<itv->point()<<std::endl;
|
||||
index[itv]=nbpts++;
|
||||
}
|
||||
os<<std::endl;
|
||||
|
||||
// Count cells and build connectivity
|
||||
nbcells=0;
|
||||
std::size_t total_size=0;
|
||||
std::ostringstream cell_stream, type_stream;
|
||||
typename LCC::Dart_const_descriptor sd;
|
||||
|
||||
// Write cells section
|
||||
for(typename LCC::template One_dart_per_cell_range<3>::const_iterator
|
||||
itvol=alcc.template one_dart_per_cell<3>().begin(),
|
||||
itvolend=alcc.template one_dart_per_cell<3>().end();
|
||||
itvol!=itvolend; ++itvol)
|
||||
{
|
||||
++nbcells;
|
||||
++total_size; // for the number of vertices
|
||||
VTK_Cell_Type cell_type=get_vtk_cell_type(alcc, itvol, sd);
|
||||
type_stream<<static_cast<int>(cell_type)<<std::endl;
|
||||
|
||||
if(cell_type==VTK_TETRA)
|
||||
{
|
||||
cell_stream<<" 4 "
|
||||
<<index[alcc.vertex_attribute(sd)]<<" "
|
||||
<<index[alcc.vertex_attribute(alcc.template beta<1>(sd))]<<" "
|
||||
<<index[alcc.vertex_attribute(alcc.template beta<0>(sd))]<<" "
|
||||
<<index[alcc.vertex_attribute(alcc.template beta<2, 0>(sd))]<<std::endl;
|
||||
total_size+=4;
|
||||
}
|
||||
else if(cell_type==VTK_PYRAMID)
|
||||
{
|
||||
cell_stream<<" 5 "
|
||||
<<index[alcc.vertex_attribute(sd)]<<" "
|
||||
<<index[alcc.vertex_attribute(alcc.template beta<1>(sd))]<<" "
|
||||
<<index[alcc.vertex_attribute(alcc.template beta<1,1>(sd))]<<" "
|
||||
<<index[alcc.vertex_attribute(alcc.template beta<0>(sd))]<<" "
|
||||
<<index[alcc.vertex_attribute(alcc.template beta<2,0>(sd))]<<std::endl;
|
||||
total_size+=5;
|
||||
}
|
||||
else if(cell_type==VTK_WEDGE)
|
||||
{
|
||||
cell_stream<<" 6 "
|
||||
<<index[alcc.vertex_attribute(sd)]<<" "
|
||||
<<index[alcc.vertex_attribute(alcc.template beta<1>(sd))]<<" "
|
||||
<<index[alcc.vertex_attribute(alcc.template beta<0>(sd))]<<" ";
|
||||
// Move to the up face
|
||||
typename LCC::Dart_const_descriptor d2=alcc.template beta<2, 1, 1, 2>(sd);
|
||||
cell_stream<<index[alcc.vertex_attribute(alcc.template beta<1>(d2))]<<" "
|
||||
<<index[alcc.vertex_attribute(d2)]<<" "
|
||||
<<index[alcc.vertex_attribute(alcc.template beta<0>(d2))]<<std::endl;
|
||||
total_size+=6;
|
||||
}
|
||||
else if(cell_type==VTK_HEXAHEDRON)
|
||||
{
|
||||
cell_stream<<" 8 ";
|
||||
for(unsigned int i=0; i<4; ++i)
|
||||
{
|
||||
cell_stream<<index[alcc.vertex_attribute(sd)]<<" ";
|
||||
sd=alcc.template beta<1>(sd);
|
||||
}
|
||||
typename LCC::Dart_const_descriptor d2=alcc.template beta<2, 1, 1, 2, 1>(sd);
|
||||
// Darts associated with particles 4, 5, 6, 7
|
||||
for(unsigned int i = 0; i < 4; i++)
|
||||
{
|
||||
cell_stream<<index[alcc.vertex_attribute(d2)]<<" ";
|
||||
d2 = alcc.template beta<0>(d2);
|
||||
}
|
||||
cell_stream<<std::endl;
|
||||
total_size+=8;
|
||||
}
|
||||
// TODO: 15 PENTAGONAL_PRISM
|
||||
// 16 HEXAGONAL_PRISM
|
||||
// 24 QUADRATIC_TETRA
|
||||
// 25 QUADRATIC_HEXAHEDRON
|
||||
// 26 QUADRATIC_WEDGE
|
||||
// 27 QUADRATIC_PYRAMID
|
||||
else
|
||||
{
|
||||
// Generic polyhedron format write as face-vertex connectivity
|
||||
std::vector<std::vector<std::size_t>> faces;
|
||||
std::size_t cell_size=1; // Start with 1 for number of faces
|
||||
++total_size; // for the same reason
|
||||
for(auto itface=alcc.template one_dart_per_incident_cell<2, 3, 2>(itvol).begin(),
|
||||
itfaceend=alcc.template one_dart_per_incident_cell<2, 3, 2>(itvol).end();
|
||||
itface!=itfaceend; ++itface)
|
||||
{
|
||||
faces.push_back(std::vector<std::size_t>());
|
||||
typename LCC::Dart_const_descriptor curdh=itface;
|
||||
do
|
||||
{
|
||||
faces.back().push_back(index[alcc.vertex_attribute(curdh)]);
|
||||
curdh=alcc.template beta<1>(curdh);
|
||||
}
|
||||
while(curdh!=itface);
|
||||
cell_size+=faces.back().size()+1; // +1 for the number of vertices in the face
|
||||
}
|
||||
cell_stream<<cell_size<<" "<<faces.size();
|
||||
for(const auto& face : faces)
|
||||
{
|
||||
cell_stream<<" "<<face.size();
|
||||
for(auto v : face)
|
||||
{ cell_stream<<" "<<v; }
|
||||
total_size+=face.size()+1; // +1 for the number of vertices in the face
|
||||
}
|
||||
cell_stream<<std::endl;
|
||||
}
|
||||
}
|
||||
os<<"CELLS "<<nbcells<<" "<<total_size<<std::endl;
|
||||
os<<cell_stream.str()<<std::endl;
|
||||
|
||||
// Write cell types
|
||||
os<<"CELL_TYPES "<<nbcells<<std::endl;
|
||||
os<<type_stream.str()<<std::endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// ============================================================================
|
||||
// Public interface implementation
|
||||
// ============================================================================
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename LCC, typename VertexScalarType, typename VolumeScalarType>
|
||||
bool read_VTK(const char* filename, LCC& alcc,
|
||||
std::vector<VertexScalarType>* vertex_scalars,
|
||||
std::vector<VolumeScalarType>* volume_scalars)
|
||||
{
|
||||
CGAL_assertion(filename!=nullptr);
|
||||
std::ifstream file(filename);
|
||||
if(!file.is_open())
|
||||
{
|
||||
std::cerr<<"[ERROR] read_VTK: cannot open file "<<filename<<std::endl;
|
||||
return false;
|
||||
}
|
||||
return internal::read_lcc_from_vtk_ascii(file, alcc,
|
||||
vertex_scalars, volume_scalars);
|
||||
}
|
||||
|
||||
template <typename LCC>
|
||||
bool read_VTK(const char* filename, LCC& alcc)
|
||||
{ return read_VTK<LCC, float, float>(filename, alcc, nullptr, nullptr); }
|
||||
|
||||
template <typename LCC, typename VertexScalarType>
|
||||
bool read_VTK(const char* filename, LCC& alcc,
|
||||
std::vector<VertexScalarType>* vertex_scalars)
|
||||
{ return read_VTK<LCC, VertexScalarType, float>
|
||||
(filename, alcc, vertex_scalars, nullptr); }
|
||||
|
||||
template <typename LCC, typename VolumeScalarType>
|
||||
bool read_VTK(const char* filename, LCC& alcc,
|
||||
std::nullptr_t,
|
||||
std::vector<VolumeScalarType>* volume_scalars)
|
||||
{ return read_VTK<LCC, float, VolumeScalarType>
|
||||
(filename, alcc, nullptr, volume_scalars); }
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename LCC, typename PointFunctor, typename CellFunctor>
|
||||
inline bool write_VTK_with_fct(const char* filename, const LCC& alcc,
|
||||
PointFunctor pointfct, CellFunctor cellfct)
|
||||
{
|
||||
CGAL_assertion(filename!=nullptr);
|
||||
std::ofstream file(filename);
|
||||
if(!file.good())
|
||||
{
|
||||
std::cerr<<"[ERROR] write_VTK: cannot open file "<<filename<<std::endl;
|
||||
return false;
|
||||
}
|
||||
std::size_t nbpts=0, nbcells=0;
|
||||
bool res=internal::write_lcc_topo_to_vtk_ascii(file, alcc, nbpts, nbcells);
|
||||
if(res)
|
||||
{
|
||||
if(pointfct)
|
||||
{ internal::Write_point_data<PointFunctor>::
|
||||
run(file, alcc, nbpts, pointfct); }
|
||||
if(cellfct)
|
||||
{ internal::Write_cell_data<CellFunctor>::
|
||||
run(file, alcc, nbcells, cellfct); }
|
||||
}
|
||||
file.close();
|
||||
return true;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename LCC, typename VertexScalarType, typename VolumeScalarType>
|
||||
bool write_VTK(const char* filename, const LCC& alcc,
|
||||
const std::vector<VertexScalarType>* vertex_scalars,
|
||||
const std::vector<VolumeScalarType>* volume_scalars)
|
||||
{
|
||||
std::function<VertexScalarType(const LCC&,
|
||||
typename LCC::Dart_const_descriptor,
|
||||
std::size_t i)> vertexfct;
|
||||
std::function<VolumeScalarType(const LCC&,
|
||||
typename LCC::Dart_const_descriptor,
|
||||
std::size_t i)> cellfct;
|
||||
if(vertex_scalars!=nullptr)
|
||||
{
|
||||
vertexfct=[&vertex_scalars](const LCC&, typename LCC::Dart_const_descriptor,
|
||||
std::size_t i) -> VertexScalarType
|
||||
{ return (*vertex_scalars)[i]; };
|
||||
}
|
||||
|
||||
if(volume_scalars!=nullptr)
|
||||
{
|
||||
cellfct=[&volume_scalars](const LCC&, typename LCC::Dart_const_descriptor,
|
||||
std::size_t i) -> VolumeScalarType
|
||||
{ return (*volume_scalars)[i]; };
|
||||
}
|
||||
|
||||
return write_VTK_with_fct(filename, alcc, vertexfct, cellfct);
|
||||
}
|
||||
|
||||
template <typename LCC>
|
||||
bool write_VTK(const char* filename, const LCC& alcc)
|
||||
{
|
||||
return write_VTK<LCC, float, float>(filename, alcc, nullptr, nullptr);
|
||||
}
|
||||
|
||||
template <typename LCC, typename VertexScalarType>
|
||||
bool write_VTK(const char* filename, const LCC& alcc,
|
||||
const std::vector<VertexScalarType>* vertex_scalars)
|
||||
{
|
||||
return write_VTK<LCC, VertexScalarType, float>(filename, alcc, vertex_scalars,
|
||||
nullptr);
|
||||
}
|
||||
|
||||
template <typename LCC, typename VolumeScalarType>
|
||||
bool write_VTK(const char* filename, const LCC& alcc,
|
||||
std::nullptr_t,
|
||||
const std::vector<VolumeScalarType>* volume_scalars)
|
||||
{
|
||||
return write_VTK<LCC, float, VolumeScalarType>(filename, alcc, nullptr,
|
||||
volume_scalars);
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
} // namespace IO
|
||||
} // namespace CGAL
|
||||
|
||||
#endif // CGAL_LCC_IO_VTK_H
|
||||
|
|
@ -213,7 +213,7 @@ namespace CGAL {
|
|||
return *this;
|
||||
}
|
||||
|
||||
/** Create a vertex attribute.
|
||||
/** Creates a vertex attribute.
|
||||
* @return a handle on the new attribute.
|
||||
*/
|
||||
template<typename ...Args>
|
||||
|
|
@ -221,7 +221,7 @@ namespace CGAL {
|
|||
{ return Base::template create_attribute<0>(args...); }
|
||||
|
||||
/**
|
||||
* Create a new dart associated with a handle through an attribute.
|
||||
* Creates a new dart associated with a handle through an attribute.
|
||||
* @param ahandle the point handle to associated with the dart.
|
||||
* @return a Dart_descriptor on the new dart.
|
||||
*/
|
||||
|
|
@ -232,7 +232,7 @@ namespace CGAL {
|
|||
return res;
|
||||
}
|
||||
|
||||
/** Create a new dart associated with a point.
|
||||
/** Creates a new dart associated with a point.
|
||||
* @param apoint the point to associated with the dart.
|
||||
* @return a Dart_descriptor on the new dart.
|
||||
*/
|
||||
|
|
@ -307,7 +307,7 @@ namespace CGAL {
|
|||
return point_of_vertex_attribute(this->template attribute<0>(adart));
|
||||
}
|
||||
|
||||
/** Test if the lcc is valid.
|
||||
/** Tests if the lcc is valid.
|
||||
* A Linear_cell_complex is valid if it is a valid Combinatorial_map with
|
||||
* an attribute associated to each dart.
|
||||
* @return true iff the map is valid.
|
||||
|
|
@ -550,7 +550,7 @@ namespace CGAL {
|
|||
return res;
|
||||
}
|
||||
|
||||
/** Create a segment given 2 points.
|
||||
/** Creates a segment given 2 points.
|
||||
* @param p0 the first point.
|
||||
* @param p1 the second point.
|
||||
* if closed==true, the edge has no 2-free dart.
|
||||
|
|
@ -564,7 +564,7 @@ namespace CGAL {
|
|||
closed);
|
||||
}
|
||||
|
||||
/** Create a triangle given 3 points.
|
||||
/** Creates a triangle given 3 points.
|
||||
* @param p0 the first point.
|
||||
* @param p1 the second point.
|
||||
* @param p2 the third point.
|
||||
|
|
@ -579,7 +579,7 @@ namespace CGAL {
|
|||
create_vertex_attribute(p2));
|
||||
}
|
||||
|
||||
/** Create a quadrangle given 4 points.
|
||||
/** Creates a quadrangle given 4 points.
|
||||
* @param p0 the first point.
|
||||
* @param p1 the second point.
|
||||
* @param p2 the third point.
|
||||
|
|
@ -598,7 +598,7 @@ namespace CGAL {
|
|||
}
|
||||
|
||||
|
||||
/** Create a tetrahedron given 4 Vertex_attribute_descriptor.
|
||||
/** Creates a tetrahedron given 4 Vertex_attribute_descriptor.
|
||||
* @param h0 the first vertex handle.
|
||||
* @param h1 the second vertex handle.
|
||||
* @param h2 the third vertex handle.
|
||||
|
|
@ -619,7 +619,7 @@ namespace CGAL {
|
|||
return this->make_combinatorial_tetrahedron(d1, d2, d3, d4);
|
||||
}
|
||||
|
||||
/** Create a tetrahedron given 4 points.
|
||||
/** Creates a tetrahedron given 4 points.
|
||||
* @param p0 the first point.
|
||||
* @param p1 the second point.
|
||||
* @param p2 the third point.
|
||||
|
|
@ -638,7 +638,7 @@ namespace CGAL {
|
|||
create_vertex_attribute(p3));
|
||||
}
|
||||
|
||||
/** Create an hexahedron given 8 Vertex_attribute_descriptor.
|
||||
/** Creates an hexahedron given 8 Vertex_attribute_descriptor.
|
||||
* (8 vertices, 12 edges and 6 facets)
|
||||
* \verbatim
|
||||
* 4----7
|
||||
|
|
@ -660,13 +660,13 @@ namespace CGAL {
|
|||
* h0,h5 and to the facet (h0,h5,h6,h1).
|
||||
*/
|
||||
Dart_descriptor make_hexahedron(Vertex_attribute_descriptor h0,
|
||||
Vertex_attribute_descriptor h1,
|
||||
Vertex_attribute_descriptor h2,
|
||||
Vertex_attribute_descriptor h3,
|
||||
Vertex_attribute_descriptor h4,
|
||||
Vertex_attribute_descriptor h5,
|
||||
Vertex_attribute_descriptor h6,
|
||||
Vertex_attribute_descriptor h7)
|
||||
Vertex_attribute_descriptor h1,
|
||||
Vertex_attribute_descriptor h2,
|
||||
Vertex_attribute_descriptor h3,
|
||||
Vertex_attribute_descriptor h4,
|
||||
Vertex_attribute_descriptor h5,
|
||||
Vertex_attribute_descriptor h6,
|
||||
Vertex_attribute_descriptor h7)
|
||||
{
|
||||
Dart_descriptor d1 = make_quadrangle(h0, h5, h6, h1);
|
||||
Dart_descriptor d2 = make_quadrangle(h1, h6, h7, h2);
|
||||
|
|
@ -678,7 +678,7 @@ namespace CGAL {
|
|||
return this->make_combinatorial_hexahedron(d1, d2, d3, d4, d5, d6);
|
||||
}
|
||||
|
||||
/** Create an hexahedron given 8 points.
|
||||
/** Creates an hexahedron given 8 points.
|
||||
* \verbatim
|
||||
* 4----7
|
||||
* /| /|
|
||||
|
|
@ -717,6 +717,133 @@ namespace CGAL {
|
|||
create_vertex_attribute(p7));
|
||||
}
|
||||
|
||||
/** Creates a prism given 6 Vertex_attribute_descriptor.
|
||||
* (6 vertices, 9 edges and 5 facets)
|
||||
* \verbatim
|
||||
* 3---4
|
||||
* |\ /|
|
||||
* 0-5-1
|
||||
* \|/
|
||||
* 2
|
||||
* \endverbatim
|
||||
* @param h0 the first vertex handle.
|
||||
* @param h1 the second vertex handle.
|
||||
* @param h2 the third vertex handle.
|
||||
* @param h3 the fourth vertex handle.
|
||||
* @param h4 the fifth vertex handle.
|
||||
* @param h5 the sixth vertex handle.
|
||||
* @return the dart of the new prism incident to h0 and to
|
||||
* the facet (h0,h1,h2).
|
||||
*/
|
||||
Dart_descriptor make_prism(Vertex_attribute_descriptor h0,
|
||||
Vertex_attribute_descriptor h1,
|
||||
Vertex_attribute_descriptor h2,
|
||||
Vertex_attribute_descriptor h3,
|
||||
Vertex_attribute_descriptor h4,
|
||||
Vertex_attribute_descriptor h5)
|
||||
{
|
||||
Dart_descriptor d1=make_triangle(h0, h1, h2);
|
||||
Dart_descriptor d2=make_quadrangle(h1, h0, h3, h4);
|
||||
Dart_descriptor d3=make_quadrangle(h2, h1, h4, h5);
|
||||
Dart_descriptor d4=make_quadrangle(h0, h2, h5, h3);
|
||||
Dart_descriptor d5=make_triangle(h4, h3, h5);
|
||||
|
||||
return make_combinatorial_prism(d1, d2, d3, d4, d5);
|
||||
}
|
||||
|
||||
/** Creates a prism given 6 points.
|
||||
* \verbatim
|
||||
* 3---4
|
||||
* |\ /|
|
||||
* 0-5-1
|
||||
* \|/
|
||||
* 2
|
||||
* \endverbatim
|
||||
* @param p0 the first point.
|
||||
* @param p1 the second point.
|
||||
* @param p2 the third point.
|
||||
* @param p3 the fourth point.
|
||||
* @param p4 the fifth point.
|
||||
* @param p5 the sixth point.
|
||||
* @return the dart of the new prism incident to p0 and to
|
||||
* the facet (p0,p1,p2).
|
||||
*/
|
||||
Dart_descriptor make_prism(const Point& p0,
|
||||
const Point& p1,
|
||||
const Point& p2,
|
||||
const Point& p3,
|
||||
const Point& p4,
|
||||
const Point& p5)
|
||||
{
|
||||
return make_prism(create_vertex_attribute(p0),
|
||||
create_vertex_attribute(p1),
|
||||
create_vertex_attribute(p2),
|
||||
create_vertex_attribute(p3),
|
||||
create_vertex_attribute(p4),
|
||||
create_vertex_attribute(p5));
|
||||
}
|
||||
|
||||
/** Creates a pyramid given 5 Vertex_attribute_descriptor.
|
||||
* (5 vertices, 8 edges and 5 facets)
|
||||
* \verbatim
|
||||
* 4
|
||||
* /|\
|
||||
* 0-|-1
|
||||
* | | |
|
||||
* 3---2
|
||||
* \endverbatim
|
||||
* @param h0 the first vertex handle.
|
||||
* @param h1 the second vertex handle.
|
||||
* @param h2 the third vertex handle.
|
||||
* @param h3 the fourth vertex handle.
|
||||
* @param h4 the fifth vertex handle.
|
||||
* @return the dart of the new pyramid incident to h0 and to
|
||||
* the facet (h0,h1,h2,h3).
|
||||
*/
|
||||
Dart_descriptor make_pyramid(Vertex_attribute_descriptor h0,
|
||||
Vertex_attribute_descriptor h1,
|
||||
Vertex_attribute_descriptor h2,
|
||||
Vertex_attribute_descriptor h3,
|
||||
Vertex_attribute_descriptor h4)
|
||||
{
|
||||
Dart_descriptor d1=make_quadrangle(h0, h1, h2, h3);
|
||||
Dart_descriptor d2=make_triangle(h1, h0, h4);
|
||||
Dart_descriptor d3=make_triangle(h0, h3, h4);
|
||||
Dart_descriptor d4=make_triangle(h3, h2, h4);
|
||||
Dart_descriptor d5=make_triangle(h2, h1, h4);
|
||||
|
||||
return make_combinatorial_pyramid(d1, d2, d3, d4, d5);
|
||||
}
|
||||
|
||||
/** Creates a pyramid given 5 points.
|
||||
* \verbatim
|
||||
* 4
|
||||
* /|\
|
||||
* 0-|-1
|
||||
* | | |
|
||||
* 3---2
|
||||
* \endverbatim
|
||||
* @param p0 the first point.
|
||||
* @param p1 the second point.
|
||||
* @param p2 the third point.
|
||||
* @param p3 the fourth point.
|
||||
* @param p4 the fifth point.
|
||||
* @return the dart of the new pyramid incident to p0 and to
|
||||
* the facet (p0,p1,p2,p3).
|
||||
*/
|
||||
Dart_descriptor make_pyramid(const Point& p0,
|
||||
const Point& p1,
|
||||
const Point& p2,
|
||||
const Point& p3,
|
||||
const Point& p4)
|
||||
{
|
||||
return make_pyramid(create_vertex_attribute(p0),
|
||||
create_vertex_attribute(p1),
|
||||
create_vertex_attribute(p2),
|
||||
create_vertex_attribute(p3),
|
||||
create_vertex_attribute(p4));
|
||||
}
|
||||
|
||||
/** Compute the barycenter of a given cell.
|
||||
* @param adart a dart incident to the cell.
|
||||
* @param adim the dimension of the cell.
|
||||
|
|
|
|||
|
|
@ -261,7 +261,7 @@ public:
|
|||
prev_dart =lcc.null_descriptor;
|
||||
}
|
||||
|
||||
void add_vertex_to_facet(size_type i)
|
||||
void add_vertex_to_facet(size_type i, std::vector<DH>* tabdarts = nullptr)
|
||||
{
|
||||
CGAL_assertion(i<vertex_map.size());
|
||||
// std::cout<<i<<" "<<std::flush;
|
||||
|
|
@ -289,6 +289,7 @@ public:
|
|||
{ first_dart=cur_dart; min_vertex=max_vertex=i; min_dart=cur_dart; }
|
||||
|
||||
prev_dart=cur_dart;
|
||||
if(tabdarts != nullptr) { tabdarts->push_back(cur_dart); }
|
||||
}
|
||||
|
||||
// End of the facet. Return the first dart of this facet.
|
||||
|
|
@ -325,11 +326,12 @@ public:
|
|||
return first_dart;
|
||||
}
|
||||
|
||||
DH add_facet(std::initializer_list<size_type> l)
|
||||
DH add_facet(std::initializer_list<size_type> l, std::vector<DH>* tabdarts = nullptr)
|
||||
{
|
||||
if(tabdarts != nullptr) { tabdarts->reserve(tabdarts->size() + l.size()); }
|
||||
begin_facet();
|
||||
for (size_type i:l)
|
||||
{ add_vertex_to_facet(i); }
|
||||
{ add_vertex_to_facet(i, tabdarts); }
|
||||
return end_facet();
|
||||
}
|
||||
|
||||
|
|
@ -404,5 +406,197 @@ private:
|
|||
|
||||
} //namespace CGAL
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/* Create an hexahedron, given the indices of its vertices (in the following
|
||||
* order), the vertex must already have been added in the incremental builder.
|
||||
* 3
|
||||
* /|\
|
||||
* 0-|-2
|
||||
* \|/
|
||||
* 1
|
||||
*/
|
||||
template<typename IncrementalBuilder>
|
||||
typename IncrementalBuilder::LCC::Dart_descriptor
|
||||
make_tetrahedron_with_builder(IncrementalBuilder& ib,
|
||||
std::size_t i0,
|
||||
std::size_t i1,
|
||||
std::size_t i2,
|
||||
std::size_t i3,
|
||||
std::vector<typename IncrementalBuilder::LCC::Dart_descriptor>*
|
||||
tabdarts=nullptr)
|
||||
{
|
||||
ib.begin_surface();
|
||||
ib.add_facet({i0,i1,i2}, tabdarts);
|
||||
ib.add_facet({i1,i0,i3}, tabdarts);
|
||||
ib.add_facet({i2,i1,i3}, tabdarts);
|
||||
ib.add_facet({i0,i2,i3}, tabdarts);
|
||||
return ib.end_surface();
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/* 4
|
||||
* /|\
|
||||
* 0-|-3
|
||||
* | | |
|
||||
* 1---2
|
||||
*/
|
||||
template<typename IncrementalBuilder>
|
||||
typename IncrementalBuilder::LCC::Dart_descriptor
|
||||
make_pyramid_with_builder(IncrementalBuilder& ib,
|
||||
std::size_t i0,
|
||||
std::size_t i1,
|
||||
std::size_t i2,
|
||||
std::size_t i3,
|
||||
std::size_t i4,
|
||||
std::vector<typename IncrementalBuilder::LCC::Dart_descriptor>*
|
||||
tabdarts=nullptr)
|
||||
{
|
||||
ib.begin_surface();
|
||||
ib.add_facet({i0,i1,i2,i3}, tabdarts);
|
||||
ib.add_facet({i1,i0,i4}, tabdarts);
|
||||
ib.add_facet({i2,i1,i4}, tabdarts);
|
||||
ib.add_facet({i3,i2,i4}, tabdarts);
|
||||
ib.add_facet({i0,i3,i4}, tabdarts);
|
||||
return ib.end_surface();
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/* 3
|
||||
* /|\
|
||||
* 4---5
|
||||
* | | |
|
||||
* | 0 |
|
||||
* |/ \|
|
||||
* 1---2
|
||||
*/
|
||||
template<typename IncrementalBuilder>
|
||||
typename IncrementalBuilder::LCC::Dart_descriptor
|
||||
make_prism_with_builder(IncrementalBuilder& ib,
|
||||
std::size_t i0,
|
||||
std::size_t i1,
|
||||
std::size_t i2,
|
||||
std::size_t i3,
|
||||
std::size_t i4,
|
||||
std::size_t i5,
|
||||
std::vector<typename IncrementalBuilder::LCC::Dart_descriptor>*
|
||||
tabdarts=nullptr)
|
||||
{
|
||||
ib.begin_surface();
|
||||
ib.add_facet({i0,i1,i2}, tabdarts);
|
||||
ib.add_facet({i1,i0,i3,i4}, tabdarts);
|
||||
ib.add_facet({i2,i1,i4,i5}, tabdarts);
|
||||
ib.add_facet({i0,i2,i5,i3}, tabdarts);
|
||||
ib.add_facet({i5,i4,i3}, tabdarts);
|
||||
return ib.end_surface();
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/* 7----6
|
||||
* /| /|
|
||||
* 4----5 |
|
||||
* | 3--|-2
|
||||
* |/ |/
|
||||
* 0----1
|
||||
*/
|
||||
template<typename IncrementalBuilder>
|
||||
typename IncrementalBuilder::LCC::Dart_descriptor
|
||||
make_hexahedron_with_builder(IncrementalBuilder& ib,
|
||||
std::size_t i0,
|
||||
std::size_t i1,
|
||||
std::size_t i2,
|
||||
std::size_t i3,
|
||||
std::size_t i4,
|
||||
std::size_t i5,
|
||||
std::size_t i6,
|
||||
std::size_t i7,
|
||||
std::vector<typename IncrementalBuilder::LCC::Dart_descriptor>*
|
||||
tabdarts=nullptr)
|
||||
{
|
||||
ib.begin_surface();
|
||||
ib.add_facet({i0,i1,i2,i3}, tabdarts);
|
||||
ib.add_facet({i1,i0,i4,i5}, tabdarts);
|
||||
ib.add_facet({i2,i1,i5,i6}, tabdarts);
|
||||
ib.add_facet({i3,i2,i6,i7}, tabdarts);
|
||||
ib.add_facet({i0,i3,i7,i4}, tabdarts);
|
||||
ib.add_facet({i7,i6,i5,i4}, tabdarts);
|
||||
return ib.end_surface();
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template<typename IncrementalBuilder>
|
||||
typename IncrementalBuilder::LCC::Dart_descriptor
|
||||
make_pentagonal_prism_with_builder(IncrementalBuilder& ib,
|
||||
std::size_t i0,
|
||||
std::size_t i1,
|
||||
std::size_t i2,
|
||||
std::size_t i3,
|
||||
std::size_t i4,
|
||||
std::size_t i5,
|
||||
std::size_t i6,
|
||||
std::size_t i7,
|
||||
std::size_t i8,
|
||||
std::size_t i9,
|
||||
std::vector<typename IncrementalBuilder::LCC::Dart_descriptor>*
|
||||
tabdarts=nullptr)
|
||||
{
|
||||
ib.begin_surface();
|
||||
ib.add_facet({i0,i1,i2,i3,i4}, tabdarts);
|
||||
ib.add_facet({i1,i0,i5,i6}, tabdarts);
|
||||
ib.add_facet({i2,i1,i6,i7}, tabdarts);
|
||||
ib.add_facet({i3,i2,i7,i8}, tabdarts);
|
||||
ib.add_facet({i4,i3,i8,i9}, tabdarts);
|
||||
ib.add_facet({i0,i4,i9,i5}, tabdarts);
|
||||
ib.add_facet({i9,i8,i7,i6,i5}, tabdarts);
|
||||
return ib.end_surface();
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template<typename IncrementalBuilder>
|
||||
typename IncrementalBuilder::LCC::Dart_descriptor
|
||||
make_hexagonal_prism_with_builder(IncrementalBuilder& ib,
|
||||
std::size_t i0,
|
||||
std::size_t i1,
|
||||
std::size_t i2,
|
||||
std::size_t i3,
|
||||
std::size_t i4,
|
||||
std::size_t i5,
|
||||
std::size_t i6,
|
||||
std::size_t i7,
|
||||
std::size_t i8,
|
||||
std::size_t i9,
|
||||
std::size_t i10,
|
||||
std::size_t i11,
|
||||
std::vector<typename IncrementalBuilder::LCC::Dart_descriptor>*
|
||||
tabdarts=nullptr)
|
||||
{
|
||||
ib.begin_surface();
|
||||
ib.add_facet({i0,i1,i2,i3,i4,i5}, tabdarts);
|
||||
ib.add_facet({i1,i0,i6,i7}, tabdarts);
|
||||
ib.add_facet({i2,i1,i7,i8}, tabdarts);
|
||||
ib.add_facet({i3,i2,i8,i9}, tabdarts);
|
||||
ib.add_facet({i4,i3,i9,i10}, tabdarts);
|
||||
ib.add_facet({i5,i4,i10,i11}, tabdarts);
|
||||
ib.add_facet({i0,i5,i11,i6}, tabdarts);
|
||||
ib.add_facet({i11,i10,i9,i8,i7,i6}, tabdarts);
|
||||
return ib.end_surface();
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template<typename IncrementalBuilder>
|
||||
typename IncrementalBuilder::LCC::Dart_descriptor
|
||||
make_generic_cell_with_builder(IncrementalBuilder& ib,
|
||||
const std::vector<std::size_t>& faces,
|
||||
std::vector<typename IncrementalBuilder::LCC::Dart_descriptor>*
|
||||
tabdarts=nullptr)
|
||||
{
|
||||
ib.begin_surface();
|
||||
std::size_t i=1, end; // Start to 1 because faces[0] is the number of faces
|
||||
for(; i<faces.size(); )
|
||||
{
|
||||
end=i+1+faces[i]; // faces[i] is the number of vertices of the face; +i is the index of the end
|
||||
++i; // I prefer to increment i after its use!
|
||||
ib.begin_facet();
|
||||
for(; i<end; ++i)
|
||||
{ ib.add_vertex_to_facet(faces[i], tabdarts); }
|
||||
ib.end_facet();
|
||||
}
|
||||
return ib.end_surface();
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#endif // CGAL_LINEAR_CELL_COMPLEX_INCREMENTAL_BUILDER_3_H //
|
||||
// EOF //
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ create_single_source_cgal_program(Linear_cell_complex_3_test.cpp ${hfiles})
|
|||
create_single_source_cgal_program(Linear_cell_complex_4_test.cpp ${hfiles})
|
||||
create_single_source_cgal_program(Linear_cell_complex_copy_test.cpp ${hfiles})
|
||||
create_single_source_cgal_program(LCC_3_incremental_builder_test.cpp ${hfiles})
|
||||
create_single_source_cgal_program(Linear_cell_complex_vtk_io_test.cpp ${hfiles})
|
||||
|
||||
# Same targets, defining USE_COMPACT_CONTAINER_WITH_INDEX to test index version
|
||||
add_executable(Linear_cell_complex_2_test_index Linear_cell_complex_2_test.cpp ${hfiles})
|
||||
|
|
|
|||
|
|
@ -5,104 +5,6 @@
|
|||
|
||||
#include "Linear_cell_complex_3_test.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/* 3
|
||||
* /|\
|
||||
* 0-|-2
|
||||
* \|/
|
||||
* 1
|
||||
*/
|
||||
template<typename IncrementalBuilder>
|
||||
void make_tetrahedron_with_builder(IncrementalBuilder& ib,
|
||||
std::size_t i0,
|
||||
std::size_t i1,
|
||||
std::size_t i2,
|
||||
std::size_t i3)
|
||||
{
|
||||
ib.begin_surface();
|
||||
ib.add_facet({i0,i1,i2});
|
||||
ib.add_facet({i1,i0,i3});
|
||||
ib.add_facet({i2,i1,i3});
|
||||
ib.add_facet({i0,i2,i3});
|
||||
ib.end_surface();
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/* 4
|
||||
* /|\
|
||||
* 0-|-3
|
||||
* | | |
|
||||
* 1---2
|
||||
*/
|
||||
template<typename IncrementalBuilder>
|
||||
void make_pyramid_with_builder(IncrementalBuilder& ib,
|
||||
std::size_t i0,
|
||||
std::size_t i1,
|
||||
std::size_t i2,
|
||||
std::size_t i3,
|
||||
std::size_t i4)
|
||||
{
|
||||
ib.begin_surface();
|
||||
ib.add_facet({i0,i1,i2,i3});
|
||||
ib.add_facet({i1,i0,i4});
|
||||
ib.add_facet({i2,i1,i4});
|
||||
ib.add_facet({i3,i2,i4});
|
||||
ib.add_facet({i0,i3,i4});
|
||||
ib.end_surface();
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/* 3
|
||||
* /|\
|
||||
* 4---5
|
||||
* | | |
|
||||
* | 0 |
|
||||
* |/ \|
|
||||
* 1---2
|
||||
*/
|
||||
template<typename IncrementalBuilder>
|
||||
void make_prism_with_builder(IncrementalBuilder& ib,
|
||||
std::size_t i0,
|
||||
std::size_t i1,
|
||||
std::size_t i2,
|
||||
std::size_t i3,
|
||||
std::size_t i4,
|
||||
std::size_t i5)
|
||||
{
|
||||
ib.begin_surface();
|
||||
ib.add_facet({i0,i1,i2});
|
||||
ib.add_facet({i1,i0,i3,i4});
|
||||
ib.add_facet({i2,i1,i4,i5});
|
||||
ib.add_facet({i0,i2,i5,i3});
|
||||
ib.add_facet({i5,i4,i3});
|
||||
ib.end_surface();
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/* 7----6
|
||||
* /| /|
|
||||
* 4----5 |
|
||||
* | 3--|-2
|
||||
* |/ |/
|
||||
* 0----1
|
||||
*/
|
||||
template<typename IncrementalBuilder>
|
||||
void make_hexahedron_with_builder(IncrementalBuilder& ib,
|
||||
std::size_t i0,
|
||||
std::size_t i1,
|
||||
std::size_t i2,
|
||||
std::size_t i3,
|
||||
std::size_t i4,
|
||||
std::size_t i5,
|
||||
std::size_t i6,
|
||||
std::size_t i7)
|
||||
{
|
||||
ib.begin_surface();
|
||||
ib.add_facet({i0,i1,i2,i3});
|
||||
ib.add_facet({i1,i0,i4,i5});
|
||||
ib.add_facet({i2,i1,i5,i6});
|
||||
ib.add_facet({i3,i2,i6,i7});
|
||||
ib.add_facet({i0,i3,i7,i4});
|
||||
ib.add_facet({i7,i6,i5,i4});
|
||||
ib.end_surface();
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template<typename LCC>
|
||||
bool test_ib(const char* filename)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,202 @@
|
|||
#include <CGAL/Linear_cell_complex_for_combinatorial_map.h>
|
||||
#include <CGAL/Linear_cell_complex/IO/VTK.h>
|
||||
#include <cassert>
|
||||
#include <vector>
|
||||
#include <cstdlib>
|
||||
|
||||
typedef CGAL::Linear_cell_complex_for_combinatorial_map<3, 3> LCC;
|
||||
|
||||
bool test_file(const char* filename)
|
||||
{
|
||||
LCC lcc1, lcc2;
|
||||
std::vector<float> vertex_scalars1, vertex_scalars2;
|
||||
std::vector<std::size_t> volume_scalars1, volume_scalars2;
|
||||
|
||||
bool res=CGAL::IO::read_VTK(filename, lcc1);
|
||||
if(!res)
|
||||
{
|
||||
std::cerr<<"[ERROR] LCC_vtk_io_test error read_VTK in test_file"<<std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::size_t nb_vertices=lcc1.number_of_vertex_attributes();
|
||||
vertex_scalars1.resize(nb_vertices);
|
||||
for(std::size_t i=0;i<nb_vertices;++i)
|
||||
{ vertex_scalars1[i]=static_cast<float>(i); }
|
||||
|
||||
std::size_t nb_volumes=0;
|
||||
for(auto itvol=lcc1.one_dart_per_cell<3>().begin(),
|
||||
itvolend=lcc1.one_dart_per_cell<3>().end(); itvol!=itvolend; ++itvol)
|
||||
{ ++nb_volumes; }
|
||||
|
||||
volume_scalars1.reserve(nb_volumes);
|
||||
for(auto itvol=lcc1.one_dart_per_cell<3>().begin(),
|
||||
itvolend=lcc1.one_dart_per_cell<3>().end(); itvol!=itvolend; ++itvol)
|
||||
{
|
||||
std::size_t nbv=lcc1.template one_dart_per_incident_cell<0,3>(itvol).size();
|
||||
volume_scalars1.push_back(nbv);
|
||||
}
|
||||
|
||||
res=CGAL::IO::write_VTK("output.vtk", lcc1,
|
||||
&vertex_scalars1, &volume_scalars1);
|
||||
if(!res)
|
||||
{
|
||||
std::cerr<<"[ERROR] LCC_vtk_io_test error write_VTK in test_file"<<std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
res=CGAL::IO::read_VTK("output.vtk", lcc2,
|
||||
&vertex_scalars2, &volume_scalars2);
|
||||
if(!res)
|
||||
{
|
||||
std::cerr<<"[ERROR] LCC_vtk_io_test error read_VTK 2 in test_file"<<std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!lcc1.is_isomorphic_to(lcc2, false, true, true))
|
||||
{
|
||||
std::cout<<"LCC1: ";
|
||||
lcc1.display_characteristics(std::cout)<<std::endl;
|
||||
std::cout<<"LCC2: ";
|
||||
lcc2.display_characteristics(std::cout)<<std::endl;
|
||||
std::cerr<<"[ERROR] LCC_vtk_io_test error lcc1 and lcc2 are not isomorphic in test_file"<<std::endl;
|
||||
res=false;
|
||||
}
|
||||
if(vertex_scalars1!=vertex_scalars2)
|
||||
{
|
||||
std::cerr<<"[ERROR] LCC_vtk_io_test error vertex_scalars1 and vertex_scalars2 are different in test_file"<<std::endl;
|
||||
res=false;
|
||||
}
|
||||
if(volume_scalars1!=volume_scalars2)
|
||||
{
|
||||
std::cerr<<"[ERROR] LCC_vtk_io_test error volume_scalars1 and volume_scalars2 are different in test_file"<<std::endl;
|
||||
res=false;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
bool test_different_scalars()
|
||||
{
|
||||
bool res=true;
|
||||
LCC lcc;
|
||||
std::vector<float> vertex_scalars;
|
||||
std::vector<std::size_t> volume_scalars;
|
||||
|
||||
/// Read the last file generated by test_file("data/beam-with-mixed-cells.vtk")
|
||||
/// i.e. beam-with-mixed-cells.vtk with point and cells scalars.
|
||||
if(!CGAL::IO::read_VTK("output.vtk", lcc,
|
||||
&vertex_scalars, &volume_scalars) ||
|
||||
vertex_scalars.size()!=719 || volume_scalars.size()!=615)
|
||||
{
|
||||
std::cerr<<"[ERROR] LCC_vtk_io_test error read_VTK in test_different_scalars"<<std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Test write with and without scalars
|
||||
if(!CGAL::IO::write_VTK("output_vol.vtk", lcc, nullptr, &volume_scalars))
|
||||
{
|
||||
std::cerr<<"[ERROR] LCC_vtk_io_test error write_VTK 1 in test_different_scalars"<<std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!CGAL::IO::write_VTK("output_vertex.vtk", lcc, &vertex_scalars))
|
||||
{
|
||||
std::cerr<<"[ERROR] LCC_vtk_io_test error write_VTK 2 in test_different_scalars"<<std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!CGAL::IO::write_VTK("output_none.vtk", lcc))
|
||||
{
|
||||
std::cerr<<"[ERROR] LCC_vtk_io_test error write_VTK 3 in test_different_scalars"<<std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// test read with only some scalars
|
||||
if(!CGAL::IO::read_VTK("output.vtk", lcc, &vertex_scalars) ||
|
||||
vertex_scalars.size()!=719)
|
||||
{
|
||||
std::cerr<<"[ERROR] LCC_vtk_io_test error read_VTK 2 in test_different_scalars"<<std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!CGAL::IO::read_VTK("output.vtk", lcc,
|
||||
nullptr, &volume_scalars) ||
|
||||
volume_scalars.size()!=615)
|
||||
{
|
||||
std::cerr<<"[ERROR] LCC_vtk_io_test error read_VTK 3 in test_different_scalars"<<std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!CGAL::IO::read_VTK("output.vtk", lcc))
|
||||
{
|
||||
std::cerr<<"[ERROR] LCC_vtk_io_test error read_VTK 4 in test_different_scalars"<<std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// test read all scalars when they are not in the file
|
||||
if(!CGAL::IO::read_VTK("output_vertex.vtk", lcc, &vertex_scalars, &volume_scalars) ||
|
||||
vertex_scalars.size()!=719 || volume_scalars.size()!=0)
|
||||
{
|
||||
std::cerr<<"[ERROR] LCC_vtk_io_test error read_VTK 5 in test_different_scalars"<<std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!CGAL::IO::read_VTK("output_vol.vtk", lcc, &vertex_scalars, &volume_scalars) ||
|
||||
vertex_scalars.size()!=0 || volume_scalars.size()!=615)
|
||||
{
|
||||
std::cerr<<"[ERROR] LCC_vtk_io_test error read_VTK 6 in test_different_scalars"<<std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!CGAL::IO::read_VTK("output_none.vtk", lcc, &vertex_scalars, &volume_scalars) ||
|
||||
vertex_scalars.size()!=0 || volume_scalars.size()!=0)
|
||||
{
|
||||
std::cerr<<"[ERROR] LCC_vtk_io_test error read_VTK 7 in test_different_scalars"<<std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
bool res=true;
|
||||
if(!test_file("data/2tetra.vtk"))
|
||||
{
|
||||
std::cerr<<"[ERROR] LCC_vtk_io_test error for file data/2tetra.vtk"<<std::endl;
|
||||
res=false;
|
||||
}
|
||||
if(!test_file("data/2hexa.vtk"))
|
||||
{
|
||||
std::cerr<<"[ERROR] LCC_vtk_io_test error for file data/2hexa.vtk"<<std::endl;
|
||||
res=false;
|
||||
}
|
||||
if(!test_file("data/2prism.vtk"))
|
||||
{
|
||||
std::cerr<<"[ERROR] LCC_vtk_io_test error for file data/2prism.vtk"<<std::endl;
|
||||
res=false;
|
||||
}
|
||||
if(!test_file("data/2pyramid.vtk"))
|
||||
{
|
||||
std::cerr<<"[ERROR] LCC_vtk_io_test error for file data/2pyramid.vtk"<<std::endl;
|
||||
res=false;
|
||||
}
|
||||
if(!test_file("data/2generic_cell.vtk"))
|
||||
{
|
||||
std::cerr<<"[ERROR] LCC_vtk_io_test error for file data/2generic_cell.vtk"<<std::endl;
|
||||
res=false;
|
||||
}
|
||||
if(!test_file("data/beam-with-mixed-cells.vtk"))
|
||||
{
|
||||
std::cerr<<"[ERROR] LCC_vtk_io_test error for file data/beam-with-mixed-cells.vtk"<<std::endl;
|
||||
res=false;
|
||||
}
|
||||
|
||||
if(!test_different_scalars())
|
||||
{ res=false; }
|
||||
|
||||
if(!res) { return EXIT_FAILURE; }
|
||||
|
||||
std::cout<<"[OK] all tests in Linear_cell_complex_vtk_io_test.cpp"<<std::endl;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue