mirror of https://github.com/CGAL/cgal
Compare commits
78 Commits
f1d5ec16dd
...
b290d9c5bb
| Author | SHA1 | Date |
|---|---|---|
|
|
b290d9c5bb | |
|
|
26a5fc70e4 | |
|
|
39dd7c5028 | |
|
|
def6c38d76 | |
|
|
f503ce9359 | |
|
|
be305f320f | |
|
|
b8db056348 | |
|
|
18ee149f2e | |
|
|
15d96571a1 | |
|
|
06996f077f | |
|
|
5f8a8fe359 | |
|
|
543d424f58 | |
|
|
8e3a59a27b | |
|
|
40ac746be7 | |
|
|
9d28892e5f | |
|
|
92a896abb9 | |
|
|
1b3556184a | |
|
|
fdf06fe969 | |
|
|
c8099415d4 | |
|
|
a0c32277d0 | |
|
|
884e9fc4ee | |
|
|
cee9effe09 | |
|
|
eb14bf2a17 | |
|
|
970f16913b | |
|
|
2096d66b3d | |
|
|
3ccdc134fe | |
|
|
5812c1d6b5 | |
|
|
48262b8068 | |
|
|
24d3cd4bec | |
|
|
76552ccca1 | |
|
|
546d0b2871 | |
|
|
828d57a419 | |
|
|
6f2c3d819e | |
|
|
459fcf3c3f | |
|
|
1c1245d5c0 | |
|
|
d1c66eaa0f | |
|
|
25844edf50 | |
|
|
6bd5ec4f8b | |
|
|
eaa25c500b | |
|
|
64e33bd6cb | |
|
|
f28e643ed0 | |
|
|
2d39ab4dd8 | |
|
|
2fb9a2d832 | |
|
|
7c3b2302b5 | |
|
|
8b4e81ab5c | |
|
|
44306e981a | |
|
|
25060734a0 | |
|
|
e70e2109f4 | |
|
|
fb748f6442 | |
|
|
f766834601 | |
|
|
5e26465b2c | |
|
|
67220b911b | |
|
|
37b6a7214d | |
|
|
592b8824ec | |
|
|
7c9b9d1592 | |
|
|
6d011a62ae | |
|
|
f6425d7773 | |
|
|
2ca338068b | |
|
|
e1ec2fd1d2 | |
|
|
ce1c890cb0 | |
|
|
8c84316796 | |
|
|
ed6eb76670 | |
|
|
66bb36e336 | |
|
|
cd248c2638 | |
|
|
1a03f8c6e1 | |
|
|
4d615a31b6 | |
|
|
5a3dbda022 | |
|
|
876db072d8 | |
|
|
8ebeb13896 | |
|
|
f25a684c95 | |
|
|
3382ac0d18 | |
|
|
707375e780 | |
|
|
f41b5b60f7 | |
|
|
cc19bd4a80 | |
|
|
464c591b5a | |
|
|
e0634c4ab1 | |
|
|
c37745641a | |
|
|
09365799e9 |
|
|
@ -30,7 +30,7 @@
|
||||||
|
|
||||||
#include <CGAL/tags.h>
|
#include <CGAL/tags.h>
|
||||||
#include <CGAL/Arr_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>
|
#include <CGAL/Arr_geometry_traits/Circle_segment_2.h>
|
||||||
|
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
|
|
@ -41,31 +41,31 @@ namespace CGAL {
|
||||||
template <typename Kernel_, bool Filter = true>
|
template <typename Kernel_, bool Filter = true>
|
||||||
class Arr_circle_segment_traits_2 {
|
class Arr_circle_segment_traits_2 {
|
||||||
public:
|
public:
|
||||||
typedef Kernel_ Kernel;
|
using Kernel = Kernel_;
|
||||||
typedef typename Kernel::FT NT;
|
using NT = typename Kernel::FT;
|
||||||
typedef typename Kernel::Point_2 Rational_point_2;
|
using Rational_point_2 = typename Kernel::Point_2;
|
||||||
typedef typename Kernel::Segment_2 Rational_segment_2;
|
using Rational_segment_2 = typename Kernel::Segment_2;
|
||||||
typedef typename Kernel::Circle_2 Rational_circle_2;
|
using Rational_circle_2 = typename Kernel::Circle_2;
|
||||||
typedef _One_root_point_2<NT, Filter> Point_2;
|
using Point_2 = _One_root_point_2<NT, Filter>;
|
||||||
typedef typename Point_2::CoordNT CoordNT;
|
using CoordNT = typename Point_2::CoordNT;
|
||||||
typedef _Circle_segment_2<Kernel, Filter> Curve_2;
|
using Curve_2 = _Circle_segment_2<Kernel, Filter>;
|
||||||
typedef _X_monotone_circle_segment_2<Kernel, Filter> X_monotone_curve_2;
|
using X_monotone_curve_2 = _X_monotone_circle_segment_2<Kernel, Filter>;
|
||||||
typedef unsigned int Multiplicity;
|
using Multiplicity = std::size_t;
|
||||||
typedef Arr_circle_segment_traits_2<Kernel, Filter> Self;
|
using Self = Arr_circle_segment_traits_2<Kernel, Filter>;
|
||||||
|
|
||||||
// Category tags:
|
// Category tags:
|
||||||
typedef Tag_true Has_left_category;
|
using Has_left_category = Tag_true;
|
||||||
typedef Tag_true Has_merge_category;
|
using Has_merge_category = Tag_true;
|
||||||
typedef Tag_false Has_do_intersect_category;
|
using Has_do_intersect_category = Tag_false;
|
||||||
|
|
||||||
typedef Arr_oblivious_side_tag Left_side_category;
|
using Left_side_category = Arr_oblivious_side_tag;
|
||||||
typedef Arr_oblivious_side_tag Bottom_side_category;
|
using Bottom_side_category = Arr_oblivious_side_tag;
|
||||||
typedef Arr_oblivious_side_tag Top_side_category;
|
using Top_side_category = Arr_oblivious_side_tag;
|
||||||
typedef Arr_oblivious_side_tag Right_side_category;
|
using Right_side_category = Arr_oblivious_side_tag;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Type definition for the intersection points mapping.
|
// 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
|
mutable Intersection_map inter_map; // Mapping pairs of curve IDs to their
|
||||||
// intersection points.
|
// intersection points.
|
||||||
|
|
@ -78,8 +78,7 @@ public:
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/*! obtains the next curve index. */
|
/*! obtains the next curve index. */
|
||||||
static unsigned int get_index ()
|
static unsigned int get_index() {
|
||||||
{
|
|
||||||
#ifdef CGAL_NO_ATOMIC
|
#ifdef CGAL_NO_ATOMIC
|
||||||
static unsigned int index;
|
static unsigned int index;
|
||||||
#else
|
#else
|
||||||
|
|
@ -91,8 +90,7 @@ public:
|
||||||
/// \name Basic functor definitions.
|
/// \name Basic functor definitions.
|
||||||
//@{
|
//@{
|
||||||
|
|
||||||
class Compare_x_2
|
class Compare_x_2 {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
/*! compares the \f$x\f$-coordinates of two points.
|
/*! compares the \f$x\f$-coordinates of two points.
|
||||||
* \param p1 The first point.
|
* \param p1 The first point.
|
||||||
|
|
@ -101,23 +99,17 @@ public:
|
||||||
* SMALLER if x(p1) < x(p2);
|
* SMALLER if x(p1) < x(p2);
|
||||||
* EQUAL 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 {
|
||||||
{
|
if (p1.identical (p2)) return (EQUAL);
|
||||||
if (p1.identical (p2))
|
|
||||||
return (EQUAL);
|
|
||||||
|
|
||||||
return (CGAL::compare (p1.x(), p2.x()));
|
return (CGAL::compare (p1.x(), p2.x()));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/*! obtains a `Compare_x_2` functor object. */
|
/*! obtains a `Compare_x_2` functor object. */
|
||||||
Compare_x_2 compare_x_2_object () const
|
Compare_x_2 compare_x_2_object () const { return Compare_x_2(); }
|
||||||
{
|
|
||||||
return Compare_x_2();
|
|
||||||
}
|
|
||||||
|
|
||||||
class Compare_xy_2
|
class Compare_xy_2 {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
/*! compares two points lexigoraphically: by x, then by y.
|
/*! compares two points lexigoraphically: by x, then by y.
|
||||||
* \param p1 The first point.
|
* \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);
|
* SMALLER if x(p1) < x(p2), or if x(p1) = x(p2) and y(p1) < y(p2);
|
||||||
* EQUAL if the two points are equal.
|
* 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 {
|
||||||
{
|
if (p1.identical (p2)) return (EQUAL);
|
||||||
if (p1.identical (p2))
|
|
||||||
return (EQUAL);
|
|
||||||
|
|
||||||
Comparison_result res = CGAL::compare (p1.x(), p2.x());
|
Comparison_result res = CGAL::compare(p1.x(), p2.x());
|
||||||
|
if (res != EQUAL) return (res);
|
||||||
if (res != EQUAL)
|
|
||||||
return (res);
|
|
||||||
|
|
||||||
return (CGAL::compare (p1.y(), p2.y()));
|
return (CGAL::compare (p1.y(), p2.y()));
|
||||||
}
|
}
|
||||||
|
|
@ -142,69 +130,51 @@ public:
|
||||||
|
|
||||||
/*! obtains a Compare_xy_2 functor object. */
|
/*! obtains a Compare_xy_2 functor object. */
|
||||||
Compare_xy_2 compare_xy_2_object () const
|
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:
|
public:
|
||||||
/*! obtains the left endpoint of the \f$x\f$-monotone curve (segment).
|
/*! obtains the left endpoint of the \f$x\f$-monotone curve (segment).
|
||||||
* \param cv The curve.
|
* \param cv The curve.
|
||||||
* \return The left endpoint.
|
* \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
|
||||||
{
|
{ return (cv.left()); }
|
||||||
return (cv.left());
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*! obtains a `Construct_min_vertex_2` functor object. */
|
/*! obtains 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(); }
|
||||||
return Construct_min_vertex_2();
|
|
||||||
}
|
|
||||||
|
|
||||||
class Construct_max_vertex_2
|
class Construct_max_vertex_2 {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
/*! obtains the right endpoint of the \f$x\f$-monotone curve (segment).
|
/*! obtains the right endpoint of the \f$x\f$-monotone curve (segment).
|
||||||
* \param cv The curve.
|
* \param cv The curve.
|
||||||
* \return The right endpoint.
|
* \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
|
||||||
{
|
{ return (cv.right()); }
|
||||||
return (cv.right());
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*! obtains a Construct_max_vertex_2 functor object. */
|
/*! obtains a Construct_max_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(); }
|
||||||
return Construct_max_vertex_2();
|
|
||||||
}
|
|
||||||
|
|
||||||
class Is_vertical_2
|
class Is_vertical_2 {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
/*! checks whether the given \f$x\f$-monotone curve is a vertical segment.
|
/*! checks whether the given \f$x\f$-monotone curve is a vertical segment.
|
||||||
* \param cv The curve.
|
* \param cv The curve.
|
||||||
* \return (true) if the curve is a vertical segment; (false) otherwise.
|
* \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
|
||||||
{
|
{ return (cv.is_vertical()); }
|
||||||
return (cv.is_vertical());
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*! obtains an `Is_vertical_2` functor object. */
|
/*! obtains an `Is_vertical_2` functor object. */
|
||||||
Is_vertical_2 is_vertical_2_object () const
|
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:
|
public:
|
||||||
/*! returns the location of the given point with respect to the input curve.
|
/*! returns the location of the given point with respect to the input curve.
|
||||||
* \param cv The 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;
|
* LARGER if y(p) > cv(x(p)), i.e. the point is above the curve;
|
||||||
* EQUAL if p lies on the curve.
|
* EQUAL if p lies on the curve.
|
||||||
*/
|
*/
|
||||||
Comparison_result operator() (const Point_2& p,
|
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_in_x_range(p));
|
||||||
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. */
|
/*! obtains a `Compare_y_at_x_2` functor object. */
|
||||||
Compare_y_at_x_2 compare_y_at_x_2_object () const
|
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:
|
public:
|
||||||
/*! compares the y value of two \f$x\f$-monotone curves immediately to the
|
/*! compares the y value of two \f$x\f$-monotone curves immediately to the
|
||||||
* right of their intersection point.
|
* right of their intersection point.
|
||||||
|
|
@ -244,30 +210,29 @@ public:
|
||||||
*/
|
*/
|
||||||
Comparison_result operator() (const X_monotone_curve_2& cv1,
|
Comparison_result operator() (const X_monotone_curve_2& cv1,
|
||||||
const X_monotone_curve_2& cv2,
|
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
|
// 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).
|
// right (so their right endpoint is lexicographically larger than p).
|
||||||
CGAL_precondition (cv1.point_position (p) == EQUAL &&
|
CGAL_precondition (cv1.point_position (p) == EQUAL &&
|
||||||
cv2.point_position (p) == EQUAL);
|
cv2.point_position (p) == EQUAL);
|
||||||
|
|
||||||
if ((CGAL::compare (cv1.left().x(),cv1.right().x()) == EQUAL) &&
|
if ((CGAL::compare (cv1.left().x(),cv1.right().x()) == EQUAL) &&
|
||||||
(CGAL::compare (cv2.left().x(),cv2.right().x()) == EQUAL))
|
(CGAL::compare (cv2.left().x(),cv2.right().x()) == EQUAL)) {
|
||||||
{ //both cv1 and cv2 are vertical
|
//both cv1 and cv2 are vertical
|
||||||
CGAL_precondition (!(cv1.right()).equals(p) && !(cv2.right()).equals(p));
|
CGAL_precondition (!(cv1.right()).equals(p) && !(cv2.right()).equals(p));
|
||||||
}
|
}
|
||||||
else if ((CGAL::compare (cv1.left().x(),cv1.right().x()) != EQUAL) &&
|
else if ((CGAL::compare (cv1.left().x(),cv1.right().x()) != EQUAL) &&
|
||||||
(CGAL::compare (cv2.left().x(),cv2.right().x()) == EQUAL))
|
(CGAL::compare (cv2.left().x(),cv2.right().x()) == EQUAL)) {
|
||||||
{ //only cv1 is vertical
|
//only cv1 is vertical
|
||||||
CGAL_precondition (!(cv1.right()).equals(p));
|
CGAL_precondition (!(cv1.right()).equals(p));
|
||||||
}
|
}
|
||||||
else if ((CGAL::compare (cv1.left().x(),cv1.right().x()) == EQUAL) &&
|
else if ((CGAL::compare (cv1.left().x(),cv1.right().x()) == EQUAL) &&
|
||||||
(CGAL::compare (cv2.left().x(),cv2.right().x()) != EQUAL))
|
(CGAL::compare (cv2.left().x(),cv2.right().x()) != EQUAL)) {
|
||||||
{ //only cv2 is vertical
|
//only cv2 is vertical
|
||||||
CGAL_precondition (!(cv2.right()).equals(p));
|
CGAL_precondition (!(cv2.right()).equals(p));
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{ //both cv1 and cv2 are non vertical
|
//both cv1 and cv2 are non vertical
|
||||||
CGAL_precondition (CGAL::compare (cv1.right().x(),p.x()) == LARGER &&
|
CGAL_precondition (CGAL::compare (cv1.right().x(),p.x()) == LARGER &&
|
||||||
CGAL::compare (cv2.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. */
|
/*! obtains a `Compare_y_at_x_right_2` functor object. */
|
||||||
Compare_y_at_x_right_2 compare_y_at_x_right_2_object () const
|
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:
|
public:
|
||||||
/*! compares the \f$y\f$-value of two \f$x\f$-monotone curves immediately to
|
/*! compares the \f$y\f$-value of two \f$x\f$-monotone curves immediately to
|
||||||
* the left of their intersection point.
|
* the left of their intersection point.
|
||||||
|
|
@ -297,8 +259,7 @@ public:
|
||||||
*/
|
*/
|
||||||
Comparison_result operator() (const X_monotone_curve_2& cv1,
|
Comparison_result operator() (const X_monotone_curve_2& cv1,
|
||||||
const X_monotone_curve_2& cv2,
|
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
|
// 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).
|
// left (so their left endpoint is lexicographically smaller than p).
|
||||||
|
|
||||||
|
|
@ -306,25 +267,25 @@ public:
|
||||||
cv2.point_position (p) == EQUAL);
|
cv2.point_position (p) == EQUAL);
|
||||||
|
|
||||||
if ((CGAL::compare (cv1.left().x(),cv1.right().x()) == EQUAL) &&
|
if ((CGAL::compare (cv1.left().x(),cv1.right().x()) == EQUAL) &&
|
||||||
(CGAL::compare (cv2.left().x(),cv2.right().x()) == EQUAL))
|
(CGAL::compare (cv2.left().x(),cv2.right().x()) == EQUAL)) {
|
||||||
{ //both cv1 and cv2 are vertical
|
//both cv1 and cv2 are vertical
|
||||||
CGAL_precondition (!(cv1.left()).equals(p) && !(cv2.left()).equals(p));
|
CGAL_precondition (!(cv1.left()).equals(p) && !(cv2.left()).equals(p));
|
||||||
}
|
}
|
||||||
else if ((CGAL::compare (cv1.left().x(),cv1.right().x()) != EQUAL) &&
|
else if ((CGAL::compare (cv1.left().x(),cv1.right().x()) != EQUAL) &&
|
||||||
(CGAL::compare (cv2.left().x(),cv2.right().x()) == EQUAL))
|
(CGAL::compare (cv2.left().x(),cv2.right().x()) == EQUAL)) {
|
||||||
{ //only cv1 is vertical
|
//only cv1 is vertical
|
||||||
CGAL_precondition (!(cv1.left()).equals(p));
|
CGAL_precondition (!(cv1.left()).equals(p));
|
||||||
}
|
}
|
||||||
else if ((CGAL::compare (cv1.left().x(),cv1.right().x()) == EQUAL) &&
|
else if ((CGAL::compare (cv1.left().x(),cv1.right().x()) == EQUAL) &&
|
||||||
(CGAL::compare (cv2.left().x(),cv2.right().x()) != EQUAL))
|
(CGAL::compare (cv2.left().x(),cv2.right().x()) != EQUAL)) {
|
||||||
{ //only cv2 is vertical
|
//only cv2 is vertical
|
||||||
CGAL_precondition (!(cv2.left()).equals(p));
|
CGAL_precondition (!(cv2.left()).equals(p));
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{ //both cv1 and cv2 are non vertical
|
//both cv1 and cv2 are non vertical
|
||||||
CGAL_precondition (CGAL::compare (cv1.left().x(),p.x()) == SMALLER &&
|
CGAL_precondition (CGAL::compare (cv1.left().x(),p.x()) == SMALLER &&
|
||||||
CGAL::compare (cv2.left().x(),p.x()) == SMALLER);
|
CGAL::compare (cv2.left().x(),p.x()) == SMALLER);
|
||||||
}
|
}
|
||||||
// Compare the two curves immediately to the left of p:
|
// Compare the two curves immediately to the left of p:
|
||||||
return (cv1.compare_to_left (cv2, p));
|
return (cv1.compare_to_left (cv2, p));
|
||||||
}
|
}
|
||||||
|
|
@ -332,12 +293,9 @@ public:
|
||||||
|
|
||||||
/*! obtains a `Compare_y_at_x_left_2` functor object. */
|
/*! obtains a `Compare_y_at_x_left_2` functor object. */
|
||||||
Compare_y_at_x_left_2 compare_y_at_x_left_2_object () const
|
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:
|
public:
|
||||||
/*! checks if the two \f$x\f$-monotone curves are the same (have the same
|
/*! checks if the two \f$x\f$-monotone curves are the same (have the same
|
||||||
* graph).
|
* graph).
|
||||||
|
|
@ -346,10 +304,8 @@ public:
|
||||||
* \return (true) if the two curves are the same; (false) otherwise.
|
* \return (true) if the two curves are the same; (false) otherwise.
|
||||||
*/
|
*/
|
||||||
bool operator() (const X_monotone_curve_2& cv1,
|
bool operator() (const X_monotone_curve_2& cv1,
|
||||||
const X_monotone_curve_2& cv2) const
|
const X_monotone_curve_2& cv2) const {
|
||||||
{
|
if (&cv1 == &cv2) return (true);
|
||||||
if (&cv1 == &cv2)
|
|
||||||
return (true);
|
|
||||||
|
|
||||||
return (cv1.equals (cv2));
|
return (cv1.equals (cv2));
|
||||||
}
|
}
|
||||||
|
|
@ -360,24 +316,20 @@ public:
|
||||||
* \return (true) if the two point are the same; (false) otherwise.
|
* \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
|
||||||
{
|
{ return (p1.equals (p2)); }
|
||||||
return (p1.equals (p2));
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*! obtains an `Equal_2` functor object. */
|
/*! obtains an `Equal_2` functor object. */
|
||||||
Equal_2 equal_2_object () const
|
Equal_2 equal_2_object () const
|
||||||
{
|
{ return Equal_2(); }
|
||||||
return Equal_2();
|
|
||||||
}
|
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
/// \name Functor definitions for approximations. Used by the landmarks
|
/// \name Functor definitions for approximations. Used by the landmarks
|
||||||
// point-location strategy and the drawing procedure.
|
// point-location strategy and the drawing procedure.
|
||||||
//@{
|
//@{
|
||||||
typedef double Approximate_number_type;
|
using Approximate_number_type = double;
|
||||||
typedef CGAL::Cartesian<Approximate_number_type> Approximate_kernel;
|
using Approximate_kernel = CGAL::Simple_cartesian<Approximate_number_type>;
|
||||||
typedef Approximate_kernel::Point_2 Approximate_point_2;
|
using Approximate_point_2 = Approximate_kernel::Point_2;
|
||||||
|
|
||||||
class Approximate_2 {
|
class Approximate_2 {
|
||||||
protected:
|
protected:
|
||||||
|
|
@ -557,7 +509,7 @@ public:
|
||||||
*/
|
*/
|
||||||
class Make_x_monotone_2 {
|
class Make_x_monotone_2 {
|
||||||
private:
|
private:
|
||||||
typedef Arr_circle_segment_traits_2<Kernel_, Filter> Self;
|
using Self = Arr_circle_segment_traits_2<Kernel_, Filter>;
|
||||||
|
|
||||||
bool m_use_cache;
|
bool m_use_cache;
|
||||||
|
|
||||||
|
|
@ -573,8 +525,7 @@ public:
|
||||||
* \return the past-the-end iterator.
|
* \return the past-the-end iterator.
|
||||||
*/
|
*/
|
||||||
template <typename OutputIterator>
|
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
|
// Increment the serial number of the curve cv, which will serve as its
|
||||||
// unique identifier.
|
// unique identifier.
|
||||||
unsigned int index = 0;
|
unsigned int index = 0;
|
||||||
|
|
@ -591,7 +542,7 @@ public:
|
||||||
|
|
||||||
// Check the case of a degenerate circle (a point).
|
// Check the case of a degenerate circle (a point).
|
||||||
const typename Kernel::Circle_2& circ = cv.supporting_circle();
|
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);
|
CGAL_precondition (sign_rad != NEGATIVE);
|
||||||
|
|
||||||
if (sign_rad == ZERO) {
|
if (sign_rad == ZERO) {
|
||||||
|
|
@ -603,8 +554,8 @@ public:
|
||||||
|
|
||||||
// The curve is circular: compute the to vertical tangency points
|
// The curve is circular: compute the to vertical tangency points
|
||||||
// of the supporting circle.
|
// of the supporting circle.
|
||||||
Point_2 vpts[2];
|
Point_2 vpts[2];
|
||||||
unsigned int n_vpts = cv.vertical_tangency_points (vpts);
|
unsigned int n_vpts = cv.vertical_tangency_points (vpts);
|
||||||
|
|
||||||
if (cv.is_full()) {
|
if (cv.is_full()) {
|
||||||
CGAL_assertion (n_vpts == 2);
|
CGAL_assertion (n_vpts == 2);
|
||||||
|
|
@ -674,8 +625,7 @@ public:
|
||||||
Make_x_monotone_2 make_x_monotone_2_object() const
|
Make_x_monotone_2 make_x_monotone_2_object() const
|
||||||
{ return Make_x_monotone_2(m_use_cache); }
|
{ return Make_x_monotone_2(m_use_cache); }
|
||||||
|
|
||||||
class Split_2
|
class Split_2 {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/*! splits 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
|
||||||
|
|
@ -687,8 +637,7 @@ public:
|
||||||
* \pre `p` lies on cv but is not one of its end-points.
|
* \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,
|
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 &&
|
CGAL_precondition (cv.point_position(p)==EQUAL &&
|
||||||
! p.equals (cv.source()) &&
|
! p.equals (cv.source()) &&
|
||||||
! p.equals (cv.target()));
|
! p.equals (cv.target()));
|
||||||
|
|
@ -699,10 +648,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
/*! obtains a `Split_2` functor object. */
|
/*! obtains a `Split_2` functor object. */
|
||||||
Split_2 split_2_object () const
|
Split_2 split_2_object () const { return Split_2(); }
|
||||||
{
|
|
||||||
return Split_2();
|
|
||||||
}
|
|
||||||
|
|
||||||
class Intersect_2 {
|
class Intersect_2 {
|
||||||
private:
|
private:
|
||||||
|
|
@ -730,8 +676,7 @@ public:
|
||||||
/*! obtains an `Intersect_2` functor object. */
|
/*! obtains an `Intersect_2` functor object. */
|
||||||
Intersect_2 intersect_2_object() const { return (Intersect_2(inter_map)); }
|
Intersect_2 intersect_2_object() const { return (Intersect_2(inter_map)); }
|
||||||
|
|
||||||
class Are_mergeable_2
|
class Are_mergeable_2 {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
/*! checks whether it is possible to merge two given \f$x\f$-monotone curves.
|
/*! checks whether it is possible to merge two given \f$x\f$-monotone curves.
|
||||||
* \param cv1 The first curve.
|
* \param cv1 The first curve.
|
||||||
|
|
@ -742,24 +687,19 @@ public:
|
||||||
*/
|
*/
|
||||||
bool operator() (const X_monotone_curve_2& cv1,
|
bool operator() (const X_monotone_curve_2& cv1,
|
||||||
const X_monotone_curve_2& cv2) const
|
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. */
|
/*! obtains an `Are_mergeable_2` functor object. */
|
||||||
Are_mergeable_2 are_mergeable_2_object () const
|
Are_mergeable_2 are_mergeable_2_object () const
|
||||||
{
|
{ return Are_mergeable_2(); }
|
||||||
return Are_mergeable_2();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! \class Merge_2
|
/*! \class Merge_2
|
||||||
* A functor that merges two \f$x\f$-monotone arcs into one.
|
* A functor that merges two \f$x\f$-monotone arcs into one.
|
||||||
*/
|
*/
|
||||||
class Merge_2
|
class Merge_2 {
|
||||||
{
|
|
||||||
protected:
|
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) */
|
/*! The traits (in case it has state) */
|
||||||
const Traits* m_traits;
|
const Traits* m_traits;
|
||||||
|
|
@ -780,8 +720,7 @@ public:
|
||||||
*/
|
*/
|
||||||
void operator() (const X_monotone_curve_2& cv1,
|
void operator() (const X_monotone_curve_2& cv1,
|
||||||
const X_monotone_curve_2& cv2,
|
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(m_traits->are_mergeable_2_object()(cv2, cv1));
|
||||||
|
|
||||||
c = cv1;
|
c = cv1;
|
||||||
|
|
@ -790,20 +729,15 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
/*! obtains a `Merge_2` functor object. */
|
/*! obtains a `Merge_2` functor object. */
|
||||||
Merge_2 merge_2_object () const
|
Merge_2 merge_2_object () const { return Merge_2(this); }
|
||||||
{
|
|
||||||
return Merge_2(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
class Compare_endpoints_xy_2
|
class Compare_endpoints_xy_2 {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
/*! compares lexicogrphic the endpoints of a \f$x\f$-monotone curve.
|
/*! compares lexicogrphic the endpoints of a \f$x\f$-monotone curve.
|
||||||
* \param cv the curve
|
* \param cv the curve
|
||||||
* \return `SMALLER` if the curve is directed right, else return `LARGER`.
|
* \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())
|
if(cv.is_directed_right())
|
||||||
return(SMALLER);
|
return(SMALLER);
|
||||||
return (LARGER);
|
return (LARGER);
|
||||||
|
|
@ -812,32 +746,25 @@ public:
|
||||||
|
|
||||||
/*! obtains a `Compare_endpoints_xy_2` functor object. */
|
/*! obtains a `Compare_endpoints_xy_2` functor object. */
|
||||||
Compare_endpoints_xy_2 compare_endpoints_xy_2_object() const
|
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:
|
public:
|
||||||
/*! constructs an opposite \f$x\f$-monotone curve.
|
/*! constructs an opposite \f$x\f$-monotone curve.
|
||||||
* \param cv the curve
|
* \param cv the curve
|
||||||
* \return an opposite \f$x\f$-monotone curve.
|
* \return an opposite \f$x\f$-monotone curve.
|
||||||
*/
|
*/
|
||||||
X_monotone_curve_2 operator()(const X_monotone_curve_2& cv) const
|
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. */
|
/*! obtains a `Construct_opposite_2` functor object. */
|
||||||
Construct_opposite_2 construct_opposite_2_object() const
|
Construct_opposite_2 construct_opposite_2_object() const
|
||||||
{
|
{ return Construct_opposite_2(); }
|
||||||
return Construct_opposite_2();
|
|
||||||
}
|
|
||||||
|
|
||||||
class Trim_2 {
|
class Trim_2 {
|
||||||
protected:
|
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) */
|
/*! The traits (in case it has state) */
|
||||||
const Traits& m_traits;
|
const Traits& m_traits;
|
||||||
|
|
@ -860,8 +787,7 @@ public:
|
||||||
*/
|
*/
|
||||||
X_monotone_curve_2 operator()(const X_monotone_curve_2& xcv,
|
X_monotone_curve_2 operator()(const X_monotone_curve_2& xcv,
|
||||||
const Point_2& src,
|
const Point_2& src,
|
||||||
const Point_2& tgt)const
|
const Point_2& tgt)const {
|
||||||
{
|
|
||||||
// make functor objects
|
// make functor objects
|
||||||
CGAL_precondition_code(Compare_y_at_x_2 compare_y_at_x_2 =
|
CGAL_precondition_code(Compare_y_at_x_2 compare_y_at_x_2 =
|
||||||
m_traits.compare_y_at_x_2_object());
|
m_traits.compare_y_at_x_2_object());
|
||||||
|
|
@ -885,7 +811,6 @@ public:
|
||||||
Trim_2 trim_2_object() const { return Trim_2(*this); }
|
Trim_2 trim_2_object() const { return Trim_2(*this); }
|
||||||
|
|
||||||
// @}
|
// @}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace CGAL
|
} // namespace CGAL
|
||||||
|
|
|
||||||
|
|
@ -40,55 +40,54 @@
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
|
|
||||||
namespace internal{
|
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:
|
public:
|
||||||
Non_x_monotonic_Circular_arc_2(): Base(){}
|
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
|
// Not Documented
|
||||||
Non_x_monotonic_Circular_arc_2(const Circle_2 &support,
|
Non_x_monotonic_Circular_arc_2(const Circle_2& support,
|
||||||
const Line_2 &l1, const bool b_l1,
|
const Line_2& l1, const bool b_l1,
|
||||||
const Line_2 &l2, const bool b_l2)
|
const Line_2& l2, const bool b_l2) :
|
||||||
: Base(support,l1,b_l1,l2,b_l2){}
|
Base(support,l1,b_l1,l2,b_l2){}
|
||||||
|
|
||||||
// Not Documented
|
// Not Documented
|
||||||
Non_x_monotonic_Circular_arc_2(const Circle_2 &c,
|
Non_x_monotonic_Circular_arc_2(const Circle_2& c,
|
||||||
const Circle_2 &c1, const bool b_1,
|
const Circle_2& c1, const bool b_1,
|
||||||
const Circle_2 &c2, const bool b_2)
|
const Circle_2& c2, const bool b_2) :
|
||||||
: Base(c,c1,b_1,c2,b_2)
|
Base(c,c1,b_1,c2,b_2)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
Non_x_monotonic_Circular_arc_2(const Point_2 &start,
|
Non_x_monotonic_Circular_arc_2(const Point_2& start,
|
||||||
const Point_2 &middle,
|
const Point_2& middle,
|
||||||
const Point_2 &end)
|
const Point_2& end) :
|
||||||
: Base(start,middle,end)
|
Base(start,middle,end)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
Non_x_monotonic_Circular_arc_2(const Circle_2 &support,
|
Non_x_monotonic_Circular_arc_2(const Circle_2& support,
|
||||||
const Circular_arc_point_2 &begin,
|
const Circular_arc_point_2& begin,
|
||||||
const Circular_arc_point_2 &end)
|
const Circular_arc_point_2& end) :
|
||||||
: Base(support,begin,end)
|
Base(support,begin,end)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
Non_x_monotonic_Circular_arc_2(const Point_2 &start,
|
Non_x_monotonic_Circular_arc_2(const Point_2& start,
|
||||||
const Point_2 &end,
|
const Point_2& end,
|
||||||
const FT &bulge)
|
const FT& bulge) :
|
||||||
: Base(start,end,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
|
} //namespace internal
|
||||||
|
|
@ -98,45 +97,40 @@ public:
|
||||||
|
|
||||||
template < typename CircularKernel >
|
template < typename CircularKernel >
|
||||||
class Arr_circular_arc_traits_2 {
|
class Arr_circular_arc_traits_2 {
|
||||||
|
|
||||||
CircularKernel ck;
|
CircularKernel ck;
|
||||||
|
|
||||||
public:
|
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;
|
using Point = typename CircularKernel::Circular_arc_point_2;
|
||||||
typedef internal::Non_x_monotonic_Circular_arc_2<CircularKernel> Curve_2;
|
using Point_2 = typename CircularKernel::Circular_arc_point_2;
|
||||||
typedef typename CircularKernel::Circular_arc_2 X_monotone_curve_2;
|
|
||||||
|
|
||||||
typedef typename CircularKernel::Circular_arc_point_2 Point;
|
using Multiplicity = std::size_t;
|
||||||
typedef typename CircularKernel::Circular_arc_point_2 Point_2;
|
|
||||||
|
|
||||||
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;
|
using Left_side_category = Arr_oblivious_side_tag;
|
||||||
typedef CGAL::Tag_false Has_merge_category;
|
using Bottom_side_category = Arr_oblivious_side_tag;
|
||||||
typedef CGAL::Tag_false Has_do_intersect_category;
|
using Top_side_category = Arr_oblivious_side_tag;
|
||||||
|
using Right_side_category = Arr_oblivious_side_tag;
|
||||||
|
|
||||||
typedef Arr_oblivious_side_tag Left_side_category;
|
Arr_circular_arc_traits_2(const CircularKernel& k = CircularKernel()) : ck(k) {}
|
||||||
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())
|
using Compare_x_2 = typename CircularKernel::Compare_x_2;
|
||||||
: ck(k) {}
|
using Compare_xy_2 = typename CircularKernel::Compare_xy_2;
|
||||||
|
using Compare_y_at_x_2 = typename CircularKernel::Compare_y_at_x_2;
|
||||||
typedef typename CircularKernel::Compare_x_2 Compare_x_2;
|
using Compare_y_at_x_right_2 = typename CircularKernel::Compare_y_to_right_2;
|
||||||
typedef typename CircularKernel::Compare_xy_2 Compare_xy_2;
|
using Construct_max_vertex_2 = typename CircularKernel::Construct_circular_max_vertex_2;
|
||||||
typedef typename CircularKernel::Compare_y_at_x_2 Compare_y_at_x_2;
|
using Construct_min_vertex_2 = typename CircularKernel::Construct_circular_min_vertex_2;
|
||||||
typedef typename CircularKernel::Compare_y_to_right_2 Compare_y_at_x_right_2;
|
using Equal_2 = typename CircularKernel::Equal_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;
|
|
||||||
// typedef typename CircularKernel::Make_x_monotone_2 Make_x_monotone_2;
|
// typedef typename CircularKernel::Make_x_monotone_2 Make_x_monotone_2;
|
||||||
typedef typename CircularKernel::Split_2 Split_2;
|
using Split_2 = typename CircularKernel::Split_2;
|
||||||
typedef typename CircularKernel::Intersect_2 Intersect_2;
|
using Intersect_2 = typename CircularKernel::Intersect_2;
|
||||||
typedef typename CircularKernel::Is_vertical_2 Is_vertical_2;
|
using Is_vertical_2 = typename CircularKernel::Is_vertical_2;
|
||||||
|
|
||||||
Compare_x_2 compare_x_2_object() const
|
Compare_x_2 compare_x_2_object() const
|
||||||
{ return ck.compare_x_2_object(); }
|
{ return ck.compare_x_2_object(); }
|
||||||
|
|
@ -160,26 +154,23 @@ public:
|
||||||
{ return ck.split_2_object(); }
|
{ return ck.split_2_object(); }
|
||||||
|
|
||||||
Intersect_2 intersect_2_object() const
|
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
|
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
|
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
|
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.
|
//! A functor for subdividing curves into x-monotone curves.
|
||||||
class Make_x_monotone_2 {
|
class Make_x_monotone_2 {
|
||||||
public:
|
public:
|
||||||
template <typename OutputIterator>
|
template <typename OutputIterator>
|
||||||
OutputIterator operator()(const Curve_2& arc, OutputIterator oi) const
|
OutputIterator operator()(const Curve_2& arc, OutputIterator oi) const {
|
||||||
{
|
using Make_x_monotone_result = std::variant<Point_2, X_monotone_curve_2>;
|
||||||
typedef std::variant<Point_2, X_monotone_curve_2>
|
|
||||||
Make_x_monotone_result;
|
|
||||||
|
|
||||||
std::vector<Make_x_monotone_result> objs;
|
std::vector<Make_x_monotone_result> objs;
|
||||||
CircularKernel().make_x_monotone_2_object()(arc, std::back_inserter(objs));
|
CircularKernel().make_x_monotone_2_object()(arc, std::back_inserter(objs));
|
||||||
|
|
|
||||||
|
|
@ -41,515 +41,395 @@
|
||||||
#include <CGAL/Arr_tags.h>
|
#include <CGAL/Arr_tags.h>
|
||||||
|
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
namespace VariantFunctors{
|
|
||||||
|
|
||||||
// Takes an iterator range of Object(Line/Circular_arc/Point),
|
namespace VariantFunctors {
|
||||||
// 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;
|
|
||||||
|
|
||||||
for (auto it = res1.begin(); it != res1.end(); ++it) {
|
// Takes an iterator range of Object(Line/Circular_arc/Point),
|
||||||
if (const Arc1* arc = CGAL::object_cast<Arc1>(&*it)) {
|
// returns a variant of Line, Circular_arc, and Point_2.
|
||||||
std::variant<Arc1, Arc2> v = *arc;
|
template <typename CK, typename Arc1, typename Arc2, typename OutputIterator>
|
||||||
*res2++ = Make_x_monotone_result(v);
|
OutputIterator object_to_object_variant(const std::vector<CGAL::Object>& res1,
|
||||||
}
|
OutputIterator res2) {
|
||||||
else if (const Arc2* line = CGAL::object_cast<Arc2>(&*it)) {
|
using Point_2 = typename CK::Circular_arc_point_2;
|
||||||
std::variant<Arc1, Arc2> v = *line;
|
using X_monotone_curve_2 = std::variant<Arc1, Arc2>;
|
||||||
*res2++ = Make_x_monotone_result(v);
|
using Make_x_monotone_result = std::variant<Point_2, X_monotone_curve_2>;
|
||||||
}
|
|
||||||
else if (const Point_2* p = CGAL::object_cast<Point_2>(&*it)) {
|
for (auto it = res1.begin(); it != res1.end(); ++it) {
|
||||||
*res2++ = Make_x_monotone_result(*p);
|
if (const Arc1* arc = CGAL::object_cast<Arc1>(&*it)) {
|
||||||
}
|
std::variant<Arc1, Arc2> v = *arc;
|
||||||
else CGAL_error();
|
*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>
|
const Arc2* arc1e = std::get_if<Arc2>(&c1);
|
||||||
class Compare_y_to_right_2
|
if ( const Arc1* arc2 = std::get_if<Arc1>(&c2)) {
|
||||||
{
|
return CircularKernel().intersect_2_object()(*arc1e, *arc2, oi);
|
||||||
public:
|
}
|
||||||
typedef CGAL::Comparison_result result_type;
|
const Arc2* arc2 = std::get_if<Arc2>(&c2);
|
||||||
typedef typename CircularKernel::Circular_arc_point_2
|
return CircularKernel().intersect_2_object()(*arc1e, *arc2, oi);
|
||||||
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 );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
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
|
result_type operator()(const std::variant< Arc1, Arc2>& A,
|
||||||
// in Arr_circular_line_arc_traits_2.
|
const Circular_arc_point_2& p,
|
||||||
namespace internal_Argt_traits {
|
std::variant< Arc1, Arc2>& ca1,
|
||||||
struct Not_X_Monotone{};
|
std::variant< Arc1, Arc2>& ca2) const {
|
||||||
inline std::ostream& operator << (std::ostream& os, const Not_X_Monotone&)
|
// TODO : optimize by extracting the references from the variants ?
|
||||||
{return os;}
|
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>
|
template <typename T>
|
||||||
class Arr_circular_line_arc_traits_2 {
|
//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;
|
public:
|
||||||
typedef typename CircularKernel::Circular_arc_2 Arc2;
|
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;
|
template <typename CircularKernel>
|
||||||
typedef typename CircularKernel::Circular_arc_point_2
|
class Variant_Construct_max_vertex_2 {
|
||||||
Circular_arc_point_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;
|
template <typename T>
|
||||||
typedef typename CircularKernel::Circular_arc_point_2 Point_2;
|
//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;
|
public:
|
||||||
typedef CGAL::Tag_false Has_merge_category;
|
/*! obtains the right endpoint of the x-monotone curve (segment).
|
||||||
typedef CGAL::Tag_false Has_do_intersect_category;
|
* \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;
|
//std::remove_reference<qualified_result_type>
|
||||||
typedef Arr_oblivious_side_tag Bottom_side_category;
|
result_type operator() (const std::variant<Arc1, Arc2>& cv) const
|
||||||
typedef Arr_oblivious_side_tag Top_side_category;
|
{ return std::visit(Variant_Construct_max_vertex_2<CircularKernel>(), cv); }
|
||||||
typedef Arr_oblivious_side_tag Right_side_category;
|
};
|
||||||
|
|
||||||
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;
|
template <typename CircularKernel, typename Arc1, typename Arc2>
|
||||||
typedef std::variant< Arc1, Arc2 > X_monotone_curve_2;
|
class Is_vertical_2 {
|
||||||
|
public:
|
||||||
|
using result_type = bool;
|
||||||
|
|
||||||
private:
|
bool operator() (const std::variant<Arc1, Arc2>& cv) const
|
||||||
CircularKernel ck;
|
{ return std::visit(Variant_Is_vertical_2<CircularKernel>(), cv); }
|
||||||
public:
|
};
|
||||||
|
|
||||||
Arr_circular_line_arc_traits_2(const CircularKernel &k = CircularKernel())
|
}
|
||||||
: ck(k) {}
|
|
||||||
|
|
||||||
typedef typename CircularKernel::Compare_x_2 Compare_x_2;
|
// an empty class used to have different types between Curve_2 and X_monotone_curve_2
|
||||||
typedef typename CircularKernel::Compare_xy_2 Compare_xy_2;
|
// in Arr_circular_line_arc_traits_2.
|
||||||
typedef typename
|
namespace internal_Argt_traits {
|
||||||
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;
|
|
||||||
|
|
||||||
Compare_x_2 compare_x_2_object() const
|
struct Not_X_Monotone{};
|
||||||
{ return ck.compare_x_2_object(); }
|
|
||||||
|
|
||||||
Compare_xy_2 compare_xy_2_object() const
|
inline std::ostream& operator << (std::ostream& os, const Not_X_Monotone&) { return os; }
|
||||||
{ 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
|
/// Traits class for CGAL::Arrangement_2 (and similar) based on a CircularKernel.
|
||||||
{ return Compare_y_at_x_right_2(); }
|
|
||||||
|
|
||||||
Equal_2 equal_2_object() const
|
template <typename CircularKernel>
|
||||||
{ return Equal_2(); }
|
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
|
using Arc1 = typename CircularKernel::Line_arc_2;
|
||||||
{ return Make_x_monotone_2(); }
|
using Arc2 = typename CircularKernel::Circular_arc_2;
|
||||||
|
|
||||||
Split_2 split_2_object() const
|
public:
|
||||||
{ return Split_2(); }
|
using Kernel = CircularKernel;
|
||||||
|
using Circular_arc_point_2 = typename CircularKernel::Circular_arc_point_2;
|
||||||
|
|
||||||
Intersect_2 intersect_2_object() const
|
using Point = typename CircularKernel::Circular_arc_point_2;
|
||||||
{ return Intersect_2(); }
|
using Point_2 = typename CircularKernel::Circular_arc_point_2;
|
||||||
|
|
||||||
Construct_min_vertex_2 construct_min_vertex_2_object() const
|
using Multiplicity = std::size_t;
|
||||||
{ return Construct_min_vertex_2(); }
|
|
||||||
|
|
||||||
Construct_max_vertex_2 construct_max_vertex_2_object() const
|
using Has_left_category = CGAL::Tag_false;
|
||||||
{ return Construct_max_vertex_2(); }
|
using Has_merge_category = CGAL::Tag_false;
|
||||||
|
using Has_do_intersect_category = CGAL::Tag_false;
|
||||||
|
|
||||||
Is_vertical_2 is_vertical_2_object() const
|
using Left_side_category = Arr_oblivious_side_tag;
|
||||||
{ return Is_vertical_2();}
|
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
|
} // namespace CGAL
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@
|
||||||
|
|
||||||
#include <boost/math/constants/constants.hpp>
|
#include <boost/math/constants/constants.hpp>
|
||||||
|
|
||||||
#include <CGAL/Cartesian.h>
|
#include <CGAL/Simple_cartesian.h>
|
||||||
#include <CGAL/tags.h>
|
#include <CGAL/tags.h>
|
||||||
#include <CGAL/Arr_tags.h>
|
#include <CGAL/Arr_tags.h>
|
||||||
#include <CGAL/Arr_enums.h>
|
#include <CGAL/Arr_enums.h>
|
||||||
|
|
@ -59,37 +59,37 @@ namespace CGAL {
|
||||||
template <typename RatKernel, typename AlgKernel, typename NtTraits>
|
template <typename RatKernel, typename AlgKernel, typename NtTraits>
|
||||||
class Arr_conic_traits_2 {
|
class Arr_conic_traits_2 {
|
||||||
public:
|
public:
|
||||||
typedef RatKernel Rat_kernel;
|
using Rat_kernel = RatKernel;
|
||||||
typedef AlgKernel Alg_kernel;
|
using Alg_kernel = AlgKernel;
|
||||||
typedef NtTraits Nt_traits;
|
using Nt_traits = NtTraits;
|
||||||
|
|
||||||
typedef typename Rat_kernel::FT Rational;
|
using Rational = typename Rat_kernel::FT;
|
||||||
typedef typename Rat_kernel::Point_2 Rat_point_2;
|
using Rat_point_2 = typename Rat_kernel::Point_2;
|
||||||
typedef typename Rat_kernel::Segment_2 Rat_segment_2;
|
using Rat_segment_2 = typename Rat_kernel::Segment_2;
|
||||||
typedef typename Rat_kernel::Line_2 Rat_line_2;
|
using Rat_line_2 = typename Rat_kernel::Line_2;
|
||||||
typedef typename Rat_kernel::Circle_2 Rat_circle_2;
|
using Rat_circle_2 = typename Rat_kernel::Circle_2;
|
||||||
|
|
||||||
typedef typename Alg_kernel::FT Algebraic;
|
using Algebraic = typename Alg_kernel::FT;
|
||||||
typedef typename Alg_kernel::Point_2 Alg_point_2;
|
using Alg_point_2 = typename Alg_kernel::Point_2;
|
||||||
|
|
||||||
typedef typename Nt_traits::Integer Integer;
|
using Integer = typename Nt_traits::Integer;
|
||||||
|
|
||||||
// Category tags:
|
// Category tags:
|
||||||
typedef Tag_true Has_left_category;
|
using Has_left_category = Tag_true;
|
||||||
typedef Tag_true Has_merge_category;
|
using Has_merge_category = Tag_true;
|
||||||
typedef Tag_false Has_do_intersect_category;
|
using Has_do_intersect_category = Tag_false;
|
||||||
//typedef std::true_type Has_line_segment_constructor;
|
//typedef std::true_type Has_line_segment_constructor;
|
||||||
|
|
||||||
typedef Arr_oblivious_side_tag Left_side_category;
|
using Left_side_category = Arr_oblivious_side_tag;
|
||||||
typedef Arr_oblivious_side_tag Bottom_side_category;
|
using Bottom_side_category = Arr_oblivious_side_tag;
|
||||||
typedef Arr_oblivious_side_tag Top_side_category;
|
using Top_side_category = Arr_oblivious_side_tag;
|
||||||
typedef Arr_oblivious_side_tag Right_side_category;
|
using Right_side_category = Arr_oblivious_side_tag;
|
||||||
|
|
||||||
// Traits objects:
|
// Traits objects:
|
||||||
typedef Conic_arc_2<Rat_kernel, Alg_kernel, Nt_traits> Curve_2;
|
using Curve_2 = Conic_arc_2<Rat_kernel, Alg_kernel, Nt_traits>;
|
||||||
typedef Conic_x_monotone_arc_2<Curve_2> X_monotone_curve_2;
|
using X_monotone_curve_2 = Conic_x_monotone_arc_2<Curve_2>;
|
||||||
typedef Conic_point_2<Alg_kernel> Point_2;
|
using Point_2 = Conic_point_2<Alg_kernel>;
|
||||||
typedef size_t Multiplicity;
|
using Multiplicity = std::size_t;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Type definition for the intersection points mapping.
|
// Type definition for the intersection points mapping.
|
||||||
|
|
@ -106,16 +106,14 @@ private:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::pair<Point_2, Multiplicity> Intersection_point;
|
using Intersection_point = std::pair<Point_2, Multiplicity>;
|
||||||
typedef std::list<Intersection_point> Intersection_list;
|
using Intersection_list = std::list<Intersection_point>;
|
||||||
typedef std::map<Conic_pair, Intersection_list, Less_conic_pair>
|
using Intersection_map = std::map<Conic_pair, Intersection_list, Less_conic_pair>;
|
||||||
Intersection_map;
|
using Intersection_map_iterator = typename Intersection_map::iterator;
|
||||||
typedef typename Intersection_map::iterator Intersection_map_iterator;
|
|
||||||
|
|
||||||
|
using Shared_rat_kernel = std::shared_ptr<Rat_kernel>;
|
||||||
typedef std::shared_ptr<Rat_kernel> Shared_rat_kernel;
|
using Shared_alg_kernel = std::shared_ptr<Alg_kernel>;
|
||||||
typedef std::shared_ptr<Alg_kernel> Shared_alg_kernel;
|
using Shared_nt_traits = std::shared_ptr<Nt_traits>;
|
||||||
typedef std::shared_ptr<Nt_traits> Shared_nt_traits;
|
|
||||||
|
|
||||||
const Shared_rat_kernel m_rat_kernel;
|
const Shared_rat_kernel m_rat_kernel;
|
||||||
const Shared_alg_kernel m_alg_kernel;
|
const Shared_alg_kernel m_alg_kernel;
|
||||||
|
|
@ -127,10 +125,10 @@ private:
|
||||||
public:
|
public:
|
||||||
/*! constructs default.
|
/*! constructs default.
|
||||||
*/
|
*/
|
||||||
Arr_conic_traits_2()
|
Arr_conic_traits_2() :
|
||||||
: m_rat_kernel(std::make_shared<Rat_kernel>()),
|
m_rat_kernel(std::make_shared<Rat_kernel>()),
|
||||||
m_alg_kernel(std::make_shared<Alg_kernel>()),
|
m_alg_kernel(std::make_shared<Alg_kernel>()),
|
||||||
m_nt_traits(std::make_shared<Nt_traits>())
|
m_nt_traits(std::make_shared<Nt_traits>())
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/*! constructs from resources.
|
/*! constructs from resources.
|
||||||
|
|
@ -360,8 +358,7 @@ public:
|
||||||
*/
|
*/
|
||||||
Comparison_result operator()(const X_monotone_curve_2& xcv1,
|
Comparison_result operator()(const X_monotone_curve_2& xcv1,
|
||||||
const X_monotone_curve_2& xcv2,
|
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
|
// 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).
|
// left (so their left endpoint is lexicographically smaller than p).
|
||||||
CGAL_precondition(m_traits.contains_point(xcv1, p) &&
|
CGAL_precondition(m_traits.contains_point(xcv1, p) &&
|
||||||
|
|
@ -538,8 +535,7 @@ public:
|
||||||
*/
|
*/
|
||||||
Comparison_result operator()(const X_monotone_curve_2& xcv1,
|
Comparison_result operator()(const X_monotone_curve_2& xcv1,
|
||||||
const X_monotone_curve_2& xcv2,
|
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
|
// 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).
|
// left (so their left endpoint is lexicographically smaller than p).
|
||||||
CGAL_precondition(m_traits.contains_point(xcv1, 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.
|
* \return `true` if the two curves are the same; `false` otherwise.
|
||||||
*/
|
*/
|
||||||
bool operator()(const X_monotone_curve_2& xcv1,
|
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;
|
if (&xcv1 == &xcv2) return true;
|
||||||
return equals(xcv1, xcv2);
|
return equals(xcv1, xcv2);
|
||||||
}
|
}
|
||||||
|
|
@ -924,8 +919,7 @@ public:
|
||||||
|
|
||||||
if (((cv.orientation() == COUNTERCLOCKWISE) &&
|
if (((cv.orientation() == COUNTERCLOCKWISE) &&
|
||||||
(start_pos == order_vpts)) ||
|
(start_pos == order_vpts)) ||
|
||||||
((cv.orientation() == CLOCKWISE) && (start_pos != order_vpts)))
|
((cv.orientation() == CLOCKWISE) && (start_pos != order_vpts))) {
|
||||||
{
|
|
||||||
ind_first = 1;
|
ind_first = 1;
|
||||||
ind_second = 0;
|
ind_second = 0;
|
||||||
}
|
}
|
||||||
|
|
@ -1101,8 +1095,7 @@ public:
|
||||||
else if (m_traits.is_between_endpoints(xcv2, xcv1.source()) &&
|
else if (m_traits.is_between_endpoints(xcv2, xcv1.source()) &&
|
||||||
m_traits.is_between_endpoints(xcv2, xcv1.target()) &&
|
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.source()) ||
|
||||||
m_traits.is_strictly_between_endpoints(xcv2, xcv1.target())))
|
m_traits.is_strictly_between_endpoints(xcv2, xcv1.target()))) {
|
||||||
{
|
|
||||||
// Case 4 - *this: +----------->
|
// Case 4 - *this: +----------->
|
||||||
// arc: +================>
|
// arc: +================>
|
||||||
overlap = xcv1;
|
overlap = xcv1;
|
||||||
|
|
@ -1285,8 +1278,7 @@ public:
|
||||||
for (i = 0; i < n_xs; ++i) {
|
for (i = 0; i < n_xs; ++i) {
|
||||||
for (j = 0; j < n_ys; ++j) {
|
for (j = 0; j < n_ys; ++j) {
|
||||||
if (xcv1.is_on_supporting_conic(xs[i], 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.
|
// Create the intersection point and set its generating conics.
|
||||||
Point_2 ip(xs[i], ys[j]);
|
Point_2 ip(xs[i], ys[j]);
|
||||||
|
|
||||||
|
|
@ -1314,8 +1306,7 @@ public:
|
||||||
OutputIterator intersect(const X_monotone_curve_2& xcv1,
|
OutputIterator intersect(const X_monotone_curve_2& xcv1,
|
||||||
const X_monotone_curve_2& xcv2,
|
const X_monotone_curve_2& xcv2,
|
||||||
Intersection_map& inter_map,
|
Intersection_map& inter_map,
|
||||||
OutputIterator oi) const
|
OutputIterator oi) const {
|
||||||
{
|
|
||||||
if (m_traits.has_same_supporting_conic(xcv1, xcv2)) {
|
if (m_traits.has_same_supporting_conic(xcv1, xcv2)) {
|
||||||
// Check for overlaps between the two arcs.
|
// Check for overlaps between the two arcs.
|
||||||
X_monotone_curve_2 overlap;
|
X_monotone_curve_2 overlap;
|
||||||
|
|
@ -1392,8 +1383,7 @@ public:
|
||||||
// both \f$x\f$-monotone arcs.
|
// both \f$x\f$-monotone arcs.
|
||||||
for (auto iter = inter_list.begin(); iter != inter_list.end(); ++iter) {
|
for (auto iter = inter_list.begin(); iter != inter_list.end(); ++iter) {
|
||||||
if (m_traits.is_between_endpoints(xcv1, (*iter).first) &&
|
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;
|
*oi++ = *iter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1481,8 +1471,7 @@ public:
|
||||||
*/
|
*/
|
||||||
void operator()(const X_monotone_curve_2& xcv1,
|
void operator()(const X_monotone_curve_2& xcv1,
|
||||||
const X_monotone_curve_2& xcv2,
|
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));
|
CGAL_precondition(m_traits.are_mergeable_2_object()(xcv2, xcv1));
|
||||||
xcv = xcv1;
|
xcv = xcv1;
|
||||||
merge(xcv, xcv2);
|
merge(xcv, xcv2);
|
||||||
|
|
@ -1523,11 +1512,11 @@ public:
|
||||||
* point-location strategy and the drawing function.
|
* point-location strategy and the drawing function.
|
||||||
*/
|
*/
|
||||||
//@{
|
//@{
|
||||||
typedef double Approximate_number_type;
|
using Approximate_number_type = double;
|
||||||
typedef CGAL::Cartesian<Approximate_number_type> Approximate_kernel;
|
using Approximate_kernel = CGAL::Simple_cartesian<Approximate_number_type>;
|
||||||
typedef Approximate_kernel::Point_2 Approximate_point_2;
|
using Approximate_point_2 = Approximate_kernel::Point_2;
|
||||||
|
|
||||||
class Approximate_curve_length_2 {
|
class Approximate_length_2 {
|
||||||
protected:
|
protected:
|
||||||
using Traits = Arr_conic_traits_2<Rat_kernel, Alg_kernel, Nt_traits>;
|
using Traits = Arr_conic_traits_2<Rat_kernel, Alg_kernel, Nt_traits>;
|
||||||
|
|
||||||
|
|
@ -1537,7 +1526,7 @@ public:
|
||||||
/*! constructs
|
/*! constructs
|
||||||
* \param traits the traits.
|
* \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>;
|
friend class Arr_conic_traits_2<Rat_kernel, Alg_kernel, Nt_traits>;
|
||||||
|
|
||||||
|
|
@ -1557,7 +1546,7 @@ public:
|
||||||
private:
|
private:
|
||||||
/*! obtains the segment length.
|
/*! 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 min_vertex = m_traits.construct_min_vertex_2_object();
|
||||||
auto max_vertex = m_traits.construct_max_vertex_2_object();
|
auto max_vertex = m_traits.construct_max_vertex_2_object();
|
||||||
const auto& minv = min_vertex(xcv);
|
const auto& minv = min_vertex(xcv);
|
||||||
|
|
@ -1597,7 +1586,7 @@ public:
|
||||||
|
|
||||||
/*! obtains the parabolic arc length.
|
/*! 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 r_m, t_m, s_m, u_m, v_m, w_m;
|
||||||
double cost, sint;
|
double cost, sint;
|
||||||
double xs_t, ys_t, xt_t, yt_t;
|
double xs_t, ys_t, xt_t, yt_t;
|
||||||
|
|
@ -1617,7 +1606,7 @@ public:
|
||||||
return d;
|
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 r_m, t_m, s_m, u_m, v_m, w_m;
|
||||||
double cost, sint;
|
double cost, sint;
|
||||||
double xs_t, ys_t, xt_t, yt_t;
|
double xs_t, ys_t, xt_t, yt_t;
|
||||||
|
|
@ -1638,7 +1627,7 @@ public:
|
||||||
return d;
|
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!");
|
CGAL_error_msg("Not implemented yet!");
|
||||||
double l(0.0);
|
double l(0.0);
|
||||||
return l;
|
return l;
|
||||||
|
|
@ -1901,8 +1890,7 @@ public:
|
||||||
template <typename OutputIterator>
|
template <typename OutputIterator>
|
||||||
OutputIterator approximate_parabola(const X_monotone_curve_2& xcv,
|
OutputIterator approximate_parabola(const X_monotone_curve_2& xcv,
|
||||||
double error, OutputIterator oi,
|
double error, OutputIterator oi,
|
||||||
bool l2r = true)
|
bool l2r = true) const {
|
||||||
const {
|
|
||||||
// std::cout << "PARABOLA\n";
|
// std::cout << "PARABOLA\n";
|
||||||
auto min_vertex = m_traits.construct_min_vertex_2_object();
|
auto min_vertex = m_traits.construct_min_vertex_2_object();
|
||||||
auto max_vertex = m_traits.construct_max_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,
|
X_monotone_curve_2 operator()(const Curve_2& cv,
|
||||||
const Point_2& source, const Point_2& target,
|
const Point_2& source, const Point_2& target,
|
||||||
const Conic_id& id) const
|
const Conic_id& id) const {
|
||||||
{
|
|
||||||
// Set the two endpoints.
|
// Set the two endpoints.
|
||||||
X_monotone_curve_2 xcv(cv, id);
|
X_monotone_curve_2 xcv(cv, id);
|
||||||
xcv.set_source(source);
|
xcv.set_source(source);
|
||||||
|
|
@ -2122,8 +2109,7 @@ public:
|
||||||
* \return A segment connecting `source` and `target`.
|
* \return A segment connecting `source` and `target`.
|
||||||
*/
|
*/
|
||||||
X_monotone_curve_2 operator()(const Point_2& source, const Point_2& target)
|
X_monotone_curve_2 operator()(const Point_2& source, const Point_2& target)
|
||||||
const
|
const {
|
||||||
{
|
|
||||||
X_monotone_curve_2 xcv;
|
X_monotone_curve_2 xcv;
|
||||||
|
|
||||||
// Set the basic properties.
|
// Set the basic properties.
|
||||||
|
|
@ -2157,8 +2143,7 @@ public:
|
||||||
X_monotone_curve_2 operator()(const Algebraic& a, const Algebraic& b,
|
X_monotone_curve_2 operator()(const Algebraic& a, const Algebraic& b,
|
||||||
const Algebraic& c,
|
const Algebraic& c,
|
||||||
const Point_2& source, const Point_2& target)
|
const Point_2& source, const Point_2& target)
|
||||||
const
|
const {
|
||||||
{
|
|
||||||
auto cmp_xy = m_traits.m_alg_kernel->compare_xy_2_object();
|
auto cmp_xy = m_traits.m_alg_kernel->compare_xy_2_object();
|
||||||
Comparison_result res = cmp_xy(source, target);
|
Comparison_result res = cmp_xy(source, target);
|
||||||
CGAL_precondition(res != EQUAL);
|
CGAL_precondition(res != EQUAL);
|
||||||
|
|
@ -2238,8 +2223,7 @@ public:
|
||||||
*/
|
*/
|
||||||
Curve_2 operator()(const Rational& r, const Rational& s, const Rational& t,
|
Curve_2 operator()(const Rational& r, const Rational& s, const Rational& t,
|
||||||
const Rational& u, const Rational& v, const Rational& w)
|
const Rational& u, const Rational& v, const Rational& w)
|
||||||
const
|
const {
|
||||||
{
|
|
||||||
// Ensure that the given curve is an ellipse (4rs - t^2 is positive).
|
// Ensure that the given curve is an ellipse (4rs - t^2 is positive).
|
||||||
CGAL_precondition(CGAL::sign(4*r*s - t*t) == 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) ||
|
if (! m_traits.is_strictly_between_endpoints(arc, mp2) ||
|
||||||
! m_traits.is_strictly_between_endpoints(arc, mp3) ||
|
! 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
|
arc.reset_flags(); // invalid arc
|
||||||
return arc;
|
return arc;
|
||||||
}
|
}
|
||||||
|
|
@ -2853,8 +2836,7 @@ public:
|
||||||
* \pre both points must be interior and must lie on \c cv
|
* \pre both points must be interior and must lie on \c cv
|
||||||
*/
|
*/
|
||||||
X_monotone_curve_2 operator()(const X_monotone_curve_2& xcv,
|
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
|
// make functor objects
|
||||||
CGAL_precondition_code(Compare_y_at_x_2 compare_y_at_x_2 =
|
CGAL_precondition_code(Compare_y_at_x_2 compare_y_at_x_2 =
|
||||||
m_traits.compare_y_at_x_2_object());
|
m_traits.compare_y_at_x_2_object());
|
||||||
|
|
@ -3084,16 +3066,14 @@ public:
|
||||||
const auto& target = cv.target();
|
const auto& target = cv.target();
|
||||||
// Make sure both endpoint lie on the supporting conic.
|
// Make sure both endpoint lie on the supporting conic.
|
||||||
if (! is_on_supporting_conic(cv, source) ||
|
if (! is_on_supporting_conic(cv, source) ||
|
||||||
! is_on_supporting_conic(cv, target))
|
! is_on_supporting_conic(cv, target)) {
|
||||||
{
|
|
||||||
cv.reset_flags(); // invalid arc
|
cv.reset_flags(); // invalid arc
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check whether we have a degree 2 curve.
|
// Check whether we have a degree 2 curve.
|
||||||
if ((CGAL::sign(r) != ZERO) || (CGAL::sign(s) != ZERO) ||
|
if ((CGAL::sign(r) != ZERO) || (CGAL::sign(s) != ZERO) ||
|
||||||
(CGAL::sign(t) != ZERO))
|
(CGAL::sign(t) != ZERO)) {
|
||||||
{
|
|
||||||
if (cv.orientation() == COLLINEAR) {
|
if (cv.orientation() == COLLINEAR) {
|
||||||
// Make sure the midpoint is on the line pair (thus making sure that
|
// Make sure the midpoint is on the line pair (thus making sure that
|
||||||
// the two points are not taken from different lines).
|
// 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(u)) * p_mid.x() +
|
||||||
(m_nt_traits->convert(s)*p_mid.y() +
|
(m_nt_traits->convert(s)*p_mid.y() +
|
||||||
m_nt_traits->convert(v)) * 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
|
cv.reset_flags(); // invalid arc
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -3645,8 +3624,7 @@ public:
|
||||||
// Compute the degree of the underlying conic.
|
// Compute the degree of the underlying conic.
|
||||||
if ((CGAL::sign(xcv.r()) != ZERO) ||
|
if ((CGAL::sign(xcv.r()) != ZERO) ||
|
||||||
(CGAL::sign(xcv.s()) != 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::DEGREE_2);
|
||||||
xcv.set_flag(X_monotone_curve_2::IS_SPECIAL_SEGMENT);
|
xcv.set_flag(X_monotone_curve_2::IS_SPECIAL_SEGMENT);
|
||||||
}
|
}
|
||||||
|
|
@ -3856,8 +3834,7 @@ public:
|
||||||
for (int j = 0; j < n_ys; ++j) {
|
for (int j = 0; j < n_ys; ++j) {
|
||||||
if (CGAL::compare(m_nt_traits->convert(Integer(two*s)) * 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(t) * xs[i] +
|
||||||
m_nt_traits->convert(v))) == EQUAL)
|
m_nt_traits->convert(v))) == EQUAL) {
|
||||||
{
|
|
||||||
ps[n++] = Point_2(xs[i], ys[j]);
|
ps[n++] = Point_2(xs[i], ys[j]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -4128,8 +4105,7 @@ public:
|
||||||
double& xs_t, double& ys_t, double& ts,
|
double& xs_t, double& ys_t, double& ts,
|
||||||
double& xt_t, double& yt_t, double& tt,
|
double& xt_t, double& yt_t, double& tt,
|
||||||
double& a, double& b, double& cx, double& cy,
|
double& a, double& b, double& cx, double& cy,
|
||||||
bool l2r = true)
|
bool l2r = true) const {
|
||||||
const {
|
|
||||||
auto min_vertex = construct_min_vertex_2_object();
|
auto min_vertex = construct_min_vertex_2_object();
|
||||||
auto max_vertex = construct_max_vertex_2_object();
|
auto max_vertex = construct_max_vertex_2_object();
|
||||||
const auto& src = (l2r) ? min_vertex(xcv) : max_vertex(xcv);
|
const auto& src = (l2r) ? min_vertex(xcv) : max_vertex(xcv);
|
||||||
|
|
@ -4206,8 +4182,7 @@ public:
|
||||||
double& xs_t, double& ys_t, double& ts,
|
double& xs_t, double& ys_t, double& ts,
|
||||||
double& xt_t, double& yt_t, double& tt,
|
double& xt_t, double& yt_t, double& tt,
|
||||||
double& a, double& b, double& cx, double& cy,
|
double& a, double& b, double& cx, double& cy,
|
||||||
bool l2r = true)
|
bool l2r = true) const {
|
||||||
const {
|
|
||||||
auto min_vertex = construct_min_vertex_2_object();
|
auto min_vertex = construct_min_vertex_2_object();
|
||||||
auto max_vertex = construct_max_vertex_2_object();
|
auto max_vertex = construct_max_vertex_2_object();
|
||||||
const auto& src = (l2r) ? min_vertex(xcv) : max_vertex(xcv);
|
const auto& src = (l2r) ? min_vertex(xcv) : max_vertex(xcv);
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@
|
||||||
#include <variant>
|
#include <variant>
|
||||||
|
|
||||||
#include <CGAL/config.h>
|
#include <CGAL/config.h>
|
||||||
#include <CGAL/Cartesian.h>
|
#include <CGAL/Simple_cartesian.h>
|
||||||
#include <CGAL/tags.h>
|
#include <CGAL/tags.h>
|
||||||
#include <CGAL/tss.h>
|
#include <CGAL/tss.h>
|
||||||
#include <CGAL/intersections.h>
|
#include <CGAL/intersections.h>
|
||||||
|
|
@ -2856,7 +2856,7 @@ public:
|
||||||
/// \name Functor definitions for the landmarks point-location strategy.
|
/// \name Functor definitions for the landmarks point-location strategy.
|
||||||
//@{
|
//@{
|
||||||
using Approximate_number_type = double;
|
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_point_2 = Arr_extended_direction_3<Approximate_kernel>;
|
||||||
using Approximate_kernel_vector_3 = Approximate_kernel::Vector_3;
|
using Approximate_kernel_vector_3 = Approximate_kernel::Vector_3;
|
||||||
using Approximate_kernel_direction_3 = Approximate_kernel::Direction_3;
|
using Approximate_kernel_direction_3 = Approximate_kernel::Direction_3;
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@
|
||||||
* Definition of the Bezier_bounding_rational_traits<Kernel> class.
|
* Definition of the Bezier_bounding_rational_traits<Kernel> class.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <CGAL/Cartesian.h>
|
|
||||||
#include <CGAL/Polygon_2_algorithms.h>
|
#include <CGAL/Polygon_2_algorithms.h>
|
||||||
#include <CGAL/Arr_geometry_traits/de_Casteljau_2.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_>;
|
friend class _One_root_point_2<NumberType_, Filter_>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef NumberType_ NT;
|
using NT = NumberType_;
|
||||||
typedef _One_root_point_2_rep<NT, Filter_> Self;
|
using Self = _One_root_point_2_rep<NT, Filter_>;
|
||||||
typedef Sqrt_extension<NT, NT, Tag_true,Boolean_tag<Filter_> > CoordNT;
|
using CoordNT = Sqrt_extension<NT, NT, Tag_true,Boolean_tag<Filter_> >;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CoordNT _x; // The coordinates.
|
CoordNT _x; // The coordinates.
|
||||||
|
|
@ -70,18 +70,17 @@ public:
|
||||||
*/
|
*/
|
||||||
template <typename NumberType_, bool Filter_>
|
template <typename NumberType_, bool Filter_>
|
||||||
class _One_root_point_2 :
|
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:
|
public:
|
||||||
typedef NumberType_ NT;
|
using NT = NumberType_;
|
||||||
typedef _One_root_point_2<NT, Filter_> Self;
|
using Self = _One_root_point_2<NT, Filter_>;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef _One_root_point_2_rep<NT, Filter_> Point_rep;
|
using Point_rep = _One_root_point_2_rep<NT, Filter_>;
|
||||||
typedef Handle_for<Point_rep> Point_handle;
|
using Point_handle = Handle_for<Point_rep>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef typename Point_rep::CoordNT CoordNT;
|
using CoordNT = typename Point_rep::CoordNT;
|
||||||
|
|
||||||
/*! constructs default. */
|
/*! constructs default. */
|
||||||
_One_root_point_2() : Point_handle(Point_rep()) {}
|
_One_root_point_2() : Point_handle(Point_rep()) {}
|
||||||
|
|
@ -106,8 +105,7 @@ public:
|
||||||
const CoordNT& y() const { return (this->ptr()->_y); }
|
const CoordNT& y() const { return (this->ptr()->_y); }
|
||||||
|
|
||||||
/*! checks for equality. */
|
/*! checks for equality. */
|
||||||
bool equals(const Self& p) const
|
bool equals(const Self& p) const {
|
||||||
{
|
|
||||||
if (this->identical(p)) return (true);
|
if (this->identical(p)) return (true);
|
||||||
|
|
||||||
return (CGAL::compare(this->ptr()->_x, p.ptr()->_x) == EQUAL &&
|
return (CGAL::compare(this->ptr()->_x, p.ptr()->_x) == EQUAL &&
|
||||||
|
|
@ -119,8 +117,7 @@ public:
|
||||||
bool operator == (const Self& p) const { return equals(p); }
|
bool operator == (const Self& p) const { return equals(p); }
|
||||||
|
|
||||||
/*! sets the point coordinates. */
|
/*! 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->copy_on_write();
|
||||||
this->ptr()->_x = CoordNT(x);
|
this->ptr()->_x = CoordNT(x);
|
||||||
this->ptr()->_y = CoordNT(y);
|
this->ptr()->_y = CoordNT(y);
|
||||||
|
|
@ -128,8 +125,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! sets the point coordinates. */
|
/*! 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->copy_on_write();
|
||||||
this->ptr()->_x = x;
|
this->ptr()->_x = x;
|
||||||
this->ptr()->_y = y;
|
this->ptr()->_y = y;
|
||||||
|
|
@ -141,8 +137,7 @@ public:
|
||||||
*/
|
*/
|
||||||
template <typename NT, bool Filter>
|
template <typename NT, bool Filter>
|
||||||
std::ostream& operator<<(std::ostream& os,
|
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());
|
os << CGAL::to_double(p.x()) << ' ' << CGAL::to_double(p.y());
|
||||||
return (os);
|
return (os);
|
||||||
}
|
}
|
||||||
|
|
@ -165,15 +160,15 @@ std::istream & operator >> (std::istream & is,
|
||||||
template <typename Kernel_, bool Filter_>
|
template <typename Kernel_, bool Filter_>
|
||||||
class _Circle_segment_2 {
|
class _Circle_segment_2 {
|
||||||
public:
|
public:
|
||||||
typedef Kernel_ Kernel;
|
using Kernel = Kernel_;
|
||||||
typedef typename Kernel::FT NT;
|
using NT = typename Kernel::FT;
|
||||||
typedef _One_root_point_2<NT, Filter_> Point_2;
|
using Point_2 = _One_root_point_2<NT, Filter_>;
|
||||||
typedef typename Kernel::Circle_2 Circle_2;
|
using Circle_2 = typename Kernel::Circle_2;
|
||||||
typedef typename Kernel::Segment_2 Segment_2;
|
using Segment_2 = typename Kernel::Segment_2;
|
||||||
typedef typename Kernel::Line_2 Line_2;
|
using Line_2 = typename Kernel::Line_2;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
typedef typename Point_2::CoordNT CoordNT;
|
using CoordNT = typename Point_2::CoordNT;
|
||||||
|
|
||||||
// Data members:
|
// Data members:
|
||||||
Line_2 m_line; // The supporting line (for line segments).
|
Line_2 m_line; // The supporting line (for line segments).
|
||||||
|
|
@ -234,8 +229,7 @@ public:
|
||||||
m_has_radius(false),
|
m_has_radius(false),
|
||||||
m_source(source),
|
m_source(source),
|
||||||
m_target(target),
|
m_target(target),
|
||||||
m_orient(COLLINEAR)
|
m_orient(COLLINEAR) {
|
||||||
{
|
|
||||||
CGAL_precondition(CGAL::compare(source.x() * line.a() + line.c(),
|
CGAL_precondition(CGAL::compare(source.x() * line.a() + line.c(),
|
||||||
-source.y() * line.b()) == EQUAL);
|
-source.y() * line.b()) == EQUAL);
|
||||||
|
|
||||||
|
|
@ -282,8 +276,7 @@ public:
|
||||||
m_has_radius(false),
|
m_has_radius(false),
|
||||||
m_source(source),
|
m_source(source),
|
||||||
m_target(target),
|
m_target(target),
|
||||||
m_orient(circ.orientation())
|
m_orient(circ.orientation()) {
|
||||||
{
|
|
||||||
CGAL_assertion(m_orient != COLLINEAR);
|
CGAL_assertion(m_orient != COLLINEAR);
|
||||||
|
|
||||||
CGAL_precondition
|
CGAL_precondition
|
||||||
|
|
@ -315,8 +308,7 @@ public:
|
||||||
m_radius(r),
|
m_radius(r),
|
||||||
m_source(source),
|
m_source(source),
|
||||||
m_target(target),
|
m_target(target),
|
||||||
m_orient(orient)
|
m_orient(orient) {
|
||||||
{
|
|
||||||
CGAL_assertion(orient != COLLINEAR);
|
CGAL_assertion(orient != COLLINEAR);
|
||||||
|
|
||||||
CGAL_precondition
|
CGAL_precondition
|
||||||
|
|
@ -343,8 +335,7 @@ public:
|
||||||
m_is_full(false),
|
m_is_full(false),
|
||||||
m_has_radius(false),
|
m_has_radius(false),
|
||||||
m_source(p1.x(), p1.y()),
|
m_source(p1.x(), p1.y()),
|
||||||
m_target(p3.x(), p3.y())
|
m_target(p3.x(), p3.y()) {
|
||||||
{
|
|
||||||
// Set the source and target.
|
// Set the source and target.
|
||||||
NT x1 = p1.x();
|
NT x1 = p1.x();
|
||||||
NT y1 = p1.y();
|
NT y1 = p1.y();
|
||||||
|
|
@ -359,7 +350,7 @@ public:
|
||||||
// Compute the lines: A1*x + B1*y + C1 = 0,
|
// Compute the lines: A1*x + B1*y + C1 = 0,
|
||||||
// and: A2*x + B2*y + C2 = 0,
|
// and: A2*x + B2*y + C2 = 0,
|
||||||
// where:
|
// where:
|
||||||
const NT _two = 2;
|
const NT _two = 2;
|
||||||
|
|
||||||
const NT A1 = _two*(x1 - x2);
|
const NT A1 = _two*(x1 - x2);
|
||||||
const NT B1 = _two*(y1 - y2);
|
const NT B1 = _two*(y1 - y2);
|
||||||
|
|
@ -423,8 +414,7 @@ public:
|
||||||
/*! obtains the supporting line.
|
/*! obtains the supporting line.
|
||||||
* \pre The curve orientation is COLLINEAR.
|
* \pre The curve orientation is COLLINEAR.
|
||||||
*/
|
*/
|
||||||
const Line_2& supporting_line() const
|
const Line_2& supporting_line() const {
|
||||||
{
|
|
||||||
CGAL_precondition(m_orient == COLLINEAR);
|
CGAL_precondition(m_orient == COLLINEAR);
|
||||||
return m_line;
|
return m_line;
|
||||||
}
|
}
|
||||||
|
|
@ -432,8 +422,7 @@ public:
|
||||||
/*! obtains the supporting circle.
|
/*! obtains the supporting circle.
|
||||||
* \pre The curve orientation is not COLLINEAR.
|
* \pre The curve orientation is not COLLINEAR.
|
||||||
*/
|
*/
|
||||||
const Circle_2& supporting_circle() const
|
const Circle_2& supporting_circle() const {
|
||||||
{
|
|
||||||
CGAL_precondition(m_orient != COLLINEAR);
|
CGAL_precondition(m_orient != COLLINEAR);
|
||||||
return m_circ;
|
return m_circ;
|
||||||
}
|
}
|
||||||
|
|
@ -444,8 +433,7 @@ public:
|
||||||
/*! obtains the source point.
|
/*! obtains the source point.
|
||||||
* \pre The curve is not a full circle.
|
* \pre The curve is not a full circle.
|
||||||
*/
|
*/
|
||||||
const Point_2& source() const
|
const Point_2& source() const {
|
||||||
{
|
|
||||||
CGAL_precondition(! m_is_full);
|
CGAL_precondition(! m_is_full);
|
||||||
return (m_source);
|
return (m_source);
|
||||||
}
|
}
|
||||||
|
|
@ -453,8 +441,7 @@ public:
|
||||||
/*! obtains the target point.
|
/*! obtains the target point.
|
||||||
* \pre The curve is not a full circle.
|
* \pre The curve is not a full circle.
|
||||||
*/
|
*/
|
||||||
const Point_2& target() const
|
const Point_2& target() const {
|
||||||
{
|
|
||||||
CGAL_precondition(! m_is_full);
|
CGAL_precondition(! m_is_full);
|
||||||
return (m_target);
|
return (m_target);
|
||||||
}
|
}
|
||||||
|
|
@ -464,8 +451,7 @@ public:
|
||||||
* \pre The curve is circular.
|
* \pre The curve is circular.
|
||||||
* \return The number of points (0, 1, or 2).
|
* \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);
|
CGAL_precondition(m_orient != COLLINEAR);
|
||||||
unsigned int n_vpts = 0;
|
unsigned int n_vpts = 0;
|
||||||
|
|
||||||
|
|
@ -519,8 +505,7 @@ private:
|
||||||
*/
|
*/
|
||||||
unsigned int _ccw_vertical_tangency_points(const Point_2& src,
|
unsigned int _ccw_vertical_tangency_points(const Point_2& src,
|
||||||
const Point_2& trg,
|
const Point_2& trg,
|
||||||
Point_2* vpts) const
|
Point_2* vpts) const {
|
||||||
{
|
|
||||||
unsigned int n_vpts = 0;
|
unsigned int n_vpts = 0;
|
||||||
const NT& x0 = m_circ.center().x();
|
const NT& x0 = m_circ.center().x();
|
||||||
const NT& y0 = m_circ.center().y();
|
const NT& y0 = m_circ.center().y();
|
||||||
|
|
@ -547,8 +532,7 @@ private:
|
||||||
if ((qs % 4) == 1) {
|
if ((qs % 4) == 1) {
|
||||||
// We collect the left tangency point when going from Q[1] to Q[2]:
|
// We collect the left tangency point when going from Q[1] to Q[2]:
|
||||||
if (CGAL::compare(x0, trg.x()) != LARGER ||
|
if (CGAL::compare(x0, trg.x()) != LARGER ||
|
||||||
CGAL::compare(y0, trg.y()) != EQUAL)
|
CGAL::compare(y0, trg.y()) != EQUAL) {
|
||||||
{
|
|
||||||
if (m_has_radius)
|
if (m_has_radius)
|
||||||
vpts[n_vpts] = Point_2(CoordNT(x0 - m_radius), y0);
|
vpts[n_vpts] = Point_2(CoordNT(x0 - m_radius), y0);
|
||||||
else
|
else
|
||||||
|
|
@ -561,8 +545,7 @@ private:
|
||||||
else if ((qs % 4) == 3) {
|
else if ((qs % 4) == 3) {
|
||||||
// We collect the right tangency point when going from Q[3] to Q[0]:
|
// We collect the right tangency point when going from Q[3] to Q[0]:
|
||||||
if (CGAL::compare(x0, trg.x()) != SMALLER ||
|
if (CGAL::compare(x0, trg.x()) != SMALLER ||
|
||||||
CGAL::compare(y0, trg.y()) != EQUAL)
|
CGAL::compare(y0, trg.y()) != EQUAL) {
|
||||||
{
|
|
||||||
if (m_has_radius)
|
if (m_has_radius)
|
||||||
vpts[n_vpts] = Point_2(CoordNT(x0 + m_radius), y0);
|
vpts[n_vpts] = Point_2(CoordNT(x0 + m_radius), y0);
|
||||||
else
|
else
|
||||||
|
|
@ -581,8 +564,7 @@ private:
|
||||||
/*! obtains the index of the quarter-plane containing the given point,
|
/*! obtains the index of the quarter-plane containing the given point,
|
||||||
* where the circle center is considered to be the origin.
|
* 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:
|
// The plane looks like:
|
||||||
//
|
//
|
||||||
// Q[1] : | Q[0]:
|
// Q[1] : | Q[0]:
|
||||||
|
|
@ -608,8 +590,7 @@ private:
|
||||||
*/
|
*/
|
||||||
template <typename Kernel, bool Filter>
|
template <typename Kernel, bool Filter>
|
||||||
std::ostream&
|
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) {
|
if (c.orientation() == COLLINEAR) {
|
||||||
os<< "segment: " << c.source() << " -> " << c.target();
|
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_>
|
template <typename Kernel_, bool Filter_>
|
||||||
class _X_monotone_circle_segment_2 {
|
class _X_monotone_circle_segment_2 {
|
||||||
public:
|
public:
|
||||||
typedef Kernel_ Kernel;
|
using Kernel = Kernel_;
|
||||||
typedef _X_monotone_circle_segment_2<Kernel, Filter_> Self;
|
using Self = _X_monotone_circle_segment_2<Kernel, Filter_>;
|
||||||
typedef typename Kernel::FT NT;
|
using NT = typename Kernel::FT;
|
||||||
typedef _One_root_point_2<NT, Filter_> Point_2;
|
using Point_2 = _One_root_point_2<NT, Filter_>;
|
||||||
typedef typename Kernel::Circle_2 Circle_2;
|
using Circle_2 = typename Kernel::Circle_2;
|
||||||
typedef typename Kernel::Line_2 Line_2;
|
using Line_2 = typename Kernel::Line_2;
|
||||||
typedef typename Point_2::CoordNT CoordNT;
|
using CoordNT = typename Point_2::CoordNT;
|
||||||
|
|
||||||
// Type definition for the intersection points mapping.
|
// Type definition for the intersection points mapping.
|
||||||
typedef std::pair<unsigned int, unsigned int> Curve_id_pair;
|
using Curve_id_pair = std::pair<unsigned int, unsigned int>;
|
||||||
typedef unsigned int Multiplicity;
|
using Multiplicity = std::size_t;
|
||||||
typedef std::pair<Point_2, Multiplicity> Intersection_point;
|
using Intersection_point = std::pair<Point_2, Multiplicity>;
|
||||||
typedef std::list<Intersection_point> Intersection_list;
|
using Intersection_list = std::list<Intersection_point>;
|
||||||
|
|
||||||
/*! \struct Less functor for Curve_id_pair.
|
/*! \struct Less functor for Curve_id_pair.
|
||||||
*/
|
*/
|
||||||
struct Less_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.
|
// Compare the pairs of IDs lexicographically.
|
||||||
return (ip1.first < ip2.first ||
|
return (ip1.first < ip2.first ||
|
||||||
(ip1.first == ip2.first && ip1.second < ip2.second));
|
(ip1.first == ip2.first && ip1.second < ip2.second));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::map<Curve_id_pair, Intersection_list, Less_id_pair>
|
using Intersection_map = std::map<Curve_id_pair, Intersection_list, Less_id_pair>;
|
||||||
Intersection_map;
|
using Intersection_map_entry = typename Intersection_map::value_type;
|
||||||
typedef typename Intersection_map::value_type Intersection_map_entry;
|
using Intersection_map_iterator = typename Intersection_map::iterator;
|
||||||
typedef typename Intersection_map::iterator Intersection_map_iterator;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
NT m_first; // The x-coordinate of the circle center.
|
NT m_first; // The x-coordinate of the circle center.
|
||||||
|
|
@ -713,8 +692,7 @@ public:
|
||||||
m_third(line.c()),
|
m_third(line.c()),
|
||||||
m_source(source),
|
m_source(source),
|
||||||
m_target(target),
|
m_target(target),
|
||||||
m_info(index << INDEX_SHIFT_BITS)
|
m_info(index << INDEX_SHIFT_BITS) {
|
||||||
{
|
|
||||||
// Check if the segment is directed left or right:
|
// Check if the segment is directed left or right:
|
||||||
Comparison_result res = CGAL::compare(source.x(), target.x());
|
Comparison_result res = CGAL::compare(source.x(), target.x());
|
||||||
|
|
||||||
|
|
@ -740,8 +718,7 @@ public:
|
||||||
const typename Kernel::Point_2& target) :
|
const typename Kernel::Point_2& target) :
|
||||||
m_source(source.x(), source.y()),
|
m_source(source.x(), source.y()),
|
||||||
m_target(target.x(), target.y()),
|
m_target(target.x(), target.y()),
|
||||||
m_info(0)
|
m_info(0) {
|
||||||
{
|
|
||||||
Line_2 line(source, target);
|
Line_2 line(source, target);
|
||||||
m_first = line.a();
|
m_first = line.a();
|
||||||
m_second = line.b();
|
m_second = line.b();
|
||||||
|
|
@ -778,8 +755,7 @@ public:
|
||||||
m_third(circ.squared_radius()),
|
m_third(circ.squared_radius()),
|
||||||
m_source(source),
|
m_source(source),
|
||||||
m_target(target),
|
m_target(target),
|
||||||
m_info(index << INDEX_SHIFT_BITS)
|
m_info(index << INDEX_SHIFT_BITS) {
|
||||||
{
|
|
||||||
// Check if the segment is directed left or right:
|
// Check if the segment is directed left or right:
|
||||||
Comparison_result res = CGAL::compare (source.x(), target.x());
|
Comparison_result res = CGAL::compare (source.x(), target.x());
|
||||||
|
|
||||||
|
|
@ -802,8 +778,7 @@ public:
|
||||||
/*! obtains the supporting line.
|
/*! obtains the supporting line.
|
||||||
* \pre The arc is linear (a line segment).
|
* \pre The arc is linear (a line segment).
|
||||||
*/
|
*/
|
||||||
Line_2 supporting_line() const
|
Line_2 supporting_line() const {
|
||||||
{
|
|
||||||
CGAL_precondition (is_linear());
|
CGAL_precondition (is_linear());
|
||||||
return (Line_2 (a(), b(), c()));
|
return (Line_2 (a(), b(), c()));
|
||||||
}
|
}
|
||||||
|
|
@ -811,8 +786,7 @@ public:
|
||||||
/*! obtains the supporting circle.
|
/*! obtains the supporting circle.
|
||||||
* \pre The arc is circular.
|
* \pre The arc is circular.
|
||||||
*/
|
*/
|
||||||
Circle_2 supporting_circle() const
|
Circle_2 supporting_circle() const {
|
||||||
{
|
|
||||||
CGAL_precondition (is_circular());
|
CGAL_precondition (is_circular());
|
||||||
|
|
||||||
typename Kernel::Point_2 center(x0(), y0());
|
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.
|
/*! 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());
|
Comparison_result res = CGAL::compare (p.x(), left().x());
|
||||||
|
|
||||||
if (res == SMALLER) return false;
|
if (res == SMALLER) return false;
|
||||||
|
|
@ -858,8 +831,7 @@ public:
|
||||||
{ return ((m_info & IS_VERTICAL_SEGMENT_MASK) != 0); }
|
{ return ((m_info & IS_VERTICAL_SEGMENT_MASK) != 0); }
|
||||||
|
|
||||||
/*! obtains the orientation of the arc. */
|
/*! obtains the orientation of the arc. */
|
||||||
inline Orientation orientation() const
|
inline Orientation orientation() const {
|
||||||
{
|
|
||||||
unsigned int or_ = (m_info & ORIENTATION_MASK);
|
unsigned int or_ = (m_info & ORIENTATION_MASK);
|
||||||
if (or_ == COUNTERCLOCKWISE_CODE) return (CGAL::COUNTERCLOCKWISE);
|
if (or_ == COUNTERCLOCKWISE_CODE) return (CGAL::COUNTERCLOCKWISE);
|
||||||
else if (or_ == CLOCKWISE_CODE) return (CGAL::CLOCKWISE);
|
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.
|
/*! 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));
|
if (is_linear()) return (_line_point_position(p));
|
||||||
else return (_circ_point_position (p));
|
else return (_circ_point_position (p));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! compares the two arcs to the right of their intersection point.
|
/*! 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 (is_linear()) {
|
||||||
if (cv.is_linear()) return (_lines_compare_to_right (cv, p));
|
if (cv.is_linear()) return (_lines_compare_to_right (cv, p));
|
||||||
Comparison_result res = cv._circ_line_compare_to_right (*this, 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.
|
/*! 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 (is_linear()) {
|
||||||
if (cv.is_linear()) return (_lines_compare_to_left (cv, p));
|
if (cv.is_linear()) return (_lines_compare_to_left (cv, p));
|
||||||
Comparison_result res = cv._circ_line_compare_to_left(*this, 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.
|
/*! 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.
|
// Check if the curve indices are the same.
|
||||||
if (_index() != 0 && _index() == cv._index()) return true;
|
if (_index() != 0 && _index() == cv._index()) return true;
|
||||||
|
|
||||||
|
|
@ -950,8 +918,7 @@ public:
|
||||||
|
|
||||||
/*! checks whether the two curves are equal.
|
/*! 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 (! this->has_same_supporting_curve(cv)) return false;
|
||||||
|
|
||||||
if (is_linear()) {
|
if (is_linear()) {
|
||||||
|
|
@ -969,8 +936,7 @@ public:
|
||||||
|
|
||||||
/*! splits the curve at a given point into two sub-arcs.
|
/*! 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.
|
// Copy the properties of this arc to the sub-arcs.
|
||||||
c1 = *this;
|
c1 = *this;
|
||||||
c2 = *this;
|
c2 = *this;
|
||||||
|
|
@ -990,8 +956,7 @@ public:
|
||||||
*/
|
*/
|
||||||
template <typename OutputIterator>
|
template <typename OutputIterator>
|
||||||
OutputIterator intersect(const Self& cv, OutputIterator oi,
|
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.
|
// First check whether the two arcs have the same supporting curve.
|
||||||
if (has_same_supporting_curve(cv)) {
|
if (has_same_supporting_curve(cv)) {
|
||||||
// Check for overlaps between the two arcs.
|
// Check for overlaps between the two arcs.
|
||||||
|
|
@ -1064,8 +1029,7 @@ public:
|
||||||
// Report only the intersection points that lie on both arcs.
|
// Report only the intersection points that lie on both arcs.
|
||||||
for (auto iter = inter_list.begin(); iter != inter_list.end(); ++iter) {
|
for (auto iter = inter_list.begin(); iter != inter_list.end(); ++iter) {
|
||||||
if (this->_is_between_endpoints (iter->first) &&
|
if (this->_is_between_endpoints (iter->first) &&
|
||||||
cv._is_between_endpoints (iter->first))
|
cv._is_between_endpoints (iter->first)) {
|
||||||
{
|
|
||||||
*oi++ = *iter;
|
*oi++ = *iter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1075,8 +1039,7 @@ public:
|
||||||
|
|
||||||
/*! checks whether it is possible to merge our arc with the given arc.
|
/*! 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
|
// In order to merge the two arcs, they should have the same supporting
|
||||||
// curve.
|
// curve.
|
||||||
if (! this->has_same_supporting_curve(cv)) return false;
|
if (! this->has_same_supporting_curve(cv)) return false;
|
||||||
|
|
@ -1089,8 +1052,7 @@ public:
|
||||||
/*! merges our arc with the given arc.
|
/*! merges our arc with the given arc.
|
||||||
* \pre The two arcs are mergeable.
|
* \pre The two arcs are mergeable.
|
||||||
*/
|
*/
|
||||||
void merge(const Self& cv)
|
void merge(const Self& cv) {
|
||||||
{
|
|
||||||
CGAL_precondition(this->can_merge_with (cv));
|
CGAL_precondition(this->can_merge_with (cv));
|
||||||
|
|
||||||
// Check if we should extend the arc to the left or to the right.
|
// Check if we should extend the arc to the left or to the right.
|
||||||
|
|
@ -1109,8 +1071,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! constructs an opposite arc. */
|
/*! constructs an opposite arc. */
|
||||||
Self construct_opposite() const
|
Self construct_opposite() const {
|
||||||
{
|
|
||||||
Self opp_cv;
|
Self opp_cv;
|
||||||
opp_cv.m_first = this->m_first;
|
opp_cv.m_first = this->m_first;
|
||||||
opp_cv.m_second = this->m_second;
|
opp_cv.m_second = this->m_second;
|
||||||
|
|
@ -1127,8 +1088,7 @@ public:
|
||||||
return (opp_cv);
|
return (opp_cv);
|
||||||
}
|
}
|
||||||
|
|
||||||
Bbox_2 bbox() const
|
Bbox_2 bbox() const {
|
||||||
{
|
|
||||||
double x_min = to_double(left().x());
|
double x_min = to_double(left().x());
|
||||||
double x_max = to_double(right().x());
|
double x_max = to_double(right().x());
|
||||||
double y_min = to_double(left().y());
|
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.
|
/*! 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();
|
Orientation orient = orientation();
|
||||||
bool dir_right = ((m_info & IS_DIRECTED_RIGHT_MASK) != 0);
|
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.
|
/*! 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.
|
// Check if we have a vertical segment.
|
||||||
|
|
||||||
CGAL_precondition(is_in_x_range(p));
|
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.
|
/*! 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());
|
Comparison_result c_res = CGAL::compare (p.y(), y0());
|
||||||
|
|
||||||
if (_is_upper()) {
|
if (_is_upper()) {
|
||||||
// Check if p lies below the "equator" (while the arc lies above it):
|
// Check if p lies below the "equator" (while the arc lies above it):
|
||||||
if (c_res == SMALLER)
|
if (c_res == SMALLER) return (SMALLER);
|
||||||
return (SMALLER);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Check if p lies above the "equator" (while the arc lies below it):
|
// Check if p lies above the "equator" (while the arc lies below it):
|
||||||
if (c_res == LARGER)
|
if (c_res == LARGER) return (LARGER);
|
||||||
return (LARGER);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if p lies inside the supporting circle, namely we have to check
|
// 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.
|
/*! compares two line segments to the right of their intersection point.
|
||||||
*/
|
*/
|
||||||
Comparison_result _lines_compare_to_right(const Self& cv,
|
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);
|
if (_index() != 0 && _index() == cv._index()) return (EQUAL);
|
||||||
|
|
||||||
// Special treatment for vertical segments: a vertical segment is larger
|
// Special treatment for vertical segments: a vertical segment is larger
|
||||||
|
|
@ -1292,8 +1246,7 @@ protected:
|
||||||
* their intersection point.
|
* their intersection point.
|
||||||
*/
|
*/
|
||||||
Comparison_result _circ_line_compare_to_right(const Self& cv,
|
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:
|
// A vertical segment lies above any other circle to the right of p:
|
||||||
if (cv.is_vertical()) return (SMALLER);
|
if (cv.is_vertical()) return (SMALLER);
|
||||||
|
|
||||||
|
|
@ -1334,8 +1287,7 @@ protected:
|
||||||
/*! compares two circular arcs to the right of their intersection point.
|
/*! compares two circular arcs to the right of their intersection point.
|
||||||
*/
|
*/
|
||||||
Comparison_result _circs_compare_to_right(const Self& cv,
|
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()) {
|
if (_index() != 0 && _index() == cv._index()) {
|
||||||
// Check the case of comparing two circular arcs that originate from the
|
// Check the case of comparing two circular arcs that originate from the
|
||||||
// same supporting circle. Their comparison result is not EQUAL only if
|
// 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.
|
// Compare the slopes of the two tangents to the circles.
|
||||||
Comparison_result slope_res;
|
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:
|
// Special case were both circles have a horizontal tangent:
|
||||||
slope_res = EQUAL;
|
slope_res = EQUAL;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
// Actually compare the slopes.
|
// Actually compare the slopes.
|
||||||
const bool swap_res = (sign_denom1 != sign_denom2);
|
const bool swap_res = (sign_denom1 != sign_denom2);
|
||||||
const CoordNT A = NT(cv.y0() - y0())*p.x() + (y0()*cv.x0() - cv.y0()*x0());
|
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.
|
/*! compares two line segments to the left of their intersection point.
|
||||||
*/
|
*/
|
||||||
Comparison_result _lines_compare_to_left(const Self& cv,
|
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);
|
if (_index() != 0 && _index() == cv._index()) return (EQUAL);
|
||||||
|
|
||||||
// Special treatment for vertical segments: a vertical segment is smaller
|
// Special treatment for vertical segments: a vertical segment is smaller
|
||||||
|
|
@ -1489,8 +1438,7 @@ protected:
|
||||||
* their intersection point.
|
* their intersection point.
|
||||||
*/
|
*/
|
||||||
Comparison_result _circ_line_compare_to_left(const Self& cv,
|
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:
|
// A vertical segment lies below any other circle to the left of p:
|
||||||
if (cv.is_vertical()) return (LARGER);
|
if (cv.is_vertical()) return (LARGER);
|
||||||
|
|
||||||
|
|
@ -1534,8 +1482,7 @@ protected:
|
||||||
/*! compares the two arcs to the left of their intersection point.
|
/*! compares the two arcs to the left of their intersection point.
|
||||||
*/
|
*/
|
||||||
Comparison_result _circs_compare_to_left(const Self& cv,
|
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()) {
|
if (_index() != 0 && _index() == cv._index()) {
|
||||||
// Check the case of comparing two circular arcs that originate from the
|
// Check the case of comparing two circular arcs that originate from the
|
||||||
// same supporting circle. Their comparison result is not EQUAL only if
|
// 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.
|
// Compare the slopes of the two tangents to the circles.
|
||||||
Comparison_result slope_res;
|
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:
|
// Special case were both circles have a horizontal tangent:
|
||||||
slope_res = EQUAL;
|
slope_res = EQUAL;
|
||||||
}
|
}
|
||||||
|
|
@ -1668,8 +1614,7 @@ protected:
|
||||||
/*! computes the intersections between two line segments.
|
/*! computes the intersections between two line segments.
|
||||||
*/
|
*/
|
||||||
void _lines_intersect(const Self& cv,
|
void _lines_intersect(const Self& cv,
|
||||||
Intersection_list& inter_list) const
|
Intersection_list& inter_list) const {
|
||||||
{
|
|
||||||
// The intersection of the lines:
|
// The intersection of the lines:
|
||||||
// a1*x + b1*y + c1 = 0 and a2*x + b2*y + c2 = 0 ,
|
// a1*x + b1*y + c1 = 0 and a2*x + b2*y + c2 = 0 ,
|
||||||
// is given by:
|
// is given by:
|
||||||
|
|
@ -1695,8 +1640,7 @@ protected:
|
||||||
* the supporting line of the segment cv.
|
* the supporting line of the segment cv.
|
||||||
*/
|
*/
|
||||||
void _circ_line_intersect(const Self& cv,
|
void _circ_line_intersect(const Self& cv,
|
||||||
Intersection_list& inter_list) const
|
Intersection_list& inter_list) const {
|
||||||
{
|
|
||||||
Point_2 p;
|
Point_2 p;
|
||||||
unsigned int mult;
|
unsigned int mult;
|
||||||
|
|
||||||
|
|
@ -1818,8 +1762,7 @@ protected:
|
||||||
|
|
||||||
/*! computes the intersections between two circles.
|
/*! 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;
|
Point_2 p;
|
||||||
unsigned int mult;
|
unsigned int mult;
|
||||||
|
|
||||||
|
|
@ -1884,8 +1827,7 @@ protected:
|
||||||
/*! checks if the given point lies on the arc.
|
/*! checks if the given point lies on the arc.
|
||||||
* \pre p lies on the supporting curve.
|
* \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_linear()) {
|
||||||
if (is_vertical()) {
|
if (is_vertical()) {
|
||||||
// Check if the point is in the y-range of the arc.
|
// 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.
|
// Check whether p lies on the upper or on the lower part of the circle.
|
||||||
Comparison_result c_res = CGAL::compare(p.y(), y0());
|
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:
|
// The point lies on the other half of the circle:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -1921,8 +1862,7 @@ protected:
|
||||||
/*! checks whether the given point lies in the interior of the arc.
|
/*! checks whether the given point lies in the interior of the arc.
|
||||||
* \pre p lies on the supporting curve.
|
* \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;
|
if (p.equals (m_source) || p.equals (m_target)) return false;
|
||||||
return (_is_between_endpoints(p));
|
return (_is_between_endpoints(p));
|
||||||
}
|
}
|
||||||
|
|
@ -1932,8 +1872,7 @@ protected:
|
||||||
* \param overlap Output: The overlapping arc (if any).
|
* \param overlap Output: The overlapping arc (if any).
|
||||||
* \return Whether we found an overlap.
|
* \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.
|
// Check if the two arcs are identical.
|
||||||
if (is_linear()) {
|
if (is_linear()) {
|
||||||
// In case of line segments we can swap the source and target:
|
// In case of line segments we can swap the source and target:
|
||||||
|
|
@ -1999,10 +1938,9 @@ protected:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
template <class OutputIterator>
|
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 x_left = CGAL::to_double(this->source().x());
|
||||||
const double y_left = CGAL::to_double(this->source().y());
|
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
|
* \pre Both ps and pt lies on the arc and must conform with the current
|
||||||
* direction of the arc.
|
* 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;
|
Self arc = *this;
|
||||||
|
|
||||||
arc.m_source = ps;
|
arc.m_source = ps;
|
||||||
|
|
@ -2063,8 +2000,7 @@ protected:
|
||||||
template <class Kernel, bool Filter>
|
template <class Kernel, bool Filter>
|
||||||
std::ostream&
|
std::ostream&
|
||||||
operator<<(std::ostream& os,
|
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())
|
if (! arc.is_linear())
|
||||||
os << "(" << arc.supporting_circle() << ") ";
|
os << "(" << arc.supporting_circle() << ") ";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,46 +43,41 @@ namespace CGAL {
|
||||||
// Traits class for CGAL::Arrangement_2 (and similar) based on a
|
// Traits class for CGAL::Arrangement_2 (and similar) based on a
|
||||||
// CircularKernel.
|
// CircularKernel.
|
||||||
|
|
||||||
template < typename CircularKernel >
|
template <typename CircularKernel>
|
||||||
class Arr_line_arc_traits_2 {
|
class Arr_line_arc_traits_2 {
|
||||||
|
|
||||||
CircularKernel ck;
|
CircularKernel ck;
|
||||||
|
|
||||||
public:
|
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;
|
using Point = typename CircularKernel::Circular_arc_point_2;
|
||||||
typedef typename CircularKernel::Line_arc_2 Curve_2;
|
using Point_2 = typename CircularKernel::Circular_arc_point_2;
|
||||||
typedef typename CircularKernel::Line_arc_2 X_monotone_curve_2;
|
|
||||||
typedef unsigned int Multiplicity;
|
|
||||||
|
|
||||||
typedef typename CircularKernel::Circular_arc_point_2 Point;
|
using Has_left_category = CGAL::Tag_false;
|
||||||
typedef typename CircularKernel::Circular_arc_point_2 Point_2;
|
using Has_merge_category = CGAL::Tag_false;
|
||||||
|
using Has_do_intersect_category = CGAL::Tag_false;
|
||||||
|
|
||||||
typedef CGAL::Tag_false Has_left_category;
|
using Left_side_category = Arr_oblivious_side_tag;
|
||||||
typedef CGAL::Tag_false Has_merge_category;
|
using Bottom_side_category = Arr_oblivious_side_tag;
|
||||||
typedef CGAL::Tag_false Has_do_intersect_category;
|
using Top_side_category = Arr_oblivious_side_tag;
|
||||||
|
using Right_side_category = Arr_oblivious_side_tag;
|
||||||
|
|
||||||
typedef Arr_oblivious_side_tag Left_side_category;
|
Arr_line_arc_traits_2(const CircularKernel& k = CircularKernel()) : ck(k) {}
|
||||||
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())
|
using Compare_x_2 = typename CircularKernel::Compare_x_2;
|
||||||
: ck(k) {}
|
using Compare_xy_2 = typename CircularKernel::Compare_xy_2;
|
||||||
|
using Compare_y_at_x_2 = typename CircularKernel::Compare_y_at_x_2;
|
||||||
typedef typename CircularKernel::Compare_x_2 Compare_x_2;
|
using Compare_y_at_x_right_2 = typename CircularKernel::Compare_y_to_right_2;
|
||||||
typedef typename CircularKernel::Compare_xy_2 Compare_xy_2;
|
using Equal_2 = typename CircularKernel::Equal_2;
|
||||||
typedef typename CircularKernel::Compare_y_at_x_2 Compare_y_at_x_2;
|
// using Make_x_monotone_2 = typename CircularKernel::Make_x_monotone_2;
|
||||||
typedef typename CircularKernel::Compare_y_to_right_2 Compare_y_at_x_right_2;
|
using Split_2 = typename CircularKernel::Split_2;
|
||||||
typedef typename CircularKernel::Equal_2 Equal_2;
|
using Construct_min_vertex_2 = typename CircularKernel::Construct_circular_min_vertex_2;
|
||||||
// typedef typename CircularKernel::Make_x_monotone_2 Make_x_monotone_2;
|
using Construct_max_vertex_2 = typename CircularKernel::Construct_circular_max_vertex_2;
|
||||||
typedef typename CircularKernel::Split_2 Split_2;
|
using Is_vertical_2 = typename CircularKernel::Is_vertical_2;
|
||||||
typedef typename CircularKernel::Construct_circular_min_vertex_2
|
using Intersect_2 = typename CircularKernel::Intersect_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;
|
|
||||||
|
|
||||||
Compare_x_2 compare_x_2_object() const
|
Compare_x_2 compare_x_2_object() const
|
||||||
{ return ck.compare_x_2_object(); }
|
{ return ck.compare_x_2_object(); }
|
||||||
|
|
@ -106,7 +101,7 @@ public:
|
||||||
{ return ck.split_2_object(); }
|
{ return ck.split_2_object(); }
|
||||||
|
|
||||||
Intersect_2 intersect_2_object() const
|
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
|
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(); }
|
||||||
|
|
@ -121,9 +116,8 @@ public:
|
||||||
class Make_x_monotone_2 {
|
class Make_x_monotone_2 {
|
||||||
public:
|
public:
|
||||||
template <typename OutputIterator>
|
template <typename OutputIterator>
|
||||||
OutputIterator operator()(const Curve_2& line, OutputIterator oi) const
|
OutputIterator operator()(const Curve_2& line, OutputIterator oi) const {
|
||||||
{
|
using Make_x_monotone_result = std::variant<Point_2, X_monotone_curve_2>;
|
||||||
typedef std::variant<Point_2, X_monotone_curve_2> Make_x_monotone_result;
|
|
||||||
*oi++ = Make_x_monotone_result(line);
|
*oi++ = Make_x_monotone_result(line);
|
||||||
return oi;
|
return oi;
|
||||||
}
|
}
|
||||||
|
|
@ -137,4 +131,4 @@ public:
|
||||||
|
|
||||||
#include <CGAL/enable_warnings.h>
|
#include <CGAL/enable_warnings.h>
|
||||||
|
|
||||||
#endif // CGAL_CIRCULAR_KERNEL_LINE_ARC_TRAITS_H
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@
|
||||||
|
|
||||||
#include <variant>
|
#include <variant>
|
||||||
|
|
||||||
#include <CGAL/Cartesian.h>
|
#include <CGAL/Simple_cartesian.h>
|
||||||
#include <CGAL/tags.h>
|
#include <CGAL/tags.h>
|
||||||
#include <CGAL/intersections.h>
|
#include <CGAL/intersections.h>
|
||||||
#include <CGAL/Arr_tags.h>
|
#include <CGAL/Arr_tags.h>
|
||||||
|
|
@ -49,58 +49,55 @@ class Arr_linear_traits_2 : public Kernel_ {
|
||||||
friend class Arr_linear_object_2<Kernel_>;
|
friend class Arr_linear_object_2<Kernel_>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef Kernel_ Kernel;
|
using Kernel = Kernel_;
|
||||||
typedef typename Kernel::FT FT;
|
using FT = typename Kernel::FT;
|
||||||
|
|
||||||
typedef typename Algebraic_structure_traits<FT>::Is_exact
|
using Has_exact_division = typename Algebraic_structure_traits<FT>::Is_exact;
|
||||||
Has_exact_division;
|
|
||||||
|
|
||||||
// Category tags:
|
// Category tags:
|
||||||
typedef Tag_true Has_left_category;
|
using Has_left_category = Tag_true;
|
||||||
typedef Tag_true Has_merge_category;
|
using Has_merge_category = Tag_true;
|
||||||
typedef Tag_false Has_do_intersect_category;
|
using Has_do_intersect_category = Tag_false;
|
||||||
|
|
||||||
typedef Arr_open_side_tag Left_side_category;
|
using Left_side_category = Arr_open_side_tag;
|
||||||
typedef Arr_open_side_tag Bottom_side_category;
|
using Bottom_side_category = Arr_open_side_tag;
|
||||||
typedef Arr_open_side_tag Top_side_category;
|
using Top_side_category = Arr_open_side_tag;
|
||||||
typedef Arr_open_side_tag Right_side_category;
|
using Right_side_category = Arr_open_side_tag;
|
||||||
|
|
||||||
typedef typename Kernel::Line_2 Line_2;
|
using Line_2 = typename Kernel::Line_2;
|
||||||
typedef typename Kernel::Ray_2 Ray_2;
|
using Ray_2 = typename Kernel::Ray_2;
|
||||||
typedef typename Kernel::Segment_2 Segment_2;
|
using Segment_2 = typename Kernel::Segment_2;
|
||||||
|
|
||||||
typedef CGAL::Segment_assertions<Arr_linear_traits_2<Kernel> >
|
using Segment_assertions = CGAL::Segment_assertions<Arr_linear_traits_2<Kernel>>;
|
||||||
Segment_assertions;
|
|
||||||
|
|
||||||
/*! \class Representation of a linear with cached data.
|
/*! \class Representation of a linear with cached data.
|
||||||
*/
|
*/
|
||||||
class _Linear_object_cached_2 {
|
class _Linear_object_cached_2 {
|
||||||
public:
|
public:
|
||||||
typedef typename Kernel::Line_2 Line_2;
|
using Line_2 = typename Kernel::Line_2;
|
||||||
typedef typename Kernel::Ray_2 Ray_2;
|
using Ray_2 = typename Kernel::Ray_2;
|
||||||
typedef typename Kernel::Segment_2 Segment_2;
|
using Segment_2 = typename Kernel::Segment_2;
|
||||||
typedef typename Kernel::Point_2 Point_2;
|
using Point_2 = typename Kernel::Point_2;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Line_2 l; // The supporting line.
|
Line_2 l; // The supporting line.
|
||||||
Point_2 ps; // The source point (if exists).
|
Point_2 ps; // The source point (if exists).
|
||||||
Point_2 pt; // The target point (if exists).
|
Point_2 pt; // The target point (if exists).
|
||||||
bool has_source; // Is the source point valid
|
bool has_source; // Is the source point valid
|
||||||
// (false for a line).
|
// (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).
|
// (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).
|
// (for segments and rays).
|
||||||
bool is_vert; // Is this a vertical object.
|
bool is_vert; // Is this a vertical object.
|
||||||
bool is_horiz; // Is this a horizontal object.
|
bool is_horiz; // Is this a horizontal object.
|
||||||
bool has_pos_slope; // Does the supporting line has a positive
|
bool has_pos_slope; // Does the supporting line has a positive
|
||||||
// slope (if all three flags is_vert, is_horiz
|
// slope (if all three flags is_vert, is_horiz
|
||||||
// and has_pos_slope are false, then the line
|
// and has_pos_slope are false, then the line
|
||||||
// has a negative slope).
|
// 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:
|
public:
|
||||||
|
|
||||||
/*! constructs default.
|
/*! constructs default.
|
||||||
*/
|
*/
|
||||||
_Linear_object_cached_2() :
|
_Linear_object_cached_2() :
|
||||||
|
|
@ -121,8 +118,7 @@ public:
|
||||||
ps(source),
|
ps(source),
|
||||||
pt(target),
|
pt(target),
|
||||||
has_source(true),
|
has_source(true),
|
||||||
has_target(true)
|
has_target(true) {
|
||||||
{
|
|
||||||
Kernel kernel;
|
Kernel kernel;
|
||||||
|
|
||||||
Comparison_result res = kernel.compare_xy_2_object()(source, target);
|
Comparison_result res = kernel.compare_xy_2_object()(source, target);
|
||||||
|
|
@ -144,8 +140,7 @@ public:
|
||||||
*/
|
*/
|
||||||
_Linear_object_cached_2(const Segment_2& seg) :
|
_Linear_object_cached_2(const Segment_2& seg) :
|
||||||
has_source(true),
|
has_source(true),
|
||||||
has_target(true)
|
has_target(true) {
|
||||||
{
|
|
||||||
Kernel kernel;
|
Kernel kernel;
|
||||||
|
|
||||||
CGAL_assertion_msg(! kernel.is_degenerate_2_object()(seg),
|
CGAL_assertion_msg(! kernel.is_degenerate_2_object()(seg),
|
||||||
|
|
@ -172,8 +167,7 @@ public:
|
||||||
*/
|
*/
|
||||||
_Linear_object_cached_2(const Ray_2& ray) :
|
_Linear_object_cached_2(const Ray_2& ray) :
|
||||||
has_source(true),
|
has_source(true),
|
||||||
has_target(false)
|
has_target(false) {
|
||||||
{
|
|
||||||
Kernel kernel;
|
Kernel kernel;
|
||||||
|
|
||||||
CGAL_assertion_msg(! kernel.is_degenerate_2_object()(ray),
|
CGAL_assertion_msg(! kernel.is_degenerate_2_object()(ray),
|
||||||
|
|
@ -201,8 +195,7 @@ public:
|
||||||
_Linear_object_cached_2(const Line_2& ln) :
|
_Linear_object_cached_2(const Line_2& ln) :
|
||||||
l(ln),
|
l(ln),
|
||||||
has_source(false),
|
has_source(false),
|
||||||
has_target(false)
|
has_target(false) {
|
||||||
{
|
|
||||||
Kernel kernel;
|
Kernel kernel;
|
||||||
|
|
||||||
CGAL_assertion_msg(! kernel.is_degenerate_2_object()(ln),
|
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;
|
* \return `ARR_LEFT_BOUNDARY` if the left point is near the boundary;
|
||||||
* `ARR_INTERIOR` if the \f$x\f$-coordinate is finite.
|
* `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);
|
if (is_vert || is_degen) return (ARR_INTERIOR);
|
||||||
|
|
||||||
return (is_right) ?
|
return (is_right) ?
|
||||||
|
|
@ -240,8 +232,7 @@ public:
|
||||||
* `ARR_INTERIOR` if the \f$y\f$-coordinate is finite.
|
* `ARR_INTERIOR` if the \f$y\f$-coordinate is finite.
|
||||||
* `ARR_TOP_BOUNDARY` if the left point is at \f$y = +\infty\f$;
|
* `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_horiz || is_degen) return ARR_INTERIOR;
|
||||||
|
|
||||||
if (is_vert) {
|
if (is_vert) {
|
||||||
|
|
@ -263,8 +254,7 @@ public:
|
||||||
/*! obtains the (lexicographically) left endpoint.
|
/*! obtains the (lexicographically) left endpoint.
|
||||||
* \pre The left point is finite.
|
* \pre The left point is finite.
|
||||||
*/
|
*/
|
||||||
const Point_2& left() const
|
const Point_2& left() const {
|
||||||
{
|
|
||||||
CGAL_precondition(has_left());
|
CGAL_precondition(has_left());
|
||||||
return (is_right ? ps : pt);
|
return (is_right ? ps : pt);
|
||||||
}
|
}
|
||||||
|
|
@ -274,8 +264,7 @@ public:
|
||||||
* \pre p lies on the supporting line to the left of the right endpoint.
|
* \pre p lies on the supporting line to the left of the right endpoint.
|
||||||
*/
|
*/
|
||||||
void set_left(const Point_2& p,
|
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(! is_degen);
|
||||||
|
|
||||||
CGAL_precondition_code(Kernel kernel);
|
CGAL_precondition_code(Kernel kernel);
|
||||||
|
|
@ -296,8 +285,7 @@ public:
|
||||||
|
|
||||||
/*! sets the (lexicographically) left endpoint as infinite.
|
/*! sets the (lexicographically) left endpoint as infinite.
|
||||||
*/
|
*/
|
||||||
void set_left()
|
void set_left() {
|
||||||
{
|
|
||||||
CGAL_precondition(! is_degen);
|
CGAL_precondition(! is_degen);
|
||||||
|
|
||||||
if (is_right) has_source = false;
|
if (is_right) has_source = false;
|
||||||
|
|
@ -308,8 +296,7 @@ public:
|
||||||
* \return `ARR_RIGHT_BOUNDARY` if the right point is near the boundary;
|
* \return `ARR_RIGHT_BOUNDARY` if the right point is near the boundary;
|
||||||
* `ARR_INTERIOR` if the \f$x\f$-coordinate is finite.
|
* `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;
|
if (is_vert || is_degen) return ARR_INTERIOR;
|
||||||
|
|
||||||
return (is_right) ?
|
return (is_right) ?
|
||||||
|
|
@ -322,8 +309,7 @@ public:
|
||||||
* `ARR_INTERIOR` if the \f$y\f$-coordinate is finite.
|
* `ARR_INTERIOR` if the \f$y\f$-coordinate is finite.
|
||||||
* `ARR_TOP_BOUNDARY` if the right point is at \f$y = +\infty\f$;
|
* `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_horiz || is_degen) return ARR_INTERIOR;
|
||||||
|
|
||||||
if (is_vert) {
|
if (is_vert) {
|
||||||
|
|
@ -345,8 +331,7 @@ public:
|
||||||
/*! obtains the (lexicographically) right endpoint.
|
/*! obtains the (lexicographically) right endpoint.
|
||||||
* \pre The right endpoint is finite.
|
* \pre The right endpoint is finite.
|
||||||
*/
|
*/
|
||||||
const Point_2& right() const
|
const Point_2& right() const {
|
||||||
{
|
|
||||||
CGAL_precondition(has_right());
|
CGAL_precondition(has_right());
|
||||||
return (is_right ? pt : ps);
|
return (is_right ? pt : ps);
|
||||||
}
|
}
|
||||||
|
|
@ -356,8 +341,7 @@ public:
|
||||||
* \pre p lies on the supporting line to the right of the left endpoint.
|
* \pre p lies on the supporting line to the right of the left endpoint.
|
||||||
*/
|
*/
|
||||||
void set_right(const Point_2& p,
|
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(! is_degen);
|
||||||
CGAL_precondition_code(Kernel kernel);
|
CGAL_precondition_code(Kernel kernel);
|
||||||
CGAL_precondition
|
CGAL_precondition
|
||||||
|
|
@ -377,8 +361,7 @@ public:
|
||||||
|
|
||||||
/*! sets the (lexicographically) right endpoint as infinite.
|
/*! sets the (lexicographically) right endpoint as infinite.
|
||||||
*/
|
*/
|
||||||
void set_right()
|
void set_right() {
|
||||||
{
|
|
||||||
CGAL_precondition(! is_degen);
|
CGAL_precondition(! is_degen);
|
||||||
|
|
||||||
if (is_right) has_target = false;
|
if (is_right) has_target = false;
|
||||||
|
|
@ -387,16 +370,14 @@ public:
|
||||||
|
|
||||||
/*! obtains the supporting line.
|
/*! obtains the supporting line.
|
||||||
*/
|
*/
|
||||||
const Line_2& supp_line() const
|
const Line_2& supp_line() const {
|
||||||
{
|
|
||||||
CGAL_precondition(! is_degen);
|
CGAL_precondition(! is_degen);
|
||||||
return (l);
|
return (l);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! checks whether the curve is vertical.
|
/*! checks whether the curve is vertical.
|
||||||
*/
|
*/
|
||||||
bool is_vertical() const
|
bool is_vertical() const {
|
||||||
{
|
|
||||||
CGAL_precondition(! is_degen);
|
CGAL_precondition(! is_degen);
|
||||||
return (is_vert);
|
return (is_vert);
|
||||||
}
|
}
|
||||||
|
|
@ -414,8 +395,7 @@ public:
|
||||||
* \return (true) is in the \f$x\f$-range of the segment; (false) if it is
|
* \return (true) is in the \f$x\f$-range of the segment; (false) if it is
|
||||||
* not.
|
* not.
|
||||||
*/
|
*/
|
||||||
bool is_in_x_range(const Point_2& p) const
|
bool is_in_x_range(const Point_2& p) const {
|
||||||
{
|
|
||||||
Kernel kernel;
|
Kernel kernel;
|
||||||
typename Kernel_::Compare_x_2 compare_x = kernel.compare_x_2_object();
|
typename Kernel_::Compare_x_2 compare_x = kernel.compare_x_2_object();
|
||||||
Comparison_result res1;
|
Comparison_result res1;
|
||||||
|
|
@ -454,8 +434,7 @@ public:
|
||||||
* \return (true) is in the \f$y\f$-range of the segment; (false) if it is
|
* \return (true) is in the \f$y\f$-range of the segment; (false) if it is
|
||||||
* not.
|
* 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());
|
CGAL_precondition(is_vertical());
|
||||||
|
|
||||||
Kernel kernel;
|
Kernel kernel;
|
||||||
|
|
@ -483,8 +462,7 @@ public:
|
||||||
private:
|
private:
|
||||||
/*! determines if the supporting line has a positive slope.
|
/*! 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_vert) return true;
|
||||||
if (is_horiz) return false;
|
if (is_horiz) return false;
|
||||||
|
|
||||||
|
|
@ -498,10 +476,10 @@ public:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Traits objects
|
// Traits objects
|
||||||
typedef typename Kernel::Point_2 Point_2;
|
using Point_2 = typename Kernel::Point_2;
|
||||||
typedef Arr_linear_object_2<Kernel> X_monotone_curve_2;
|
using X_monotone_curve_2 = Arr_linear_object_2<Kernel>;
|
||||||
typedef Arr_linear_object_2<Kernel> Curve_2;
|
using Curve_2 = Arr_linear_object_2<Kernel>;
|
||||||
typedef unsigned int Multiplicity;
|
using Multiplicity = std::size_t;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*! constructs default.
|
/*! constructs default.
|
||||||
|
|
@ -514,7 +492,7 @@ public:
|
||||||
/*! A functor that compares the \f$x\f$-coordinates of two points */
|
/*! A functor that compares the \f$x\f$-coordinates of two points */
|
||||||
class Compare_x_2 {
|
class Compare_x_2 {
|
||||||
protected:
|
protected:
|
||||||
typedef Arr_linear_traits_2<Kernel> Traits;
|
using Traits = Arr_linear_traits_2<Kernel>;
|
||||||
|
|
||||||
/*! The traits (in case it has state) */
|
/*! The traits (in case it has state) */
|
||||||
const Traits& m_traits;
|
const Traits& m_traits;
|
||||||
|
|
@ -538,8 +516,7 @@ public:
|
||||||
* SMALLER if x(p1) < x(p2);
|
* SMALLER if x(p1) < x(p2);
|
||||||
* EQUAL 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;
|
const Kernel& kernel = m_traits;
|
||||||
return (kernel.compare_x_2_object()(p1, p2));
|
return (kernel.compare_x_2_object()(p1, p2));
|
||||||
}
|
}
|
||||||
|
|
@ -567,7 +544,7 @@ public:
|
||||||
|
|
||||||
class Trim_2 {
|
class Trim_2 {
|
||||||
protected:
|
protected:
|
||||||
typedef Arr_linear_traits_2<Kernel> Traits;
|
using Traits = Arr_linear_traits_2<Kernel>;
|
||||||
|
|
||||||
/*! The traits (in case it has state) */
|
/*! The traits (in case it has state) */
|
||||||
const Traits& m_traits;
|
const Traits& m_traits;
|
||||||
|
|
@ -586,10 +563,8 @@ public:
|
||||||
public:
|
public:
|
||||||
X_monotone_curve_2 operator()(const X_monotone_curve_2 xcv,
|
X_monotone_curve_2 operator()(const X_monotone_curve_2 xcv,
|
||||||
const Point_2 src,
|
const Point_2 src,
|
||||||
const Point_2 tgt)
|
const Point_2 tgt) {
|
||||||
{
|
/* "Line_segment, line, and ray" will become line segments
|
||||||
/*
|
|
||||||
* "Line_segment, line, and ray" will become line segments
|
|
||||||
* when trimmed.
|
* when trimmed.
|
||||||
*/
|
*/
|
||||||
Equal_2 equal = Equal_2();
|
Equal_2 equal = Equal_2();
|
||||||
|
|
@ -619,7 +594,7 @@ public:
|
||||||
|
|
||||||
class Construct_opposite_2{
|
class Construct_opposite_2{
|
||||||
protected:
|
protected:
|
||||||
typedef Arr_linear_traits_2<Kernel> Traits;
|
using Traits = Arr_linear_traits_2<Kernel>;
|
||||||
|
|
||||||
/*! The traits (in case it has state) */
|
/*! The traits (in case it has state) */
|
||||||
const Traits& m_traits;
|
const Traits& m_traits;
|
||||||
|
|
@ -636,8 +611,7 @@ public:
|
||||||
friend class Arr_linear_traits_2<Kernel>;
|
friend class Arr_linear_traits_2<Kernel>;
|
||||||
|
|
||||||
public:
|
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());
|
CGAL_precondition(! xcv.is_degenerate());
|
||||||
|
|
||||||
X_monotone_curve_2 opp_xcv;
|
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);
|
* SMALLER if x(p1) < x(p2), or if x(p1) = x(p2) and y(p1) < y(p2);
|
||||||
* EQUAL if the two points are equal.
|
* 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;
|
Kernel kernel;
|
||||||
return (kernel.compare_xy_2_object()(p1, p2));
|
return (kernel.compare_xy_2_object()(p1, p2));
|
||||||
}
|
}
|
||||||
|
|
@ -685,8 +658,7 @@ public:
|
||||||
* \pre The left end of cv is a valid (bounded) point.
|
* \pre The left end of cv is a valid (bounded) point.
|
||||||
* \return The left endpoint.
|
* \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.is_degenerate());
|
||||||
CGAL_precondition(cv.has_left());
|
CGAL_precondition(cv.has_left());
|
||||||
|
|
||||||
|
|
@ -706,8 +678,7 @@ public:
|
||||||
* \pre The right end of cv is a valid (bounded) point.
|
* \pre The right end of cv is a valid (bounded) point.
|
||||||
* \return The right endpoint.
|
* \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.is_degenerate());
|
||||||
CGAL_precondition(cv.has_right());
|
CGAL_precondition(cv.has_right());
|
||||||
|
|
||||||
|
|
@ -726,8 +697,7 @@ public:
|
||||||
* \param cv The curve.
|
* \param cv The curve.
|
||||||
* \return (true) if the curve is a vertical segment; (false) otherwise.
|
* \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());
|
CGAL_precondition(! cv.is_degenerate());
|
||||||
return (cv.is_vertical());
|
return (cv.is_vertical());
|
||||||
}
|
}
|
||||||
|
|
@ -741,7 +711,7 @@ public:
|
||||||
*/
|
*/
|
||||||
class Compare_y_at_x_2 {
|
class Compare_y_at_x_2 {
|
||||||
protected:
|
protected:
|
||||||
typedef Arr_linear_traits_2<Kernel> Traits;
|
using Traits = Arr_linear_traits_2<Kernel>;
|
||||||
|
|
||||||
/*! The traits (in case it has state) */
|
/*! The traits (in case it has state) */
|
||||||
const Traits& m_traits;
|
const Traits& m_traits;
|
||||||
|
|
@ -767,8 +737,7 @@ public:
|
||||||
* EQUAL if p lies on the curve.
|
* EQUAL if p lies on the curve.
|
||||||
*/
|
*/
|
||||||
Comparison_result operator()(const Point_2& p,
|
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_degenerate());
|
||||||
CGAL_precondition(cv.is_in_x_range(p));
|
CGAL_precondition(cv.is_in_x_range(p));
|
||||||
|
|
||||||
|
|
@ -809,8 +778,7 @@ public:
|
||||||
*/
|
*/
|
||||||
Comparison_result operator()(const X_monotone_curve_2& cv1,
|
Comparison_result operator()(const X_monotone_curve_2& cv1,
|
||||||
const X_monotone_curve_2& cv2,
|
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(! cv1.is_degenerate());
|
||||||
CGAL_precondition(! cv2.is_degenerate());
|
CGAL_precondition(! cv2.is_degenerate());
|
||||||
|
|
||||||
|
|
@ -861,8 +829,7 @@ public:
|
||||||
*/
|
*/
|
||||||
Comparison_result operator()(const X_monotone_curve_2& cv1,
|
Comparison_result operator()(const X_monotone_curve_2& cv1,
|
||||||
const X_monotone_curve_2& cv2,
|
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(! cv1.is_degenerate());
|
||||||
CGAL_precondition(! cv2.is_degenerate());
|
CGAL_precondition(! cv2.is_degenerate());
|
||||||
|
|
||||||
|
|
@ -906,8 +873,7 @@ public:
|
||||||
* \return (true) if the two curves are the same; (false) otherwise.
|
* \return (true) if the two curves are the same; (false) otherwise.
|
||||||
*/
|
*/
|
||||||
bool operator()(const X_monotone_curve_2& cv1,
|
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(! cv1.is_degenerate());
|
||||||
CGAL_precondition(! cv2.is_degenerate());
|
CGAL_precondition(! cv2.is_degenerate());
|
||||||
|
|
||||||
|
|
@ -918,17 +884,13 @@ public:
|
||||||
if (! equal(cv1.supp_line(), cv2.supp_line()) &&
|
if (! equal(cv1.supp_line(), cv2.supp_line()) &&
|
||||||
! equal(cv1.supp_line(),
|
! equal(cv1.supp_line(),
|
||||||
kernel.construct_opposite_line_2_object()(cv2.supp_line())))
|
kernel.construct_opposite_line_2_object()(cv2.supp_line())))
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
// Check that either the two left endpoints are at infinity, or they
|
// Check that either the two left endpoints are at infinity, or they
|
||||||
// are bounded and equal.
|
// are bounded and equal.
|
||||||
if ((cv1.has_left() != cv2.has_left()) ||
|
if ((cv1.has_left() != cv2.has_left()) ||
|
||||||
(cv1.has_left() && ! equal(cv1.left(), cv2.left())))
|
(cv1.has_left() && ! equal(cv1.left(), cv2.left())))
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
// Check that either the two right endpoints are at infinity, or they
|
// Check that either the two right endpoints are at infinity, or they
|
||||||
// are bounded and equal.
|
// are bounded and equal.
|
||||||
|
|
@ -941,8 +903,7 @@ public:
|
||||||
* \param p2 The second point.
|
* \param p2 The second point.
|
||||||
* \return (true) if the two point are the same; (false) otherwise.
|
* \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;
|
Kernel kernel;
|
||||||
return (kernel.equal_2_object()(p1, p2));
|
return (kernel.equal_2_object()(p1, p2));
|
||||||
}
|
}
|
||||||
|
|
@ -973,8 +934,7 @@ public:
|
||||||
* the left at the line right end.
|
* the left at the line right end.
|
||||||
*/
|
*/
|
||||||
Arr_parameter_space operator()(const X_monotone_curve_2 & xcv,
|
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());
|
CGAL_precondition(! xcv.is_degenerate());
|
||||||
return (ce == ARR_MIN_END) ?
|
return (ce == ARR_MIN_END) ?
|
||||||
xcv.left_infinite_in_x() : xcv.right_infinite_in_x();
|
xcv.left_infinite_in_x() : xcv.right_infinite_in_x();
|
||||||
|
|
@ -1015,8 +975,7 @@ public:
|
||||||
* right end.
|
* right end.
|
||||||
*/
|
*/
|
||||||
Arr_parameter_space operator()(const X_monotone_curve_2 & xcv,
|
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());
|
CGAL_precondition(! xcv.is_degenerate());
|
||||||
|
|
||||||
return (ce == ARR_MIN_END) ?
|
return (ce == ARR_MIN_END) ?
|
||||||
|
|
@ -1040,7 +999,7 @@ public:
|
||||||
*/
|
*/
|
||||||
class Compare_x_on_boundary_2 {
|
class Compare_x_on_boundary_2 {
|
||||||
protected:
|
protected:
|
||||||
typedef Arr_linear_traits_2<Kernel> Traits;
|
using Traits = Arr_linear_traits_2<Kernel>;
|
||||||
|
|
||||||
/*! The traits (in case it has state) */
|
/*! The traits (in case it has state) */
|
||||||
const Traits& m_traits;
|
const Traits& m_traits;
|
||||||
|
|
@ -1074,8 +1033,7 @@ public:
|
||||||
*/
|
*/
|
||||||
Comparison_result operator()(const Point_2 & p,
|
Comparison_result operator()(const Point_2 & p,
|
||||||
const X_monotone_curve_2 & xcv,
|
const X_monotone_curve_2 & xcv,
|
||||||
Arr_curve_end ) const
|
Arr_curve_end ) const {
|
||||||
{
|
|
||||||
CGAL_precondition(! xcv.is_degenerate());
|
CGAL_precondition(! xcv.is_degenerate());
|
||||||
CGAL_precondition(xcv.is_vertical());
|
CGAL_precondition(xcv.is_vertical());
|
||||||
|
|
||||||
|
|
@ -1105,8 +1063,7 @@ public:
|
||||||
Comparison_result operator()(const X_monotone_curve_2 & xcv1,
|
Comparison_result operator()(const X_monotone_curve_2 & xcv1,
|
||||||
Arr_curve_end /* ce1 */,
|
Arr_curve_end /* ce1 */,
|
||||||
const X_monotone_curve_2 & xcv2,
|
const X_monotone_curve_2 & xcv2,
|
||||||
Arr_curve_end /* ce2 */) const
|
Arr_curve_end /* ce2 */) const {
|
||||||
{
|
|
||||||
CGAL_precondition(! xcv1.is_degenerate());
|
CGAL_precondition(! xcv1.is_degenerate());
|
||||||
CGAL_precondition(! xcv2.is_degenerate());
|
CGAL_precondition(! xcv2.is_degenerate());
|
||||||
CGAL_precondition(xcv1.is_vertical());
|
CGAL_precondition(xcv1.is_vertical());
|
||||||
|
|
@ -1152,8 +1109,7 @@ public:
|
||||||
Comparison_result
|
Comparison_result
|
||||||
operator()(const X_monotone_curve_2& CGAL_precondition_code(xcv1),
|
operator()(const X_monotone_curve_2& CGAL_precondition_code(xcv1),
|
||||||
const X_monotone_curve_2& CGAL_precondition_code(xcv2),
|
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(! xcv1.is_degenerate());
|
||||||
CGAL_precondition(! xcv2.is_degenerate());
|
CGAL_precondition(! xcv2.is_degenerate());
|
||||||
CGAL_precondition(xcv1.is_vertical());
|
CGAL_precondition(xcv1.is_vertical());
|
||||||
|
|
@ -1171,7 +1127,7 @@ public:
|
||||||
*/
|
*/
|
||||||
class Compare_y_near_boundary_2 {
|
class Compare_y_near_boundary_2 {
|
||||||
protected:
|
protected:
|
||||||
typedef Arr_linear_traits_2<Kernel> Traits;
|
using Traits = Arr_linear_traits_2<Kernel>;
|
||||||
|
|
||||||
/*! The traits (in case it has state) */
|
/*! The traits (in case it has state) */
|
||||||
const Traits& m_traits;
|
const Traits& m_traits;
|
||||||
|
|
@ -1199,8 +1155,7 @@ public:
|
||||||
*/
|
*/
|
||||||
Comparison_result operator()(const X_monotone_curve_2 & xcv1,
|
Comparison_result operator()(const X_monotone_curve_2 & xcv1,
|
||||||
const X_monotone_curve_2 & xcv2,
|
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
|
// Make sure both curves are defined at \f$x = -\infty\f$ (or at
|
||||||
// \f$x = +\infty\f$).
|
// \f$x = +\infty\f$).
|
||||||
CGAL_precondition(! xcv1.is_degenerate());
|
CGAL_precondition(! xcv1.is_degenerate());
|
||||||
|
|
@ -1252,11 +1207,9 @@ public:
|
||||||
* \return The past-the-end iterator.
|
* \return The past-the-end iterator.
|
||||||
*/
|
*/
|
||||||
template <typename OutputIterator>
|
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.
|
// Wrap the segment with a variant.
|
||||||
typedef std::variant<Point_2, X_monotone_curve_2>
|
using Make_x_monotone_result = std::variant<Point_2, X_monotone_curve_2>;
|
||||||
Make_x_monotone_result;
|
|
||||||
*oi++ = Make_x_monotone_result(cv);
|
*oi++ = Make_x_monotone_result(cv);
|
||||||
return oi;
|
return oi;
|
||||||
}
|
}
|
||||||
|
|
@ -1277,8 +1230,7 @@ public:
|
||||||
* \pre `p` lies on `cv` but is not one of its end-points.
|
* \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,
|
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());
|
CGAL_precondition(! cv.is_degenerate());
|
||||||
|
|
||||||
// Make sure that p lies on the interior of the curve.
|
// Make sure that p lies on the interior of the curve.
|
||||||
|
|
@ -1306,7 +1258,7 @@ public:
|
||||||
|
|
||||||
class Intersect_2 {
|
class Intersect_2 {
|
||||||
protected:
|
protected:
|
||||||
typedef Arr_linear_traits_2<Kernel> Traits;
|
using Traits = Arr_linear_traits_2<Kernel>;
|
||||||
|
|
||||||
/*! The traits (in case it has state) */
|
/*! The traits (in case it has state) */
|
||||||
const Traits& m_traits;
|
const Traits& m_traits;
|
||||||
|
|
@ -1330,9 +1282,8 @@ public:
|
||||||
template <typename OutputIterator>
|
template <typename OutputIterator>
|
||||||
OutputIterator operator()(const X_monotone_curve_2& cv1,
|
OutputIterator operator()(const X_monotone_curve_2& cv1,
|
||||||
const X_monotone_curve_2& cv2,
|
const X_monotone_curve_2& cv2,
|
||||||
OutputIterator oi) const
|
OutputIterator oi) const {
|
||||||
{
|
using Intersection_point = std::pair<Point_2, Multiplicity>;
|
||||||
typedef std::pair<Point_2, Multiplicity> Intersection_point;
|
|
||||||
|
|
||||||
CGAL_precondition(! cv1.is_degenerate());
|
CGAL_precondition(! cv1.is_degenerate());
|
||||||
CGAL_precondition(! cv2.is_degenerate());
|
CGAL_precondition(! cv2.is_degenerate());
|
||||||
|
|
@ -1429,8 +1380,7 @@ public:
|
||||||
* by the same line and share a common endpoint; (false) otherwise.
|
* by the same line and share a common endpoint; (false) otherwise.
|
||||||
*/
|
*/
|
||||||
bool operator()(const X_monotone_curve_2& cv1,
|
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(! cv1.is_degenerate());
|
||||||
CGAL_precondition(! cv2.is_degenerate());
|
CGAL_precondition(! cv2.is_degenerate());
|
||||||
|
|
||||||
|
|
@ -1460,7 +1410,7 @@ public:
|
||||||
*/
|
*/
|
||||||
class Merge_2 {
|
class Merge_2 {
|
||||||
protected:
|
protected:
|
||||||
typedef Arr_linear_traits_2<Kernel> Traits;
|
using Traits = Arr_linear_traits_2<Kernel>;
|
||||||
|
|
||||||
/*! The traits (in case it has state) */
|
/*! The traits (in case it has state) */
|
||||||
const Traits& m_traits;
|
const Traits& m_traits;
|
||||||
|
|
@ -1481,8 +1431,7 @@ public:
|
||||||
*/
|
*/
|
||||||
void operator()(const X_monotone_curve_2& cv1,
|
void operator()(const X_monotone_curve_2& cv1,
|
||||||
const X_monotone_curve_2& cv2,
|
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(m_traits.are_mergeable_2_object()(cv2, cv1));
|
||||||
|
|
||||||
CGAL_precondition(!cv1.is_degenerate());
|
CGAL_precondition(!cv1.is_degenerate());
|
||||||
|
|
@ -1492,8 +1441,7 @@ public:
|
||||||
|
|
||||||
// Check which curve extends to the right of the other.
|
// Check which curve extends to the right of the other.
|
||||||
if (cv1.has_right() && cv2.has_left() &&
|
if (cv1.has_right() && cv2.has_left() &&
|
||||||
equal(cv1.right(), cv2.left()))
|
equal(cv1.right(), cv2.left())) {
|
||||||
{
|
|
||||||
// cv2 extends cv1 to the right.
|
// cv2 extends cv1 to the right.
|
||||||
c = cv1;
|
c = cv1;
|
||||||
|
|
||||||
|
|
@ -1519,9 +1467,9 @@ public:
|
||||||
|
|
||||||
/// \name Functor definitions for the landmarks point-location strategy.
|
/// \name Functor definitions for the landmarks point-location strategy.
|
||||||
//@{
|
//@{
|
||||||
typedef double Approximate_number_type;
|
using Approximate_number_type = double;
|
||||||
typedef CGAL::Cartesian<Approximate_number_type> Approximate_kernel;
|
using Approximate_kernel = CGAL::Simple_cartesian<Approximate_number_type>;
|
||||||
typedef Approximate_kernel::Point_2 Approximate_point_2;
|
using Approximate_point_2 = Approximate_kernel::Point_2;
|
||||||
|
|
||||||
class Approximate_2 {
|
class Approximate_2 {
|
||||||
protected:
|
protected:
|
||||||
|
|
@ -1545,8 +1493,7 @@ public:
|
||||||
* \return An approximation of `p`'s \f$x\f$-coordinate (if `i` == 0), or an
|
* \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).
|
* 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));
|
CGAL_precondition((i == 0) || (i == 1));
|
||||||
return (i == 0) ? CGAL::to_double(p.x()) : CGAL::to_double(p.y());
|
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();
|
auto max_vertex = m_traits.construct_max_vertex_2_object();
|
||||||
const auto& src = (l2r) ? min_vertex(xcv) : max_vertex(xcv);
|
const auto& src = (l2r) ? min_vertex(xcv) : max_vertex(xcv);
|
||||||
const auto& trg = (l2r) ? max_vertex(xcv) : min_vertex(xcv);
|
const auto& trg = (l2r) ? max_vertex(xcv) : min_vertex(xcv);
|
||||||
auto xs = CGAL::to_double(src.x());
|
*oi++ = operator()(src);
|
||||||
auto ys = CGAL::to_double(src.y());
|
*oi++ = operator()(trg);
|
||||||
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);
|
|
||||||
return oi;
|
return oi;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1580,8 +1523,7 @@ public:
|
||||||
template <typename OutputIterator>
|
template <typename OutputIterator>
|
||||||
OutputIterator operator()(const X_monotone_curve_2& xcv, double /* error */,
|
OutputIterator operator()(const X_monotone_curve_2& xcv, double /* error */,
|
||||||
OutputIterator oi, const Bbox_2& bbox,
|
OutputIterator oi, const Bbox_2& bbox,
|
||||||
bool l2r = true) const
|
bool l2r = true) const {
|
||||||
{
|
|
||||||
using Approx_pnt = Approximate_point_2;
|
using Approx_pnt = Approximate_point_2;
|
||||||
using Approx_seg = Approximate_kernel::Segment_2;
|
using Approx_seg = Approximate_kernel::Segment_2;
|
||||||
using Approx_ray = Approximate_kernel::Ray_2;
|
using Approx_ray = Approximate_kernel::Ray_2;
|
||||||
|
|
@ -1657,8 +1599,7 @@ public:
|
||||||
* \pre p and q must not be the same.
|
* \pre p and q must not be the same.
|
||||||
* \return A segment connecting `p` and `q`.
|
* \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;
|
Kernel kernel;
|
||||||
Segment_2 seg = kernel.construct_segment_2_object()(p, q);
|
Segment_2 seg = kernel.construct_segment_2_object()(p, q);
|
||||||
|
|
||||||
|
|
@ -1675,7 +1616,7 @@ public:
|
||||||
//@{
|
//@{
|
||||||
|
|
||||||
//! Functor
|
//! 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. */
|
/*! obtains a `Construct_curve_2` functor object. */
|
||||||
Construct_curve_2 construct_curve_2_object() const
|
Construct_curve_2 construct_curve_2_object() const
|
||||||
|
|
@ -1688,18 +1629,16 @@ public:
|
||||||
*/
|
*/
|
||||||
template <typename Kernel_>
|
template <typename Kernel_>
|
||||||
class Arr_linear_object_2 :
|
class Arr_linear_object_2 :
|
||||||
public Arr_linear_traits_2<Kernel_>::_Linear_object_cached_2
|
public Arr_linear_traits_2<Kernel_>::_Linear_object_cached_2 {
|
||||||
{
|
using Base = typename Arr_linear_traits_2<Kernel_>::_Linear_object_cached_2;
|
||||||
typedef typename Arr_linear_traits_2<Kernel_>::_Linear_object_cached_2
|
|
||||||
Base;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef Kernel_ Kernel;
|
using Kernel = Kernel_;
|
||||||
|
|
||||||
typedef typename Kernel::Point_2 Point_2;
|
using Point_2 = typename Kernel::Point_2;
|
||||||
typedef typename Kernel::Segment_2 Segment_2;
|
using Segment_2 = typename Kernel::Segment_2;
|
||||||
typedef typename Kernel::Ray_2 Ray_2;
|
using Ray_2 = typename Kernel::Ray_2;
|
||||||
typedef typename Kernel::Line_2 Line_2;
|
using Line_2 = typename Kernel::Line_2;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*! constructs default.
|
/*! constructs default.
|
||||||
|
|
@ -1739,8 +1678,7 @@ public:
|
||||||
/*! casts to a segment.
|
/*! casts to a segment.
|
||||||
* \pre The linear object is really a segment.
|
* \pre The linear object is really a segment.
|
||||||
*/
|
*/
|
||||||
Segment_2 segment() const
|
Segment_2 segment() const {
|
||||||
{
|
|
||||||
CGAL_precondition(is_segment());
|
CGAL_precondition(is_segment());
|
||||||
|
|
||||||
Kernel kernel;
|
Kernel kernel;
|
||||||
|
|
@ -1756,8 +1694,7 @@ public:
|
||||||
/*! casts to a ray.
|
/*! casts to a ray.
|
||||||
* \pre The linear object is really a ray.
|
* \pre The linear object is really a ray.
|
||||||
*/
|
*/
|
||||||
Ray_2 ray() const
|
Ray_2 ray() const {
|
||||||
{
|
|
||||||
CGAL_precondition(is_ray());
|
CGAL_precondition(is_ray());
|
||||||
|
|
||||||
Kernel kernel;
|
Kernel kernel;
|
||||||
|
|
@ -1776,8 +1713,7 @@ public:
|
||||||
/*! casts to a line.
|
/*! casts to a line.
|
||||||
* \pre The linear object is really a line.
|
* \pre The linear object is really a line.
|
||||||
*/
|
*/
|
||||||
Line_2 line() const
|
Line_2 line() const {
|
||||||
{
|
|
||||||
CGAL_precondition(is_line());
|
CGAL_precondition(is_line());
|
||||||
return (this->l);
|
return (this->l);
|
||||||
}
|
}
|
||||||
|
|
@ -1785,8 +1721,7 @@ public:
|
||||||
/*! obtains the supporting line.
|
/*! obtains the supporting line.
|
||||||
* \pre The object is not a point.
|
* \pre The object is not a point.
|
||||||
*/
|
*/
|
||||||
const Line_2& supporting_line() const
|
const Line_2& supporting_line() const {
|
||||||
{
|
|
||||||
CGAL_precondition(! this->is_degen);
|
CGAL_precondition(! this->is_degen);
|
||||||
return (this->l);
|
return (this->l);
|
||||||
}
|
}
|
||||||
|
|
@ -1794,8 +1729,7 @@ public:
|
||||||
/*! obtains the source point.
|
/*! obtains the source point.
|
||||||
* \pre The object is a point, a segment or a ray.
|
* \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());
|
CGAL_precondition(! is_line());
|
||||||
|
|
||||||
if (this->is_degen) return (this->ps); // For a point.
|
if (this->is_degen) return (this->ps); // For a point.
|
||||||
|
|
@ -1806,16 +1740,14 @@ public:
|
||||||
/*! obtains the target point.
|
/*! obtains the target point.
|
||||||
* \pre The object is a point or a segment.
|
* \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());
|
CGAL_precondition(! is_line() && ! is_ray());
|
||||||
return (this->pt);
|
return (this->pt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! creates a bounding box for the linear object.
|
/*! creates a bounding box for the linear object.
|
||||||
*/
|
*/
|
||||||
Bbox_2 bbox() const
|
Bbox_2 bbox() const {
|
||||||
{
|
|
||||||
CGAL_precondition(this->is_segment());
|
CGAL_precondition(this->is_segment());
|
||||||
Kernel kernel;
|
Kernel kernel;
|
||||||
Segment_2 seg = kernel.construct_segment_2_object()(this->ps, this->pt);
|
Segment_2 seg = kernel.construct_segment_2_object()(this->ps, this->pt);
|
||||||
|
|
@ -1834,8 +1766,7 @@ public:
|
||||||
*/
|
*/
|
||||||
template <typename Kernel, typename OutputStream>
|
template <typename Kernel, typename OutputStream>
|
||||||
OutputStream& operator<<(OutputStream& os,
|
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.
|
// Print a letter identifying the object type, then the object itself.
|
||||||
if (lobj.is_segment()) os << " S " << lobj.segment();
|
if (lobj.is_segment()) os << " S " << lobj.segment();
|
||||||
else if (lobj.is_ray()) os << " R " << lobj.ray();
|
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.
|
/*! Importer for the segment class used by the traits-class.
|
||||||
*/
|
*/
|
||||||
template <typename Kernel, typename InputStream>
|
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.
|
// Read the object type.
|
||||||
char c;
|
char c;
|
||||||
do {
|
do {
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@
|
||||||
* functors required by the concept it models.
|
* functors required by the concept it models.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <CGAL/Cartesian.h>
|
#include <CGAL/Simple_cartesian.h>
|
||||||
#include <CGAL/Algebraic_structure_traits.h>
|
#include <CGAL/Algebraic_structure_traits.h>
|
||||||
#include <CGAL/number_utils.h>
|
#include <CGAL/number_utils.h>
|
||||||
#include <CGAL/tags.h>
|
#include <CGAL/tags.h>
|
||||||
|
|
@ -44,34 +44,28 @@ namespace CGAL {
|
||||||
* A model of the AosBasicTraits_2 concept that handles \f$x\f$-monotone
|
* A model of the AosBasicTraits_2 concept that handles \f$x\f$-monotone
|
||||||
* non-intersecting line segments.
|
* non-intersecting line segments.
|
||||||
*/
|
*/
|
||||||
template <class T_Kernel>
|
template <typename T_Kernel>
|
||||||
class Arr_non_caching_segment_basic_traits_2 : public T_Kernel
|
class Arr_non_caching_segment_basic_traits_2 : public T_Kernel {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
using Kernel = T_Kernel;
|
||||||
typedef T_Kernel Kernel;
|
using FT = typename Kernel::FT;
|
||||||
|
|
||||||
typedef typename Kernel::FT FT;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef Algebraic_structure_traits<FT> AST;
|
using AST = Algebraic_structure_traits<FT>;
|
||||||
typedef typename AST::Is_exact FT_is_exact;
|
using FT_is_exact = typename AST::Is_exact;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
using Has_exact_division = Boolean_tag<FT_is_exact::value>;
|
||||||
typedef Boolean_tag<FT_is_exact::value> Has_exact_division;
|
using Segment_assertions = CGAL::Segment_assertions<Arr_non_caching_segment_basic_traits_2<Kernel>>;
|
||||||
|
|
||||||
typedef
|
|
||||||
CGAL::Segment_assertions<Arr_non_caching_segment_basic_traits_2<Kernel> >
|
|
||||||
Segment_assertions;
|
|
||||||
|
|
||||||
// Categories:
|
// Categories:
|
||||||
typedef Tag_true Has_left_category;
|
using Has_left_category = Tag_true;
|
||||||
typedef Tag_false Has_do_intersect_category;
|
using Has_do_intersect_category = Tag_false;
|
||||||
|
|
||||||
typedef Arr_oblivious_side_tag Left_side_category;
|
using Left_side_category = Arr_oblivious_side_tag;
|
||||||
typedef Arr_oblivious_side_tag Bottom_side_category;
|
using Bottom_side_category = Arr_oblivious_side_tag;
|
||||||
typedef Arr_oblivious_side_tag Top_side_category;
|
using Top_side_category = Arr_oblivious_side_tag;
|
||||||
typedef Arr_oblivious_side_tag Right_side_category;
|
using Right_side_category = Arr_oblivious_side_tag;
|
||||||
|
|
||||||
/*! constructs default */
|
/*! constructs default */
|
||||||
Arr_non_caching_segment_basic_traits_2() {}
|
Arr_non_caching_segment_basic_traits_2() {}
|
||||||
|
|
@ -80,30 +74,30 @@ public:
|
||||||
//@{
|
//@{
|
||||||
|
|
||||||
// Traits types:
|
// Traits types:
|
||||||
typedef typename Kernel::Point_2 Point_2;
|
using Point_2 = typename Kernel::Point_2;
|
||||||
typedef typename Kernel::Segment_2 X_monotone_curve_2;
|
using X_monotone_curve_2 = typename Kernel::Segment_2;
|
||||||
typedef unsigned int Multiplicity;
|
using Multiplicity = std::size_t;
|
||||||
|
|
||||||
/*! Compare the \f$x\f$-coordinates of two points. */
|
/*! compares the \f$x\f$-coordinates of two points. */
|
||||||
typedef typename Kernel::Compare_x_2 Compare_x_2;
|
using Compare_x_2 = typename Kernel::Compare_x_2;
|
||||||
|
|
||||||
/*! Compare two points lexigoraphically; by \f$x\f$, then by \f$y\f$. */
|
/*! compares two points lexigoraphically; by \f$x\f$, then by \f$y\f$. */
|
||||||
typedef typename Kernel::Compare_xy_2 Compare_xy_2;
|
using Compare_xy_2 = typename Kernel::Compare_xy_2;
|
||||||
|
|
||||||
/*! Obtain the left endpoint of a given segment. */
|
/*! obtains the left endpoint of a given segment. */
|
||||||
typedef typename Kernel::Construct_min_vertex_2 Construct_min_vertex_2;
|
using Construct_min_vertex_2 = typename Kernel::Construct_min_vertex_2;
|
||||||
|
|
||||||
/*! Obtain the right endpoint of a given segment. */
|
/*! obtains the right endpoint of a given segment. */
|
||||||
typedef typename Kernel::Construct_max_vertex_2 Construct_max_vertex_2;
|
using Construct_max_vertex_2 = typename Kernel::Construct_max_vertex_2;
|
||||||
|
|
||||||
/*! Check whether a given segment is vertical. */
|
/*! checks whether a given segment is vertical. */
|
||||||
typedef typename Kernel::Is_vertical_2 Is_vertical_2;
|
using Is_vertical_2 = typename Kernel::Is_vertical_2;
|
||||||
|
|
||||||
/*! Return the location of a given point with respect to an input segment. */
|
/*! returns 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;
|
using Compare_y_at_x_2 = typename Kernel::Compare_y_at_x_2;
|
||||||
|
|
||||||
/*! Check if two segments or if two points are identical. */
|
/*! checks if two segments or if two points are identical. */
|
||||||
typedef typename Kernel::Equal_2 Equal_2;
|
using Equal_2 = typename Kernel::Equal_2;
|
||||||
|
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
|
|
@ -127,8 +121,7 @@ public:
|
||||||
*/
|
*/
|
||||||
Comparison_result operator()(const X_monotone_curve_2& cv1,
|
Comparison_result operator()(const X_monotone_curve_2& cv1,
|
||||||
const X_monotone_curve_2& cv2,
|
const X_monotone_curve_2& cv2,
|
||||||
const Point_2& CGAL_precondition_code(p)) const
|
const Point_2& CGAL_precondition_code(p)) const {
|
||||||
{
|
|
||||||
Kernel kernel;
|
Kernel kernel;
|
||||||
|
|
||||||
// The two segments must be defined at q and also to its left.
|
// 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();
|
Compare_xy_2 compare_xy = kernel.compare_xy_2_object();
|
||||||
typename Kernel::Construct_vertex_2 construct_vertex =
|
typename Kernel::Construct_vertex_2 construct_vertex =
|
||||||
kernel.construct_vertex_2_object();
|
kernel.construct_vertex_2_object();
|
||||||
const Point_2 & source1 = construct_vertex(cv1, 0);
|
const Point_2& source1 = construct_vertex(cv1, 0);
|
||||||
const Point_2 & target1 = construct_vertex(cv1, 1);
|
const Point_2& target1 = construct_vertex(cv1, 1);
|
||||||
const Point_2 & left1 =
|
const Point_2& left1 =
|
||||||
(kernel.less_xy_2_object()(source1, target1)) ? source1 : target1;
|
(kernel.less_xy_2_object()(source1, target1)) ? source1 : target1;
|
||||||
const Point_2 & source2 = construct_vertex(cv2, 0);
|
const Point_2& source2 = construct_vertex(cv2, 0);
|
||||||
const Point_2 & target2 = construct_vertex(cv2, 1);
|
const Point_2& target2 = construct_vertex(cv2, 1);
|
||||||
const Point_2 & left2 =
|
const Point_2& left2 =
|
||||||
(kernel.less_xy_2_object()(source2, target2)) ? source2 : target2;
|
(kernel.less_xy_2_object()(source2, target2)) ? source2 : target2;
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -181,10 +174,9 @@ public:
|
||||||
* to the right of `p`: `SMALLER`, `LARGER`, or `EQUAL`.
|
* to the right of `p`: `SMALLER`, `LARGER`, or `EQUAL`.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Comparison_result operator()(const X_monotone_curve_2 & cv1,
|
Comparison_result operator()(const X_monotone_curve_2& cv1,
|
||||||
const X_monotone_curve_2 & cv2,
|
const X_monotone_curve_2& cv2,
|
||||||
const Point_2 & CGAL_precondition_code(p)) const
|
const Point_2& CGAL_precondition_code(p)) const {
|
||||||
{
|
|
||||||
Kernel kernel;
|
Kernel kernel;
|
||||||
|
|
||||||
// The two segments must be defined at q and also to its right.
|
// 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();
|
Compare_xy_2 compare_xy = kernel.compare_xy_2_object();
|
||||||
typename Kernel::Construct_vertex_2 construct_vertex =
|
typename Kernel::Construct_vertex_2 construct_vertex =
|
||||||
kernel.construct_vertex_2_object();
|
kernel.construct_vertex_2_object();
|
||||||
const Point_2 & source1 = construct_vertex(cv1, 0);
|
const Point_2& source1 = construct_vertex(cv1, 0);
|
||||||
const Point_2 & target1 = construct_vertex(cv1, 1);
|
const Point_2& target1 = construct_vertex(cv1, 1);
|
||||||
const Point_2 & right1 =
|
const Point_2& right1 =
|
||||||
(kernel.less_xy_2_object()(source1, target1)) ? target1 : source1;
|
(kernel.less_xy_2_object()(source1, target1)) ? target1 : source1;
|
||||||
const Point_2 & source2 = construct_vertex(cv2, 0);
|
const Point_2& source2 = construct_vertex(cv2, 0);
|
||||||
const Point_2 & target2 = construct_vertex(cv2, 1);
|
const Point_2& target2 = construct_vertex(cv2, 1);
|
||||||
const Point_2 & right2 =
|
const Point_2& right2 =
|
||||||
(kernel.less_xy_2_object()(source2, target2)) ? target2 : source2;
|
(kernel.less_xy_2_object()(source2, target2)) ? target2 : source2;
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -222,9 +214,9 @@ public:
|
||||||
|
|
||||||
/// \name Functor definitions for the landmarks point-location strategy.
|
/// \name Functor definitions for the landmarks point-location strategy.
|
||||||
//@{
|
//@{
|
||||||
typedef double Approximate_number_type;
|
using Approximate_number_type = double;
|
||||||
typedef CGAL::Cartesian<Approximate_number_type> Approximate_kernel;
|
using Approximate_kernel = CGAL::Simple_cartesian<Approximate_number_type>;
|
||||||
typedef Approximate_kernel::Point_2 Approximate_point_2;
|
using Approximate_point_2 = Approximate_kernel::Point_2;
|
||||||
|
|
||||||
class Approximate_2 {
|
class Approximate_2 {
|
||||||
protected:
|
protected:
|
||||||
|
|
@ -267,12 +259,8 @@ public:
|
||||||
auto max_vertex = m_traits.construct_max_vertex_2_object();
|
auto max_vertex = m_traits.construct_max_vertex_2_object();
|
||||||
const auto& src = (l2r) ? min_vertex(xcv) : max_vertex(xcv);
|
const auto& src = (l2r) ? min_vertex(xcv) : max_vertex(xcv);
|
||||||
const auto& trg = (l2r) ? max_vertex(xcv) : min_vertex(xcv);
|
const auto& trg = (l2r) ? max_vertex(xcv) : min_vertex(xcv);
|
||||||
auto xs = CGAL::to_double(src.x());
|
*oi++ = operator()(src);
|
||||||
auto ys = CGAL::to_double(src.y());
|
*oi++ = operator()(trg);
|
||||||
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);
|
|
||||||
return oi;
|
return oi;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -280,7 +268,7 @@ public:
|
||||||
/*! obtains an Approximate_2 functor object. */
|
/*! obtains an Approximate_2 functor object. */
|
||||||
Approximate_2 approximate_2_object () const { return Approximate_2(*this); }
|
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. */
|
/*! obtains a `Construct_x_monotone_curve_2` functor object. */
|
||||||
Construct_x_monotone_curve_2 construct_x_monotone_curve_2_object () const
|
Construct_x_monotone_curve_2 construct_x_monotone_curve_2_object () const
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@
|
||||||
#include <variant>
|
#include <variant>
|
||||||
|
|
||||||
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
||||||
#include <CGAL/Cartesian.h>
|
#include <CGAL/Simple_cartesian.h>
|
||||||
#include <CGAL/tags.h>
|
#include <CGAL/tags.h>
|
||||||
#include <CGAL/intersections.h>
|
#include <CGAL/intersections.h>
|
||||||
#include <CGAL/Arr_tags.h>
|
#include <CGAL/Arr_tags.h>
|
||||||
|
|
@ -52,35 +52,32 @@ class Arr_segment_2;
|
||||||
template <typename Kernel_ = Exact_predicates_exact_constructions_kernel>
|
template <typename Kernel_ = Exact_predicates_exact_constructions_kernel>
|
||||||
class Arr_segment_traits_2 : public Kernel_ {
|
class Arr_segment_traits_2 : public Kernel_ {
|
||||||
friend class Arr_segment_2<Kernel_>;
|
friend class Arr_segment_2<Kernel_>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef Kernel_ Kernel;
|
using Kernel = Kernel_;
|
||||||
typedef typename Kernel::FT FT;
|
using FT = typename Kernel::FT;
|
||||||
|
|
||||||
typedef typename Algebraic_structure_traits<FT>::Is_exact
|
using Has_exact_division = typename Algebraic_structure_traits<FT>::Is_exact;
|
||||||
Has_exact_division;
|
|
||||||
|
|
||||||
// Category tags:
|
// Category tags:
|
||||||
typedef Tag_true Has_left_category;
|
using Has_left_category = Tag_true;
|
||||||
typedef Tag_true Has_merge_category;
|
using Has_merge_category = Tag_true;
|
||||||
typedef Tag_false Has_do_intersect_category;
|
using Has_do_intersect_category = Tag_false;
|
||||||
|
|
||||||
typedef Arr_oblivious_side_tag Left_side_category;
|
using Left_side_category = Arr_oblivious_side_tag;
|
||||||
typedef Arr_oblivious_side_tag Bottom_side_category;
|
using Bottom_side_category = Arr_oblivious_side_tag;
|
||||||
typedef Arr_oblivious_side_tag Top_side_category;
|
using Top_side_category = Arr_oblivious_side_tag;
|
||||||
typedef Arr_oblivious_side_tag Right_side_category;
|
using Right_side_category = Arr_oblivious_side_tag;
|
||||||
|
|
||||||
typedef typename Kernel::Line_2 Line_2;
|
using Line_2 = typename Kernel::Line_2;
|
||||||
typedef CGAL::Segment_assertions<Arr_segment_traits_2<Kernel> >
|
using Segment_assertions = CGAL::Segment_assertions<Arr_segment_traits_2<Kernel>>;
|
||||||
Segment_assertions;
|
|
||||||
|
|
||||||
/*! \class Representation of a segment with cached data.
|
/*! \class Representation of a segment with cached data.
|
||||||
*/
|
*/
|
||||||
class _Segment_cached_2 {
|
class _Segment_cached_2 {
|
||||||
public:
|
public:
|
||||||
typedef typename Kernel::Line_2 Line_2;
|
using Line_2 = typename Kernel::Line_2;
|
||||||
typedef typename Kernel::Segment_2 Segment_2;
|
using Segment_2 = typename Kernel::Segment_2;
|
||||||
typedef typename Kernel::Point_2 Point_2;
|
using Point_2 = typename Kernel::Point_2;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
mutable Line_2 m_l; // the line that supports the segment.
|
mutable Line_2 m_l; // the line that supports the segment.
|
||||||
|
|
@ -228,10 +225,10 @@ public:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Traits objects
|
// Traits objects
|
||||||
typedef typename Kernel::Point_2 Point_2;
|
using Point_2 = typename Kernel::Point_2;
|
||||||
typedef Arr_segment_2<Kernel> X_monotone_curve_2;
|
using X_monotone_curve_2 = Arr_segment_2<Kernel>;
|
||||||
typedef Arr_segment_2<Kernel> Curve_2;
|
using Curve_2 = Arr_segment_2<Kernel>;
|
||||||
typedef unsigned int Multiplicity;
|
using Multiplicity = std::size_t;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*! constructs default. */
|
/*! constructs default. */
|
||||||
|
|
@ -242,7 +239,7 @@ public:
|
||||||
|
|
||||||
class Compare_x_2 {
|
class Compare_x_2 {
|
||||||
protected:
|
protected:
|
||||||
typedef Arr_segment_traits_2<Kernel> Traits;
|
using Traits = Arr_segment_traits_2<Kernel>;
|
||||||
|
|
||||||
//! The traits (in case it has state).
|
//! The traits (in case it has state).
|
||||||
const Traits& m_traits;
|
const Traits& m_traits;
|
||||||
|
|
@ -262,8 +259,7 @@ public:
|
||||||
* `SMALLER` if x(p1) < x(p2);
|
* `SMALLER` if x(p1) < x(p2);
|
||||||
* `EQUAL` 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;
|
const Kernel& kernel = m_traits;
|
||||||
return (kernel.compare_x_2_object()(p1, p2));
|
return (kernel.compare_x_2_object()(p1, p2));
|
||||||
}
|
}
|
||||||
|
|
@ -274,7 +270,7 @@ public:
|
||||||
|
|
||||||
class Compare_xy_2 {
|
class Compare_xy_2 {
|
||||||
protected:
|
protected:
|
||||||
typedef Arr_segment_traits_2<Kernel> Traits;
|
using Traits = Arr_segment_traits_2<Kernel>;
|
||||||
|
|
||||||
/*! The traits (in case it has state) */
|
/*! The traits (in case it has state) */
|
||||||
const Traits& m_traits;
|
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);
|
* SMALLER if x(p1) < x(p2), or if x(p1) = x(p2) and y(p1) < y(p2);
|
||||||
* EQUAL if the two points are equal.
|
* 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;
|
const Kernel& kernel = m_traits;
|
||||||
return (kernel.compare_xy_2_object()(p1, p2));
|
return (kernel.compare_xy_2_object()(p1, p2));
|
||||||
}
|
}
|
||||||
|
|
@ -347,7 +342,7 @@ public:
|
||||||
|
|
||||||
class Compare_y_at_x_2 {
|
class Compare_y_at_x_2 {
|
||||||
protected:
|
protected:
|
||||||
typedef Arr_segment_traits_2<Kernel> Traits;
|
using Traits = Arr_segment_traits_2<Kernel>;
|
||||||
|
|
||||||
/*! The traits (in case it has state) */
|
/*! The traits (in case it has state) */
|
||||||
const Traits& m_traits;
|
const Traits& m_traits;
|
||||||
|
|
@ -369,8 +364,7 @@ public:
|
||||||
* `EQUAL` if `p` lies on the curve.
|
* `EQUAL` if `p` lies on the curve.
|
||||||
*/
|
*/
|
||||||
Comparison_result operator()(const Point_2& p,
|
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));
|
CGAL_precondition(m_traits.is_in_x_range_2_object()(cv, p));
|
||||||
|
|
||||||
const Kernel& kernel = m_traits;
|
const Kernel& kernel = m_traits;
|
||||||
|
|
@ -396,7 +390,7 @@ public:
|
||||||
|
|
||||||
class Compare_y_at_x_left_2 {
|
class Compare_y_at_x_left_2 {
|
||||||
protected:
|
protected:
|
||||||
typedef Arr_segment_traits_2<Kernel> Traits;
|
using Traits = Arr_segment_traits_2<Kernel>;
|
||||||
|
|
||||||
/*! The traits (in case it has state) */
|
/*! The traits (in case it has state) */
|
||||||
const Traits& m_traits;
|
const Traits& m_traits;
|
||||||
|
|
@ -421,8 +415,7 @@ public:
|
||||||
*/
|
*/
|
||||||
Comparison_result operator()(const X_monotone_curve_2& cv1,
|
Comparison_result operator()(const X_monotone_curve_2& cv1,
|
||||||
const X_monotone_curve_2& cv2,
|
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;
|
const Kernel& kernel = m_traits;
|
||||||
|
|
||||||
// Make sure that p lies on both curves, and that both are defined to its
|
// 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 {
|
class Compare_y_at_x_right_2 {
|
||||||
protected:
|
protected:
|
||||||
typedef Arr_segment_traits_2<Kernel> Traits;
|
using Traits = Arr_segment_traits_2<Kernel>;
|
||||||
|
|
||||||
/*! The traits (in case it has state) */
|
/*! The traits (in case it has state) */
|
||||||
const Traits& m_traits;
|
const Traits& m_traits;
|
||||||
|
|
@ -475,8 +468,7 @@ public:
|
||||||
*/
|
*/
|
||||||
Comparison_result operator()(const X_monotone_curve_2& cv1,
|
Comparison_result operator()(const X_monotone_curve_2& cv1,
|
||||||
const X_monotone_curve_2& cv2,
|
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;
|
const Kernel& kernel = m_traits;
|
||||||
|
|
||||||
// Make sure that p lies on both curves, and that both are defined to its
|
// Make sure that p lies on both curves, and that both are defined to its
|
||||||
|
|
@ -502,7 +494,7 @@ public:
|
||||||
|
|
||||||
class Equal_2 {
|
class Equal_2 {
|
||||||
protected:
|
protected:
|
||||||
typedef Arr_segment_traits_2<Kernel> Traits;
|
using Traits = Arr_segment_traits_2<Kernel>;
|
||||||
|
|
||||||
/*! The traits (in case it has state) */
|
/*! The traits (in case it has state) */
|
||||||
const Traits& m_traits;
|
const Traits& m_traits;
|
||||||
|
|
@ -522,8 +514,7 @@ public:
|
||||||
* \return (true) if the two curves are the same; (false) otherwise.
|
* \return (true) if the two curves are the same; (false) otherwise.
|
||||||
*/
|
*/
|
||||||
bool operator()(const X_monotone_curve_2& cv1,
|
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;
|
const Kernel& kernel = m_traits;
|
||||||
typename Kernel::Equal_2 equal = kernel.equal_2_object();
|
typename Kernel::Equal_2 equal = kernel.equal_2_object();
|
||||||
|
|
||||||
|
|
@ -536,8 +527,7 @@ public:
|
||||||
* \param p2 the second point.
|
* \param p2 the second point.
|
||||||
* \return (true) if the two point are the same; (false) otherwise.
|
* \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;
|
const Kernel& kernel = m_traits;
|
||||||
return (kernel.equal_2_object()(p1, p2));
|
return (kernel.equal_2_object()(p1, p2));
|
||||||
}
|
}
|
||||||
|
|
@ -566,11 +556,9 @@ public:
|
||||||
* \return the past-the-end output iterator.
|
* \return the past-the-end output iterator.
|
||||||
*/
|
*/
|
||||||
template <typename OutputIterator>
|
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.
|
// Wrap the segment with a variant.
|
||||||
typedef std::variant<Point_2, X_monotone_curve_2>
|
using Make_x_monotone_result = std::variant<Point_2, X_monotone_curve_2>;
|
||||||
Make_x_monotone_result;
|
|
||||||
*oi++ = Make_x_monotone_result(cv);
|
*oi++ = Make_x_monotone_result(cv);
|
||||||
return oi;
|
return oi;
|
||||||
}
|
}
|
||||||
|
|
@ -582,7 +570,7 @@ public:
|
||||||
|
|
||||||
class Split_2 {
|
class Split_2 {
|
||||||
protected:
|
protected:
|
||||||
typedef Arr_segment_traits_2<Kernel> Traits;
|
using Traits = Arr_segment_traits_2<Kernel>;
|
||||||
|
|
||||||
/*! The traits (in case it has state) */
|
/*! The traits (in case it has state) */
|
||||||
const Traits& m_traits;
|
const Traits& m_traits;
|
||||||
|
|
@ -595,7 +583,7 @@ public:
|
||||||
friend class Arr_segment_traits_2<Kernel>;
|
friend class Arr_segment_traits_2<Kernel>;
|
||||||
|
|
||||||
public:
|
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.
|
* sub-curves.
|
||||||
* \param cv the curve to split
|
* \param cv the curve to split
|
||||||
* \param p the split point.
|
* \param p the split point.
|
||||||
|
|
@ -604,8 +592,7 @@ public:
|
||||||
* \pre `p` lies on cv but is not one of its endpoints.
|
* \pre `p` lies on cv but is not one of its endpoints.
|
||||||
*/
|
*/
|
||||||
void operator()(const X_monotone_curve_2& cv, const Point_2& p,
|
void operator()(const X_monotone_curve_2& cv, const Point_2& p,
|
||||||
X_monotone_curve_2& c1, X_monotone_curve_2& c2) const
|
X_monotone_curve_2& c1, X_monotone_curve_2& c2) const {
|
||||||
{
|
|
||||||
// Make sure that p lies on the interior of the curve.
|
// Make sure that p lies on the interior of the curve.
|
||||||
CGAL_precondition_code(const Kernel& kernel = m_traits;
|
CGAL_precondition_code(const Kernel& kernel = m_traits;
|
||||||
auto compare_xy = kernel.compare_xy_2_object());
|
auto compare_xy = kernel.compare_xy_2_object());
|
||||||
|
|
@ -628,7 +615,7 @@ public:
|
||||||
|
|
||||||
class Intersect_2 {
|
class Intersect_2 {
|
||||||
protected:
|
protected:
|
||||||
typedef Arr_segment_traits_2<Kernel> Traits;
|
using Traits = Arr_segment_traits_2<Kernel>;
|
||||||
|
|
||||||
/*! The traits (in case it has state) */
|
/*! The traits (in case it has state) */
|
||||||
const Traits& m_traits;
|
const Traits& m_traits;
|
||||||
|
|
@ -644,8 +631,7 @@ public:
|
||||||
// this point, we already know which point is left / right for
|
// this point, we already know which point is left / right for
|
||||||
// both segments
|
// both segments
|
||||||
bool do_intersect(const Point_2& A1, const Point_2& A2,
|
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;
|
const Kernel& kernel = m_traits;
|
||||||
auto compare_xy = kernel.compare_xy_2_object();
|
auto compare_xy = kernel.compare_xy_2_object();
|
||||||
namespace interx = CGAL::Intersections::internal;
|
namespace interx = CGAL::Intersections::internal;
|
||||||
|
|
@ -686,8 +672,7 @@ public:
|
||||||
/*! determines whether the bounding boxes of two segments overlap
|
/*! determines whether the bounding boxes of two segments overlap
|
||||||
*/
|
*/
|
||||||
bool do_bboxes_overlap(const X_monotone_curve_2& cv1,
|
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;
|
const Kernel& kernel = m_traits;
|
||||||
auto construct_bbox = kernel.construct_bbox_2_object();
|
auto construct_bbox = kernel.construct_bbox_2_object();
|
||||||
auto bbox1 = construct_bbox(cv1.source()) + construct_bbox(cv1.target());
|
auto bbox1 = construct_bbox(cv1.source()) + construct_bbox(cv1.target());
|
||||||
|
|
@ -707,9 +692,8 @@ public:
|
||||||
template <typename OutputIterator>
|
template <typename OutputIterator>
|
||||||
OutputIterator operator()(const X_monotone_curve_2& cv1,
|
OutputIterator operator()(const X_monotone_curve_2& cv1,
|
||||||
const X_monotone_curve_2& cv2,
|
const X_monotone_curve_2& cv2,
|
||||||
OutputIterator oi) const
|
OutputIterator oi) const {
|
||||||
{
|
using Intersection_point = std::pair<Point_2, Multiplicity>;
|
||||||
typedef std::pair<Point_2, Multiplicity> Intersection_point;
|
|
||||||
|
|
||||||
// Early ending with Bbox overlapping test
|
// Early ending with Bbox overlapping test
|
||||||
if (! do_bboxes_overlap(cv1, cv2)) return oi;
|
if (! do_bboxes_overlap(cv1, cv2)) return oi;
|
||||||
|
|
@ -787,7 +771,7 @@ public:
|
||||||
|
|
||||||
class Are_mergeable_2 {
|
class Are_mergeable_2 {
|
||||||
protected:
|
protected:
|
||||||
typedef Arr_segment_traits_2<Kernel> Traits;
|
using Traits = Arr_segment_traits_2<Kernel>;
|
||||||
|
|
||||||
/*! The traits (in case it has state) */
|
/*! The traits (in case it has state) */
|
||||||
const Traits& m_traits;
|
const Traits& m_traits;
|
||||||
|
|
@ -808,8 +792,7 @@ public:
|
||||||
* \pre `cv1` and `cv2` share a common endpoint.
|
* \pre `cv1` and `cv2` share a common endpoint.
|
||||||
*/
|
*/
|
||||||
bool operator()(const X_monotone_curve_2& cv1,
|
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;
|
const Kernel& kernel = m_traits;
|
||||||
typename Kernel::Equal_2 equal = kernel.equal_2_object();
|
typename Kernel::Equal_2 equal = kernel.equal_2_object();
|
||||||
if (! equal(cv1.right(), cv2.left()) &&
|
if (! equal(cv1.right(), cv2.left()) &&
|
||||||
|
|
@ -832,7 +815,7 @@ public:
|
||||||
*/
|
*/
|
||||||
class Merge_2 {
|
class Merge_2 {
|
||||||
protected:
|
protected:
|
||||||
typedef Arr_segment_traits_2<Kernel> Traits;
|
using Traits = Arr_segment_traits_2<Kernel>;
|
||||||
|
|
||||||
/*! The traits (in case it has state) */
|
/*! The traits (in case it has state) */
|
||||||
const Traits& m_traits;
|
const Traits& m_traits;
|
||||||
|
|
@ -853,14 +836,13 @@ public:
|
||||||
*/
|
*/
|
||||||
void operator()(const X_monotone_curve_2& cv1,
|
void operator()(const X_monotone_curve_2& cv1,
|
||||||
const X_monotone_curve_2& cv2,
|
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));
|
CGAL_precondition(m_traits.are_mergeable_2_object()(cv1, cv2));
|
||||||
|
|
||||||
const Kernel& kernel = m_traits;
|
const Kernel& kernel = m_traits;
|
||||||
auto equal = kernel.equal_2_object();
|
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())) {
|
if (equal(cv1.right(), cv2.left())) {
|
||||||
// cv2 extends cv1 to the right.
|
// cv2 extends cv1 to the right.
|
||||||
c = cv1;
|
c = cv1;
|
||||||
|
|
@ -882,9 +864,9 @@ public:
|
||||||
|
|
||||||
/// \name Functor definitions for the landmarks point-location strategy.
|
/// \name Functor definitions for the landmarks point-location strategy.
|
||||||
//@{
|
//@{
|
||||||
typedef double Approximate_number_type;
|
using Approximate_number_type = double;
|
||||||
typedef CGAL::Cartesian<Approximate_number_type> Approximate_kernel;
|
using Approximate_kernel = CGAL::Simple_cartesian<Approximate_number_type>;
|
||||||
typedef Approximate_kernel::Point_2 Approximate_point_2;
|
using Approximate_point_2 = Approximate_kernel::Point_2;
|
||||||
|
|
||||||
class Approximate_2 {
|
class Approximate_2 {
|
||||||
protected:
|
protected:
|
||||||
|
|
@ -927,12 +909,8 @@ public:
|
||||||
auto max_vertex = m_traits.construct_max_vertex_2_object();
|
auto max_vertex = m_traits.construct_max_vertex_2_object();
|
||||||
const auto& src = (l2r) ? min_vertex(xcv) : max_vertex(xcv);
|
const auto& src = (l2r) ? min_vertex(xcv) : max_vertex(xcv);
|
||||||
const auto& trg = (l2r) ? max_vertex(xcv) : min_vertex(xcv);
|
const auto& trg = (l2r) ? max_vertex(xcv) : min_vertex(xcv);
|
||||||
auto xs = CGAL::to_double(src.x());
|
*oi++ = operator()(src);
|
||||||
auto ys = CGAL::to_double(src.y());
|
*oi++ = operator()(trg);
|
||||||
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);
|
|
||||||
return oi;
|
return oi;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -943,7 +921,7 @@ public:
|
||||||
//! Functor
|
//! Functor
|
||||||
class Construct_x_monotone_curve_2 {
|
class Construct_x_monotone_curve_2 {
|
||||||
protected:
|
protected:
|
||||||
typedef Arr_segment_traits_2<Kernel> Traits;
|
using Traits = Arr_segment_traits_2<Kernel>;
|
||||||
|
|
||||||
//! The traits (in case it has state).
|
//! The traits (in case it has state).
|
||||||
const Traits& m_traits;
|
const Traits& m_traits;
|
||||||
|
|
@ -956,7 +934,7 @@ public:
|
||||||
friend class Arr_segment_traits_2<Kernel>;
|
friend class Arr_segment_traits_2<Kernel>;
|
||||||
|
|
||||||
public:
|
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.
|
/*! obtains an \f$x\f$-monotone curve connecting two given endpoints.
|
||||||
* \param source the first point.
|
* \param source the first point.
|
||||||
|
|
@ -965,8 +943,7 @@ public:
|
||||||
* \return a segment connecting `source` and `target`.
|
* \return a segment connecting `source` and `target`.
|
||||||
*/
|
*/
|
||||||
X_monotone_curve_2 operator()(const Point_2& source,
|
X_monotone_curve_2 operator()(const Point_2& source,
|
||||||
const Point_2& target) const
|
const Point_2& target) const {
|
||||||
{
|
|
||||||
const Kernel& kernel = m_traits;
|
const Kernel& kernel = m_traits;
|
||||||
auto line = kernel.construct_line_2_object()(source, target);
|
auto line = kernel.construct_line_2_object()(source, target);
|
||||||
Comparison_result res = kernel.compare_xy_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.
|
* \pre the segment is not degenerate.
|
||||||
* \return a segment that is the same as `seg`..
|
* \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;
|
const Kernel& kernel = m_traits;
|
||||||
auto line = kernel.construct_line_2_object()(seg);
|
auto line = kernel.construct_line_2_object()(seg);
|
||||||
auto vertex_ctr = kernel.construct_vertex_2_object();
|
auto vertex_ctr = kernel.construct_vertex_2_object();
|
||||||
|
|
@ -1011,8 +987,7 @@ public:
|
||||||
*/
|
*/
|
||||||
X_monotone_curve_2 operator()(const Line_2& line,
|
X_monotone_curve_2 operator()(const Line_2& line,
|
||||||
const Point_2& source,
|
const Point_2& source,
|
||||||
const Point_2& target) const
|
const Point_2& target) const {
|
||||||
{
|
|
||||||
const Kernel& kernel = m_traits;
|
const Kernel& kernel = m_traits;
|
||||||
CGAL_precondition
|
CGAL_precondition
|
||||||
(Segment_assertions::_assert_is_point_on(source, line,
|
(Segment_assertions::_assert_is_point_on(source, line,
|
||||||
|
|
@ -1039,7 +1014,7 @@ public:
|
||||||
//@{
|
//@{
|
||||||
|
|
||||||
//! Functor
|
//! 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. */
|
/*! obtains a `Construct_curve_2` functor object. */
|
||||||
Construct_curve_2 construct_curve_2_object() const
|
Construct_curve_2 construct_curve_2_object() const
|
||||||
|
|
@ -1051,7 +1026,7 @@ public:
|
||||||
|
|
||||||
class Trim_2 {
|
class Trim_2 {
|
||||||
protected:
|
protected:
|
||||||
typedef Arr_segment_traits_2<Kernel> Traits;
|
using Traits = Arr_segment_traits_2<Kernel>;
|
||||||
|
|
||||||
/*! The traits (in case it has state). */
|
/*! The traits (in case it has state). */
|
||||||
const Traits& m_traits;
|
const Traits& m_traits;
|
||||||
|
|
@ -1074,8 +1049,7 @@ public:
|
||||||
public:
|
public:
|
||||||
X_monotone_curve_2 operator()(const X_monotone_curve_2& xcv,
|
X_monotone_curve_2 operator()(const X_monotone_curve_2& xcv,
|
||||||
const Point_2& src,
|
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(Equal_2 equal = m_traits.equal_2_object());
|
||||||
CGAL_precondition_code(Compare_y_at_x_2 compare_y_at_x =
|
CGAL_precondition_code(Compare_y_at_x_2 compare_y_at_x =
|
||||||
m_traits.compare_y_at_x_2_object());
|
m_traits.compare_y_at_x_2_object());
|
||||||
|
|
@ -1119,7 +1093,7 @@ public:
|
||||||
|
|
||||||
class Construct_opposite_2 {
|
class Construct_opposite_2 {
|
||||||
public:
|
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.
|
* \param cv the curve.
|
||||||
* \return the opposite curve.
|
* \return the opposite curve.
|
||||||
*/
|
*/
|
||||||
|
|
@ -1137,12 +1111,12 @@ public:
|
||||||
|
|
||||||
class Is_in_x_range_2 {
|
class Is_in_x_range_2 {
|
||||||
protected:
|
protected:
|
||||||
typedef Arr_segment_traits_2<Kernel> Traits;
|
using Traits = Arr_segment_traits_2<Kernel>;
|
||||||
|
|
||||||
//! The traits (in case it has state).
|
//! The traits (in case it has state).
|
||||||
const Traits& m_traits;
|
const Traits& m_traits;
|
||||||
|
|
||||||
/*! Construct
|
/*! constructs
|
||||||
* \param traits the traits (in case it has state)
|
* \param traits the traits (in case it has state)
|
||||||
*/
|
*/
|
||||||
Is_in_x_range_2(const Traits& traits) : m_traits(traits) {}
|
Is_in_x_range_2(const Traits& traits) : m_traits(traits) {}
|
||||||
|
|
@ -1156,8 +1130,7 @@ public:
|
||||||
* \param p the point.
|
* \param p the point.
|
||||||
* \return true if p is in the \f$x\f$-range of cv; false otherwise.
|
* \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;
|
const Kernel& kernel = m_traits;
|
||||||
auto compare_x = kernel.compare_x_2_object();
|
auto compare_x = kernel.compare_x_2_object();
|
||||||
Comparison_result res1 = compare_x(p, cv.left());
|
Comparison_result res1 = compare_x(p, cv.left());
|
||||||
|
|
@ -1176,7 +1149,7 @@ public:
|
||||||
|
|
||||||
class Is_in_y_range_2 {
|
class Is_in_y_range_2 {
|
||||||
protected:
|
protected:
|
||||||
typedef Arr_segment_traits_2<Kernel> Traits;
|
using Traits = Arr_segment_traits_2<Kernel>;
|
||||||
|
|
||||||
//! The traits (in case it has state).
|
//! The traits (in case it has state).
|
||||||
const Traits& m_traits;
|
const Traits& m_traits;
|
||||||
|
|
@ -1195,8 +1168,7 @@ public:
|
||||||
* \param p the point.
|
* \param p the point.
|
||||||
* \return true if p is in the \f$y\f$-range of cv; false otherwise.
|
* \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;
|
const Kernel& kernel = m_traits;
|
||||||
auto compare_y = kernel.compare_y_2_object();
|
auto compare_y = kernel.compare_y_2_object();
|
||||||
Comparison_result res1 = compare_y(p, cv.left());
|
Comparison_result res1 = compare_y(p, cv.left());
|
||||||
|
|
@ -1232,8 +1204,7 @@ template <typename Kernel>
|
||||||
Arr_segment_traits_2<Kernel>::
|
Arr_segment_traits_2<Kernel>::
|
||||||
_Segment_cached_2::_Segment_cached_2(const Segment_2& seg) :
|
_Segment_cached_2::_Segment_cached_2(const Segment_2& seg) :
|
||||||
m_is_vert(false),
|
m_is_vert(false),
|
||||||
m_is_computed(false)
|
m_is_computed(false) {
|
||||||
{
|
|
||||||
Kernel kernel;
|
Kernel kernel;
|
||||||
auto vertex_ctr = kernel.construct_vertex_2_object();
|
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_ps(source),
|
||||||
m_pt(target),
|
m_pt(target),
|
||||||
m_is_vert(false),
|
m_is_vert(false),
|
||||||
m_is_computed(false)
|
m_is_computed(false) {
|
||||||
{
|
|
||||||
Kernel kernel;
|
Kernel kernel;
|
||||||
|
|
||||||
Comparison_result res = kernel.compare_xy_2_object()(m_ps, m_pt);
|
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) :
|
const Point_2& target) :
|
||||||
m_l(line),
|
m_l(line),
|
||||||
m_ps(source),
|
m_ps(source),
|
||||||
m_pt(target)
|
m_pt(target) {
|
||||||
{
|
|
||||||
Kernel kernel;
|
Kernel kernel;
|
||||||
|
|
||||||
CGAL_precondition
|
CGAL_precondition
|
||||||
|
|
@ -1312,8 +1281,7 @@ _Segment_cached_2(const Line_2& line,
|
||||||
//! \brief assigns.
|
//! \brief assigns.
|
||||||
template <typename Kernel>
|
template <typename Kernel>
|
||||||
const typename Arr_segment_traits_2<Kernel>::_Segment_cached_2&
|
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;
|
Kernel kernel;
|
||||||
auto vertex_ctr = kernel.construct_vertex_2_object();
|
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.
|
//! \brief obtains the supporting line.
|
||||||
template <typename Kernel>
|
template <typename Kernel>
|
||||||
const typename Kernel::Line_2&
|
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) {
|
if (!m_is_computed) {
|
||||||
Kernel kernel;
|
Kernel kernel;
|
||||||
m_l = kernel.construct_line_2_object()(m_ps, m_pt);
|
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.
|
//! \brief determines whether the curve is vertical.
|
||||||
template <typename Kernel>
|
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
|
// Force computation of line is orientation is still unknown
|
||||||
if (! m_is_computed) line();
|
if (! m_is_computed) line();
|
||||||
CGAL_precondition(!m_is_degen);
|
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.
|
//! \brief sets the (lexicographically) left endpoint.
|
||||||
template <typename Kernel>
|
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(! m_is_degen);
|
||||||
CGAL_precondition_code(Kernel kernel);
|
CGAL_precondition_code(Kernel kernel);
|
||||||
CGAL_precondition
|
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.
|
//! \brief sets the (lexicographically) right endpoint.
|
||||||
template <typename Kernel>
|
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(! m_is_degen);
|
||||||
CGAL_precondition_code(Kernel kernel);
|
CGAL_precondition_code(Kernel kernel);
|
||||||
CGAL_precondition
|
CGAL_precondition
|
||||||
|
|
@ -1428,8 +1392,7 @@ void Arr_segment_traits_2<Kernel>::_Segment_cached_2::set_right(const Point_2& p
|
||||||
*/
|
*/
|
||||||
template <typename Kernel>
|
template <typename Kernel>
|
||||||
bool Arr_segment_traits_2<Kernel>::_Segment_cached_2::
|
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;
|
Kernel kernel;
|
||||||
typename Kernel::Compare_x_2 compare_x = kernel.compare_x_2_object();
|
typename Kernel::Compare_x_2 compare_x = kernel.compare_x_2_object();
|
||||||
const Comparison_result res1 = compare_x(p, left());
|
const Comparison_result res1 = compare_x(p, left());
|
||||||
|
|
@ -1446,8 +1409,7 @@ is_in_x_range(const Point_2& p) const
|
||||||
*/
|
*/
|
||||||
template <typename Kernel>
|
template <typename Kernel>
|
||||||
bool Arr_segment_traits_2<Kernel>::_Segment_cached_2::
|
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;
|
Kernel kernel;
|
||||||
typename Kernel::Compare_y_2 compare_y = kernel.compare_y_2_object();
|
typename Kernel::Compare_y_2 compare_y = kernel.compare_y_2_object();
|
||||||
const Comparison_result res1 = compare_y(p, left());
|
const Comparison_result res1 = compare_y(p, left());
|
||||||
|
|
@ -1464,31 +1426,31 @@ is_in_y_range(const Point_2& p) const
|
||||||
*/
|
*/
|
||||||
template <typename Kernel_>
|
template <typename Kernel_>
|
||||||
class Arr_segment_2 : public Arr_segment_traits_2<Kernel_>::_Segment_cached_2 {
|
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;
|
using Base = typename Arr_segment_traits_2<Kernel>::_Segment_cached_2;
|
||||||
typedef typename Kernel::Segment_2 Segment_2;
|
using Segment_2 = typename Kernel::Segment_2;
|
||||||
typedef typename Kernel::Point_2 Point_2;
|
using Point_2 = typename Kernel::Point_2;
|
||||||
typedef typename Kernel::Line_2 Line_2;
|
using Line_2 = typename Kernel::Line_2;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*! Construct default. */
|
/*! constructs default. */
|
||||||
Arr_segment_2();
|
Arr_segment_2();
|
||||||
|
|
||||||
/*! Construct a segment from a "kernel" segment.
|
/*! constructs a segment from a "kernel" segment.
|
||||||
* \param seg the segment.
|
* \param seg the segment.
|
||||||
* \pre the segment is not degenerate.
|
* \pre the segment is not degenerate.
|
||||||
*/
|
*/
|
||||||
Arr_segment_2(const Segment_2& seg);
|
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 source the source point.
|
||||||
* \param target the target point.
|
* \param target the target point.
|
||||||
* \pre `source` and `target` are not equal.
|
* \pre `source` and `target` are not equal.
|
||||||
*/
|
*/
|
||||||
Arr_segment_2(const Point_2& source, const Point_2& target);
|
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 line the supporting line.
|
||||||
* \param source the source point.
|
* \param source the source point.
|
||||||
* \param target the target point.
|
* \param target the target point.
|
||||||
|
|
@ -1498,7 +1460,7 @@ public:
|
||||||
Arr_segment_2(const Line_2& line,
|
Arr_segment_2(const Line_2& line,
|
||||||
const Point_2& source, const Point_2& target);
|
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 line the supporting line.
|
||||||
* \param source the source point.
|
* \param source the source point.
|
||||||
* \param target the target point.
|
* \param target the target point.
|
||||||
|
|
@ -1510,11 +1472,11 @@ public:
|
||||||
const Point_2& source, const Point_2& target,
|
const Point_2& source, const Point_2& target,
|
||||||
bool is_directed_right, bool is_vert, bool is_degen);
|
bool is_directed_right, bool is_vert, bool is_degen);
|
||||||
|
|
||||||
/*! Cast to a segment.
|
/*! casts to a segment.
|
||||||
*/
|
*/
|
||||||
operator Segment_2() const;
|
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;
|
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.
|
//! \brief casts to a segment.
|
||||||
template <typename Kernel>
|
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;
|
Kernel kernel;
|
||||||
auto seg_ctr = kernel.construct_segment_2_object();
|
auto seg_ctr = kernel.construct_segment_2_object();
|
||||||
return seg_ctr(this->source(), this->target());
|
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).
|
//! \brief flips the segment (swap its source and target).
|
||||||
template <typename Kernel>
|
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(),
|
return Arr_segment_2(this->line(), this->target(), this->source(),
|
||||||
! (this->is_directed_right()), this->is_vertical(),
|
! (this->is_directed_right()), this->is_vertical(),
|
||||||
this->is_degenerate());
|
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.
|
/*! Exporter for the segment class used by the traits-class.
|
||||||
*/
|
*/
|
||||||
template <typename Kernel, typename OutputStream>
|
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);
|
os << static_cast<typename Kernel::Segment_2>(seg);
|
||||||
return (os);
|
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.
|
/*! Importer for the segment class used by the traits-class.
|
||||||
*/
|
*/
|
||||||
template <typename Kernel, typename InputStream>
|
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;
|
typename Kernel::Segment_2 kernel_seg;
|
||||||
is >> kernel_seg;
|
is >> kernel_seg;
|
||||||
seg = kernel_seg;
|
seg = kernel_seg;
|
||||||
|
|
|
||||||
|
|
@ -290,7 +290,7 @@ public:
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
I_Filtered_iterator (T* p) :
|
I_Filtered_iterator (T* p) :
|
||||||
nt (pointer(p)),
|
nt (reinterpret_cast<pointer>(p)),
|
||||||
iend (nt)
|
iend (nt)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
@ -314,7 +314,7 @@ public:
|
||||||
template <typename P>
|
template <typename P>
|
||||||
I_Filtered_iterator& operator= (const P* p)
|
I_Filtered_iterator& operator= (const P* p)
|
||||||
{
|
{
|
||||||
nt = pointer(p);
|
nt = reinterpret_cast<pointer>(p);
|
||||||
iend =nt;
|
iend =nt;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
@ -455,7 +455,7 @@ public:
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
I_Filtered_const_iterator (T* p) :
|
I_Filtered_const_iterator (T* p) :
|
||||||
nt (pointer(p)),
|
nt (reinterpret_cast<pointer>(p)),
|
||||||
iend (nt)
|
iend (nt)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
@ -488,7 +488,7 @@ public:
|
||||||
template <typename P>
|
template <typename P>
|
||||||
I_Filtered_const_iterator& operator= (const P* p)
|
I_Filtered_const_iterator& operator= (const P* p)
|
||||||
{
|
{
|
||||||
nt = pointer(p);
|
nt = reinterpret_cast<pointer>(p);
|
||||||
iend =nt;
|
iend =nt;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -588,7 +588,7 @@ private:
|
||||||
|
|
||||||
#ifdef CGAL_USE_BASIC_VIEWER
|
#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 "
|
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.");
|
"X_monotone_curve_2. Traits on curved surfaces needs additional support for parameterization.");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
#include <CGAL/bounding_box.h>
|
#include <CGAL/bounding_box.h>
|
||||||
#include <CGAL/tags.h>
|
#include <CGAL/tags.h>
|
||||||
#include <CGAL/IO/read_points.h>
|
#include <CGAL/IO/read_points.h>
|
||||||
#include <CGAL/IO/write_ply_points.h>
|
#include <CGAL/IO/PLY.h>
|
||||||
|
|
||||||
#include <CGAL/Real_timer.h>
|
#include <CGAL/Real_timer.h>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1068,8 +1068,18 @@ If \link GenericMap::are_attributes_automatically_managed `are_attributes_automa
|
||||||
template <unsigned int i>
|
template <unsigned int i>
|
||||||
size_type remove_cell(Dart_descriptor d);
|
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 */
|
}; /* end GenericMap */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,9 @@
|
||||||
/// \defgroup PkgCombinatorialMapsClasses Classes
|
/// \defgroup PkgCombinatorialMapsClasses Classes
|
||||||
/// \ingroup PkgCombinatorialMapsRef
|
/// \ingroup PkgCombinatorialMapsRef
|
||||||
|
|
||||||
|
/// \defgroup PkgCombinatorialMapsRefIO IO Functions for CMap
|
||||||
|
/// \ingroup PkgCombinatorialMapsRef
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\addtogroup PkgCombinatorialMapsRef
|
\addtogroup PkgCombinatorialMapsRef
|
||||||
\cgalPkgDescriptionBegin{Combinatorial Maps,PkgCombinatorialMaps}
|
\cgalPkgDescriptionBegin{Combinatorial Maps,PkgCombinatorialMaps}
|
||||||
|
|
@ -36,5 +39,9 @@
|
||||||
- `CGAL::Cell_attribute_with_id<CMap,Info_,Tag,OnMerge,OnSplit>`
|
- `CGAL::Cell_attribute_with_id<CMap,Info_,Tag,OnMerge,OnSplit>`
|
||||||
- `CGAL::Generic_map_min_items`
|
- `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
|
// (here we cannot use CGAL::Unique_hash_map because it does not provide
|
||||||
// iterators...
|
// iterators...
|
||||||
std::unordered_map<Dart_descriptor_2, Dart_descriptor> local_dartmap;
|
std::unordered_map<Dart_descriptor_2, Dart_descriptor> local_dartmap;
|
||||||
|
|
@ -585,7 +585,7 @@ namespace CGAL {
|
||||||
bool copy_perforated_darts=false,
|
bool copy_perforated_darts=false,
|
||||||
size_type mark_perforated=INVALID_MARK)
|
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
|
// (here we cannot use CGAL::Unique_hash_map because it does not provide
|
||||||
// iterators...
|
// iterators...
|
||||||
std::unordered_map
|
std::unordered_map
|
||||||
|
|
@ -661,7 +661,7 @@ namespace CGAL {
|
||||||
return is;
|
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
|
* The marks of the darts are initialized with mmask_marks, i.e. the dart
|
||||||
* is unmarked for all the marks.
|
* is unmarked for all the marks.
|
||||||
* @return a Dart_descriptor on the new dart.
|
* @return a Dart_descriptor on the new dart.
|
||||||
|
|
@ -968,7 +968,7 @@ namespace CGAL {
|
||||||
size_type number_of_used_marks() const
|
size_type number_of_used_marks() const
|
||||||
{ return mnb_used_marks; }
|
{ 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).
|
* @return true iff the mark is reserved (i.e. in used).
|
||||||
*/
|
*/
|
||||||
bool is_reserved(size_type amark) const
|
bool is_reserved(size_type amark) const
|
||||||
|
|
@ -997,14 +997,14 @@ namespace CGAL {
|
||||||
return number_of_darts() - number_of_marked_darts(amark);
|
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.
|
* @param amark the mark index.
|
||||||
* @return true iff all the darts are unmarked for amark.
|
* @return true iff all the darts are unmarked for amark.
|
||||||
*/
|
*/
|
||||||
bool is_whole_map_unmarked(size_type amark) const
|
bool is_whole_map_unmarked(size_type amark) const
|
||||||
{ return number_of_marked_darts(amark) == 0; }
|
{ 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.
|
* @param amark the mark index.
|
||||||
* @return true iff all the darts are marked for amark.
|
* @return true iff all the darts are marked for amark.
|
||||||
*/
|
*/
|
||||||
|
|
@ -1071,7 +1071,7 @@ namespace CGAL {
|
||||||
mmask_marks.flip(amark);
|
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 adart the dart to test.
|
||||||
* @param amark the given mark.
|
* @param amark the given mark.
|
||||||
* @return true iff adart is marked for the mark amark.
|
* @return true iff adart is marked for the mark amark.
|
||||||
|
|
@ -1239,7 +1239,7 @@ namespace CGAL {
|
||||||
std::size_t orient(size_type amark) const
|
std::size_t orient(size_type amark) const
|
||||||
{ negate_mark(amark); return number_of_darts(); }
|
{ 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.
|
* @param i the dimension.
|
||||||
* @return true iff all the darts are not i-free.
|
* @return true iff all the darts are not i-free.
|
||||||
* @pre 1<=i<=n
|
* @pre 1<=i<=n
|
||||||
|
|
@ -1253,7 +1253,7 @@ namespace CGAL {
|
||||||
return true;
|
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.
|
* @return true iff all the darts are non free.
|
||||||
*/
|
*/
|
||||||
bool is_without_boundary() const
|
bool is_without_boundary() const
|
||||||
|
|
@ -1334,7 +1334,7 @@ namespace CGAL {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Test if the map is valid.
|
/** Tests if the map is valid.
|
||||||
* @return true iff the map is valid.
|
* @return true iff the map is valid.
|
||||||
*/
|
*/
|
||||||
bool is_valid(bool show_errors=true) const
|
bool is_valid(bool show_errors=true) const
|
||||||
|
|
@ -1579,7 +1579,7 @@ namespace CGAL {
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new attribute.
|
/// Creates a new attribute.
|
||||||
/// @return a descriptor on the new attribute.
|
/// @return a descriptor on the new attribute.
|
||||||
template<unsigned int i, typename ...Args>
|
template<unsigned int i, typename ...Args>
|
||||||
typename Attribute_descriptor<i>::type create_attribute(const Args&... args)
|
typename Attribute_descriptor<i>::type create_attribute(const Args&... args)
|
||||||
|
|
@ -1988,7 +1988,7 @@ namespace CGAL {
|
||||||
else unlink_beta_for_involution(adart, i);
|
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 adart1 the first dart.
|
||||||
* @param adart2 the second dart.
|
* @param adart2 the second dart.
|
||||||
* @return true iff \em adart1 can be i-sewn with \em adart2.
|
* @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,
|
* isomorphic to the connected component of map2 containing dart dh2,
|
||||||
* starting from dh1 and dh2.
|
* starting from dh1 and dh2.
|
||||||
* @param dh1 initial dart for this map
|
* @param dh1 initial dart for this map
|
||||||
|
|
@ -3648,7 +3648,7 @@ namespace CGAL {
|
||||||
return match;
|
return match;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Test if this cmap is isomorphic to map2.
|
/** Tests if this cmap is isomorphic to map2.
|
||||||
* @pre cmap is connected.
|
* @pre cmap is connected.
|
||||||
* @param map2 the second combinatorial map
|
* @param map2 the second combinatorial map
|
||||||
* @param testDartInfo Boolean to test the equality of dart info (true)
|
* @param testDartInfo Boolean to test the equality of dart info (true)
|
||||||
|
|
@ -3687,7 +3687,7 @@ namespace CGAL {
|
||||||
return false;
|
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.
|
* @return true iff the boolean automatic_attributes_management is set to true.
|
||||||
*/
|
*/
|
||||||
bool are_attributes_automatically_managed() const
|
bool are_attributes_automatically_managed() const
|
||||||
|
|
@ -3710,13 +3710,13 @@ namespace CGAL {
|
||||||
void set_automatic_attributes_management_without_correction(bool newval)
|
void set_automatic_attributes_management_without_correction(bool newval)
|
||||||
{ this->automatic_attributes_management = newval; }
|
{ this->automatic_attributes_management = newval; }
|
||||||
|
|
||||||
/** Create a halfedge.
|
/** Creates a halfedge.
|
||||||
* @return a dart of the new halfedge.
|
* @return a dart of the new half-edge.
|
||||||
*/
|
*/
|
||||||
Dart_descriptor make_half_edge()
|
Dart_descriptor make_half_edge()
|
||||||
{ return create_dart(); }
|
{ return create_dart(); }
|
||||||
|
|
||||||
/** Create an edge.
|
/** Creates an edge.
|
||||||
* if closed==true, the edge has no 2-free dart.
|
* if closed==true, the edge has no 2-free dart.
|
||||||
* (note that for CMap there is no difference between true and false, but
|
* (note that for CMap there is no difference between true and false, but
|
||||||
* this is not the case for GMap)
|
* this is not the case for GMap)
|
||||||
|
|
@ -3730,7 +3730,7 @@ namespace CGAL {
|
||||||
return d1;
|
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
|
* Note that this function can be used only if 0-attributes are non void
|
||||||
* @param h0 the first vertex descriptor.
|
* @param h0 the first vertex descriptor.
|
||||||
* @param h1 the second vertex descriptor.
|
* @param h1 the second vertex descriptor.
|
||||||
|
|
@ -3751,7 +3751,7 @@ namespace CGAL {
|
||||||
return d1;
|
return d1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Create a combinatorial polygon of length alg
|
/** Creates a combinatorial polygon of length alg
|
||||||
* (a cycle of alg darts beta1 links together).
|
* (a cycle of alg darts beta1 links together).
|
||||||
* @return a new dart.
|
* @return a new dart.
|
||||||
*/
|
*/
|
||||||
|
|
@ -3772,7 +3772,7 @@ namespace CGAL {
|
||||||
return start;
|
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).
|
* (a cycle of alg darts beta1 links together).
|
||||||
* @param adart an initial dart
|
* @param adart an initial dart
|
||||||
* @return true iff the face containing adart is a polygon of length alg.
|
* @return true iff the face containing adart is a polygon of length alg.
|
||||||
|
|
@ -3794,7 +3794,7 @@ namespace CGAL {
|
||||||
return (nb==alg);
|
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 h0 the first descriptor.
|
||||||
* @param h1 the second descriptor.
|
* @param h1 the second descriptor.
|
||||||
* @param h2 the third descriptor.
|
* @param h2 the third descriptor.
|
||||||
|
|
@ -3814,7 +3814,7 @@ namespace CGAL {
|
||||||
return d1;
|
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 h0 the first vertex descriptor.
|
||||||
* @param h1 the second vertex descriptor.
|
* @param h1 the second vertex descriptor.
|
||||||
* @param h2 the third vertex descriptor.
|
* @param h2 the third vertex descriptor.
|
||||||
|
|
@ -3837,7 +3837,7 @@ namespace CGAL {
|
||||||
return d1;
|
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 d1 a dart onto a first triangle.
|
||||||
* @param d2 a dart onto a second triangle.
|
* @param d2 a dart onto a second triangle.
|
||||||
* @param d3 a dart onto a third triangle.
|
* @param d3 a dart onto a third triangle.
|
||||||
|
|
@ -3859,9 +3859,9 @@ namespace CGAL {
|
||||||
return d1;
|
return d1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Test if a volume is a combinatorial tetrahedron.
|
/** Tests if a volume is a combinatorial tetrahedron.
|
||||||
* @param adart an initial dart
|
* @param d1 an initial dart
|
||||||
* @return true iff the volume containing adart is a combinatorial tetrahedron.
|
* @return true iff the volume containing d1 is a combinatorial tetrahedron.
|
||||||
*/
|
*/
|
||||||
bool is_volume_combinatorial_tetrahedron(Dart_const_descriptor d1) const
|
bool is_volume_combinatorial_tetrahedron(Dart_const_descriptor d1) const
|
||||||
{
|
{
|
||||||
|
|
@ -3892,7 +3892,7 @@ namespace CGAL {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Create a new combinatorial tetrahedron.
|
/** Creates a new combinatorial tetrahedron.
|
||||||
* @return a new dart.
|
* @return a new dart.
|
||||||
*/
|
*/
|
||||||
Dart_descriptor make_combinatorial_tetrahedron()
|
Dart_descriptor make_combinatorial_tetrahedron()
|
||||||
|
|
@ -3905,7 +3905,7 @@ namespace CGAL {
|
||||||
return make_combinatorial_tetrahedron(d1, d2, d3, d4);
|
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 d1 a dart onto a first quadrilateral.
|
||||||
* @param d2 a dart onto a second quadrilateral.
|
* @param d2 a dart onto a second quadrilateral.
|
||||||
* @param d3 a dart onto a third quadrilateral.
|
* @param d3 a dart onto a third quadrilateral.
|
||||||
|
|
@ -3952,9 +3952,9 @@ namespace CGAL {
|
||||||
return d1;
|
return d1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Test if a volume is a combinatorial hexahedron.
|
/** Tests if a volume is a combinatorial hexahedron.
|
||||||
* @param adart an initial dart
|
* @param d1 an initial dart
|
||||||
* @return true iff the volume containing adart is a combinatorial hexahedron.
|
* @return true iff the volume containing d1 is a combinatorial hexahedron.
|
||||||
*/
|
*/
|
||||||
bool is_volume_combinatorial_hexahedron(Dart_const_descriptor d1) const
|
bool is_volume_combinatorial_hexahedron(Dart_const_descriptor d1) const
|
||||||
{
|
{
|
||||||
|
|
@ -4004,7 +4004,7 @@ namespace CGAL {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Create a new combinatorial hexahedron.
|
/** Creates a new combinatorial hexahedron.
|
||||||
* @return a new dart.
|
* @return a new dart.
|
||||||
*/
|
*/
|
||||||
Dart_descriptor make_combinatorial_hexahedron()
|
Dart_descriptor make_combinatorial_hexahedron()
|
||||||
|
|
@ -4019,7 +4019,362 @@ namespace CGAL {
|
||||||
return make_combinatorial_hexahedron(d1, d2, d3, d4, d5, d6);
|
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,
|
* 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.
|
* or if there are at most two (i+1)-cell incident to it.
|
||||||
* @param adart a dart of the i-cell.
|
* @param adart a dart of the i-cell.
|
||||||
|
|
@ -4041,7 +4396,7 @@ namespace CGAL {
|
||||||
run(*this,adart,update_attributes);
|
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
|
* An i-cell can be contracted if i==1
|
||||||
* or if there are at most two (i-1)-cell incident to it.
|
* or if there are at most two (i-1)-cell incident to it.
|
||||||
* @param adart a dart of the i-cell.
|
* @param adart a dart of the i-cell.
|
||||||
|
|
@ -4407,7 +4762,7 @@ namespace CGAL {
|
||||||
return this->template beta<0>(adart1);
|
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 adart1 a first dart.
|
||||||
* @param adart2 a second dart.
|
* @param adart2 a second dart.
|
||||||
* @return true iff an edge can be inserted between adart1 and adart2.
|
* @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);
|
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.
|
* between two given darts.
|
||||||
* @param adart1 a first dart.
|
* @param adart1 a first dart.
|
||||||
* @param adart2 a second dart.
|
* @param adart2 a second dart.
|
||||||
|
|
@ -4627,7 +4982,7 @@ namespace CGAL {
|
||||||
return this->template beta<0>(adart1);
|
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.
|
* a path of edges.
|
||||||
* @param afirst iterator on the beginning of the path.
|
* @param afirst iterator on the beginning of the path.
|
||||||
* @param alast iterator on the end of the path.
|
* @param alast iterator on the end of the path.
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,208 @@
|
||||||
|
// Copyright (c) 2025 CNRS and LIRIS' Establishments (France).
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org)
|
||||||
|
//
|
||||||
|
// $URL$
|
||||||
|
// $Id$
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
|
//
|
||||||
|
// Author(s) : Guillaume Damiand <guillaume.damiand@liris.cnrs.fr>
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#ifndef CMAP_ELEMENT_TOPO_H
|
||||||
|
#define CMAP_ELEMENT_TOPO_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
namespace CMap {
|
||||||
|
namespace Element_topo {
|
||||||
|
|
||||||
|
enum cell_topo
|
||||||
|
{
|
||||||
|
SQUARE=0,
|
||||||
|
TRIANGLE=1,
|
||||||
|
HEXAHEDRON=2,
|
||||||
|
TETRAHEDRON=3,
|
||||||
|
PRISM=4,
|
||||||
|
PYRAMID=5,
|
||||||
|
GENERIC_2D=6,
|
||||||
|
GENERIC_3D=7,
|
||||||
|
EDGE=8,
|
||||||
|
TETRAHEDRON10=9,
|
||||||
|
PENTAGONAL_PRISM=10,
|
||||||
|
HEXAGONAL_PRISM=11,
|
||||||
|
NO_TYPE=-1
|
||||||
|
};
|
||||||
|
|
||||||
|
inline
|
||||||
|
std::string topo_name(cell_topo t)
|
||||||
|
{
|
||||||
|
switch(t)
|
||||||
|
{
|
||||||
|
case SQUARE: return "SQUARE";
|
||||||
|
case TRIANGLE: return "TRIANGLE";
|
||||||
|
case HEXAHEDRON: return "HEXAHEDRON";
|
||||||
|
case TETRAHEDRON: return "TETRAHEDRON";
|
||||||
|
case PRISM: return "PRISM";
|
||||||
|
case PYRAMID: return "PYRAMID";
|
||||||
|
case GENERIC_2D: return "GENERIC_2D";
|
||||||
|
case GENERIC_3D: return "GENERIC_3D";
|
||||||
|
case EDGE: return "EDGE";
|
||||||
|
case TETRAHEDRON10: return "TETRAHEDRON10";
|
||||||
|
case PENTAGONAL_PRISM: return "PENTAGONAL_PRISM";
|
||||||
|
case HEXAGONAL_PRISM: return "HEXAGONAL_PRISM";
|
||||||
|
case NO_TYPE: return "NO_TYPE";
|
||||||
|
}
|
||||||
|
return "UNKNOWN";
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
cell_topo topo_from_name(const std::string& t)
|
||||||
|
{
|
||||||
|
if (t=="SQUARE") return SQUARE;
|
||||||
|
if (t=="TRIANGLE") return TRIANGLE;
|
||||||
|
if (t=="HEXAHEDRON") return HEXAHEDRON;
|
||||||
|
if (t=="TETRAHEDRON") return TETRAHEDRON;
|
||||||
|
if (t=="PRISM") return PRISM;
|
||||||
|
if (t=="PYRAMID") return PYRAMID;
|
||||||
|
if (t=="GENERIC_2D") return GENERIC_2D;
|
||||||
|
if (t=="GENERIC_3D") return GENERIC_3D;
|
||||||
|
if (t=="EDGE") return EDGE;
|
||||||
|
if (t=="TETRAHEDRON10") return TETRAHEDRON10;
|
||||||
|
if (t=="PENTAGONAL_PRISM") return PENTAGONAL_PRISM;
|
||||||
|
if (t=="HEXAGONAL_PRISM") return HEXAGONAL_PRISM;
|
||||||
|
if (t=="NO_TYPE") return NO_TYPE;
|
||||||
|
return NO_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief To get the type of `dimD` cell of the `CMap` of `cmapdim` dimension.
|
||||||
|
*/
|
||||||
|
template<typename CMap, unsigned int dimcell,
|
||||||
|
unsigned int cmapdim=CMap::dimension>
|
||||||
|
struct Get_cell_topo
|
||||||
|
{
|
||||||
|
static cell_topo run(CMap&, typename CMap::Dart_descriptor dh,
|
||||||
|
typename CMap::Dart_descriptor& starting_dart)
|
||||||
|
{
|
||||||
|
starting_dart=dh;
|
||||||
|
return NO_TYPE;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief To get the type associated of an edge. For now only one type.
|
||||||
|
*/
|
||||||
|
template<typename CMap, unsigned int cmapdim>
|
||||||
|
struct Get_cell_topo<CMap, 1, cmapdim>
|
||||||
|
{
|
||||||
|
static cell_topo run(CMap&, typename CMap::Dart_descriptor it,
|
||||||
|
typename CMap::Dart_descriptor& starting_dart)
|
||||||
|
{
|
||||||
|
starting_dart=it;
|
||||||
|
return EDGE;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief To get the type of 2D cell of the CMap of cmapdim dimension.
|
||||||
|
*/
|
||||||
|
template<typename CMap, unsigned int cmapdim>
|
||||||
|
struct Get_cell_topo<CMap, 2, cmapdim>
|
||||||
|
{
|
||||||
|
static cell_topo run(CMap& cmap, typename CMap::Dart_descriptor it,
|
||||||
|
typename CMap::Dart_descriptor& starting_dart)
|
||||||
|
{
|
||||||
|
starting_dart=it;
|
||||||
|
|
||||||
|
if (cmap.is_face_combinatorial_polygon(it, 3))
|
||||||
|
{ return TRIANGLE; }
|
||||||
|
|
||||||
|
else if (cmap.is_face_combinatorial_polygon(it, 4))
|
||||||
|
{ return SQUARE; }
|
||||||
|
|
||||||
|
return GENERIC_2D;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief To get the type of 3D cell of the CMap of dimension 3.
|
||||||
|
*/
|
||||||
|
template<typename CMap>
|
||||||
|
struct Get_cell_topo<CMap, 3, 3>
|
||||||
|
{
|
||||||
|
static cell_topo run(CMap& cmap, typename CMap::Dart_descriptor it,
|
||||||
|
typename CMap::Dart_descriptor& starting_dart)
|
||||||
|
{
|
||||||
|
starting_dart=it;
|
||||||
|
|
||||||
|
if (cmap.is_volume_combinatorial_tetrahedron(it))
|
||||||
|
{ return TETRAHEDRON; }
|
||||||
|
|
||||||
|
else if (cmap.is_volume_combinatorial_hexahedron(it))
|
||||||
|
{ return HEXAHEDRON; }
|
||||||
|
|
||||||
|
else if(cmap.is_volume_combinatorial_tetrahedron10(it))
|
||||||
|
{ return TETRAHEDRON10; }
|
||||||
|
|
||||||
|
// For non symetric object, we need to test all darts
|
||||||
|
for (auto itv=cmap.template darts_of_cell<3>(it).begin(),
|
||||||
|
itvend=cmap.template darts_of_cell<3>(it).end(); itv!=itvend; ++itv)
|
||||||
|
{
|
||||||
|
starting_dart=itv;
|
||||||
|
|
||||||
|
if (cmap.is_volume_combinatorial_prism(itv))
|
||||||
|
{ return PRISM; }
|
||||||
|
|
||||||
|
else if (cmap.is_volume_combinatorial_pentagonal_prism(itv))
|
||||||
|
{ return PENTAGONAL_PRISM; }
|
||||||
|
|
||||||
|
else if (cmap.is_volume_combinatorial_pyramid(itv))
|
||||||
|
{ return PYRAMID; }
|
||||||
|
|
||||||
|
else if (cmap.is_volume_combinatorial_hexagonal_prism(itv))
|
||||||
|
{ return HEXAGONAL_PRISM; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return GENERIC_3D;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<unsigned int dimcell, typename CMap>
|
||||||
|
cell_topo get_cell_topo(CMap& cmap, typename CMap::Dart_descriptor it,
|
||||||
|
typename CMap::Dart_descriptor& starting_dart)
|
||||||
|
{ return Get_cell_topo<CMap, dimcell>::run(cmap, it, starting_dart); }
|
||||||
|
|
||||||
|
template<unsigned int dimcell, typename CMap>
|
||||||
|
cell_topo get_cell_topo(CMap& cmap, typename CMap::Dart_descriptor it)
|
||||||
|
{
|
||||||
|
typename CMap::Dart_descriptor dummy;
|
||||||
|
return get_cell_topo<dimcell, CMap>(cmap, it, dummy);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<unsigned int dimcell, typename CMap>
|
||||||
|
cell_topo get_cell_topo(const CMap& cmap, typename CMap::Dart_const_descriptor it,
|
||||||
|
typename CMap::Dart_const_descriptor& starting_dart)
|
||||||
|
{
|
||||||
|
typename CMap::Dart_descriptor it2=const_cast<CMap&>(cmap).dart_descriptor
|
||||||
|
(cmap.darts().index(it));
|
||||||
|
typename CMap::Dart_descriptor sd2;
|
||||||
|
cell_topo res=Get_cell_topo<CMap, dimcell>::run(const_cast<CMap&>(cmap),
|
||||||
|
it2, sd2);
|
||||||
|
starting_dart=sd2;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<unsigned int dimcell, typename CMap>
|
||||||
|
cell_topo get_cell_topo(const CMap& cmap, typename CMap::Dart_const_descriptor it)
|
||||||
|
{
|
||||||
|
typename CMap::Dart_descriptor it2=it;
|
||||||
|
return Get_cell_topo<CMap, dimcell>::run(const_cast<CMap&>(cmap), it2);
|
||||||
|
}
|
||||||
|
|
||||||
|
} } } // namespace CGAL::CMap::Element_topo
|
||||||
|
|
||||||
|
#endif // CMAP_ELEMENT_TOPO_H
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
#include <CGAL/make_conforming_constrained_Delaunay_triangulation_3.h>
|
#include <CGAL/make_conforming_constrained_Delaunay_triangulation_3.h>
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
using K = CGAL::Exact_predicates_inexact_constructions_kernel;
|
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: "
|
<< "Number of constrained facets in the CDT: "
|
||||||
<< ccdt.number_of_constrained_facets() << '\n';
|
<< 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");
|
std::ofstream ofs(argc > 2 ? argv[2] : "out.mesh");
|
||||||
ofs.precision(17);
|
ofs.precision(17);
|
||||||
CGAL::IO::write_MEDIT(ofs, ccdt);
|
CGAL::IO::write_MEDIT(ofs, ccdt);
|
||||||
|
|
|
||||||
|
|
@ -1034,7 +1034,7 @@ public:
|
||||||
*/
|
*/
|
||||||
CDT_3_signed_index face_constraint_index(typename Triangulation::Cell_handle ch, int i) const
|
CDT_3_signed_index face_constraint_index(typename Triangulation::Cell_handle ch, int i) const
|
||||||
{
|
{
|
||||||
return ch->face_id[static_cast<unsigned>(i)];
|
return ch->ccdt_3_data().face_constraint_index(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,7 @@ public:
|
||||||
CGAL::read(is, i);
|
CGAL::read(is, i);
|
||||||
}
|
}
|
||||||
if(!is) return is;
|
if(!is) return is;
|
||||||
c.face_id[li] = i;
|
c->ccdt_3_data().set_face_constraint_index(li, i);
|
||||||
}
|
}
|
||||||
return is;
|
return is;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -123,11 +123,11 @@ In the example below, we can see a query where:
|
||||||
</center>
|
</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.
|
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
|
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.
|
while working at the Max-Planck Institute for Informatics in Saarbrücken, Germany.
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,6 @@ Modular_arithmetic
|
||||||
Number_types
|
Number_types
|
||||||
Orthtree
|
Orthtree
|
||||||
Point_set_3
|
Point_set_3
|
||||||
Point_set_processing_3
|
|
||||||
Polygon
|
Polygon
|
||||||
Polygon_mesh_processing
|
Polygon_mesh_processing
|
||||||
Principal_component_analysis
|
Principal_component_analysis
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,6 @@ Modular_arithmetic
|
||||||
Number_types
|
Number_types
|
||||||
Orthtree
|
Orthtree
|
||||||
Point_set_3
|
Point_set_3
|
||||||
Point_set_processing_3
|
|
||||||
Polygon
|
Polygon
|
||||||
Polygon_mesh_processing
|
Polygon_mesh_processing
|
||||||
Principal_component_analysis
|
Principal_component_analysis
|
||||||
|
|
|
||||||
|
|
@ -1795,8 +1795,8 @@ bool MainWindow::loadScript(QFileInfo info)
|
||||||
QString program;
|
QString program;
|
||||||
QString filename = info.absoluteFilePath();
|
QString filename = info.absoluteFilePath();
|
||||||
QFile script_file(filename);
|
QFile script_file(filename);
|
||||||
script_file.open(QIODevice::ReadOnly);
|
bool success = script_file.open(QIODevice::ReadOnly);
|
||||||
if(!script_file.isReadable()) {
|
if((! success) || (!script_file.isReadable())) {
|
||||||
throw std::ios_base::failure(script_file.errorString().toStdString());
|
throw std::ios_base::failure(script_file.errorString().toStdString());
|
||||||
}
|
}
|
||||||
program = script_file.readAll();
|
program = script_file.readAll();
|
||||||
|
|
@ -2747,9 +2747,9 @@ void MainWindow::exportStatistics()
|
||||||
if(filename.isEmpty())
|
if(filename.isEmpty())
|
||||||
return;
|
return;
|
||||||
QFile output(filename);
|
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";
|
qDebug() << "- Error, unable to open" << "outputFilename" << "for output";
|
||||||
}
|
}
|
||||||
QTextStream outStream(&output);
|
QTextStream outStream(&output);
|
||||||
|
|
|
||||||
|
|
@ -93,18 +93,20 @@ bool Camera_positions_list::save(QString filename) {
|
||||||
if(m_model->rowCount() <1)
|
if(m_model->rowCount() <1)
|
||||||
return false;
|
return false;
|
||||||
QFile file(filename);
|
QFile file(filename);
|
||||||
file.open(QIODevice::WriteOnly);
|
if(file.open(QIODevice::WriteOnly)){
|
||||||
QTextStream out(&file);
|
QTextStream out(&file);
|
||||||
for(int i = 0; i < m_model->rowCount(); ++i)
|
for(int i = 0; i < m_model->rowCount(); ++i)
|
||||||
{
|
{
|
||||||
QStandardItem* item = m_model->item(i);
|
QStandardItem* item = m_model->item(i);
|
||||||
out << item->data(Qt::DisplayRole).toString()
|
out << item->data(Qt::DisplayRole).toString()
|
||||||
<< "\n"
|
<< "\n"
|
||||||
<< item->data(Qt::UserRole).toString()
|
<< item->data(Qt::UserRole).toString()
|
||||||
<< "\n";
|
<< "\n";
|
||||||
|
}
|
||||||
|
file.close();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
file.close();
|
return false;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Camera_positions_list::on_saveButton_pressed()
|
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) {
|
void Camera_positions_list::load(QString filename) {
|
||||||
QFile file(filename);
|
QFile file(filename);
|
||||||
std::clog << "Loading camera positions " << qPrintable(filename) << std::endl;
|
|
||||||
file.open(QIODevice::ReadOnly);
|
if(file.open(QIODevice::ReadOnly)){
|
||||||
QTextStream input(&file);
|
std::clog << "Loading camera positions " << qPrintable(filename) << std::endl;
|
||||||
while(!input.atEnd()) {
|
|
||||||
QString text = input.readLine(1000);
|
QTextStream input(&file);
|
||||||
QString coord = input.readLine(1000);
|
while(!input.atEnd()) {
|
||||||
if(text.isNull() || coord.isNull()) return;
|
QString text = input.readLine(1000);
|
||||||
CGAL::qglviewer::Frame frame;
|
QString coord = input.readLine(1000);
|
||||||
if(Three::activeViewer()->readFrame(coord, frame))
|
if(text.isNull() || coord.isNull()) return;
|
||||||
{
|
CGAL::qglviewer::Frame frame;
|
||||||
addItem(text,
|
if(Three::activeViewer()->readFrame(coord, frame))
|
||||||
Three::activeViewer()->dumpFrame(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.
|
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
|
\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
|
\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.
|
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
|
/// \defgroup PkgDrawLinearCellComplex Draw a Linear Cell Complex
|
||||||
/// \ingroup PkgLinearCellComplexRef
|
/// \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
|
\addtogroup PkgLinearCellComplexRef
|
||||||
|
|
@ -74,4 +82,10 @@
|
||||||
- \link PkgDrawLinearCellComplex CGAL::draw<LCC>() \endlink
|
- \link PkgDrawLinearCellComplex CGAL::draw<LCC>() \endlink
|
||||||
- \link PkgDrawLinearCellComplex CGAL::add_in_graphics_scene<LCC, BufferType, DrawingFunctor>() \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/linear_cell_complex_3_incremental_builder.cpp
|
||||||
\example Linear_cell_complex/draw_linear_cell_complex.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_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("read_plane_graph_in_lcc_2.cpp")
|
||||||
create_single_source_cgal_program("voronoi_2.cpp")
|
create_single_source_cgal_program("voronoi_2.cpp")
|
||||||
create_single_source_cgal_program("voronoi_3.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")
|
create_single_source_cgal_program("draw_linear_cell_complex.cpp")
|
||||||
if(CGAL_Qt6_FOUND)
|
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;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Create a vertex attribute.
|
/** Creates a vertex attribute.
|
||||||
* @return a handle on the new attribute.
|
* @return a handle on the new attribute.
|
||||||
*/
|
*/
|
||||||
template<typename ...Args>
|
template<typename ...Args>
|
||||||
|
|
@ -221,7 +221,7 @@ namespace CGAL {
|
||||||
{ return Base::template create_attribute<0>(args...); }
|
{ 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.
|
* @param ahandle the point handle to associated with the dart.
|
||||||
* @return a Dart_descriptor on the new dart.
|
* @return a Dart_descriptor on the new dart.
|
||||||
*/
|
*/
|
||||||
|
|
@ -232,7 +232,7 @@ namespace CGAL {
|
||||||
return res;
|
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.
|
* @param apoint the point to associated with the dart.
|
||||||
* @return a Dart_descriptor on the new 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));
|
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
|
* A Linear_cell_complex is valid if it is a valid Combinatorial_map with
|
||||||
* an attribute associated to each dart.
|
* an attribute associated to each dart.
|
||||||
* @return true iff the map is valid.
|
* @return true iff the map is valid.
|
||||||
|
|
@ -550,7 +550,7 @@ namespace CGAL {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Create a segment given 2 points.
|
/** Creates a segment given 2 points.
|
||||||
* @param p0 the first point.
|
* @param p0 the first point.
|
||||||
* @param p1 the second point.
|
* @param p1 the second point.
|
||||||
* if closed==true, the edge has no 2-free dart.
|
* if closed==true, the edge has no 2-free dart.
|
||||||
|
|
@ -564,7 +564,7 @@ namespace CGAL {
|
||||||
closed);
|
closed);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Create a triangle given 3 points.
|
/** Creates a triangle given 3 points.
|
||||||
* @param p0 the first point.
|
* @param p0 the first point.
|
||||||
* @param p1 the second point.
|
* @param p1 the second point.
|
||||||
* @param p2 the third point.
|
* @param p2 the third point.
|
||||||
|
|
@ -579,7 +579,7 @@ namespace CGAL {
|
||||||
create_vertex_attribute(p2));
|
create_vertex_attribute(p2));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Create a quadrangle given 4 points.
|
/** Creates a quadrangle given 4 points.
|
||||||
* @param p0 the first point.
|
* @param p0 the first point.
|
||||||
* @param p1 the second point.
|
* @param p1 the second point.
|
||||||
* @param p2 the third 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 h0 the first vertex handle.
|
||||||
* @param h1 the second vertex handle.
|
* @param h1 the second vertex handle.
|
||||||
* @param h2 the third vertex handle.
|
* @param h2 the third vertex handle.
|
||||||
|
|
@ -619,7 +619,7 @@ namespace CGAL {
|
||||||
return this->make_combinatorial_tetrahedron(d1, d2, d3, d4);
|
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 p0 the first point.
|
||||||
* @param p1 the second point.
|
* @param p1 the second point.
|
||||||
* @param p2 the third point.
|
* @param p2 the third point.
|
||||||
|
|
@ -638,7 +638,7 @@ namespace CGAL {
|
||||||
create_vertex_attribute(p3));
|
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)
|
* (8 vertices, 12 edges and 6 facets)
|
||||||
* \verbatim
|
* \verbatim
|
||||||
* 4----7
|
* 4----7
|
||||||
|
|
@ -660,13 +660,13 @@ namespace CGAL {
|
||||||
* h0,h5 and to the facet (h0,h5,h6,h1).
|
* h0,h5 and to the facet (h0,h5,h6,h1).
|
||||||
*/
|
*/
|
||||||
Dart_descriptor make_hexahedron(Vertex_attribute_descriptor h0,
|
Dart_descriptor make_hexahedron(Vertex_attribute_descriptor h0,
|
||||||
Vertex_attribute_descriptor h1,
|
Vertex_attribute_descriptor h1,
|
||||||
Vertex_attribute_descriptor h2,
|
Vertex_attribute_descriptor h2,
|
||||||
Vertex_attribute_descriptor h3,
|
Vertex_attribute_descriptor h3,
|
||||||
Vertex_attribute_descriptor h4,
|
Vertex_attribute_descriptor h4,
|
||||||
Vertex_attribute_descriptor h5,
|
Vertex_attribute_descriptor h5,
|
||||||
Vertex_attribute_descriptor h6,
|
Vertex_attribute_descriptor h6,
|
||||||
Vertex_attribute_descriptor h7)
|
Vertex_attribute_descriptor h7)
|
||||||
{
|
{
|
||||||
Dart_descriptor d1 = make_quadrangle(h0, h5, h6, h1);
|
Dart_descriptor d1 = make_quadrangle(h0, h5, h6, h1);
|
||||||
Dart_descriptor d2 = make_quadrangle(h1, h6, h7, h2);
|
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);
|
return this->make_combinatorial_hexahedron(d1, d2, d3, d4, d5, d6);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Create an hexahedron given 8 points.
|
/** Creates an hexahedron given 8 points.
|
||||||
* \verbatim
|
* \verbatim
|
||||||
* 4----7
|
* 4----7
|
||||||
* /| /|
|
* /| /|
|
||||||
|
|
@ -717,6 +717,133 @@ namespace CGAL {
|
||||||
create_vertex_attribute(p7));
|
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.
|
/** Compute the barycenter of a given cell.
|
||||||
* @param adart a dart incident to the cell.
|
* @param adart a dart incident to the cell.
|
||||||
* @param adim the dimension of the cell.
|
* @param adim the dimension of the cell.
|
||||||
|
|
|
||||||
|
|
@ -261,7 +261,7 @@ public:
|
||||||
prev_dart =lcc.null_descriptor;
|
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());
|
CGAL_assertion(i<vertex_map.size());
|
||||||
// std::cout<<i<<" "<<std::flush;
|
// std::cout<<i<<" "<<std::flush;
|
||||||
|
|
@ -289,6 +289,7 @@ public:
|
||||||
{ first_dart=cur_dart; min_vertex=max_vertex=i; min_dart=cur_dart; }
|
{ first_dart=cur_dart; min_vertex=max_vertex=i; min_dart=cur_dart; }
|
||||||
|
|
||||||
prev_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.
|
// End of the facet. Return the first dart of this facet.
|
||||||
|
|
@ -325,11 +326,12 @@ public:
|
||||||
return first_dart;
|
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();
|
begin_facet();
|
||||||
for (size_type i:l)
|
for (size_type i:l)
|
||||||
{ add_vertex_to_facet(i); }
|
{ add_vertex_to_facet(i, tabdarts); }
|
||||||
return end_facet();
|
return end_facet();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -404,5 +406,197 @@ private:
|
||||||
|
|
||||||
} //namespace CGAL
|
} //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 //
|
#endif // CGAL_LINEAR_CELL_COMPLEX_INCREMENTAL_BUILDER_3_H //
|
||||||
// EOF //
|
// 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_4_test.cpp ${hfiles})
|
||||||
create_single_source_cgal_program(Linear_cell_complex_copy_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(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
|
# 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})
|
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"
|
#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>
|
template<typename LCC>
|
||||||
bool test_ib(const char* filename)
|
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;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
# vtk DataFile Version 2.0
|
||||||
|
3D Mesh
|
||||||
|
ASCII
|
||||||
|
DATASET UNSTRUCTURED_GRID
|
||||||
|
POINTS 21 double
|
||||||
|
0.797233 -3.0657 2.80231
|
||||||
|
1.04552 -2.81344 1.77789
|
||||||
|
-0.00261142 -2.87459 1.50879
|
||||||
|
-0.2509 -3.12685 2.53322
|
||||||
|
0.682428 -3.76202 2.31634
|
||||||
|
0.806573 -3.63589 1.80413
|
||||||
|
0.282506 -3.66646 1.66958
|
||||||
|
0.158362 -3.79259 2.1818
|
||||||
|
0.567624 -4.45834 1.83037
|
||||||
|
1.48429 0.147175 1.04918
|
||||||
|
-0.357656 0.0397078 0.576288
|
||||||
|
-0.146018 -1.80958 0.172206
|
||||||
|
1.69593 -1.70211 0.645098
|
||||||
|
-0.66619 -0.27376 1.84928
|
||||||
|
-0.974724 -0.587227 3.12228
|
||||||
|
-0.454552 -2.12305 1.4452
|
||||||
|
-0.763086 -2.43652 2.7182
|
||||||
|
1.38739 -2.01558 1.91809
|
||||||
|
1.07886 -2.32905 3.19109
|
||||||
|
1.17576 -0.166292 2.32218
|
||||||
|
0.867223 -0.47976 3.59517
|
||||||
|
|
||||||
|
CELLS 2 115
|
||||||
|
62 13 3 8 4 5 3 4 8 7 4 5 4 0 1 3 8 5 6 3 7 8 6 4 4 7 3 0 4 1 0 18 17 4 5 1 2 6 4 7 6 2 3 4 0 3 16 18 4 17 18 16 15 4 1 17 15 2 4 3 2 15 16
|
||||||
|
51 10 4 9 19 13 10 4 19 9 12 17 4 13 19 20 14 4 10 13 15 11 4 9 10 11 12 4 17 12 11 15 4 19 17 18 20 4 14 20 18 16 4 13 14 16 15 4 17 15 16 18
|
||||||
|
|
||||||
|
CELL_TYPES 2
|
||||||
|
42
|
||||||
|
42
|
||||||
|
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
# vtk DataFile Version 2.0
|
||||||
|
3D Mesh
|
||||||
|
ASCII
|
||||||
|
DATASET UNSTRUCTURED_GRID
|
||||||
|
POINTS 12 double
|
||||||
|
-1 -1 -1
|
||||||
|
-1 1 -1
|
||||||
|
-1 -1 1
|
||||||
|
-1 1 1
|
||||||
|
1 -1 -1
|
||||||
|
1 1 -1
|
||||||
|
1 -1 1
|
||||||
|
1 1 1
|
||||||
|
3 -1 1
|
||||||
|
3 -1 -1
|
||||||
|
3 1 1
|
||||||
|
3 1 -1
|
||||||
|
|
||||||
|
CELLS 2 18
|
||||||
|
8 0 1 3 2 4 5 7 6
|
||||||
|
8 5 7 6 4 11 10 8 9
|
||||||
|
|
||||||
|
CELL_TYPES 2
|
||||||
|
12
|
||||||
|
12
|
||||||
|
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
# vtk DataFile Version 2.0
|
||||||
|
3D Mesh
|
||||||
|
ASCII
|
||||||
|
DATASET UNSTRUCTURED_GRID
|
||||||
|
POINTS 14 double
|
||||||
|
-1.78261 2.8477 -1.15226
|
||||||
|
-1.6885 2.94623 2.26566
|
||||||
|
0.921521 1.54537 2.23417
|
||||||
|
1.01511 -1.41435 2.31691
|
||||||
|
-1.59491 -0.0134989 2.3484
|
||||||
|
0.920989 -1.51287 -1.10101
|
||||||
|
-1.68903 -0.112022 -1.06953
|
||||||
|
0.827405 1.44685 -1.18375
|
||||||
|
0.921521 1.54537 2.23417
|
||||||
|
1.01511 -1.41435 2.31691
|
||||||
|
-1.59491 -0.0134989 2.3484
|
||||||
|
0.920989 -1.51287 -1.10101
|
||||||
|
-1.68903 -0.112022 -1.06953
|
||||||
|
0.827405 1.44685 -1.18375
|
||||||
|
|
||||||
|
CELLS 3 21
|
||||||
|
6 6 0 7 4 1 2
|
||||||
|
6 2 4 3 7 6 5
|
||||||
|
6 9 8 10 11 13 12
|
||||||
|
|
||||||
|
CELL_TYPES 3
|
||||||
|
13
|
||||||
|
13
|
||||||
|
13
|
||||||
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
# vtk DataFile Version 2.0
|
||||||
|
3D Mesh
|
||||||
|
ASCII
|
||||||
|
DATASET UNSTRUCTURED_GRID
|
||||||
|
POINTS 7 double
|
||||||
|
-0.149372 -0.608056 -1.19224
|
||||||
|
-2.05784 -0.0940108 -3.6419
|
||||||
|
-0.607052 -1.32749 -4.22213
|
||||||
|
0.70406 0.167065 -4.12109
|
||||||
|
-0.746726 1.40055 -3.54086
|
||||||
|
-2.13885 -2.38807 -3.52093
|
||||||
|
-1.35014 -2.31961 -1.69441
|
||||||
|
|
||||||
|
CELLS 2 12
|
||||||
|
5 2 1 4 3 0
|
||||||
|
5 2 0 6 5 1
|
||||||
|
|
||||||
|
CELL_TYPES 2
|
||||||
|
14
|
||||||
|
14
|
||||||
|
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
# vtk DataFile Version 2.0
|
||||||
|
CGAL Linear_cell_complex
|
||||||
|
ASCII
|
||||||
|
DATASET UNSTRUCTURED_GRID
|
||||||
|
|
||||||
|
POINTS 5 double
|
||||||
|
-3.38189 0.624914 -0.442232
|
||||||
|
-3.04657 -1.38801 -0.227267
|
||||||
|
-1.24112 -0.450255 -0.494661
|
||||||
|
-1.42311 -1.94845 0.895599
|
||||||
|
-2.49044 0.337128 1.70461
|
||||||
|
|
||||||
|
CELLS 2 10
|
||||||
|
4 1 0 4 2
|
||||||
|
4 1 2 4 3
|
||||||
|
|
||||||
|
CELL_TYPES 2
|
||||||
|
10
|
||||||
|
10
|
||||||
|
|
||||||
|
POINT_DATA 5
|
||||||
|
SCALARS point_scalars float 1
|
||||||
|
LOOKUP_TABLE default
|
||||||
|
0
|
||||||
|
1
|
||||||
|
2
|
||||||
|
3
|
||||||
|
4
|
||||||
|
CELL_DATA 2
|
||||||
|
SCALARS cell_scalars unsigned_long 1
|
||||||
|
LOOKUP_TABLE default
|
||||||
|
4
|
||||||
|
4
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
|
|
@ -138,7 +138,12 @@ public Q_SLOTS:
|
||||||
private:
|
private:
|
||||||
void showFileBox(QString title, QString fileName) {
|
void showFileBox(QString title, QString fileName) {
|
||||||
QFile textFile(fileName);
|
QFile textFile(fileName);
|
||||||
textFile.open(QIODevice::ReadOnly);
|
bool b = textFile.open(QIODevice::ReadOnly);
|
||||||
|
if(!b){
|
||||||
|
QMessageBox::critical(this, tr("Error"),
|
||||||
|
tr("Could not open file %1.").arg(fileName));
|
||||||
|
return;
|
||||||
|
}
|
||||||
QMessageBox mb(QMessageBox::NoIcon,
|
QMessageBox mb(QMessageBox::NoIcon,
|
||||||
title,
|
title,
|
||||||
QTextStream(&textFile).readAll(),
|
QTextStream(&textFile).readAll(),
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,7 @@
|
||||||
@INCLUDE = ${CGAL_DOC_PACKAGE_DEFAULTS}
|
@INCLUDE = ${CGAL_DOC_PACKAGE_DEFAULTS}
|
||||||
PROJECT_NAME = "CGAL ${CGAL_DOC_VERSION} - 3D Point Set"
|
PROJECT_NAME = "CGAL ${CGAL_DOC_VERSION} - 3D Point Set"
|
||||||
|
|
||||||
|
EXTRACT_ALL = false
|
||||||
|
HIDE_UNDOC_MEMBERS = true
|
||||||
|
HIDE_UNDOC_CLASSES = true
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,9 +43,6 @@
|
||||||
/// I/O Functions for the \ref IOStreamXYZ
|
/// I/O Functions for the \ref IOStreamXYZ
|
||||||
/// \ingroup PkgPointSet3IO
|
/// \ingroup PkgPointSet3IO
|
||||||
|
|
||||||
/// \defgroup PkgPointSet3IODeprecated Input/Output (Deprecated)
|
|
||||||
/// \ingroup PkgPointSet3IO
|
|
||||||
/// These I/O functions are deprecated and newer versions should be used.
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\addtogroup PkgPointSet3Ref
|
\addtogroup PkgPointSet3Ref
|
||||||
|
|
|
||||||
|
|
@ -13,10 +13,8 @@
|
||||||
|
|
||||||
#include <CGAL/license/Point_set_3.h>
|
#include <CGAL/license/Point_set_3.h>
|
||||||
|
|
||||||
#ifdef CGAL_LINKED_WITH_LASLIB
|
#include <CGAL/IO/LAS/read_las_points.h>
|
||||||
#include <CGAL/IO/read_las_points.h>
|
#include <CGAL/IO/LAS/write_las_points.h>
|
||||||
#include <CGAL/IO/write_las_points.h>
|
|
||||||
#endif // LAS
|
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,8 @@
|
||||||
#include <CGAL/Named_function_parameters.h>
|
#include <CGAL/Named_function_parameters.h>
|
||||||
#include <CGAL/boost/graph/named_params_helper.h>
|
#include <CGAL/boost/graph/named_params_helper.h>
|
||||||
#include <CGAL/IO/helpers.h>
|
#include <CGAL/IO/helpers.h>
|
||||||
#include <CGAL/IO/read_off_points.h>
|
#include <CGAL/IO/OFF/read_off_points.h>
|
||||||
#include <CGAL/IO/write_off_points.h>
|
#include <CGAL/IO/OFF/write_off_points.h>
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
|
||||||
|
|
@ -15,8 +15,8 @@
|
||||||
|
|
||||||
#include <CGAL/Named_function_parameters.h>
|
#include <CGAL/Named_function_parameters.h>
|
||||||
#include <CGAL/boost/graph/named_params_helper.h>
|
#include <CGAL/boost/graph/named_params_helper.h>
|
||||||
#include <CGAL/IO/read_xyz_points.h>
|
#include <CGAL/IO/XYZ/read_xyz_points.h>
|
||||||
#include <CGAL/IO/write_xyz_points.h>
|
#include <CGAL/IO/XYZ/write_xyz_points.h>
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ Kernel_d
|
||||||
Modular_arithmetic
|
Modular_arithmetic
|
||||||
Number_types
|
Number_types
|
||||||
Point_set_3
|
Point_set_3
|
||||||
Point_set_processing_3
|
|
||||||
Polygon
|
Polygon
|
||||||
Profiling_tools
|
Profiling_tools
|
||||||
Property_map
|
Property_map
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||||
|
|
||||||
#include <CGAL/Point_set_3.h>
|
#include <CGAL/Point_set_3.h>
|
||||||
#include <CGAL/IO/write_xyz_points.h>
|
|
||||||
#include <CGAL/grid_simplify_point_set.h>
|
#include <CGAL/grid_simplify_point_set.h>
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
|
||||||
|
|
@ -10,23 +10,6 @@ simplification, etc.).
|
||||||
\defgroup PkgPointSetProcessing3IO I/O Functions
|
\defgroup PkgPointSetProcessing3IO I/O Functions
|
||||||
\ingroup PkgPointSetProcessing3Ref
|
\ingroup PkgPointSetProcessing3Ref
|
||||||
|
|
||||||
\defgroup PkgPointSetProcessing3IOOff I/O (OFF Formats)
|
|
||||||
\ingroup PkgPointSetProcessing3Ref
|
|
||||||
|
|
||||||
\defgroup PkgPointSetProcessing3IOXyz I/O (XYZ Formats)
|
|
||||||
\ingroup PkgPointSetProcessing3Ref
|
|
||||||
|
|
||||||
\defgroup PkgPointSetProcessing3IOPly I/O (PLY Format)
|
|
||||||
\ingroup PkgPointSetProcessing3Ref
|
|
||||||
|
|
||||||
Read and write points (with or without additional properties) in PLY
|
|
||||||
format.
|
|
||||||
|
|
||||||
\defgroup PkgPointSetProcessing3IOLas I/O (LAS Format)
|
|
||||||
\ingroup PkgPointSetProcessing3Ref
|
|
||||||
|
|
||||||
Read and write points (with or without additional properties) in LAS
|
|
||||||
format.
|
|
||||||
|
|
||||||
\addtogroup PkgPointSetProcessing3Ref
|
\addtogroup PkgPointSetProcessing3Ref
|
||||||
\cgalPkgDescriptionBegin{Point Set Processing,PkgPointSetProcessing3}
|
\cgalPkgDescriptionBegin{Point Set Processing,PkgPointSetProcessing3}
|
||||||
|
|
@ -84,14 +67,14 @@ format.
|
||||||
|
|
||||||
\cgalCRPSection{I/O (XYZ/OFF Formats)}
|
\cgalCRPSection{I/O (XYZ/OFF Formats)}
|
||||||
|
|
||||||
- \link PkgPointSetProcessing3IOOff OFF I/O Functions (`read_OFF()` and `write_OFF()`)\endlink
|
- \link PkgStreamSupportIoFuncsOFF OFF I/O Functions (`read_OFF()` and `write_OFF()`)\endlink
|
||||||
- \link PkgPointSetProcessing3IOXyz XYZ I/O Functions (`read_XYZ()` and `write_XYZ()`)\endlink
|
- \link PkgStreamSupportIoFuncsXYZ XYZ I/O Functions (`read_XYZ()` and `write_XYZ()`)\endlink
|
||||||
|
|
||||||
\cgalCRPSection{I/O (PLY Format)}
|
\cgalCRPSection{I/O (PLY Format)}
|
||||||
|
|
||||||
- \link PkgPointSetProcessing3IOPly `CGAL::IO::read_PLY()` \endlink
|
- \link PkgStreamSupportIoFuncsPLY `CGAL::IO::read_PLY()` \endlink
|
||||||
- `CGAL::IO::read_PLY_with_properties()`
|
- `CGAL::IO::read_PLY_with_properties()`
|
||||||
- \link PkgPointSetProcessing3IOPly `CGAL::IO::write_PLY()` \endlink
|
- \link PkgStreamSupportIoFuncsPLY `CGAL::IO::write_PLY()` \endlink
|
||||||
- `CGAL::IO::write_PLY_with_properties()`
|
- `CGAL::IO::write_PLY_with_properties()`
|
||||||
- `CGAL::IO::PLY_property<T>`
|
- `CGAL::IO::PLY_property<T>`
|
||||||
- `CGAL::IO::make_ply_point_reader()`
|
- `CGAL::IO::make_ply_point_reader()`
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#include <CGAL/Simple_cartesian.h>
|
#include <CGAL/Simple_cartesian.h>
|
||||||
#include <CGAL/IO/read_las_points.h>
|
#include <CGAL/Point_set_3/IO/LAS.h>
|
||||||
#include <CGAL/IO/write_ply_points.h>
|
#include <CGAL/IO/LAS.h>
|
||||||
|
#include <CGAL/IO/PLY.h>
|
||||||
#include <CGAL/jet_estimate_normals.h>
|
#include <CGAL/jet_estimate_normals.h>
|
||||||
#include <CGAL/scanline_orient_normals.h>
|
#include <CGAL/scanline_orient_normals.h>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||||
|
|
||||||
#include <CGAL/property_map.h>
|
#include <CGAL/property_map.h>
|
||||||
#include <CGAL/IO/read_las_points.h>
|
#include <CGAL/IO/LAS.h>
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||||
|
|
||||||
#include <CGAL/property_map.h>
|
#include <CGAL/property_map.h>
|
||||||
#include <CGAL/IO/read_ply_points.h>
|
#include <CGAL/IO/PLY.h>
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||||
|
|
||||||
#include <CGAL/property_map.h>
|
#include <CGAL/property_map.h>
|
||||||
#include <CGAL/IO/read_xyz_points.h>
|
#include <CGAL/IO/XYZ.h>
|
||||||
#include <CGAL/IO/write_xyz_points.h>
|
|
||||||
|
|
||||||
#include <utility> // defines std::pair
|
#include <utility> // defines std::pair
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||||
|
|
||||||
#include <CGAL/property_map.h>
|
#include <CGAL/property_map.h>
|
||||||
#include <CGAL/IO/read_las_points.h>
|
#include <CGAL/IO/LAS.h>
|
||||||
#include <CGAL/IO/write_las_points.h>
|
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||||
|
|
||||||
#include <CGAL/property_map.h>
|
#include <CGAL/property_map.h>
|
||||||
#include <CGAL/IO/write_ply_points.h>
|
#include <CGAL/IO/PLY.h>
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
|
||||||
|
|
@ -1,367 +0,0 @@
|
||||||
// Copyright (c) 2015 Geometry Factory
|
|
||||||
// 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) : Simon Giraudot
|
|
||||||
|
|
||||||
#ifndef CGAL_POINT_SET_PROCESSING_READ_PLY_POINTS_H
|
|
||||||
#define CGAL_POINT_SET_PROCESSING_READ_PLY_POINTS_H
|
|
||||||
|
|
||||||
#include <CGAL/license/Point_set_processing_3.h>
|
|
||||||
|
|
||||||
#include <CGAL/config.h>
|
|
||||||
|
|
||||||
#include <CGAL/IO/PLY.h>
|
|
||||||
#include <CGAL/property_map.h>
|
|
||||||
#include <CGAL/value_type_traits.h>
|
|
||||||
#include <CGAL/Kernel_traits.h>
|
|
||||||
#include <CGAL/IO/io.h>
|
|
||||||
|
|
||||||
#include <CGAL/Named_function_parameters.h>
|
|
||||||
#include <CGAL/boost/graph/named_params_helper.h>
|
|
||||||
|
|
||||||
#include <boost/version.hpp>
|
|
||||||
#include <boost/cstdint.hpp>
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <fstream>
|
|
||||||
#include <sstream>
|
|
||||||
#include <string>
|
|
||||||
#include <tuple>
|
|
||||||
|
|
||||||
namespace CGAL {
|
|
||||||
|
|
||||||
namespace IO {
|
|
||||||
|
|
||||||
#ifdef DOXYGEN_RUNNING // Document some parts from Stream_support here for convenience
|
|
||||||
/**
|
|
||||||
\ingroup PkgPointSetProcessing3IOPly
|
|
||||||
|
|
||||||
Class used to identify a %PLY property as a type and a name.
|
|
||||||
|
|
||||||
\sa `read_PLY_with_properties()`
|
|
||||||
*/
|
|
||||||
template <typename T>
|
|
||||||
struct PLY_property
|
|
||||||
{
|
|
||||||
typedef T type;
|
|
||||||
const char* name;
|
|
||||||
PLY_property(const char* name) : name(name) { }
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
\ingroup PkgPointSetProcessing3IOPly
|
|
||||||
|
|
||||||
Generates a %PLY property handler to read 3D points. Points are
|
|
||||||
constructed from the input using 3 %PLY properties of type `FT`
|
|
||||||
and named `x`, `y` and `z`. `FT` is `float` if the points use
|
|
||||||
`CGAL::Simple_cartesian<float>` and `double` otherwise.
|
|
||||||
|
|
||||||
\tparam PointMap the property map used to store points.
|
|
||||||
|
|
||||||
\sa `read_PLY_with_properties()`
|
|
||||||
\sa \ref IOStreamPLY
|
|
||||||
*/
|
|
||||||
template <typename PointMap>
|
|
||||||
std::tuple<PointMap,
|
|
||||||
typename Kernel_traits<typename PointMap::value_type>::Kernel::Construct_point_3,
|
|
||||||
PLY_property<FT>, PLY_property<FT>, PLY_property<FT> >
|
|
||||||
make_ply_point_reader(PointMap point_map);
|
|
||||||
|
|
||||||
/**
|
|
||||||
\ingroup PkgPointSetProcessing3IOPly
|
|
||||||
|
|
||||||
Generates a %PLY property handler to read 3D normal
|
|
||||||
vectors. Vectors are constructed from the input using 3 PLY
|
|
||||||
properties of type `FT` and named `nx`, `ny` and `nz`. `FT`
|
|
||||||
is `float` if the points use `CGAL::Simple_cartesian<float>` and
|
|
||||||
`double` otherwise.
|
|
||||||
|
|
||||||
\tparam VectorMap the property map used to store vectors.
|
|
||||||
|
|
||||||
\sa `read_PLY_with_properties()`
|
|
||||||
\sa \ref IOStreamPLY
|
|
||||||
*/
|
|
||||||
template <typename VectorMap>
|
|
||||||
std::tuple<VectorMap,
|
|
||||||
typename Kernel_traits<typename VectorMap::value_type>::Kernel::Construct_vector_3,
|
|
||||||
PLY_property<FT>, PLY_property<FT>, PLY_property<FT> >
|
|
||||||
make_ply_normal_reader(VectorMap normal_map);
|
|
||||||
|
|
||||||
#endif // DOXYGEN_RUNNING
|
|
||||||
|
|
||||||
/**
|
|
||||||
\ingroup PkgPointSetProcessing3IOPly
|
|
||||||
|
|
||||||
\brief reads user-selected points properties from a .ply stream (ASCII or binary).
|
|
||||||
|
|
||||||
Potential additional point properties and faces are ignored.
|
|
||||||
|
|
||||||
Properties are handled through a variadic list of property
|
|
||||||
handlers. A `PropertyHandler` can either be:
|
|
||||||
|
|
||||||
- A `std::pair<PropertyMap, PLY_property<T> >` if the user wants
|
|
||||||
to read a %PLY property as a scalar value T (for example, storing
|
|
||||||
an `int` %PLY property into an `int` variable).
|
|
||||||
|
|
||||||
- A `std::tuple<PropertyMap, Constructor,
|
|
||||||
PLY_property<T>...>` if the user wants to use one or several PLY
|
|
||||||
properties to construct a complex object (for example, storing 3
|
|
||||||
`uchar` %PLY properties into a %Color object that can for example
|
|
||||||
be a `std::array<unsigned char, 3>`). In that case, the
|
|
||||||
second element of the tuple should be a functor that constructs
|
|
||||||
the value type of `PropertyMap` from N objects of types `T`.
|
|
||||||
|
|
||||||
\attention To read a binary file, the flag `std::ios::binary` must be set during the creation of the `ifstream`.
|
|
||||||
|
|
||||||
\tparam OutputIteratorValueType type of objects that can be put in `PointOutputIterator`.
|
|
||||||
It must be a model of `DefaultConstructible` and defaults to `value_type_traits<PointOutputIterator>::%type`.
|
|
||||||
It can be omitted when the default is fine.
|
|
||||||
\tparam PointOutputIterator iterator over output points.
|
|
||||||
\tparam PropertyHandler handlers to recover properties.
|
|
||||||
|
|
||||||
\returns `true` if reading was successful, `false` otherwise.
|
|
||||||
|
|
||||||
\sa \ref IOStreamPLY
|
|
||||||
\sa `make_ply_point_reader()`
|
|
||||||
\sa `make_ply_normal_reader()`
|
|
||||||
*/
|
|
||||||
template <typename OutputIteratorValueType,
|
|
||||||
typename PointOutputIterator,
|
|
||||||
typename ... PropertyHandler>
|
|
||||||
bool read_PLY_with_properties(std::istream& is,
|
|
||||||
PointOutputIterator output,
|
|
||||||
PropertyHandler&& ... properties)
|
|
||||||
{
|
|
||||||
if(!is)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
internal::PLY_reader reader(true);
|
|
||||||
|
|
||||||
if(!(reader.init(is)))
|
|
||||||
{
|
|
||||||
is.setstate(std::ios::failbit);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(std::size_t i = 0; i < reader.number_of_elements(); ++ i)
|
|
||||||
{
|
|
||||||
internal::PLY_element& element = reader.element(i);
|
|
||||||
|
|
||||||
for(std::size_t j = 0; j < element.number_of_items(); ++ j)
|
|
||||||
{
|
|
||||||
for(std::size_t k = 0; k < element.number_of_properties(); ++ k)
|
|
||||||
{
|
|
||||||
internal::PLY_read_number* property = element.property(k);
|
|
||||||
property->get(is);
|
|
||||||
|
|
||||||
if(is.fail())
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(element.name() == "vertex" || element.name() == "vertices")
|
|
||||||
{
|
|
||||||
OutputIteratorValueType new_element;
|
|
||||||
internal::process_properties(element, new_element, std::forward<PropertyHandler>(properties)...);
|
|
||||||
*(output ++) = new_element;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \cond SKIP_IN_MANUAL
|
|
||||||
|
|
||||||
template <typename OutputIterator,
|
|
||||||
typename ... PropertyHandler>
|
|
||||||
bool read_PLY_with_properties(std::istream& is,
|
|
||||||
OutputIterator output,
|
|
||||||
PropertyHandler&& ... properties)
|
|
||||||
{
|
|
||||||
typedef typename value_type_traits<OutputIterator>::type OutputValueType;
|
|
||||||
|
|
||||||
return read_PLY_with_properties<OutputValueType>(is, output, std::forward<PropertyHandler>(properties)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \endcond
|
|
||||||
|
|
||||||
/**
|
|
||||||
\ingroup PkgPointSetProcessing3IOPly
|
|
||||||
|
|
||||||
\brief reads points (positions + normals, if available), using the \ref IOStreamPLY.
|
|
||||||
|
|
||||||
Potential additional point properties and faces are ignored.
|
|
||||||
|
|
||||||
\attention To read a binary file, the flag `std::ios::binary` must be set during the creation of the `ifstream`.
|
|
||||||
|
|
||||||
\tparam OutputIteratorValueType type of objects that can be put in `PointOutputIterator`.
|
|
||||||
It must be a model of `DefaultConstructible` and defaults to `value_type_traits<PointOutputIterator>::%type`.
|
|
||||||
It can be omitted when the default is fine.
|
|
||||||
\tparam PointOutputIterator iterator over output points.
|
|
||||||
\tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters"
|
|
||||||
|
|
||||||
\param is input stream.
|
|
||||||
\param output output iterator over points.
|
|
||||||
\param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below
|
|
||||||
|
|
||||||
\cgalNamedParamsBegin
|
|
||||||
\cgalParamNBegin{point_map}
|
|
||||||
\cgalParamDescription{a property map associating points to the elements of the point range}
|
|
||||||
\cgalParamType{a model of `WritablePropertyMap` with value type `geom_traits::Point_3`}
|
|
||||||
\cgalParamDefault{`CGAL::Identity_property_map<geom_traits::Point_3>`}
|
|
||||||
\cgalParamNEnd
|
|
||||||
|
|
||||||
\cgalParamNBegin{normal_map}
|
|
||||||
\cgalParamDescription{a property map associating normals to the elements of the point range}
|
|
||||||
\cgalParamType{a model of `WritablePropertyMap` with value type `geom_traits::Vector_3`}
|
|
||||||
\cgalParamDefault{If this parameter is omitted, normals in the input stream are ignored.}
|
|
||||||
\cgalParamNEnd
|
|
||||||
|
|
||||||
\cgalParamNBegin{geom_traits}
|
|
||||||
\cgalParamDescription{an instance of a geometric traits class}
|
|
||||||
\cgalParamType{a model of `Kernel`}
|
|
||||||
\cgalParamDefault{a \cgal Kernel deduced from the point type, using `CGAL::Kernel_traits`}
|
|
||||||
\cgalParamNEnd
|
|
||||||
\cgalNamedParamsEnd
|
|
||||||
|
|
||||||
\returns `true` if reading was successful, `false` otherwise.
|
|
||||||
|
|
||||||
\sa `read_PLY_with_properties()`
|
|
||||||
*/
|
|
||||||
template <typename OutputIteratorValueType,
|
|
||||||
typename PointOutputIterator,
|
|
||||||
typename CGAL_NP_TEMPLATE_PARAMETERS>
|
|
||||||
bool read_PLY(std::istream& is,
|
|
||||||
PointOutputIterator output,
|
|
||||||
const CGAL_NP_CLASS& np = parameters::default_values()
|
|
||||||
#ifndef DOXYGEN_RUNNING
|
|
||||||
, std::enable_if_t<CGAL::is_iterator<PointOutputIterator>::value>* = nullptr
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
{
|
|
||||||
using parameters::choose_parameter;
|
|
||||||
using parameters::get_parameter;
|
|
||||||
|
|
||||||
typedef Point_set_processing_3::Fake_point_range<OutputIteratorValueType> PointRange;
|
|
||||||
|
|
||||||
// basic geometric types
|
|
||||||
typedef Point_set_processing_3_np_helper<PointRange, CGAL_NP_CLASS> NP_helper;
|
|
||||||
typedef typename NP_helper::Point_map PointMap;
|
|
||||||
typedef typename NP_helper::Normal_map NormalMap;
|
|
||||||
|
|
||||||
PointMap point_map = NP_helper::get_point_map(np);
|
|
||||||
NormalMap normal_map = NP_helper::get_normal_map(np);
|
|
||||||
|
|
||||||
return read_PLY_with_properties(is, output,
|
|
||||||
make_ply_point_reader(point_map),
|
|
||||||
make_ply_normal_reader(normal_map));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
\ingroup PkgPointSetProcessing3IOPly
|
|
||||||
|
|
||||||
\brief reads points (positions + normals, if available), using the \ref IOStreamPLY.
|
|
||||||
|
|
||||||
Potential additional point properties and faces are ignored.
|
|
||||||
|
|
||||||
\tparam OutputIteratorValueType type of objects that can be put in `PointOutputIterator`.
|
|
||||||
It must be a model of `DefaultConstructible` and defaults to `value_type_traits<PointOutputIterator>::%type`.
|
|
||||||
It can be omitted when the default is fine.
|
|
||||||
\tparam PointOutputIterator iterator over output points.
|
|
||||||
\tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters"
|
|
||||||
|
|
||||||
\param fname input file name.
|
|
||||||
\param output output iterator over points.
|
|
||||||
\param np optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below.
|
|
||||||
|
|
||||||
\cgalNamedParamsBegin
|
|
||||||
\cgalParamNBegin{use_binary_mode}
|
|
||||||
\cgalParamDescription{indicates whether data should be read in binary (`true`) or in \ascii (`false`)}
|
|
||||||
\cgalParamType{Boolean}
|
|
||||||
\cgalParamDefault{`true`}
|
|
||||||
\cgalParamNEnd
|
|
||||||
|
|
||||||
\cgalParamNBegin{point_map}
|
|
||||||
\cgalParamDescription{a property map associating points to the elements of the point range}
|
|
||||||
\cgalParamType{a model of `WritablePropertyMap` with value type `geom_traits::Point_3`}
|
|
||||||
\cgalParamDefault{`CGAL::Identity_property_map<geom_traits::Point_3>`}
|
|
||||||
\cgalParamNEnd
|
|
||||||
|
|
||||||
\cgalParamNBegin{normal_map}
|
|
||||||
\cgalParamDescription{a property map associating normals to the elements of the point range}
|
|
||||||
\cgalParamType{a model of `WritablePropertyMap` with value type `geom_traits::Vector_3`}
|
|
||||||
\cgalParamDefault{If this parameter is omitted, normals in the input stream are ignored.}
|
|
||||||
\cgalParamNEnd
|
|
||||||
|
|
||||||
\cgalParamNBegin{geom_traits}
|
|
||||||
\cgalParamDescription{an instance of a geometric traits class}
|
|
||||||
\cgalParamType{a model of `Kernel`}
|
|
||||||
\cgalParamDefault{a \cgal Kernel deduced from the point type, using `CGAL::Kernel_traits`}
|
|
||||||
\cgalParamNEnd
|
|
||||||
\cgalNamedParamsEnd
|
|
||||||
|
|
||||||
\returns `true` if reading was successful, `false` otherwise.
|
|
||||||
|
|
||||||
\sa \ref IOStreamPLY
|
|
||||||
\sa `read_PLY_with_properties()`
|
|
||||||
*/
|
|
||||||
template <typename OutputIteratorValueType,
|
|
||||||
typename PointOutputIterator,
|
|
||||||
typename CGAL_NP_TEMPLATE_PARAMETERS>
|
|
||||||
bool read_PLY(const std::string& fname,
|
|
||||||
PointOutputIterator output,
|
|
||||||
const CGAL_NP_CLASS& np = parameters::default_values()
|
|
||||||
#ifndef DOXYGEN_RUNNING
|
|
||||||
, std::enable_if_t<CGAL::is_iterator<PointOutputIterator>::value>* = nullptr
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
{
|
|
||||||
const bool binary = CGAL::parameters::choose_parameter(CGAL::parameters::get_parameter(np, internal_np::use_binary_mode), true);
|
|
||||||
if(binary)
|
|
||||||
{
|
|
||||||
std::ifstream is(fname, std::ios::binary);
|
|
||||||
CGAL::IO::set_mode(is, CGAL::IO::BINARY);
|
|
||||||
return read_PLY<OutputIteratorValueType>(is, output, np);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::ifstream is(fname);
|
|
||||||
CGAL::IO::set_mode(is, CGAL::IO::ASCII);
|
|
||||||
return read_PLY<OutputIteratorValueType>(is, output, np);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \cond SKIP_IN_MANUAL
|
|
||||||
|
|
||||||
// variants with default output iterator value type
|
|
||||||
template <typename OutputIterator, typename CGAL_NP_TEMPLATE_PARAMETERS>
|
|
||||||
bool read_PLY(std::istream& is, OutputIterator output, const CGAL_NP_CLASS& np = parameters::default_values(),
|
|
||||||
std::enable_if_t<CGAL::is_iterator<OutputIterator>::value>* = nullptr)
|
|
||||||
{
|
|
||||||
return read_PLY<typename value_type_traits<OutputIterator>::type>(is, output, np);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename OutputIterator,typename CGAL_NP_TEMPLATE_PARAMETERS>
|
|
||||||
bool read_PLY(const std::string& fname, OutputIterator output, const CGAL_NP_CLASS& np = parameters::default_values(),
|
|
||||||
std::enable_if_t<CGAL::is_iterator<OutputIterator>::value>* = nullptr)
|
|
||||||
{
|
|
||||||
return read_PLY<typename value_type_traits<OutputIterator>::type>(fname, output, np);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \endcond
|
|
||||||
|
|
||||||
} // namespace IO
|
|
||||||
|
|
||||||
} // namespace CGAL
|
|
||||||
|
|
||||||
#undef TRY_TO_GENERATE_POINT_PROPERTY
|
|
||||||
#undef TRY_TO_GENERATE_SIZED_FACE_PROPERTY
|
|
||||||
#undef TRY_TO_GENERATE_FACE_PROPERTY
|
|
||||||
|
|
||||||
#endif // CGAL_POINT_SET_PROCESSING_READ_PLY_POINTS_H
|
|
||||||
|
|
@ -1,203 +0,0 @@
|
||||||
// Copyright (c) 2007-09 INRIA Sophia-Antipolis (France).
|
|
||||||
// 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) : Pierre Alliez and Laurent Saboret
|
|
||||||
|
|
||||||
#ifndef CGAL_POINT_SET_PROCESSING_WRITE_OFF_POINTS_H
|
|
||||||
#define CGAL_POINT_SET_PROCESSING_WRITE_OFF_POINTS_H
|
|
||||||
|
|
||||||
#include <CGAL/license/Point_set_processing_3.h>
|
|
||||||
|
|
||||||
#include <CGAL/IO/helpers.h>
|
|
||||||
#include <CGAL/IO/OFF.h>
|
|
||||||
|
|
||||||
#include <CGAL/Named_function_parameters.h>
|
|
||||||
#include <CGAL/boost/graph/named_params_helper.h>
|
|
||||||
#include <CGAL/property_map.h>
|
|
||||||
#include <CGAL/Iterator_range.h>
|
|
||||||
#include <CGAL/assertions.h>
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <fstream>
|
|
||||||
#include <iterator>
|
|
||||||
#include <type_traits>
|
|
||||||
|
|
||||||
namespace CGAL {
|
|
||||||
namespace Point_set_processing_3 {
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
template <typename PointRange, typename CGAL_NP_TEMPLATE_PARAMETERS>
|
|
||||||
bool write_OFF_PSP(std::ostream& os,
|
|
||||||
const PointRange& points,
|
|
||||||
const CGAL_NP_CLASS& np = CGAL::parameters::default_values())
|
|
||||||
{
|
|
||||||
using CGAL::parameters::is_default_parameter;
|
|
||||||
|
|
||||||
// basic geometric types
|
|
||||||
typedef Point_set_processing_3_np_helper<PointRange, CGAL_NP_CLASS> NP_helper;
|
|
||||||
typedef typename NP_helper::Const_point_map PointMap;
|
|
||||||
typedef typename NP_helper::Normal_map NormalMap;
|
|
||||||
|
|
||||||
const bool has_normals = NP_helper::has_normal_map(points, np);
|
|
||||||
|
|
||||||
PointMap point_map = NP_helper::get_const_point_map(points, np);
|
|
||||||
NormalMap normal_map = NP_helper::get_normal_map(points, np);
|
|
||||||
|
|
||||||
CGAL_precondition(points.begin() != points.end());
|
|
||||||
|
|
||||||
if(!os)
|
|
||||||
{
|
|
||||||
std::cerr << "Error: cannot open file" << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
set_stream_precision_from_NP(os, np);
|
|
||||||
|
|
||||||
// Write header
|
|
||||||
if (has_normals)
|
|
||||||
os << "NOFF" << std::endl;
|
|
||||||
else
|
|
||||||
os << "OFF" << std::endl;
|
|
||||||
os << points.size() << " 0 0" << std::endl;
|
|
||||||
|
|
||||||
// Write positions + normals
|
|
||||||
for(typename PointRange::const_iterator it = points.begin(); it != points.end(); it++)
|
|
||||||
{
|
|
||||||
os << get(point_map, *it);
|
|
||||||
if (has_normals)
|
|
||||||
os << " " << get(normal_map, *it);
|
|
||||||
os << "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
os << std::flush;
|
|
||||||
|
|
||||||
return !os.fail();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
} // namespace Point_set_processing_3
|
|
||||||
|
|
||||||
namespace IO {
|
|
||||||
|
|
||||||
/**
|
|
||||||
\ingroup PkgPointSetProcessing3IOOff
|
|
||||||
|
|
||||||
\brief writes the range of `points` (positions + normals, if available), using the \ref IOStreamOFF.
|
|
||||||
|
|
||||||
\tparam PointRange is a model of `ConstRange`. The value type of
|
|
||||||
its iterator is the key type of the named parameter `point_map`.
|
|
||||||
\tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters"
|
|
||||||
|
|
||||||
\param os output stream
|
|
||||||
\param points input point range
|
|
||||||
\param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below
|
|
||||||
|
|
||||||
\cgalNamedParamsBegin
|
|
||||||
\cgalParamNBegin{point_map}
|
|
||||||
\cgalParamDescription{a property map associating points to the elements of the point range}
|
|
||||||
\cgalParamType{a model of `ReadablePropertyMap` with value type `geom_traits::Point_3`}
|
|
||||||
\cgalParamDefault{`CGAL::Identity_property_map<geom_traits::Point_3>`}
|
|
||||||
\cgalParamNEnd
|
|
||||||
|
|
||||||
\cgalParamNBegin{normal_map}
|
|
||||||
\cgalParamDescription{a property map associating normals to the elements of the point range}
|
|
||||||
\cgalParamType{a model of `ReadablePropertyMap` with value type `geom_traits::Vector_3`}
|
|
||||||
\cgalParamDefault{If this parameter is omitted, normals are not written in the output stream.}
|
|
||||||
\cgalParamNEnd
|
|
||||||
|
|
||||||
\cgalParamNBegin{geom_traits}
|
|
||||||
\cgalParamDescription{an instance of a geometric traits class}
|
|
||||||
\cgalParamType{a model of `Kernel`}
|
|
||||||
\cgalParamDefault{a \cgal Kernel deduced from the point type, using `CGAL::Kernel_traits`}
|
|
||||||
\cgalParamNEnd
|
|
||||||
|
|
||||||
\cgalParamNBegin{stream_precision}
|
|
||||||
\cgalParamDescription{a parameter used to set the precision (i.e. how many digits are generated) of the output stream}
|
|
||||||
\cgalParamType{int}
|
|
||||||
\cgalParamDefault{the precision of the stream `os`}
|
|
||||||
\cgalParamNEnd
|
|
||||||
\cgalNamedParamsEnd
|
|
||||||
|
|
||||||
\returns `true` if writing was successful, `false` otherwise.
|
|
||||||
*/
|
|
||||||
template <typename PointRange, typename CGAL_NP_TEMPLATE_PARAMETERS>
|
|
||||||
bool write_OFF(std::ostream& os,
|
|
||||||
const PointRange& points,
|
|
||||||
const CGAL_NP_CLASS& np = parameters::default_values()
|
|
||||||
#ifndef DOXYGEN_RUNNING
|
|
||||||
, std::enable_if_t<internal::is_Range<PointRange>::value>* = nullptr
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return Point_set_processing_3::internal::write_OFF_PSP(os, points, np);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
\ingroup PkgPointSetProcessing3IOOff
|
|
||||||
|
|
||||||
\brief writes the range of `points` (positions + normals, if available), using the \ref IOStreamOFF.
|
|
||||||
|
|
||||||
\tparam PointRange is a model of `ConstRange`. The value type of
|
|
||||||
its iterator is the key type of the named parameter `point_map`.
|
|
||||||
\tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters"
|
|
||||||
|
|
||||||
\param filename the path to the output file
|
|
||||||
\param points input point range
|
|
||||||
\param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below
|
|
||||||
|
|
||||||
\cgalNamedParamsBegin
|
|
||||||
\cgalParamNBegin{point_map}
|
|
||||||
\cgalParamDescription{a property map associating points to the elements of the point range}
|
|
||||||
\cgalParamType{a model of `ReadablePropertyMap` with value type `geom_traits::Point_3`}
|
|
||||||
\cgalParamDefault{`CGAL::Identity_property_map<geom_traits::Point_3>`}
|
|
||||||
\cgalParamNEnd
|
|
||||||
|
|
||||||
\cgalParamNBegin{normal_map}
|
|
||||||
\cgalParamDescription{a property map associating normals to the elements of the point range}
|
|
||||||
\cgalParamType{a model of `ReadablePropertyMap` with value type `geom_traits::Vector_3`}
|
|
||||||
\cgalParamDefault{If this parameter is omitted, normals are not written in the output file.}
|
|
||||||
\cgalParamNEnd
|
|
||||||
|
|
||||||
\cgalParamNBegin{geom_traits}
|
|
||||||
\cgalParamDescription{an instance of a geometric traits class}
|
|
||||||
\cgalParamType{a model of `Kernel`}
|
|
||||||
\cgalParamDefault{a \cgal Kernel deduced from the point type, using `CGAL::Kernel_traits`}
|
|
||||||
\cgalParamNEnd
|
|
||||||
|
|
||||||
\cgalParamNBegin{stream_precision}
|
|
||||||
\cgalParamDescription{a parameter used to set the precision (i.e. how many digits are generated) of the output stream}
|
|
||||||
\cgalParamType{int}
|
|
||||||
\cgalParamDefault{`6`}
|
|
||||||
\cgalParamNEnd
|
|
||||||
\cgalNamedParamsEnd
|
|
||||||
|
|
||||||
\returns `true` if writing was successful, `false` otherwise.
|
|
||||||
|
|
||||||
\sa \ref IOStreamOFF
|
|
||||||
*/
|
|
||||||
template <typename PointRange,
|
|
||||||
typename CGAL_NP_TEMPLATE_PARAMETERS>
|
|
||||||
bool write_OFF(const std::string& filename,
|
|
||||||
const PointRange& points,
|
|
||||||
const CGAL_NP_CLASS& np = parameters::default_values()
|
|
||||||
#ifndef DOXYGEN_RUNNING
|
|
||||||
, std::enable_if_t<internal::is_Range<PointRange>::value>* = nullptr
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
{
|
|
||||||
std::ofstream os(filename);
|
|
||||||
set_stream_precision_from_NP(os, np);
|
|
||||||
return write_OFF(os, points, np);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // IO namespace
|
|
||||||
|
|
||||||
} // namespace CGAL
|
|
||||||
|
|
||||||
#endif // CGAL_POINT_SET_PROCESSING_WRITE_OFF_POINTS_H
|
|
||||||
|
|
@ -1,303 +0,0 @@
|
||||||
// Copyright (c) 2015 Geometry Factory
|
|
||||||
// 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) : Simon Giraudot
|
|
||||||
|
|
||||||
#ifndef CGAL_POINT_SET_PROCESSING_WRITE_PLY_POINTS_H
|
|
||||||
#define CGAL_POINT_SET_PROCESSING_WRITE_PLY_POINTS_H
|
|
||||||
|
|
||||||
#include <CGAL/license/Point_set_processing_3.h>
|
|
||||||
|
|
||||||
#include <CGAL/IO/helpers.h>
|
|
||||||
#include <CGAL/IO/PLY.h>
|
|
||||||
|
|
||||||
#include <CGAL/property_map.h>
|
|
||||||
#include <CGAL/assertions.h>
|
|
||||||
#include <CGAL/Iterator_range.h>
|
|
||||||
|
|
||||||
#include <CGAL/Named_function_parameters.h>
|
|
||||||
#include <CGAL/boost/graph/named_params_helper.h>
|
|
||||||
|
|
||||||
#include <boost/version.hpp>
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <fstream>
|
|
||||||
#include <iterator>
|
|
||||||
#include <tuple>
|
|
||||||
#include <type_traits>
|
|
||||||
|
|
||||||
namespace CGAL {
|
|
||||||
|
|
||||||
namespace IO {
|
|
||||||
|
|
||||||
#ifdef DOXYGEN_RUNNING // Document some parts from Stream_support here for convenience
|
|
||||||
/**
|
|
||||||
\ingroup PkgPointSetProcessing3IOPly
|
|
||||||
|
|
||||||
Generates a %PLY property handler to write 3D points. Points are
|
|
||||||
written as 3 %PLY properties of type `FT` and named `x`, `y` and
|
|
||||||
`z`. `FT` is `float` if the points use
|
|
||||||
`CGAL::Simple_cartesian<float>` and `double` otherwise.
|
|
||||||
|
|
||||||
\tparam PointMap the property map used to store points.
|
|
||||||
|
|
||||||
\sa `write_PLY_with_properties()`
|
|
||||||
\sa \ref IOStreamPLY
|
|
||||||
*/
|
|
||||||
template <typename PointMap>
|
|
||||||
std::tuple<PointMap, PLY_property<FT>, PLY_property<FT>, PLY_property<FT> >
|
|
||||||
make_ply_point_writer(PointMap point_map);
|
|
||||||
|
|
||||||
/**
|
|
||||||
\ingroup PkgPointSetProcessing3IOPly
|
|
||||||
|
|
||||||
Generates a %PLY property handler to write 3D normal
|
|
||||||
vectors. Vectors are written as 3 %PLY properties of type `FT`
|
|
||||||
and named `nx`, `ny` and `nz`. `FT` is `float` if the vectors use
|
|
||||||
`CGAL::Simple_cartesian<float>` and `double` otherwise.
|
|
||||||
|
|
||||||
\tparam VectorMap the property map used to store vectors.
|
|
||||||
|
|
||||||
\sa `write_PLY_with_properties()`
|
|
||||||
\sa \ref IOStreamPLY
|
|
||||||
*/
|
|
||||||
template <typename VectorMap>
|
|
||||||
std::tuple<VectorMap, PLY_property<FT>, PLY_property<FT>, PLY_property<FT> >
|
|
||||||
make_ply_normal_writer(VectorMap normal_map);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
\ingroup PkgPointSetProcessing3IOPly
|
|
||||||
|
|
||||||
\brief writes the range of `points` with properties using \ref IOStreamPLY.
|
|
||||||
|
|
||||||
Properties are handled through a variadic list of property
|
|
||||||
handlers. A `PropertyHandler` can either be:
|
|
||||||
|
|
||||||
- A `std::pair<PropertyMap, PLY_property<T> >` if the user wants
|
|
||||||
to write a scalar value T as a %PLY property (for example, writing
|
|
||||||
an `int` variable as an `int` %PLY property).
|
|
||||||
|
|
||||||
- A `std::tuple<PropertyMap, PLY_property<T>...>` if the
|
|
||||||
user wants to write a complex object as several %PLY
|
|
||||||
properties. In that case, a specialization of `Output_rep` must
|
|
||||||
be provided for `PropertyMap::value_type` that handles both ASCII
|
|
||||||
and binary output (see `CGAL::IO::get_mode()`).
|
|
||||||
|
|
||||||
\attention To write to a binary file, the flag `std::ios::binary` must be set during the creation
|
|
||||||
of the `ofstream`, and the \link PkgStreamSupportEnumRef `IO::Mode` \endlink
|
|
||||||
of the stream must be set to `BINARY`.
|
|
||||||
|
|
||||||
\tparam PointRange is a model of `ConstRange`. The value type of
|
|
||||||
its iterator is the key type of the `PropertyMap` objects provided
|
|
||||||
within the `PropertyHandler` parameter.
|
|
||||||
\tparam PropertyHandler handlers to recover properties.
|
|
||||||
|
|
||||||
\returns `true` if writing was successful, `false` otherwise.
|
|
||||||
|
|
||||||
\sa \ref IOStreamPLY
|
|
||||||
\sa `make_ply_point_writer()`
|
|
||||||
\sa `make_ply_normal_writer()`
|
|
||||||
*/
|
|
||||||
template <typename PointRange,
|
|
||||||
typename ... PropertyHandler>
|
|
||||||
bool write_PLY_with_properties(std::ostream& os, ///< output stream.
|
|
||||||
const PointRange& points, ///< input point range.
|
|
||||||
PropertyHandler&& ... properties) ///< parameter pack of property handlers
|
|
||||||
{
|
|
||||||
CGAL_precondition(points.begin() != points.end());
|
|
||||||
|
|
||||||
if(!os)
|
|
||||||
{
|
|
||||||
std::cerr << "Error: cannot open file" << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write header
|
|
||||||
os << "ply" << std::endl
|
|
||||||
<< ((get_mode(os) == BINARY) ? "format binary_little_endian 1.0" : "format ascii 1.0") << std::endl
|
|
||||||
<< "comment Generated by the CGAL library" << std::endl
|
|
||||||
<< "element vertex " << points.size() << std::endl;
|
|
||||||
|
|
||||||
internal::output_property_header (os, std::forward<PropertyHandler>(properties)...);
|
|
||||||
|
|
||||||
os << "end_header" << std::endl;
|
|
||||||
|
|
||||||
// Write positions + normals
|
|
||||||
for(typename PointRange::const_iterator it = points.begin(); it != points.end(); it++)
|
|
||||||
internal::output_properties (os, it, std::forward<PropertyHandler>(properties)...);
|
|
||||||
|
|
||||||
return !os.fail();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
\ingroup PkgPointSetProcessing3IOPly
|
|
||||||
|
|
||||||
\brief writes the range of `points` (positions + normals, if available) using \ref IOStreamPLY.
|
|
||||||
|
|
||||||
\attention To write to a binary file, the flag `std::ios::binary` must be set during the creation
|
|
||||||
of the `ofstream`, and the \link PkgStreamSupportEnumRef `IO::Mode` \endlink
|
|
||||||
of the stream must be set to `BINARY`.
|
|
||||||
|
|
||||||
\tparam PointRange is a model of `ConstRange`. The value type of
|
|
||||||
its iterator is the key type of the named parameter `point_map`.
|
|
||||||
\tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters"
|
|
||||||
|
|
||||||
\param os output stream
|
|
||||||
\param points input point range
|
|
||||||
\param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below
|
|
||||||
|
|
||||||
\cgalNamedParamsBegin
|
|
||||||
\cgalParamNBegin{point_map}
|
|
||||||
\cgalParamDescription{a property map associating points to the elements of the point range}
|
|
||||||
\cgalParamType{a model of `ReadablePropertyMap` with value type `geom_traits::Point_3`}
|
|
||||||
\cgalParamDefault{`CGAL::Identity_property_map<geom_traits::Point_3>`}
|
|
||||||
\cgalParamNEnd
|
|
||||||
|
|
||||||
\cgalParamNBegin{normal_map}
|
|
||||||
\cgalParamDescription{a property map associating normals to the elements of the point range}
|
|
||||||
\cgalParamType{a model of `ReadablePropertyMap` with value type `geom_traits::Vector_3`}
|
|
||||||
\cgalParamDefault{If this parameter is omitted, normals are not written in the output stream.}
|
|
||||||
\cgalParamNEnd
|
|
||||||
|
|
||||||
\cgalParamNBegin{geom_traits}
|
|
||||||
\cgalParamDescription{an instance of a geometric traits class}
|
|
||||||
\cgalParamType{a model of `Kernel`}
|
|
||||||
\cgalParamDefault{a \cgal Kernel deduced from the point type, using `CGAL::Kernel_traits`}
|
|
||||||
\cgalParamNEnd
|
|
||||||
|
|
||||||
\cgalParamNBegin{stream_precision}
|
|
||||||
\cgalParamDescription{a parameter used to set the precision (i.e. how many digits are generated) of the output stream}
|
|
||||||
\cgalParamType{int}
|
|
||||||
\cgalParamDefault{the precision of the stream `os`}
|
|
||||||
\cgalParamExtra{This parameter is only meaningful while using \ascii encoding.}
|
|
||||||
\cgalParamNEnd
|
|
||||||
\cgalNamedParamsEnd
|
|
||||||
|
|
||||||
\returns `true` if writing was successful, `false` otherwise.
|
|
||||||
|
|
||||||
\sa `write_PLY_with_properties()`
|
|
||||||
*/
|
|
||||||
template <typename PointRange, typename CGAL_NP_TEMPLATE_PARAMETERS>
|
|
||||||
bool write_PLY(std::ostream& os,
|
|
||||||
const PointRange& points,
|
|
||||||
const CGAL_NP_CLASS& np = parameters::default_values()
|
|
||||||
#ifndef DOXYGEN_RUNNING
|
|
||||||
, std::enable_if_t<internal::is_Range<PointRange>::value>* = nullptr
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
{
|
|
||||||
using parameters::choose_parameter;
|
|
||||||
using parameters::get_parameter;
|
|
||||||
|
|
||||||
// basic geometric types
|
|
||||||
typedef Point_set_processing_3_np_helper<PointRange, CGAL_NP_CLASS> NP_helper;
|
|
||||||
typedef typename NP_helper::Const_point_map PointMap;
|
|
||||||
typedef typename NP_helper::Normal_map NormalMap;
|
|
||||||
|
|
||||||
const bool has_normals = NP_helper::has_normal_map(points, np);
|
|
||||||
|
|
||||||
PointMap point_map = NP_helper::get_const_point_map(points, np);
|
|
||||||
NormalMap normal_map = NP_helper::get_normal_map(points, np);
|
|
||||||
|
|
||||||
if(!os)
|
|
||||||
{
|
|
||||||
std::cerr << "Error: cannot open file" << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
set_stream_precision_from_NP(os, np);
|
|
||||||
|
|
||||||
if(has_normals)
|
|
||||||
return write_PLY_with_properties(os, points,
|
|
||||||
make_ply_point_writer(point_map),
|
|
||||||
make_ply_normal_writer(normal_map));
|
|
||||||
|
|
||||||
return write_PLY_with_properties(os, points, make_ply_point_writer(point_map));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
\ingroup PkgPointSetProcessing3IOPly
|
|
||||||
|
|
||||||
\brief writes the range of `points` (positions + normals, if available) using \ref IOStreamPLY.
|
|
||||||
|
|
||||||
\tparam PointRange is a model of `ConstRange`. The value type of
|
|
||||||
its iterator is the key type of the named parameter `point_map`.
|
|
||||||
\tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters"
|
|
||||||
|
|
||||||
\param filename the path to the output file
|
|
||||||
\param points input point range
|
|
||||||
\param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below
|
|
||||||
|
|
||||||
\cgalNamedParamsBegin
|
|
||||||
\cgalParamNBegin{use_binary_mode}
|
|
||||||
\cgalParamDescription{indicates whether data should be written in binary (`true`) or in \ascii (`false`)}
|
|
||||||
\cgalParamType{Boolean}
|
|
||||||
\cgalParamDefault{`true`}
|
|
||||||
\cgalParamNEnd
|
|
||||||
|
|
||||||
\cgalParamNBegin{point_map}
|
|
||||||
\cgalParamDescription{a property map associating points to the elements of the point range}
|
|
||||||
\cgalParamType{a model of `ReadablePropertyMap` with value type `geom_traits::Point_3`}
|
|
||||||
\cgalParamDefault{`CGAL::Identity_property_map<geom_traits::Point_3>`}
|
|
||||||
\cgalParamNEnd
|
|
||||||
|
|
||||||
\cgalParamNBegin{normal_map}
|
|
||||||
\cgalParamDescription{a property map associating normals to the elements of the point range}
|
|
||||||
\cgalParamType{a model of `ReadablePropertyMap` with value type `geom_traits::Vector_3`}
|
|
||||||
\cgalParamDefault{If this parameter is omitted, normals are not written in the output file.}
|
|
||||||
\cgalParamNEnd
|
|
||||||
|
|
||||||
\cgalParamNBegin{geom_traits}
|
|
||||||
\cgalParamDescription{an instance of a geometric traits class}
|
|
||||||
\cgalParamType{a model of `Kernel`}
|
|
||||||
\cgalParamDefault{a \cgal Kernel deduced from the point type, using `CGAL::Kernel_traits`}
|
|
||||||
\cgalParamNEnd
|
|
||||||
|
|
||||||
\cgalParamNBegin{stream_precision}
|
|
||||||
\cgalParamDescription{a parameter used to set the precision (i.e. how many digits are generated) of the output stream}
|
|
||||||
\cgalParamType{int}
|
|
||||||
\cgalParamDefault{`6`}
|
|
||||||
\cgalParamExtra{This parameter is only meaningful while using \ascii encoding.}
|
|
||||||
\cgalParamNEnd
|
|
||||||
\cgalNamedParamsEnd
|
|
||||||
|
|
||||||
\returns `true` if writing was successful, `false` otherwise.
|
|
||||||
|
|
||||||
\sa `write_PLY_with_properties()`
|
|
||||||
*/
|
|
||||||
template <typename PointRange, typename CGAL_NP_TEMPLATE_PARAMETERS>
|
|
||||||
bool write_PLY(const std::string& filename,
|
|
||||||
const PointRange& points,
|
|
||||||
const CGAL_NP_CLASS& np = parameters::default_values()
|
|
||||||
#ifndef DOXYGEN_RUNNING
|
|
||||||
, std::enable_if_t<internal::is_Range<PointRange>::value>* = nullptr
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
{
|
|
||||||
const bool binary = CGAL::parameters::choose_parameter(CGAL::parameters::get_parameter(np, internal_np::use_binary_mode), true);
|
|
||||||
if(binary)
|
|
||||||
{
|
|
||||||
std::ofstream os(filename, std::ios::binary);
|
|
||||||
CGAL::IO::set_mode(os, CGAL::IO::BINARY);
|
|
||||||
return write_PLY(os, points, np);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::ofstream os(filename);
|
|
||||||
CGAL::IO::set_mode(os, CGAL::IO::ASCII);
|
|
||||||
return write_PLY(os, points, np);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace IO
|
|
||||||
|
|
||||||
} // namespace CGAL
|
|
||||||
|
|
||||||
#endif // CGAL_POINT_SET_PROCESSING_WRITE_PLY_POINTS_H
|
|
||||||
|
|
@ -1,194 +0,0 @@
|
||||||
// Copyright (c) 2007-09 INRIA Sophia-Antipolis (France).
|
|
||||||
// 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) : Pierre Alliez and Laurent Saboret
|
|
||||||
|
|
||||||
#ifndef CGAL_POINT_SET_PROCESSING_WRITE_XYZ_POINTS_H
|
|
||||||
#define CGAL_POINT_SET_PROCESSING_WRITE_XYZ_POINTS_H
|
|
||||||
|
|
||||||
#include <CGAL/license/Point_set_processing_3.h>
|
|
||||||
|
|
||||||
#include <CGAL/IO/helpers.h>
|
|
||||||
|
|
||||||
#include <CGAL/property_map.h>
|
|
||||||
#include <CGAL/assertions.h>
|
|
||||||
#include <CGAL/Kernel_traits.h>
|
|
||||||
#include <CGAL/Iterator_range.h>
|
|
||||||
|
|
||||||
#include <CGAL/Named_function_parameters.h>
|
|
||||||
#include <CGAL/boost/graph/named_params_helper.h>
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <fstream>
|
|
||||||
#include <iterator>
|
|
||||||
#include <type_traits>
|
|
||||||
|
|
||||||
namespace CGAL {
|
|
||||||
namespace Point_set_processing_3 {
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
template <typename PointRange, typename CGAL_NP_TEMPLATE_PARAMETERS>
|
|
||||||
bool write_XYZ_PSP(std::ostream& os,
|
|
||||||
const PointRange& points,
|
|
||||||
const CGAL_NP_CLASS& np = CGAL::parameters::default_values())
|
|
||||||
{
|
|
||||||
using CGAL::parameters::choose_parameter;
|
|
||||||
using CGAL::parameters::get_parameter;
|
|
||||||
|
|
||||||
// basic geometric types
|
|
||||||
typedef Point_set_processing_3_np_helper<PointRange, CGAL_NP_CLASS> NP_helper;
|
|
||||||
typedef typename NP_helper::Const_point_map PointMap;
|
|
||||||
typedef typename NP_helper::Normal_map NormalMap;
|
|
||||||
|
|
||||||
const bool has_normals = NP_helper::has_normal_map(points, np);
|
|
||||||
|
|
||||||
PointMap point_map = NP_helper::get_const_point_map(points, np);
|
|
||||||
NormalMap normal_map = NP_helper::get_normal_map(points, np);
|
|
||||||
|
|
||||||
CGAL_precondition(points.begin() != points.end());
|
|
||||||
|
|
||||||
if(!os)
|
|
||||||
{
|
|
||||||
std::cerr << "Error: cannot open file" << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
set_stream_precision_from_NP(os, np);
|
|
||||||
|
|
||||||
// Write positions + normals
|
|
||||||
for(typename PointRange::const_iterator it = points.begin(); it != points.end(); it++)
|
|
||||||
{
|
|
||||||
os << get(point_map, *it);
|
|
||||||
if(has_normals)
|
|
||||||
os << " " << get(normal_map, *it);
|
|
||||||
os << "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
os << std::flush;
|
|
||||||
|
|
||||||
return !os.fail();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
} // Point_set_processing_3
|
|
||||||
|
|
||||||
namespace IO {
|
|
||||||
|
|
||||||
/**
|
|
||||||
\ingroup PkgPointSetProcessing3IOXyz
|
|
||||||
|
|
||||||
\brief writes the range of `points` (positions + normals, if available), using the \ref IOStreamXYZ.
|
|
||||||
|
|
||||||
\tparam PointRange is a model of `ConstRange`. The value type of
|
|
||||||
its iterator is the key type of the named parameter `point_map`.
|
|
||||||
\tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters"
|
|
||||||
|
|
||||||
\param os output stream
|
|
||||||
\param points input point range
|
|
||||||
\param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below
|
|
||||||
|
|
||||||
\cgalNamedParamsBegin
|
|
||||||
\cgalParamNBegin{point_map}
|
|
||||||
\cgalParamDescription{a property map associating points to the elements of the point range}
|
|
||||||
\cgalParamType{a model of `ReadablePropertyMap` with value type `geom_traits::Point_3`}
|
|
||||||
\cgalParamDefault{`CGAL::Identity_property_map<geom_traits::Point_3>`}
|
|
||||||
\cgalParamNEnd
|
|
||||||
|
|
||||||
\cgalParamNBegin{normal_map}
|
|
||||||
\cgalParamDescription{a property map associating normals to the elements of the point range}
|
|
||||||
\cgalParamType{a model of `ReadablePropertyMap` with value type `geom_traits::Vector_3`}
|
|
||||||
\cgalParamDefault{If this parameter is omitted, normals are not written in the output stream.}
|
|
||||||
\cgalParamNEnd
|
|
||||||
|
|
||||||
\cgalParamNBegin{geom_traits}
|
|
||||||
\cgalParamDescription{an instance of a geometric traits class}
|
|
||||||
\cgalParamType{a model of `Kernel`}
|
|
||||||
\cgalParamDefault{a \cgal Kernel deduced from the point type, using `CGAL::Kernel_traits`}
|
|
||||||
\cgalParamNEnd
|
|
||||||
|
|
||||||
\cgalParamNBegin{stream_precision}
|
|
||||||
\cgalParamDescription{a parameter used to set the precision (i.e. how many digits are generated) of the output stream}
|
|
||||||
\cgalParamType{int}
|
|
||||||
\cgalParamDefault{the precision of the stream `os`}
|
|
||||||
\cgalParamNEnd
|
|
||||||
\cgalNamedParamsEnd
|
|
||||||
|
|
||||||
\returns `true` if writing was successful, `false` otherwise.
|
|
||||||
*/
|
|
||||||
template <typename PointRange, typename CGAL_NP_TEMPLATE_PARAMETERS>
|
|
||||||
bool write_XYZ(std::ostream& os,
|
|
||||||
const PointRange& points,
|
|
||||||
const CGAL_NP_CLASS& np = parameters::default_values()
|
|
||||||
#ifndef DOXYGEN_RUNNING
|
|
||||||
, std::enable_if_t<internal::is_Range<PointRange>::value>* = nullptr
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return Point_set_processing_3::internal::write_XYZ_PSP(os, points, np);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
\ingroup PkgPointSetProcessing3IOXyz
|
|
||||||
|
|
||||||
\brief writes the range of `points` (positions + normals, if available), using the \ref IOStreamXYZ.
|
|
||||||
|
|
||||||
\tparam PointRange is a model of `ConstRange`. The value type of
|
|
||||||
its iterator is the key type of the named parameter `point_map`.
|
|
||||||
\tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters"
|
|
||||||
|
|
||||||
\param filename path to the output file
|
|
||||||
\param points input point range
|
|
||||||
\param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below
|
|
||||||
|
|
||||||
\cgalNamedParamsBegin
|
|
||||||
\cgalParamNBegin{point_map}
|
|
||||||
\cgalParamDescription{a property map associating points to the elements of the point range}
|
|
||||||
\cgalParamType{a model of `ReadablePropertyMap` with value type `geom_traits::Point_3`}
|
|
||||||
\cgalParamDefault{`CGAL::Identity_property_map<geom_traits::Point_3>`}
|
|
||||||
\cgalParamNEnd
|
|
||||||
|
|
||||||
\cgalParamNBegin{normal_map}
|
|
||||||
\cgalParamDescription{a property map associating normals to the elements of the point range}
|
|
||||||
\cgalParamType{a model of `ReadablePropertyMap` with value type `geom_traits::Vector_3`}
|
|
||||||
\cgalParamDefault{If this parameter is omitted, normals are not written in the output file.}
|
|
||||||
\cgalParamNEnd
|
|
||||||
|
|
||||||
\cgalParamNBegin{geom_traits}
|
|
||||||
\cgalParamDescription{an instance of a geometric traits class}
|
|
||||||
\cgalParamType{a model of `Kernel`}
|
|
||||||
\cgalParamDefault{a \cgal Kernel deduced from the point type, using `CGAL::Kernel_traits`}
|
|
||||||
\cgalParamNEnd
|
|
||||||
|
|
||||||
\cgalParamNBegin{stream_precision}
|
|
||||||
\cgalParamDescription{a parameter used to set the precision (i.e. how many digits are generated) of the output stream}
|
|
||||||
\cgalParamType{int}
|
|
||||||
\cgalParamDefault{`6`}
|
|
||||||
\cgalParamNEnd
|
|
||||||
\cgalNamedParamsEnd
|
|
||||||
|
|
||||||
\returns `true` if writing was successful, `false` otherwise.
|
|
||||||
*/
|
|
||||||
template <typename PointRange, typename CGAL_NP_TEMPLATE_PARAMETERS>
|
|
||||||
bool write_XYZ(const std::string& filename,
|
|
||||||
const PointRange& points,
|
|
||||||
const CGAL_NP_CLASS& np = parameters::default_values()
|
|
||||||
#ifndef DOXYGEN_RUNNING
|
|
||||||
, std::enable_if_t<internal::is_Range<PointRange>::value>* = nullptr
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
{
|
|
||||||
std::ofstream os(filename);
|
|
||||||
return write_XYZ(os, points, np);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace IO
|
|
||||||
|
|
||||||
} // namespace CGAL
|
|
||||||
|
|
||||||
#endif // CGAL_POINT_SET_PROCESSING_WRITE_XYZ_POINTS_H
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
POLYGON((0 0, 40 0, 40 40, 0 40))
|
POLYGON((0 0, 40 0, 40 40, 0 40, 0 0))
|
||||||
POLYGON((10 10 , 30 10, 30 30, 0 30))
|
POLYGON((10 10 , 30 10, 30 30, 0 30, 10 10))
|
||||||
POLYGON((1 1, 2 1, 2 2, 1 2))
|
POLYGON((1 1, 2 1, 2 2, 1 2, 1 1))
|
||||||
POLYGON((11 11, 12 11, 12 12, 11 12))
|
POLYGON((11 11, 12 11, 12 12, 11 12, 11 11))
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
POLYGON((0 0, 10 0, 10 6, 6 6, 6 4 , 10 4, 10 10, 0 10))
|
POLYGON((0 0, 10 0, 10 6, 6 6, 6 4 , 10 4, 10 10, 0 10, 0 0))
|
||||||
|
|
@ -1 +1 @@
|
||||||
MULTIPOLYGON(((0 0,1 0,1 1,0 1,0 0)),((1 0.25,2 0.25,2 0.75,1 0.75,1 0)))
|
MULTIPOLYGON(((0 0,1 0,1 1,0 1,0 0)),((1 0.25,2 0.25,2 0.75,1 0.75,1 0.25)))
|
||||||
|
|
@ -5,8 +5,8 @@
|
||||||
#include <CGAL/Shape_detection/Region_growing/Point_set.h>
|
#include <CGAL/Shape_detection/Region_growing/Point_set.h>
|
||||||
|
|
||||||
|
|
||||||
#include <CGAL/IO/read_xyz_points.h>
|
#include <CGAL/IO/XYZ.h>
|
||||||
#include <CGAL/IO/write_ply_points.h>
|
#include <CGAL/IO/PLY.h>
|
||||||
|
|
||||||
#include <CGAL/Real_timer.h>
|
#include <CGAL/Real_timer.h>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ each specific format.
|
||||||
- \ref IOStreamMedit
|
- \ref IOStreamMedit
|
||||||
- \ref IOStreamTetgen
|
- \ref IOStreamTetgen
|
||||||
- \ref IOStreamWKT
|
- \ref IOStreamWKT
|
||||||
|
- \ref IOStreamVTKLCC
|
||||||
|
|
||||||
\section IOStreamOFF Object File Format (OFF)
|
\section IOStreamOFF Object File Format (OFF)
|
||||||
|
|
||||||
|
|
@ -61,7 +62,7 @@ The following table lists some \cgal data structures that have I/O functions com
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Any point range</td>
|
<td>Any point range</td>
|
||||||
<td>\link PkgPointSetProcessing3IOOff CGAL::IO::read_OFF(const std::string&, PointOutputIterator)\endlink</td>
|
<td>\link PkgStreamSupportIoFuncsOFF CGAL::IO::read_OFF(const std::string&, PointOutputIterator)\endlink</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Polygon Soup</td>
|
<td>Polygon Soup</td>
|
||||||
|
|
@ -89,7 +90,7 @@ The following table lists some \cgal data structures that have I/O functions com
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Any point range</td>
|
<td>Any point range</td>
|
||||||
<td>\link PkgPointSetProcessing3IOOff CGAL::IO::write_OFF(const std::string&, const PointRange&)\endlink</td>
|
<td>\link PkgStreamSupportIoFuncsOFF CGAL::IO::write_OFF(const std::string&, const PointRange&)\endlink</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Polygon Soup</td>
|
<td>Polygon Soup</td>
|
||||||
|
|
@ -239,7 +240,7 @@ A precise specification of those formats is available <a href="https://paulbourk
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Any point range</td>
|
<td>Any point range</td>
|
||||||
<td>\link PkgPointSetProcessing3IOPly CGAL::IO::read_PLY(const std::string&, PointRange&)\endlink</td>
|
<td>\link PkgStreamSupportIoFuncsPLY CGAL::IO::read_PLY(const std::string&, PointRange&)\endlink</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Polygon Soup</td>
|
<td>Polygon Soup</td>
|
||||||
|
|
@ -263,7 +264,7 @@ A precise specification of those formats is available <a href="https://paulbourk
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Any point range</td>
|
<td>Any point range</td>
|
||||||
<td>\link PkgPointSetProcessing3IOPly CGAL::IO::write_PLY(const std::string&, const PointRange&)\endlink</td>
|
<td>\link PkgStreamSupportIoFuncsPLY CGAL::IO::write_PLY(const std::string&, const PointRange&)\endlink</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Polygon Soup</td>
|
<td>Polygon Soup</td>
|
||||||
|
|
@ -298,7 +299,7 @@ A precise specification of those formats is available
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Any point range</td>
|
<td>Any point range</td>
|
||||||
<td>\link PkgPointSetProcessing3IOLas CGAL::IO::read_LAS(const std::string&, PointRange&)\endlink</td>
|
<td>\link PkgStreamSupportIoFuncsLAS CGAL::IO::read_LAS(const std::string&, PointRange&)\endlink</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td rowspan="2">Output</td>
|
<td rowspan="2">Output</td>
|
||||||
|
|
@ -308,7 +309,7 @@ A precise specification of those formats is available
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Any point range</td>
|
<td>Any point range</td>
|
||||||
<td>\link PkgPointSetProcessing3IOLas CGAL::IO::write_LAS(const std::string&, const PointRange&)\endlink</td>
|
<td>\link PkgStreamSupportIoFuncsLAS CGAL::IO::write_LAS(const std::string&, const PointRange&)\endlink</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|
@ -331,7 +332,7 @@ of its coordinates and other properties. Only coordinates and normals are curren
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Any point range</td>
|
<td>Any point range</td>
|
||||||
<td>\link PkgPointSetProcessing3IOXyz CGAL::IO::read_XYZ(const std::string&, PointRange&)\endlink</td>
|
<td>\link PkgStreamSupportIoFuncsXYZ CGAL::IO::read_XYZ(const std::string&, PointRange&)\endlink</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td rowspan="2">Output</td>
|
<td rowspan="2">Output</td>
|
||||||
|
|
@ -341,7 +342,7 @@ of its coordinates and other properties. Only coordinates and normals are curren
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Any point range</td>
|
<td>Any point range</td>
|
||||||
<td>\link PkgPointSetProcessing3IOXyz CGAL::IO::write_XYZ(const std::string&, const PointRange&)\endlink</td>
|
<td>\link PkgStreamSupportIoFuncsXYZ CGAL::IO::write_XYZ(const std::string&, const PointRange&)\endlink</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|
@ -504,6 +505,30 @@ The following \cgal data structures can be exported into the `.VTU` file format:
|
||||||
- `CGAL::Mesh_complex_3_in_triangulation_3`, using \link CGAL::IO::output_to_vtu() `CGAL::IO::output_to_vtu()` \endlink
|
- `CGAL::Mesh_complex_3_in_triangulation_3`, using \link CGAL::IO::output_to_vtu() `CGAL::IO::output_to_vtu()` \endlink
|
||||||
- `CGAL::Constrained_Delaunay_triangulation_2`, using the function \link CGAL::IO::write_VTU `CGAL::IO::write_VTU()` \endlink
|
- `CGAL::Constrained_Delaunay_triangulation_2`, using the function \link CGAL::IO::write_VTU `CGAL::IO::write_VTU()` \endlink
|
||||||
|
|
||||||
|
\section IOStreamVTKLCC VTK Legacy File Format for Linear Cell Complex
|
||||||
|
|
||||||
|
The VTK legacy format, using file extension `.vtk`, is an \ascii format used to store 3D volumetric meshes.
|
||||||
|
This specific implementation supports Linear Cell Complex structures with various 3D cell types including
|
||||||
|
tetrahedra, hexahedra, prisms, pyramids, and generic polyhedra. Optional scalar data can be associated
|
||||||
|
with both vertices and volumes.
|
||||||
|
|
||||||
|
<table class="iotable">
|
||||||
|
<tr>
|
||||||
|
<th colspan="4">VTK Legacy File Format for Linear Cell Complex</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td rowspan="1" width="75">Input</td>
|
||||||
|
<td rowspan="1" width="175">3D Volumetric Mesh</td>
|
||||||
|
<td width="250">`CGAL::Linear_cell_complex_for_combinatorial_map<3,3>`</td>
|
||||||
|
<td width="550"> \link PkgLinearCellComplexRefIOVTK `CGAL::IO::read_VTK()` \endlink</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td rowspan="1">Output</td>
|
||||||
|
<td rowspan="1">3D Volumetric Mesh</td>
|
||||||
|
<td>`CGAL::Linear_cell_complex_for_combinatorial_map<3,3>`</td>
|
||||||
|
<td> \link PkgLinearCellComplexRefIOVTK `CGAL::IO::Write_VTK<LCC>()` \endlink</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
\section IOStreamAvizo Avizo File Format
|
\section IOStreamAvizo Avizo File Format
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -306,23 +306,23 @@ The following table shows which file formats can be read from and written for po
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>\ref IOStreamOFF "OFF"</th>
|
<th>\ref IOStreamOFF "OFF"</th>
|
||||||
<td>\link PkgPointSetProcessing3IOOff `CGAL::IO::read_OFF()` \endlink</td>
|
<td>\link PkgStreamSupportIoFuncsOFF `CGAL::IO::read_OFF()` \endlink</td>
|
||||||
<td>\link PkgPointSetProcessing3IOOff `CGAL::IO::write_OFF()` \endlink</td>
|
<td>\link PkgStreamSupportIoFuncsOFF `CGAL::IO::write_OFF()` \endlink</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>\ref IOStreamXYZ "XYZ"</th>
|
<th>\ref IOStreamXYZ "XYZ"</th>
|
||||||
<td>\link PkgPointSetProcessing3IOXyz `CGAL::IO::read_XYZ()` \endlink</td>
|
<td>\link PkgStreamSupportIoFuncsXYZ `CGAL::IO::read_XYZ()` \endlink</td>
|
||||||
<td>\link PkgPointSetProcessing3IOXyz `CGAL::IO::write_XYZ()` \endlink</td>
|
<td>\link PkgStreamSupportIoFuncsXYZ `CGAL::IO::write_XYZ()` \endlink</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>\ref IOStreamPLY "PLY"</th>
|
<th>\ref IOStreamPLY "PLY"</th>
|
||||||
<td>\link PkgPointSetProcessing3IOPly `CGAL::IO::read_PLY()` \endlink</td>
|
<td>\link PkgStreamSupportIoFuncsPLY `CGAL::IO::read_PLY()` \endlink</td>
|
||||||
<td>\link PkgPointSetProcessing3IOPly `CGAL::IO::write_PLY()` \endlink</td>
|
<td>\link PkgStreamSupportIoFuncsPLY `CGAL::IO::write_PLY()` \endlink</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>\ref IOStreamLAS "LAS"</th>
|
<th>\ref IOStreamLAS "LAS"</th>
|
||||||
<td>\link PkgPointSetProcessing3IOLas `CGAL::IO::read_LAS()` \endlink</td>
|
<td>\link PkgStreamSupportIoFuncsLAS `CGAL::IO::read_LAS()` \endlink</td>
|
||||||
<td>\link PkgPointSetProcessing3IOLas `CGAL::IO::write_LAS()` \endlink</td>
|
<td>\link PkgStreamSupportIoFuncsLAS `CGAL::IO::write_LAS()` \endlink</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,14 @@
|
||||||
/// I/O Functions for the \ref IOStream3MF
|
/// I/O Functions for the \ref IOStream3MF
|
||||||
/// \ingroup IOstreamFunctions
|
/// \ingroup IOstreamFunctions
|
||||||
|
|
||||||
|
/// \defgroup PkgStreamSupportIoFuncsLAS LAS I/O Functions
|
||||||
|
/// I/O Functions for the \ref IOStreamLAS
|
||||||
|
/// \ingroup IOstreamFunctions
|
||||||
|
|
||||||
|
/// \defgroup PkgStreamSupportIoFuncsXYZ XYZ I/O Functions
|
||||||
|
/// I/O Functions for the \ref IOStreamXYZ
|
||||||
|
/// \ingroup IOstreamFunctions
|
||||||
|
|
||||||
/// \defgroup PkgStreamSupportEnumRef I/O Enums
|
/// \defgroup PkgStreamSupportEnumRef I/O Enums
|
||||||
/// \ingroup PkgStreamSupportRef
|
/// \ingroup PkgStreamSupportRef
|
||||||
|
|
||||||
|
|
@ -99,5 +107,7 @@ the printing mode.
|
||||||
- \link PkgStreamSupportIoFuncsVTK I/O for VTK files \endlink
|
- \link PkgStreamSupportIoFuncsVTK I/O for VTK files \endlink
|
||||||
- \link PkgStreamSupportIoFuncs3MF I/O for 3MF files \endlink
|
- \link PkgStreamSupportIoFuncs3MF I/O for 3MF files \endlink
|
||||||
- \link PkgStreamSupportIoFuncsWKT I/O for WKT files \endlink
|
- \link PkgStreamSupportIoFuncsWKT I/O for WKT files \endlink
|
||||||
|
- \link PkgStreamSupportIoFuncsLAS I/O for LAS files \endlink
|
||||||
|
- \link PkgStreamSupportIoFuncsXYZ I/O for XYZ files \endlink
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ Arrangement_on_surface_2
|
||||||
BGL
|
BGL
|
||||||
Constrained_triangulation_3
|
Constrained_triangulation_3
|
||||||
Kernel_23
|
Kernel_23
|
||||||
|
Linear_cell_complex
|
||||||
Manual
|
Manual
|
||||||
Mesh_2
|
Mesh_2
|
||||||
Mesh_3
|
Mesh_3
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,357 @@
|
||||||
|
// Copyright (c) 2017 GeometryFactory
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org);
|
||||||
|
//
|
||||||
|
// $URL$
|
||||||
|
// $Id$
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
|
//
|
||||||
|
// Author(s) : Simon Giraudot
|
||||||
|
|
||||||
|
#ifndef CGAL_IO_LAS_H
|
||||||
|
#define CGAL_IO_LAS_H
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <CGAL/IO/LAS/Las_property.h>
|
||||||
|
#include <CGAL/IO/helpers.h>
|
||||||
|
#include <CGAL/Named_function_parameters.h>
|
||||||
|
#include <CGAL/boost/graph/named_params_helper.h>
|
||||||
|
#include <CGAL/Kernel_traits.h>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Read
|
||||||
|
|
||||||
|
namespace IO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
\ingroup PkgStreamSupportIoFuncsLAS
|
||||||
|
|
||||||
|
generates a %LAS property handler to read 3D points. Points are
|
||||||
|
constructed from the input the using 3 %LAS properties
|
||||||
|
`LAS_property::X`, `LAS_property::Y` and `LAS_property::Z`.
|
||||||
|
|
||||||
|
\tparam PointMap the property map used to store points.
|
||||||
|
|
||||||
|
\sa `read_LAS_with_properties()`
|
||||||
|
\sa \ref IOStreamLAS
|
||||||
|
*/
|
||||||
|
template <typename PointMap>
|
||||||
|
std::tuple<PointMap,
|
||||||
|
typename Kernel_traits<typename PointMap::value_type>::Kernel::Construct_point_3,
|
||||||
|
LAS_property::X, LAS_property::Y, LAS_property::Z >
|
||||||
|
make_las_point_reader(PointMap point_map);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\ingroup PkgStreamSupportIoFuncsLAS
|
||||||
|
|
||||||
|
\brief reads user-selected points properties from a .las or .laz stream.
|
||||||
|
Potential additional properties are ignored.
|
||||||
|
|
||||||
|
Properties are handled through a variadic list of property
|
||||||
|
handlers. A `PropertyHandler` can either be:
|
||||||
|
|
||||||
|
- A `std::pair<PropertyMap, LAS_property::Tag >` if the user wants to
|
||||||
|
read a %LAS property as a scalar value `LAS_property::Tag::type` (for
|
||||||
|
example, storing an `int` %LAS property into an `int` variable).
|
||||||
|
|
||||||
|
- A `std::tuple<PropertyMap, Constructor,
|
||||||
|
LAS_property::Tag...>` if the user wants to use one or several
|
||||||
|
%LAS properties to construct a complex object (for example,
|
||||||
|
storing 4 `unsigned short` %LAS properties into a %Color object
|
||||||
|
that can for example be a `std::array<unsigned short,
|
||||||
|
4>`). In that case, the second element of the tuple should be a
|
||||||
|
functor that constructs the value type of `PropertyMap` from N
|
||||||
|
objects of of type `LAS_property::Tag::type`.
|
||||||
|
|
||||||
|
The %LAS standard defines a fixed set of properties accessible
|
||||||
|
through the following tag classes:
|
||||||
|
|
||||||
|
- `LAS_property::X` with type `double`
|
||||||
|
- `LAS_property::Y` with type `double`
|
||||||
|
- `LAS_property::Z` with type `double`
|
||||||
|
- `LAS_property::Intensity` with type `unsigned short`
|
||||||
|
- `LAS_property::Return_number` with type `unsigned char`
|
||||||
|
- `LAS_property::Number_of_returns` with type `unsigned char`
|
||||||
|
- `LAS_property::Scan_direction_flag` with type `unsigned char`
|
||||||
|
- `LAS_property::Edge_of_flight_line` with type `unsigned char`
|
||||||
|
- `LAS_property::Classification` with type `unsigned char`
|
||||||
|
- `LAS_property::Synthetic_flag` with type `unsigned char`
|
||||||
|
- `LAS_property::Keypoint_flag` with type `unsigned char`
|
||||||
|
- `LAS_property::Withheld_flag` with type `unsigned char`
|
||||||
|
- `LAS_property::Scan_angle` with type `double`
|
||||||
|
- `LAS_property::User_data` with type `unsigned char`
|
||||||
|
- `LAS_property::Point_source_ID` with type `unsigned short`
|
||||||
|
- `LAS_property::Deleted_flag` with type `unsigned int`
|
||||||
|
- `LAS_property::GPS_time` with type `double`
|
||||||
|
- `LAS_property::R` with type `unsigned short`
|
||||||
|
- `LAS_property::G` with type `unsigned short`
|
||||||
|
- `LAS_property::B` with type `unsigned short`
|
||||||
|
- `LAS_property::I` with type `unsigned short`
|
||||||
|
|
||||||
|
\attention To read a binary file, the flag `std::ios::binary` must be set during the creation of the `ifstream`.
|
||||||
|
|
||||||
|
\tparam OutputIteratorValueType type of objects that can be put in `PointOutputIterator`.
|
||||||
|
It must be a model of `DefaultConstructible` and defaults to `value_type_traits<PointOutputIterator>::%type`.
|
||||||
|
It can be omitted if the default is fine.
|
||||||
|
\tparam PointOutputIterator iterator over output points.
|
||||||
|
\tparam PropertyHandler handlers to recover properties.
|
||||||
|
|
||||||
|
\returns `true` if reading was successful, `false` otherwise.
|
||||||
|
|
||||||
|
\sa `make_las_point_reader()`
|
||||||
|
|
||||||
|
\sa \ref IOStreamLAS
|
||||||
|
*/
|
||||||
|
template <typename OutputIteratorValueType,
|
||||||
|
typename PointOutputIterator,
|
||||||
|
typename ... PropertyHandler>
|
||||||
|
bool read_LAS_with_properties(std::istream& is,
|
||||||
|
PointOutputIterator output,
|
||||||
|
PropertyHandler&& ... properties);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\ingroup PkgStreamSupportIoFuncsLAS
|
||||||
|
|
||||||
|
\brief reads points (position only) using the \ref IOStreamLAS.
|
||||||
|
|
||||||
|
Potential additional properties are ignored.
|
||||||
|
|
||||||
|
\attention To read a binary file, the flag `std::ios::binary` must be set during the creation of the `ifstream`.
|
||||||
|
|
||||||
|
\tparam OutputIteratorValueType type of objects that can be put in `PointOutputIterator`.
|
||||||
|
It must be a model of `DefaultConstructible` and defaults to `value_type_traits<PointOutputIterator>::%type`.
|
||||||
|
It can be omitted when the default is fine.
|
||||||
|
\tparam PointOutputIterator iterator over output points.
|
||||||
|
\tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters"
|
||||||
|
|
||||||
|
\param is input stream
|
||||||
|
\param output output iterator over points
|
||||||
|
\param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below
|
||||||
|
|
||||||
|
\cgalNamedParamsBegin
|
||||||
|
\cgalParamNBegin{point_map}
|
||||||
|
\cgalParamDescription{a property map associating points to the elements of the point range}
|
||||||
|
\cgalParamType{a model of `WritablePropertyMap` with value type `geom_traits::Point_3`}
|
||||||
|
\cgalParamDefault{`CGAL::Identity_property_map<geom_traits::Point_3>`}
|
||||||
|
\cgalParamNEnd
|
||||||
|
|
||||||
|
\cgalParamNBegin{geom_traits}
|
||||||
|
\cgalParamDescription{an instance of a geometric traits class}
|
||||||
|
\cgalParamType{a model of `Kernel`}
|
||||||
|
\cgalParamDefault{a \cgal Kernel deduced from the point type, using `CGAL::Kernel_traits`}
|
||||||
|
\cgalParamNEnd
|
||||||
|
\cgalNamedParamsEnd
|
||||||
|
|
||||||
|
\returns `true` if reading was successful, `false` otherwise.
|
||||||
|
|
||||||
|
\sa `read_LAS_with_properties()`
|
||||||
|
*/
|
||||||
|
template <typename OutputIteratorValueType,
|
||||||
|
typename PointOutputIterator,
|
||||||
|
typename CGAL_NP_TEMPLATE_PARAMETERS>
|
||||||
|
bool read_LAS(std::istream& is,
|
||||||
|
PointOutputIterator output,
|
||||||
|
const CGAL_NP_CLASS& np = parameters::default_values());
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\ingroup PkgStreamSupportIoFuncsLAS
|
||||||
|
|
||||||
|
\brief reads points (position only) using the \ref IOStreamLAS.
|
||||||
|
|
||||||
|
Potential additional properties are ignored.
|
||||||
|
|
||||||
|
\tparam OutputIteratorValueType type of objects that can be put in `PointOutputIterator`.
|
||||||
|
It must be a model of `DefaultConstructible` and defaults to `value_type_traits<PointOutputIterator>::%type`.
|
||||||
|
It can be omitted when the default is fine.
|
||||||
|
\tparam PointOutputIterator iterator over output points.
|
||||||
|
\tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters"
|
||||||
|
|
||||||
|
\param filename name of the input file
|
||||||
|
\param output output iterator over points
|
||||||
|
\param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below
|
||||||
|
|
||||||
|
\cgalNamedParamsBegin
|
||||||
|
\cgalParamNBegin{point_map}
|
||||||
|
\cgalParamDescription{a property map associating points to the elements of the point range}
|
||||||
|
\cgalParamType{a model of `WritablePropertyMap` with value type `geom_traits::Point_3`}
|
||||||
|
\cgalParamDefault{`CGAL::Identity_property_map<geom_traits::Point_3>`}
|
||||||
|
\cgalParamNEnd
|
||||||
|
|
||||||
|
\cgalParamNBegin{geom_traits}
|
||||||
|
\cgalParamDescription{an instance of a geometric traits class}
|
||||||
|
\cgalParamType{a model of `Kernel`}
|
||||||
|
\cgalParamDefault{a \cgal Kernel deduced from the point type, using `CGAL::Kernel_traits`}
|
||||||
|
\cgalParamNEnd
|
||||||
|
\cgalNamedParamsEnd
|
||||||
|
|
||||||
|
\returns `true` if reading was successful, `false` otherwise.
|
||||||
|
|
||||||
|
\sa `read_LAS_with_properties()`
|
||||||
|
*/
|
||||||
|
template <typename OutputIteratorValueType,
|
||||||
|
typename PointOutputIterator,
|
||||||
|
typename CGAL_NP_TEMPLATE_PARAMETERS>
|
||||||
|
bool read_LAS(const std::string& filename,
|
||||||
|
PointOutputIterator output,
|
||||||
|
const CGAL_NP_CLASS& np = parameters::default_values());
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\ingroup PkgStreamSupportIoFuncsLAS
|
||||||
|
|
||||||
|
\brief generates a %LAS property handler to write 3D points.
|
||||||
|
|
||||||
|
\tparam PointMap the property map used to store points.
|
||||||
|
|
||||||
|
\sa `write_LAS()`
|
||||||
|
\sa \ref IOStreamLAS
|
||||||
|
*/
|
||||||
|
template <typename PointMap>
|
||||||
|
std::tuple<PointMap, LAS_property::X, LAS_property::Y, LAS_property::Z >
|
||||||
|
make_las_point_writer(PointMap point_map);
|
||||||
|
|
||||||
|
/**
|
||||||
|
\ingroup PkgStreamSupportIoFuncsLAS
|
||||||
|
|
||||||
|
\brief writes the range of `points` with properties to a .las stream.
|
||||||
|
|
||||||
|
Properties are handled through a variadic list of property
|
||||||
|
handlers. A `PropertyHandle` is a `std::pair<PropertyMap,
|
||||||
|
LAS_property::Tag >` used to write a scalar value
|
||||||
|
`LAS_property::Tag::type` as a %LAS property (for example,
|
||||||
|
writing an `int` variable as an `int` %LAS property). An exception
|
||||||
|
is used for points that are written using a `std::tuple` object.
|
||||||
|
|
||||||
|
See documentation of `read_LAS_with_properties()` for the
|
||||||
|
list of available `LAS_property::Tag` classes.
|
||||||
|
|
||||||
|
\attention To write to a binary file, the flag `std::ios::binary` must be set during the creation of the `ofstream`.
|
||||||
|
|
||||||
|
\tparam PointRange is a model of `ConstRange`. The value type of
|
||||||
|
its iterator is the key type of the named parameter `point_map`.
|
||||||
|
\tparam PointMap is a model of `ReadablePropertyMap` with a value_type = `CGAL::Point_3`.
|
||||||
|
\tparam PropertyHandler handlers to recover properties.
|
||||||
|
|
||||||
|
\returns `true` if writing was successful, `false` otherwise.
|
||||||
|
|
||||||
|
\sa `make_las_point_writer()`
|
||||||
|
\sa \ref IOStreamLAS
|
||||||
|
*/
|
||||||
|
template <typename PointRange,
|
||||||
|
typename PointMap,
|
||||||
|
typename ... PropertyHandler>
|
||||||
|
bool write_LAS_with_properties(std::ostream& os, ///< output stream.
|
||||||
|
const PointRange& points, ///< input point range.
|
||||||
|
std::tuple<PointMap,
|
||||||
|
LAS_property::X,
|
||||||
|
LAS_property::Y,
|
||||||
|
LAS_property::Z> point_property, ///< property handler for points
|
||||||
|
PropertyHandler&& ... properties ///< parameter pack of property handlers
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
\ingroup PkgStreamSupportIoFuncsLAS
|
||||||
|
|
||||||
|
\brief writes the range of `points` (positions only), using the \ref IOStreamLAS.
|
||||||
|
|
||||||
|
\attention To write to a binary file, the flag `std::ios::binary` must be set during the creation of the `ofstream`.
|
||||||
|
|
||||||
|
\tparam PointRange is a model of `ConstRange`. The value type of
|
||||||
|
its iterator is the key type of the named parameter `point_map`.
|
||||||
|
\tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters"
|
||||||
|
|
||||||
|
\param os output stream
|
||||||
|
\param points input point range
|
||||||
|
\param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below
|
||||||
|
|
||||||
|
\cgalNamedParamsBegin
|
||||||
|
\cgalParamNBegin{point_map}
|
||||||
|
\cgalParamDescription{a property map associating points to the elements of the point range}
|
||||||
|
\cgalParamType{a model of `ReadablePropertyMap` with value type `geom_traits::Point_3`}
|
||||||
|
\cgalParamDefault{`CGAL::Identity_property_map<geom_traits::Point_3>`}
|
||||||
|
\cgalParamNEnd
|
||||||
|
|
||||||
|
\cgalParamNBegin{geom_traits}
|
||||||
|
\cgalParamDescription{an instance of a geometric traits class}
|
||||||
|
\cgalParamType{a model of `Kernel`}
|
||||||
|
\cgalParamDefault{a \cgal Kernel deduced from the point type, using `CGAL::Kernel_traits`}
|
||||||
|
\cgalParamNEnd
|
||||||
|
\cgalNamedParamsEnd
|
||||||
|
|
||||||
|
\returns `true` if writing was successful, `false` otherwise.
|
||||||
|
|
||||||
|
\sa \ref IOStreamLAS
|
||||||
|
\sa `write_LAS_with_properties()`
|
||||||
|
*/
|
||||||
|
template <typename PointRange, typename CGAL_NP_TEMPLATE_PARAMETERS>
|
||||||
|
bool write_LAS(std::ostream& os,
|
||||||
|
const PointRange& points,
|
||||||
|
const CGAL_NP_CLASS& np = parameters::default_values()
|
||||||
|
#ifndef DOXYGEN_RUNNING
|
||||||
|
, std::enable_if_t<internal::is_Range<PointRange>::value>* = nullptr
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\ingroup PkgStreamSupportIoFuncsLAS
|
||||||
|
|
||||||
|
writes the range of `points` (positions only), using the \ref IOStreamLAS.
|
||||||
|
|
||||||
|
\tparam PointRange is a model of `ConstRange`. The value type of
|
||||||
|
its iterator is the key type of the named parameter `point_map`.
|
||||||
|
\tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters"
|
||||||
|
|
||||||
|
\param filename the path the output file
|
||||||
|
\param points input point range
|
||||||
|
\param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below
|
||||||
|
|
||||||
|
\cgalNamedParamsBegin
|
||||||
|
\cgalParamNBegin{point_map}
|
||||||
|
\cgalParamDescription{a property map associating points to the elements of the point range}
|
||||||
|
\cgalParamType{a model of `ReadablePropertyMap` with value type `geom_traits::Point_3`}
|
||||||
|
\cgalParamDefault{`CGAL::Identity_property_map<geom_traits::Point_3>`}
|
||||||
|
\cgalParamNEnd
|
||||||
|
|
||||||
|
\cgalParamNBegin{geom_traits}
|
||||||
|
\cgalParamDescription{an instance of a geometric traits class}
|
||||||
|
\cgalParamType{a model of `Kernel`}
|
||||||
|
\cgalParamDefault{a \cgal Kernel deduced from the point type, using `CGAL::Kernel_traits`}
|
||||||
|
\cgalParamNEnd
|
||||||
|
\cgalNamedParamsEnd
|
||||||
|
|
||||||
|
\returns `true` if writing was successful, `false` otherwise.
|
||||||
|
|
||||||
|
\sa `write_LAS_with_properties()`
|
||||||
|
*/
|
||||||
|
template <typename PointRange, typename CGAL_NP_TEMPLATE_PARAMETERS>
|
||||||
|
bool write_LAS(const std::string& filename,
|
||||||
|
const PointRange& points,
|
||||||
|
const CGAL_NP_CLASS& np = parameters::default_values()
|
||||||
|
#ifndef DOXYGEN_RUNNING
|
||||||
|
, std::enable_if_t<internal::is_Range<PointRange>::value>* = nullptr
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
|
||||||
|
} // namespace IO
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
|
||||||
|
#include <CGAL/IO/LAS/read_las_points.h>
|
||||||
|
#include <CGAL/IO/LAS/write_las_points.h>
|
||||||
|
|
||||||
|
|
||||||
|
#endif // CGAL_IO_LAS_H
|
||||||
|
|
@ -0,0 +1,94 @@
|
||||||
|
// Copyright (c) 2017 GeometryFactory
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org);
|
||||||
|
//
|
||||||
|
// $URL$
|
||||||
|
// $Id$
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
|
//
|
||||||
|
// Author(s) : Simon Giraudot
|
||||||
|
|
||||||
|
#ifndef CGAL_IO_LAS_LAS_PROPERTY_H
|
||||||
|
#define CGAL_IO_LAS_LAS_PROPERTY_H
|
||||||
|
|
||||||
|
#include <tuple>
|
||||||
|
#include <CGAL/Kernel_traits.h>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
namespace IO {
|
||||||
|
|
||||||
|
namespace LAS_property {
|
||||||
|
namespace Id {
|
||||||
|
|
||||||
|
enum Id
|
||||||
|
{
|
||||||
|
X,
|
||||||
|
Y,
|
||||||
|
Z,
|
||||||
|
Intensity,
|
||||||
|
Return_number,
|
||||||
|
Number_of_returns,
|
||||||
|
Scan_direction_flag,
|
||||||
|
Edge_of_flight_line,
|
||||||
|
Classification,
|
||||||
|
Synthetic_flag,
|
||||||
|
Keypoint_flag,
|
||||||
|
Withheld_flag,
|
||||||
|
Scan_angle,
|
||||||
|
User_data,
|
||||||
|
Point_source_ID,
|
||||||
|
Deleted_flag,
|
||||||
|
GPS_time,
|
||||||
|
R,
|
||||||
|
G,
|
||||||
|
B,
|
||||||
|
I
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Id
|
||||||
|
|
||||||
|
template <typename T, Id::Id id>
|
||||||
|
struct Base
|
||||||
|
{
|
||||||
|
typedef T type;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef Base<double, Id::X> X;
|
||||||
|
typedef Base<double, Id::Y> Y;
|
||||||
|
typedef Base<double, Id::Z> Z;
|
||||||
|
typedef Base<unsigned short, Id::Intensity> Intensity;
|
||||||
|
typedef Base<unsigned char, Id::Return_number> Return_number;
|
||||||
|
typedef Base<unsigned char, Id::Number_of_returns> Number_of_returns;
|
||||||
|
typedef Base<unsigned char, Id::Scan_direction_flag> Scan_direction_flag;
|
||||||
|
typedef Base<unsigned char, Id::Edge_of_flight_line> Edge_of_flight_line;
|
||||||
|
typedef Base<unsigned char, Id::Classification> Classification;
|
||||||
|
typedef Base<unsigned char, Id::Synthetic_flag> Synthetic_flag;
|
||||||
|
typedef Base<unsigned char, Id::Keypoint_flag> Keypoint_flag;
|
||||||
|
typedef Base<unsigned char, Id::Withheld_flag> Withheld_flag;
|
||||||
|
typedef Base<float, Id::Scan_angle> Scan_angle;
|
||||||
|
typedef Base<unsigned char, Id::User_data> User_data;
|
||||||
|
typedef Base<unsigned short, Id::Point_source_ID> Point_source_ID;
|
||||||
|
typedef Base<unsigned int, Id::Deleted_flag> Deleted_flag;
|
||||||
|
typedef Base<double, Id::GPS_time> GPS_time;
|
||||||
|
typedef Base<unsigned short, Id::R> R;
|
||||||
|
typedef Base<unsigned short, Id::G> G;
|
||||||
|
typedef Base<unsigned short, Id::B> B;
|
||||||
|
typedef Base<unsigned short, Id::I> I;
|
||||||
|
} // namespace LAS_property
|
||||||
|
|
||||||
|
// documenation in ../LAS.h
|
||||||
|
template <typename PointMap>
|
||||||
|
std::tuple<PointMap,
|
||||||
|
typename Kernel_traits<typename PointMap::value_type>::Kernel::Construct_point_3,
|
||||||
|
LAS_property::X, LAS_property::Y, LAS_property::Z >
|
||||||
|
make_las_point_reader(PointMap point_map)
|
||||||
|
{
|
||||||
|
return std::make_tuple (point_map, typename Kernel_traits<typename PointMap::value_type>::Kernel::Construct_point_3(),
|
||||||
|
LAS_property::X(), LAS_property::Y(), LAS_property::Z());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace IO
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -1,21 +1,22 @@
|
||||||
// Copyright (c) 2017 Geometry Factory
|
// Copyright (c) 2017 GeometryFactory
|
||||||
// All rights reserved.
|
|
||||||
//
|
//
|
||||||
// This file is part of CGAL (www.cgal.org).
|
// This file is part of CGAL (www.cgal.org);
|
||||||
//
|
//
|
||||||
// $URL$
|
// $URL$
|
||||||
// $Id$
|
// $Id$
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
//
|
//
|
||||||
// Author(s) : Simon Giraudot
|
// Author(s) : Simon Giraudot
|
||||||
|
|
||||||
#ifndef CGAL_POINT_SET_PROCESSING_READ_LAS_POINTS_H
|
#ifndef CGAL_IO_LAS_READ_LAS_POINTS_H
|
||||||
#define CGAL_POINT_SET_PROCESSING_READ_LAS_POINTS_H
|
#define CGAL_IO_LAS_READ_LAS_POINTS_H
|
||||||
|
|
||||||
#include <CGAL/license/Point_set_processing_3.h>
|
#ifdef CGAL_LINKED_WITH_LASLIB
|
||||||
|
|
||||||
#include <CGAL/config.h>
|
#include <CGAL/config.h>
|
||||||
|
|
||||||
|
#include <CGAL/IO/LAS/Las_property.h>
|
||||||
|
#include <CGAL/IO/LAS.h>
|
||||||
#include <CGAL/property_map.h>
|
#include <CGAL/property_map.h>
|
||||||
#include <CGAL/value_type_traits.h>
|
#include <CGAL/value_type_traits.h>
|
||||||
#include <CGAL/Kernel_traits.h>
|
#include <CGAL/Kernel_traits.h>
|
||||||
|
|
@ -59,89 +60,6 @@ namespace CGAL {
|
||||||
|
|
||||||
namespace IO {
|
namespace IO {
|
||||||
|
|
||||||
/// \cond SKIP_IN_MANUAL
|
|
||||||
namespace LAS_property {
|
|
||||||
namespace Id {
|
|
||||||
|
|
||||||
enum Id
|
|
||||||
{
|
|
||||||
X,
|
|
||||||
Y,
|
|
||||||
Z,
|
|
||||||
Intensity,
|
|
||||||
Return_number,
|
|
||||||
Number_of_returns,
|
|
||||||
Scan_direction_flag,
|
|
||||||
Edge_of_flight_line,
|
|
||||||
Classification,
|
|
||||||
Synthetic_flag,
|
|
||||||
Keypoint_flag,
|
|
||||||
Withheld_flag,
|
|
||||||
Scan_angle,
|
|
||||||
User_data,
|
|
||||||
Point_source_ID,
|
|
||||||
Deleted_flag,
|
|
||||||
GPS_time,
|
|
||||||
R,
|
|
||||||
G,
|
|
||||||
B,
|
|
||||||
I
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Id
|
|
||||||
|
|
||||||
template <typename T, Id::Id id>
|
|
||||||
struct Base
|
|
||||||
{
|
|
||||||
typedef T type;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef Base<double, Id::X> X;
|
|
||||||
typedef Base<double, Id::Y> Y;
|
|
||||||
typedef Base<double, Id::Z> Z;
|
|
||||||
typedef Base<unsigned short, Id::Intensity> Intensity;
|
|
||||||
typedef Base<unsigned char, Id::Return_number> Return_number;
|
|
||||||
typedef Base<unsigned char, Id::Number_of_returns> Number_of_returns;
|
|
||||||
typedef Base<unsigned char, Id::Scan_direction_flag> Scan_direction_flag;
|
|
||||||
typedef Base<unsigned char, Id::Edge_of_flight_line> Edge_of_flight_line;
|
|
||||||
typedef Base<unsigned char, Id::Classification> Classification;
|
|
||||||
typedef Base<unsigned char, Id::Synthetic_flag> Synthetic_flag;
|
|
||||||
typedef Base<unsigned char, Id::Keypoint_flag> Keypoint_flag;
|
|
||||||
typedef Base<unsigned char, Id::Withheld_flag> Withheld_flag;
|
|
||||||
typedef Base<float, Id::Scan_angle> Scan_angle;
|
|
||||||
typedef Base<unsigned char, Id::User_data> User_data;
|
|
||||||
typedef Base<unsigned short, Id::Point_source_ID> Point_source_ID;
|
|
||||||
typedef Base<unsigned int, Id::Deleted_flag> Deleted_flag;
|
|
||||||
typedef Base<double, Id::GPS_time> GPS_time;
|
|
||||||
typedef Base<unsigned short, Id::R> R;
|
|
||||||
typedef Base<unsigned short, Id::G> G;
|
|
||||||
typedef Base<unsigned short, Id::B> B;
|
|
||||||
typedef Base<unsigned short, Id::I> I;
|
|
||||||
}
|
|
||||||
/// \endcond
|
|
||||||
|
|
||||||
/**
|
|
||||||
\ingroup PkgPointSetProcessing3IOLas
|
|
||||||
|
|
||||||
generates a %LAS property handler to read 3D points. Points are
|
|
||||||
constructed from the input the using 3 %LAS properties
|
|
||||||
`LAS_property::X`, `LAS_property::Y` and `LAS_property::Z`.
|
|
||||||
|
|
||||||
\tparam PointMap the property map used to store points.
|
|
||||||
|
|
||||||
\sa `read_LAS_with_properties()`
|
|
||||||
\sa \ref IOStreamLAS
|
|
||||||
*/
|
|
||||||
template <typename PointMap>
|
|
||||||
std::tuple<PointMap,
|
|
||||||
typename Kernel_traits<typename PointMap::value_type>::Kernel::Construct_point_3,
|
|
||||||
LAS_property::X, LAS_property::Y, LAS_property::Z >
|
|
||||||
make_las_point_reader(PointMap point_map)
|
|
||||||
{
|
|
||||||
return std::make_tuple (point_map, typename Kernel_traits<typename PointMap::value_type>::Kernel::Construct_point_3(),
|
|
||||||
LAS_property::X(), LAS_property::Y(), LAS_property::Z());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \cond SKIP_IN_MANUAL
|
/// \cond SKIP_IN_MANUAL
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
@ -309,69 +227,10 @@ void process_properties (const LASpoint& reader, OutputValueType& new_element,
|
||||||
} // namespace LAS
|
} // namespace LAS
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
|
||||||
|
|
||||||
/// \endcond
|
/// \endcond
|
||||||
|
|
||||||
/**
|
// documenation in ../LAS.h
|
||||||
\ingroup PkgPointSetProcessing3IOLas
|
|
||||||
|
|
||||||
\brief reads user-selected points properties from a .las or .laz stream.
|
|
||||||
Potential additional properties are ignored.
|
|
||||||
|
|
||||||
Properties are handled through a variadic list of property
|
|
||||||
handlers. A `PropertyHandler` can either be:
|
|
||||||
|
|
||||||
- A `std::pair<PropertyMap, LAS_property::Tag >` if the user wants to
|
|
||||||
read a %LAS property as a scalar value `LAS_property::Tag::type` (for
|
|
||||||
example, storing an `int` %LAS property into an `int` variable).
|
|
||||||
|
|
||||||
- A `std::tuple<PropertyMap, Constructor,
|
|
||||||
LAS_property::Tag...>` if the user wants to use one or several
|
|
||||||
%LAS properties to construct a complex object (for example,
|
|
||||||
storing 4 `unsigned short` %LAS properties into a %Color object
|
|
||||||
that can for example be a `std::array<unsigned short,
|
|
||||||
4>`). In that case, the second element of the tuple should be a
|
|
||||||
functor that constructs the value type of `PropertyMap` from N
|
|
||||||
objects of of type `LAS_property::Tag::type`.
|
|
||||||
|
|
||||||
The %LAS standard defines a fixed set of properties accessible
|
|
||||||
through the following tag classes:
|
|
||||||
|
|
||||||
- `LAS_property::X` with type `double`
|
|
||||||
- `LAS_property::Y` with type `double`
|
|
||||||
- `LAS_property::Z` with type `double`
|
|
||||||
- `LAS_property::Intensity` with type `unsigned short`
|
|
||||||
- `LAS_property::Return_number` with type `unsigned char`
|
|
||||||
- `LAS_property::Number_of_returns` with type `unsigned char`
|
|
||||||
- `LAS_property::Scan_direction_flag` with type `unsigned char`
|
|
||||||
- `LAS_property::Edge_of_flight_line` with type `unsigned char`
|
|
||||||
- `LAS_property::Classification` with type `unsigned char`
|
|
||||||
- `LAS_property::Synthetic_flag` with type `unsigned char`
|
|
||||||
- `LAS_property::Keypoint_flag` with type `unsigned char`
|
|
||||||
- `LAS_property::Withheld_flag` with type `unsigned char`
|
|
||||||
- `LAS_property::Scan_angle` with type `double`
|
|
||||||
- `LAS_property::User_data` with type `unsigned char`
|
|
||||||
- `LAS_property::Point_source_ID` with type `unsigned short`
|
|
||||||
- `LAS_property::Deleted_flag` with type `unsigned int`
|
|
||||||
- `LAS_property::GPS_time` with type `double`
|
|
||||||
- `LAS_property::R` with type `unsigned short`
|
|
||||||
- `LAS_property::G` with type `unsigned short`
|
|
||||||
- `LAS_property::B` with type `unsigned short`
|
|
||||||
- `LAS_property::I` with type `unsigned short`
|
|
||||||
|
|
||||||
\attention To read a binary file, the flag `std::ios::binary` must be set during the creation of the `ifstream`.
|
|
||||||
|
|
||||||
\tparam OutputIteratorValueType type of objects that can be put in `PointOutputIterator`.
|
|
||||||
It must be a model of `DefaultConstructible` and defaults to `value_type_traits<PointOutputIterator>::%type`.
|
|
||||||
It can be omitted if the default is fine.
|
|
||||||
\tparam PointOutputIterator iterator over output points.
|
|
||||||
\tparam PropertyHandler handlers to recover properties.
|
|
||||||
|
|
||||||
\returns `true` if reading was successful, `false` otherwise.
|
|
||||||
|
|
||||||
\sa `make_las_point_reader()`
|
|
||||||
|
|
||||||
\sa \ref IOStreamLAS
|
|
||||||
*/
|
|
||||||
template <typename OutputIteratorValueType,
|
template <typename OutputIteratorValueType,
|
||||||
typename PointOutputIterator,
|
typename PointOutputIterator,
|
||||||
typename ... PropertyHandler>
|
typename ... PropertyHandler>
|
||||||
|
|
@ -420,49 +279,13 @@ bool read_LAS_with_properties(std::istream& is,
|
||||||
|
|
||||||
/// \endcond
|
/// \endcond
|
||||||
|
|
||||||
/**
|
// documenation in ../LAS.h
|
||||||
\ingroup PkgPointSetProcessing3IOLas
|
|
||||||
|
|
||||||
\brief reads points (position only) using the \ref IOStreamLAS.
|
|
||||||
|
|
||||||
Potential additional properties are ignored.
|
|
||||||
|
|
||||||
\attention To read a binary file, the flag `std::ios::binary` must be set during the creation of the `ifstream`.
|
|
||||||
|
|
||||||
\tparam OutputIteratorValueType type of objects that can be put in `PointOutputIterator`.
|
|
||||||
It must be a model of `DefaultConstructible` and defaults to `value_type_traits<PointOutputIterator>::%type`.
|
|
||||||
It can be omitted when the default is fine.
|
|
||||||
\tparam PointOutputIterator iterator over output points.
|
|
||||||
\tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters"
|
|
||||||
|
|
||||||
\param is input stream
|
|
||||||
\param output output iterator over points
|
|
||||||
\param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below
|
|
||||||
|
|
||||||
\cgalNamedParamsBegin
|
|
||||||
\cgalParamNBegin{point_map}
|
|
||||||
\cgalParamDescription{a property map associating points to the elements of the point range}
|
|
||||||
\cgalParamType{a model of `WritablePropertyMap` with value type `geom_traits::Point_3`}
|
|
||||||
\cgalParamDefault{`CGAL::Identity_property_map<geom_traits::Point_3>`}
|
|
||||||
\cgalParamNEnd
|
|
||||||
|
|
||||||
\cgalParamNBegin{geom_traits}
|
|
||||||
\cgalParamDescription{an instance of a geometric traits class}
|
|
||||||
\cgalParamType{a model of `Kernel`}
|
|
||||||
\cgalParamDefault{a \cgal Kernel deduced from the point type, using `CGAL::Kernel_traits`}
|
|
||||||
\cgalParamNEnd
|
|
||||||
\cgalNamedParamsEnd
|
|
||||||
|
|
||||||
\returns `true` if reading was successful, `false` otherwise.
|
|
||||||
|
|
||||||
\sa `read_LAS_with_properties()`
|
|
||||||
*/
|
|
||||||
template <typename OutputIteratorValueType,
|
template <typename OutputIteratorValueType,
|
||||||
typename PointOutputIterator,
|
typename PointOutputIterator,
|
||||||
typename CGAL_NP_TEMPLATE_PARAMETERS>
|
typename CGAL_NP_TEMPLATE_PARAMETERS_NO_DEFAULT>
|
||||||
bool read_LAS(std::istream& is,
|
bool read_LAS(std::istream& is,
|
||||||
PointOutputIterator output,
|
PointOutputIterator output,
|
||||||
const CGAL_NP_CLASS& np = parameters::default_values())
|
const CGAL_NP_CLASS& np)
|
||||||
{
|
{
|
||||||
using parameters::choose_parameter;
|
using parameters::choose_parameter;
|
||||||
using parameters::get_parameter;
|
using parameters::get_parameter;
|
||||||
|
|
@ -486,47 +309,13 @@ bool read_LAS(std::istream& is, OutputIterator output, const CGAL_NP_CLASS& np =
|
||||||
|
|
||||||
/// \endcond
|
/// \endcond
|
||||||
|
|
||||||
/**
|
// documentation in ../LAS.h
|
||||||
\ingroup PkgPointSetProcessing3IOLas
|
|
||||||
|
|
||||||
\brief reads points (position only) using the \ref IOStreamLAS.
|
|
||||||
|
|
||||||
Potential additional properties are ignored.
|
|
||||||
|
|
||||||
\tparam OutputIteratorValueType type of objects that can be put in `PointOutputIterator`.
|
|
||||||
It must be a model of `DefaultConstructible` and defaults to `value_type_traits<PointOutputIterator>::%type`.
|
|
||||||
It can be omitted when the default is fine.
|
|
||||||
\tparam PointOutputIterator iterator over output points.
|
|
||||||
\tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters"
|
|
||||||
|
|
||||||
\param filename name of the input file
|
|
||||||
\param output output iterator over points
|
|
||||||
\param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below
|
|
||||||
|
|
||||||
\cgalNamedParamsBegin
|
|
||||||
\cgalParamNBegin{point_map}
|
|
||||||
\cgalParamDescription{a property map associating points to the elements of the point range}
|
|
||||||
\cgalParamType{a model of `WritablePropertyMap` with value type `geom_traits::Point_3`}
|
|
||||||
\cgalParamDefault{`CGAL::Identity_property_map<geom_traits::Point_3>`}
|
|
||||||
\cgalParamNEnd
|
|
||||||
|
|
||||||
\cgalParamNBegin{geom_traits}
|
|
||||||
\cgalParamDescription{an instance of a geometric traits class}
|
|
||||||
\cgalParamType{a model of `Kernel`}
|
|
||||||
\cgalParamDefault{a \cgal Kernel deduced from the point type, using `CGAL::Kernel_traits`}
|
|
||||||
\cgalParamNEnd
|
|
||||||
\cgalNamedParamsEnd
|
|
||||||
|
|
||||||
\returns `true` if reading was successful, `false` otherwise.
|
|
||||||
|
|
||||||
\sa `read_LAS_with_properties()`
|
|
||||||
*/
|
|
||||||
template <typename OutputIteratorValueType,
|
template <typename OutputIteratorValueType,
|
||||||
typename PointOutputIterator,
|
typename PointOutputIterator,
|
||||||
typename CGAL_NP_TEMPLATE_PARAMETERS>
|
typename CGAL_NP_TEMPLATE_PARAMETERS_NO_DEFAULT>
|
||||||
bool read_LAS(const std::string& filename,
|
bool read_LAS(const std::string& filename,
|
||||||
PointOutputIterator output,
|
PointOutputIterator output,
|
||||||
const CGAL_NP_CLASS& np = parameters::default_values())
|
const CGAL_NP_CLASS& np)
|
||||||
{
|
{
|
||||||
std::ifstream is(filename, std::ios::binary);
|
std::ifstream is(filename, std::ios::binary);
|
||||||
CGAL::IO::set_mode(is, CGAL::IO::BINARY);
|
CGAL::IO::set_mode(is, CGAL::IO::BINARY);
|
||||||
|
|
@ -549,4 +338,5 @@ bool read_LAS(const std::string& fname, OutputIterator output, const CGAL_NP_CLA
|
||||||
|
|
||||||
} // namespace CGAL
|
} // namespace CGAL
|
||||||
|
|
||||||
#endif // CGAL_POINT_SET_PROCESSING_READ_LAS_POINTS_H
|
#endif // CGAL_LINKED_WITH_LASLIB
|
||||||
|
#endif // CGAL_IO_LAS_READ_LAS_POINTS_H
|
||||||
|
|
@ -1,21 +1,21 @@
|
||||||
// Copyright (c) 2017 Geometry Factory
|
// Copyright (c) 2017 GeometryFactory
|
||||||
// All rights reserved.
|
|
||||||
//
|
//
|
||||||
// This file is part of CGAL (www.cgal.org).
|
// This file is part of CGAL (www.cgal.org);
|
||||||
//
|
//
|
||||||
// $URL$
|
// $URL$
|
||||||
// $Id$
|
// $Id$
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
//
|
//
|
||||||
// Author(s) : Simon Giraudot
|
// Author(s) : Simon Giraudot
|
||||||
|
|
||||||
#ifndef CGAL_POINT_SET_PROCESSING_WRITE_LAS_POINTS_H
|
#ifndef CGAL_IO_LAS_WRITE_LAS_POINTS_H
|
||||||
#define CGAL_POINT_SET_PROCESSING_WRITE_LAS_POINTS_H
|
#define CGAL_IO_LAS_WRITE_LAS_POINTS_H
|
||||||
|
|
||||||
#include <CGAL/license/Point_set_processing_3.h>
|
#ifdef CGAL_LINKED_WITH_LASLIB
|
||||||
|
|
||||||
#include <CGAL/IO/helpers.h>
|
#include <CGAL/IO/helpers.h>
|
||||||
|
#include <CGAL/IO/LAS/Las_property.h>
|
||||||
|
#include <CGAL/IO/LAS.h>
|
||||||
#include <CGAL/Bbox_3.h>
|
#include <CGAL/Bbox_3.h>
|
||||||
#include <CGAL/Named_function_parameters.h>
|
#include <CGAL/Named_function_parameters.h>
|
||||||
#include <CGAL/boost/graph/named_params_helper.h>
|
#include <CGAL/boost/graph/named_params_helper.h>
|
||||||
|
|
@ -62,16 +62,7 @@ namespace CGAL {
|
||||||
|
|
||||||
namespace IO {
|
namespace IO {
|
||||||
|
|
||||||
/**
|
// documented in ../LAS.h
|
||||||
\ingroup PkgPointSetProcessing3IOLas
|
|
||||||
|
|
||||||
\brief generates a %LAS property handler to write 3D points.
|
|
||||||
|
|
||||||
\tparam PointMap the property map used to store points.
|
|
||||||
|
|
||||||
\sa `write_LAS()`
|
|
||||||
\sa \ref IOStreamLAS
|
|
||||||
*/
|
|
||||||
template <typename PointMap>
|
template <typename PointMap>
|
||||||
std::tuple<PointMap, LAS_property::X, LAS_property::Y, LAS_property::Z >
|
std::tuple<PointMap, LAS_property::X, LAS_property::Y, LAS_property::Z >
|
||||||
make_las_point_writer(PointMap point_map)
|
make_las_point_writer(PointMap point_map)
|
||||||
|
|
@ -192,33 +183,7 @@ namespace LAS {
|
||||||
|
|
||||||
/// \endcond
|
/// \endcond
|
||||||
|
|
||||||
/**
|
// documented in ../LAS.h
|
||||||
\ingroup PkgPointSetProcessing3IOLas
|
|
||||||
|
|
||||||
\brief writes the range of `points` with properties to a .las stream.
|
|
||||||
|
|
||||||
Properties are handled through a variadic list of property
|
|
||||||
handlers. A `PropertyHandle` is a `std::pair<PropertyMap,
|
|
||||||
LAS_property::Tag >` used to write a scalar value
|
|
||||||
`LAS_property::Tag::type` as a %LAS property (for example,
|
|
||||||
writing an `int` variable as an `int` %LAS property). An exception
|
|
||||||
is used for points that are written using a `std::tuple` object.
|
|
||||||
|
|
||||||
See documentation of `read_LAS_with_properties()` for the
|
|
||||||
list of available `LAS_property::Tag` classes.
|
|
||||||
|
|
||||||
\attention To write to a binary file, the flag `std::ios::binary` must be set during the creation of the `ofstream`.
|
|
||||||
|
|
||||||
\tparam PointRange is a model of `ConstRange`. The value type of
|
|
||||||
its iterator is the key type of the named parameter `point_map`.
|
|
||||||
\tparam PointMap is a model of `ReadablePropertyMap` with a value_type = `CGAL::Point_3`.
|
|
||||||
\tparam PropertyHandler handlers to recover properties.
|
|
||||||
|
|
||||||
\returns `true` if writing was successful, `false` otherwise.
|
|
||||||
|
|
||||||
\sa `make_las_point_writer()`
|
|
||||||
\sa \ref IOStreamLAS
|
|
||||||
*/
|
|
||||||
template <typename PointRange,
|
template <typename PointRange,
|
||||||
typename PointMap,
|
typename PointMap,
|
||||||
typename ... PropertyHandler>
|
typename ... PropertyHandler>
|
||||||
|
|
@ -280,47 +245,12 @@ bool write_LAS_with_properties(std::ostream& os, ///< output stream.
|
||||||
return !os.fail();
|
return !os.fail();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// documented in ../LAS.h
|
||||||
\ingroup PkgPointSetProcessing3IOLas
|
template <typename PointRange, typename CGAL_NP_TEMPLATE_PARAMETERS_NO_DEFAULT>
|
||||||
|
|
||||||
\brief writes the range of `points` (positions only), using the \ref IOStreamLAS.
|
|
||||||
|
|
||||||
\attention To write to a binary file, the flag `std::ios::binary` must be set during the creation of the `ofstream`.
|
|
||||||
|
|
||||||
\tparam PointRange is a model of `ConstRange`. The value type of
|
|
||||||
its iterator is the key type of the named parameter `point_map`.
|
|
||||||
\tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters"
|
|
||||||
|
|
||||||
\param os output stream
|
|
||||||
\param points input point range
|
|
||||||
\param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below
|
|
||||||
|
|
||||||
\cgalNamedParamsBegin
|
|
||||||
\cgalParamNBegin{point_map}
|
|
||||||
\cgalParamDescription{a property map associating points to the elements of the point range}
|
|
||||||
\cgalParamType{a model of `ReadablePropertyMap` with value type `geom_traits::Point_3`}
|
|
||||||
\cgalParamDefault{`CGAL::Identity_property_map<geom_traits::Point_3>`}
|
|
||||||
\cgalParamNEnd
|
|
||||||
|
|
||||||
\cgalParamNBegin{geom_traits}
|
|
||||||
\cgalParamDescription{an instance of a geometric traits class}
|
|
||||||
\cgalParamType{a model of `Kernel`}
|
|
||||||
\cgalParamDefault{a \cgal Kernel deduced from the point type, using `CGAL::Kernel_traits`}
|
|
||||||
\cgalParamNEnd
|
|
||||||
\cgalNamedParamsEnd
|
|
||||||
|
|
||||||
\returns `true` if writing was successful, `false` otherwise.
|
|
||||||
|
|
||||||
\sa \ref IOStreamLAS
|
|
||||||
\sa `write_LAS_with_properties()`
|
|
||||||
*/
|
|
||||||
template <typename PointRange, typename CGAL_NP_TEMPLATE_PARAMETERS>
|
|
||||||
bool write_LAS(std::ostream& os,
|
bool write_LAS(std::ostream& os,
|
||||||
const PointRange& points,
|
const PointRange& points,
|
||||||
const CGAL_NP_CLASS& np = parameters::default_values()
|
const CGAL_NP_CLASS& np,
|
||||||
#ifndef DOXYGEN_RUNNING
|
std::enable_if_t<internal::is_Range<PointRange>::value>*
|
||||||
, std::enable_if_t<internal::is_Range<PointRange>::value>* = nullptr
|
|
||||||
#endif
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
using parameters::choose_parameter;
|
using parameters::choose_parameter;
|
||||||
|
|
@ -338,44 +268,12 @@ bool write_LAS(std::ostream& os,
|
||||||
return write_LAS_with_properties(os, points, make_las_point_writer(point_map));
|
return write_LAS_with_properties(os, points, make_las_point_writer(point_map));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// documented in ../LAS.h
|
||||||
\ingroup PkgPointSetProcessing3IOLas
|
template <typename PointRange, typename CGAL_NP_TEMPLATE_PARAMETERS_NO_DEFAULT>
|
||||||
|
|
||||||
writes the range of `points` (positions only), using the \ref IOStreamLAS.
|
|
||||||
|
|
||||||
\tparam PointRange is a model of `ConstRange`. The value type of
|
|
||||||
its iterator is the key type of the named parameter `point_map`.
|
|
||||||
\tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters"
|
|
||||||
|
|
||||||
\param filename the path the output file
|
|
||||||
\param points input point range
|
|
||||||
\param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below
|
|
||||||
|
|
||||||
\cgalNamedParamsBegin
|
|
||||||
\cgalParamNBegin{point_map}
|
|
||||||
\cgalParamDescription{a property map associating points to the elements of the point range}
|
|
||||||
\cgalParamType{a model of `ReadablePropertyMap` with value type `geom_traits::Point_3`}
|
|
||||||
\cgalParamDefault{`CGAL::Identity_property_map<geom_traits::Point_3>`}
|
|
||||||
\cgalParamNEnd
|
|
||||||
|
|
||||||
\cgalParamNBegin{geom_traits}
|
|
||||||
\cgalParamDescription{an instance of a geometric traits class}
|
|
||||||
\cgalParamType{a model of `Kernel`}
|
|
||||||
\cgalParamDefault{a \cgal Kernel deduced from the point type, using `CGAL::Kernel_traits`}
|
|
||||||
\cgalParamNEnd
|
|
||||||
\cgalNamedParamsEnd
|
|
||||||
|
|
||||||
\returns `true` if writing was successful, `false` otherwise.
|
|
||||||
|
|
||||||
\sa `write_LAS_with_properties()`
|
|
||||||
*/
|
|
||||||
template <typename PointRange, typename CGAL_NP_TEMPLATE_PARAMETERS>
|
|
||||||
bool write_LAS(const std::string& filename,
|
bool write_LAS(const std::string& filename,
|
||||||
const PointRange& points,
|
const PointRange& points,
|
||||||
const CGAL_NP_CLASS& np = parameters::default_values()
|
const CGAL_NP_CLASS& np,
|
||||||
#ifndef DOXYGEN_RUNNING
|
std::enable_if_t<internal::is_Range<PointRange>::value>*
|
||||||
, std::enable_if_t<internal::is_Range<PointRange>::value>* = nullptr
|
|
||||||
#endif
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
std::ofstream os(filename, std::ios::binary);
|
std::ofstream os(filename, std::ios::binary);
|
||||||
|
|
@ -387,4 +285,5 @@ bool write_LAS(const std::string& filename,
|
||||||
|
|
||||||
} // namespace CGAL
|
} // namespace CGAL
|
||||||
|
|
||||||
#endif // CGAL_POINT_SET_PROCESSING_WRITE_LAS_POINTS_H
|
#endif // CGAL_LINKED_WITH_LASLIB
|
||||||
|
#endif // CGAL_IO_LAS_WRITE_LAS_POINTS_H
|
||||||
|
|
@ -344,6 +344,213 @@ bool write_OFF(const std::string& fname,
|
||||||
return writer(points, polygons, np);
|
return writer(points, polygons, np);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
\ingroup PkgStreamSupportIoFuncsOFF
|
||||||
|
|
||||||
|
\brief reads points (positions + normals, if available), using the \ref IOStreamOFF.
|
||||||
|
|
||||||
|
\tparam OutputIteratorValueType type of objects that can be put in `PointOutputIterator`.
|
||||||
|
It must be a model of `DefaultConstructible` and defaults to `value_type_traits<PointOutputIterator>::%type`.
|
||||||
|
It can be omitted when the default is fine.
|
||||||
|
\tparam PointOutputIterator iterator over output points.
|
||||||
|
\tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters"
|
||||||
|
|
||||||
|
\param is input stream
|
||||||
|
\param output output iterator over points
|
||||||
|
\param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below
|
||||||
|
|
||||||
|
\cgalNamedParamsBegin
|
||||||
|
\cgalParamNBegin{point_map}
|
||||||
|
\cgalParamDescription{a property map associating points to the elements of the point range}
|
||||||
|
\cgalParamType{a model of `WritablePropertyMap` with value type `geom_traits::Point_3`}
|
||||||
|
\cgalParamDefault{`CGAL::Identity_property_map<geom_traits::Point_3>`}
|
||||||
|
\cgalParamNEnd
|
||||||
|
|
||||||
|
\cgalParamNBegin{normal_map}
|
||||||
|
\cgalParamDescription{a property map associating normals to the elements of the point range}
|
||||||
|
\cgalParamType{a model of `WritablePropertyMap` with value type `geom_traits::Vector_3`}
|
||||||
|
\cgalParamDefault{If this parameter is omitted, normals in the input stream are ignored.}
|
||||||
|
\cgalParamNEnd
|
||||||
|
|
||||||
|
\cgalParamNBegin{geom_traits}
|
||||||
|
\cgalParamDescription{an instance of a geometric traits class}
|
||||||
|
\cgalParamType{a model of `Kernel`}
|
||||||
|
\cgalParamDefault{a \cgal Kernel deduced from the point type, using `CGAL::Kernel_traits`}
|
||||||
|
\cgalParamNEnd
|
||||||
|
\cgalNamedParamsEnd
|
||||||
|
|
||||||
|
\returns `true` if reading was successful, `false` otherwise.
|
||||||
|
|
||||||
|
\sa \ref IOStreamOFF
|
||||||
|
*/
|
||||||
|
template <typename OutputIteratorValueType,
|
||||||
|
typename PointOutputIterator,
|
||||||
|
typename CGAL_NP_TEMPLATE_PARAMETERS>
|
||||||
|
bool read_OFF(std::istream& is,
|
||||||
|
PointOutputIterator output,
|
||||||
|
const CGAL_NP_CLASS& np = parameters::default_values()
|
||||||
|
#ifndef DOXYGEN_RUNNING
|
||||||
|
, std::enable_if_t<CGAL::is_iterator<PointOutputIterator>::value>* = nullptr
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\ingroup PkgStreamSupportIoFuncsOFF
|
||||||
|
|
||||||
|
\brief reads points (positions + normals, if available), using the \ref IOStreamOFF.
|
||||||
|
|
||||||
|
\tparam OutputIteratorValueType type of objects that can be put in `PointOutputIterator`.
|
||||||
|
It must be a model of `DefaultConstructible` and defaults to `value_type_traits<PointOutputIterator>::%type`.
|
||||||
|
It can be omitted when the default is fine.
|
||||||
|
\tparam PointOutputIterator iterator over output points.
|
||||||
|
\tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters"
|
||||||
|
|
||||||
|
\param fname input file name
|
||||||
|
\param output output iterator over points
|
||||||
|
\param np optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below.
|
||||||
|
|
||||||
|
\cgalNamedParamsBegin
|
||||||
|
\cgalParamNBegin{point_map}
|
||||||
|
\cgalParamDescription{a property map associating points to the elements of the point range}
|
||||||
|
\cgalParamType{a model of `WritablePropertyMap` with value type `geom_traits::Point_3`}
|
||||||
|
\cgalParamDefault{`CGAL::Identity_property_map<geom_traits::Point_3>`}
|
||||||
|
\cgalParamNEnd
|
||||||
|
|
||||||
|
\cgalParamNBegin{normal_map}
|
||||||
|
\cgalParamDescription{a property map associating normals to the elements of the point range}
|
||||||
|
\cgalParamType{a model of `WritablePropertyMap` with value type `geom_traits::Vector_3`}
|
||||||
|
\cgalParamDefault{If this parameter is omitted, normals in the input stream are ignored.}
|
||||||
|
\cgalParamNEnd
|
||||||
|
|
||||||
|
\cgalParamNBegin{geom_traits}
|
||||||
|
\cgalParamDescription{an instance of a geometric traits class}
|
||||||
|
\cgalParamType{a model of `Kernel`}
|
||||||
|
\cgalParamDefault{a \cgal Kernel deduced from the point type, using `CGAL::Kernel_traits`}
|
||||||
|
\cgalParamNEnd
|
||||||
|
\cgalNamedParamsEnd
|
||||||
|
|
||||||
|
\returns `true` if reading was successful, `false` otherwise.
|
||||||
|
|
||||||
|
\sa \ref IOStreamOFF
|
||||||
|
*/
|
||||||
|
template <typename OutputIteratorValueType,
|
||||||
|
typename PointOutputIterator,
|
||||||
|
typename CGAL_NP_TEMPLATE_PARAMETERS>
|
||||||
|
bool read_OFF(const std::string& fname,
|
||||||
|
PointOutputIterator output,
|
||||||
|
const CGAL_NP_CLASS& np = parameters::default_values()
|
||||||
|
#ifndef DOXYGEN_RUNNING
|
||||||
|
, std::enable_if_t<CGAL::is_iterator<PointOutputIterator>::value>* = nullptr
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
\ingroup PkgStreamSupportIoFuncsOFF
|
||||||
|
|
||||||
|
\brief writes the range of `points` (positions + normals, if available), using the \ref IOStreamOFF.
|
||||||
|
|
||||||
|
\tparam PointRange is a model of `ConstRange`. The value type of
|
||||||
|
its iterator is the key type of the named parameter `point_map`.
|
||||||
|
\tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters"
|
||||||
|
|
||||||
|
\param os output stream
|
||||||
|
\param points input point range
|
||||||
|
\param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below
|
||||||
|
|
||||||
|
\cgalNamedParamsBegin
|
||||||
|
\cgalParamNBegin{point_map}
|
||||||
|
\cgalParamDescription{a property map associating points to the elements of the point range}
|
||||||
|
\cgalParamType{a model of `ReadablePropertyMap` with value type `geom_traits::Point_3`}
|
||||||
|
\cgalParamDefault{`CGAL::Identity_property_map<geom_traits::Point_3>`}
|
||||||
|
\cgalParamNEnd
|
||||||
|
|
||||||
|
\cgalParamNBegin{normal_map}
|
||||||
|
\cgalParamDescription{a property map associating normals to the elements of the point range}
|
||||||
|
\cgalParamType{a model of `ReadablePropertyMap` with value type `geom_traits::Vector_3`}
|
||||||
|
\cgalParamDefault{If this parameter is omitted, normals are not written in the output stream.}
|
||||||
|
\cgalParamNEnd
|
||||||
|
|
||||||
|
\cgalParamNBegin{geom_traits}
|
||||||
|
\cgalParamDescription{an instance of a geometric traits class}
|
||||||
|
\cgalParamType{a model of `Kernel`}
|
||||||
|
\cgalParamDefault{a \cgal Kernel deduced from the point type, using `CGAL::Kernel_traits`}
|
||||||
|
\cgalParamNEnd
|
||||||
|
|
||||||
|
\cgalParamNBegin{stream_precision}
|
||||||
|
\cgalParamDescription{a parameter used to set the precision (i.e. how many digits are generated) of the output stream}
|
||||||
|
\cgalParamType{int}
|
||||||
|
\cgalParamDefault{the precision of the stream `os`}
|
||||||
|
\cgalParamNEnd
|
||||||
|
\cgalNamedParamsEnd
|
||||||
|
|
||||||
|
\returns `true` if writing was successful, `false` otherwise.
|
||||||
|
*/
|
||||||
|
template <typename PointRange, typename CGAL_NP_TEMPLATE_PARAMETERS>
|
||||||
|
bool write_OFF(std::ostream& os,
|
||||||
|
const PointRange& points,
|
||||||
|
const CGAL_NP_CLASS& np = parameters::default_values()
|
||||||
|
#ifndef DOXYGEN_RUNNING
|
||||||
|
, std::enable_if_t<internal::is_Range<PointRange>::value>* = nullptr
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\ingroup PkgStreamSupportIoFuncsOFF
|
||||||
|
|
||||||
|
\brief writes the range of `points` (positions + normals, if available), using the \ref IOStreamOFF.
|
||||||
|
|
||||||
|
\tparam PointRange is a model of `ConstRange`. The value type of
|
||||||
|
its iterator is the key type of the named parameter `point_map`.
|
||||||
|
\tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters"
|
||||||
|
|
||||||
|
\param filename the path to the output file
|
||||||
|
\param points input point range
|
||||||
|
\param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below
|
||||||
|
|
||||||
|
\cgalNamedParamsBegin
|
||||||
|
\cgalParamNBegin{point_map}
|
||||||
|
\cgalParamDescription{a property map associating points to the elements of the point range}
|
||||||
|
\cgalParamType{a model of `ReadablePropertyMap` with value type `geom_traits::Point_3`}
|
||||||
|
\cgalParamDefault{`CGAL::Identity_property_map<geom_traits::Point_3>`}
|
||||||
|
\cgalParamNEnd
|
||||||
|
|
||||||
|
\cgalParamNBegin{normal_map}
|
||||||
|
\cgalParamDescription{a property map associating normals to the elements of the point range}
|
||||||
|
\cgalParamType{a model of `ReadablePropertyMap` with value type `geom_traits::Vector_3`}
|
||||||
|
\cgalParamDefault{If this parameter is omitted, normals are not written in the output file.}
|
||||||
|
\cgalParamNEnd
|
||||||
|
|
||||||
|
\cgalParamNBegin{geom_traits}
|
||||||
|
\cgalParamDescription{an instance of a geometric traits class}
|
||||||
|
\cgalParamType{a model of `Kernel`}
|
||||||
|
\cgalParamDefault{a \cgal Kernel deduced from the point type, using `CGAL::Kernel_traits`}
|
||||||
|
\cgalParamNEnd
|
||||||
|
|
||||||
|
\cgalParamNBegin{stream_precision}
|
||||||
|
\cgalParamDescription{a parameter used to set the precision (i.e. how many digits are generated) of the output stream}
|
||||||
|
\cgalParamType{int}
|
||||||
|
\cgalParamDefault{`6`}
|
||||||
|
\cgalParamNEnd
|
||||||
|
\cgalNamedParamsEnd
|
||||||
|
|
||||||
|
\returns `true` if writing was successful, `false` otherwise.
|
||||||
|
|
||||||
|
\sa \ref IOStreamOFF
|
||||||
|
*/
|
||||||
|
template <typename PointRange,
|
||||||
|
typename CGAL_NP_TEMPLATE_PARAMETERS>
|
||||||
|
bool write_OFF(const std::string& filename,
|
||||||
|
const PointRange& points,
|
||||||
|
const CGAL_NP_CLASS& np = parameters::default_values()
|
||||||
|
#ifndef DOXYGEN_RUNNING
|
||||||
|
, std::enable_if_t<internal::is_Range<PointRange>::value>* = nullptr
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
|
||||||
} // namespace IO
|
} // namespace IO
|
||||||
|
|
||||||
} // namespace CGAL
|
} // namespace CGAL
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,21 @@
|
||||||
// Copyright (c) 2007-09 INRIA Sophia-Antipolis (France).
|
// Copyright (c) 1997
|
||||||
// All rights reserved.
|
// Utrecht University (The Netherlands),
|
||||||
|
// ETH Zurich (Switzerland),
|
||||||
|
// INRIA Sophia-Antipolis (France),
|
||||||
|
// Max-Planck-Institute Saarbruecken (Germany),
|
||||||
|
// and Tel-Aviv University (Israel). All rights reserved.
|
||||||
//
|
//
|
||||||
// This file is part of CGAL (www.cgal.org).
|
// This file is part of CGAL (www.cgal.org);
|
||||||
//
|
//
|
||||||
// $URL$
|
// $URL$
|
||||||
// $Id$
|
// $Id$
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
//
|
//
|
||||||
// Author(s) : Pierre Alliez and Laurent Saboret
|
// Author(s) : Pierre Alliez and Laurent Saboret
|
||||||
|
|
||||||
#ifndef CGAL_POINT_SET_PROCESSING_READ_OFF_POINTS_H
|
#ifndef CGAL_IO_OFF_READ_OFF_POINTS_H
|
||||||
#define CGAL_POINT_SET_PROCESSING_READ_OFF_POINTS_H
|
#define CGAL_IO_OFF_READ_OFF_POINTS_H
|
||||||
|
|
||||||
#include <CGAL/license/Point_set_processing_3.h>
|
|
||||||
|
|
||||||
#include <CGAL/IO/io.h>
|
#include <CGAL/IO/io.h>
|
||||||
#include <CGAL/property_map.h>
|
#include <CGAL/property_map.h>
|
||||||
|
|
@ -21,10 +24,12 @@
|
||||||
#include <CGAL/Kernel_traits.h>
|
#include <CGAL/Kernel_traits.h>
|
||||||
#include <CGAL/iterator.h>
|
#include <CGAL/iterator.h>
|
||||||
#include <CGAL/type_traits/is_iterator.h>
|
#include <CGAL/type_traits/is_iterator.h>
|
||||||
|
#include <CGAL/IO/OFF.h>
|
||||||
|
|
||||||
#include <CGAL/Named_function_parameters.h>
|
#include <CGAL/Named_function_parameters.h>
|
||||||
#include <CGAL/boost/graph/named_params_helper.h>
|
#include <CGAL/boost/graph/named_params_helper.h>
|
||||||
|
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
@ -35,54 +40,14 @@ namespace CGAL {
|
||||||
|
|
||||||
namespace IO {
|
namespace IO {
|
||||||
|
|
||||||
/**
|
// doxygen in ../OFF.h
|
||||||
\ingroup PkgPointSetProcessing3IOOff
|
|
||||||
|
|
||||||
\brief reads points (positions + normals, if available), using the \ref IOStreamOFF.
|
|
||||||
|
|
||||||
\tparam OutputIteratorValueType type of objects that can be put in `PointOutputIterator`.
|
|
||||||
It must be a model of `DefaultConstructible` and defaults to `value_type_traits<PointOutputIterator>::%type`.
|
|
||||||
It can be omitted when the default is fine.
|
|
||||||
\tparam PointOutputIterator iterator over output points.
|
|
||||||
\tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters"
|
|
||||||
|
|
||||||
\param is input stream
|
|
||||||
\param output output iterator over points
|
|
||||||
\param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below
|
|
||||||
|
|
||||||
\cgalNamedParamsBegin
|
|
||||||
\cgalParamNBegin{point_map}
|
|
||||||
\cgalParamDescription{a property map associating points to the elements of the point range}
|
|
||||||
\cgalParamType{a model of `WritablePropertyMap` with value type `geom_traits::Point_3`}
|
|
||||||
\cgalParamDefault{`CGAL::Identity_property_map<geom_traits::Point_3>`}
|
|
||||||
\cgalParamNEnd
|
|
||||||
|
|
||||||
\cgalParamNBegin{normal_map}
|
|
||||||
\cgalParamDescription{a property map associating normals to the elements of the point range}
|
|
||||||
\cgalParamType{a model of `WritablePropertyMap` with value type `geom_traits::Vector_3`}
|
|
||||||
\cgalParamDefault{If this parameter is omitted, normals in the input stream are ignored.}
|
|
||||||
\cgalParamNEnd
|
|
||||||
|
|
||||||
\cgalParamNBegin{geom_traits}
|
|
||||||
\cgalParamDescription{an instance of a geometric traits class}
|
|
||||||
\cgalParamType{a model of `Kernel`}
|
|
||||||
\cgalParamDefault{a \cgal Kernel deduced from the point type, using `CGAL::Kernel_traits`}
|
|
||||||
\cgalParamNEnd
|
|
||||||
\cgalNamedParamsEnd
|
|
||||||
|
|
||||||
\returns `true` if reading was successful, `false` otherwise.
|
|
||||||
|
|
||||||
\sa \ref IOStreamOFF
|
|
||||||
*/
|
|
||||||
template <typename OutputIteratorValueType,
|
template <typename OutputIteratorValueType,
|
||||||
typename PointOutputIterator,
|
typename PointOutputIterator,
|
||||||
typename CGAL_NP_TEMPLATE_PARAMETERS>
|
typename CGAL_NP_TEMPLATE_PARAMETERS_NO_DEFAULT>
|
||||||
bool read_OFF(std::istream& is,
|
bool read_OFF(std::istream& is,
|
||||||
PointOutputIterator output,
|
PointOutputIterator output,
|
||||||
const CGAL_NP_CLASS& np = parameters::default_values()
|
const CGAL_NP_CLASS& np,
|
||||||
#ifndef DOXYGEN_RUNNING
|
std::enable_if_t<CGAL::is_iterator<PointOutputIterator>::value>*
|
||||||
, std::enable_if_t<CGAL::is_iterator<PointOutputIterator>::value>* = nullptr
|
|
||||||
#endif
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
using parameters::choose_parameter;
|
using parameters::choose_parameter;
|
||||||
|
|
@ -194,54 +159,14 @@ bool read_OFF(std::istream& is,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// doxygen in ../OFF.h
|
||||||
\ingroup PkgPointSetProcessing3IOOff
|
|
||||||
|
|
||||||
\brief reads points (positions + normals, if available), using the \ref IOStreamOFF.
|
|
||||||
|
|
||||||
\tparam OutputIteratorValueType type of objects that can be put in `PointOutputIterator`.
|
|
||||||
It must be a model of `DefaultConstructible` and defaults to `value_type_traits<PointOutputIterator>::%type`.
|
|
||||||
It can be omitted when the default is fine.
|
|
||||||
\tparam PointOutputIterator iterator over output points.
|
|
||||||
\tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters"
|
|
||||||
|
|
||||||
\param fname input file name
|
|
||||||
\param output output iterator over points
|
|
||||||
\param np optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below.
|
|
||||||
|
|
||||||
\cgalNamedParamsBegin
|
|
||||||
\cgalParamNBegin{point_map}
|
|
||||||
\cgalParamDescription{a property map associating points to the elements of the point range}
|
|
||||||
\cgalParamType{a model of `WritablePropertyMap` with value type `geom_traits::Point_3`}
|
|
||||||
\cgalParamDefault{`CGAL::Identity_property_map<geom_traits::Point_3>`}
|
|
||||||
\cgalParamNEnd
|
|
||||||
|
|
||||||
\cgalParamNBegin{normal_map}
|
|
||||||
\cgalParamDescription{a property map associating normals to the elements of the point range}
|
|
||||||
\cgalParamType{a model of `WritablePropertyMap` with value type `geom_traits::Vector_3`}
|
|
||||||
\cgalParamDefault{If this parameter is omitted, normals in the input stream are ignored.}
|
|
||||||
\cgalParamNEnd
|
|
||||||
|
|
||||||
\cgalParamNBegin{geom_traits}
|
|
||||||
\cgalParamDescription{an instance of a geometric traits class}
|
|
||||||
\cgalParamType{a model of `Kernel`}
|
|
||||||
\cgalParamDefault{a \cgal Kernel deduced from the point type, using `CGAL::Kernel_traits`}
|
|
||||||
\cgalParamNEnd
|
|
||||||
\cgalNamedParamsEnd
|
|
||||||
|
|
||||||
\returns `true` if reading was successful, `false` otherwise.
|
|
||||||
|
|
||||||
\sa \ref IOStreamOFF
|
|
||||||
*/
|
|
||||||
template <typename OutputIteratorValueType,
|
template <typename OutputIteratorValueType,
|
||||||
typename PointOutputIterator,
|
typename PointOutputIterator,
|
||||||
typename CGAL_NP_TEMPLATE_PARAMETERS>
|
typename CGAL_NP_TEMPLATE_PARAMETERS_NO_DEFAULT>
|
||||||
bool read_OFF(const std::string& fname,
|
bool read_OFF(const std::string& fname,
|
||||||
PointOutputIterator output,
|
PointOutputIterator output,
|
||||||
const CGAL_NP_CLASS& np = parameters::default_values()
|
const CGAL_NP_CLASS& np,
|
||||||
#ifndef DOXYGEN_RUNNING
|
std::enable_if_t<CGAL::is_iterator<PointOutputIterator>::value>*
|
||||||
, std::enable_if_t<CGAL::is_iterator<PointOutputIterator>::value>* = nullptr
|
|
||||||
#endif
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
std::ifstream is(fname);
|
std::ifstream is(fname);
|
||||||
|
|
@ -273,4 +198,4 @@ bool read_OFF(const std::string& fname, OutputIterator output, const CGAL_NP_CLA
|
||||||
|
|
||||||
} // namespace CGAL
|
} // namespace CGAL
|
||||||
|
|
||||||
#endif // CGAL_POINT_SET_PROCESSING_READ_OFF_POINTS_H
|
#endif // CGAL_IO_OFF_READ_OFF_POINTS_H
|
||||||
|
|
@ -0,0 +1,119 @@
|
||||||
|
// Copyright (c) 1997
|
||||||
|
// Utrecht University (The Netherlands),
|
||||||
|
// ETH Zurich (Switzerland),
|
||||||
|
// INRIA Sophia-Antipolis (France),
|
||||||
|
// Max-Planck-Institute Saarbruecken (Germany),
|
||||||
|
// and Tel-Aviv University (Israel). 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) : Pierre Alliez and Laurent Saboret
|
||||||
|
|
||||||
|
#ifndef CGAL_IO_OFF_WRITE_OFF_POINTS_H
|
||||||
|
#define CGAL_IO_OFF_WRITE_OFF_POINTS_H
|
||||||
|
|
||||||
|
#include <CGAL/IO/helpers.h>
|
||||||
|
#include <CGAL/IO/OFF.h>
|
||||||
|
|
||||||
|
#include <CGAL/Named_function_parameters.h>
|
||||||
|
#include <CGAL/boost/graph/named_params_helper.h>
|
||||||
|
#include <CGAL/property_map.h>
|
||||||
|
#include <CGAL/Iterator_range.h>
|
||||||
|
#include <CGAL/assertions.h>
|
||||||
|
#include <CGAL/IO/OFF.h>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <iterator>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
namespace Point_set_processing_3 {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
template <typename PointRange, typename CGAL_NP_TEMPLATE_PARAMETERS>
|
||||||
|
bool write_OFF_PSP(std::ostream& os,
|
||||||
|
const PointRange& points,
|
||||||
|
const CGAL_NP_CLASS& np = CGAL::parameters::default_values())
|
||||||
|
{
|
||||||
|
using CGAL::parameters::is_default_parameter;
|
||||||
|
|
||||||
|
// basic geometric types
|
||||||
|
typedef Point_set_processing_3_np_helper<PointRange, CGAL_NP_CLASS> NP_helper;
|
||||||
|
typedef typename NP_helper::Const_point_map PointMap;
|
||||||
|
typedef typename NP_helper::Normal_map NormalMap;
|
||||||
|
|
||||||
|
const bool has_normals = NP_helper::has_normal_map(points, np);
|
||||||
|
|
||||||
|
PointMap point_map = NP_helper::get_const_point_map(points, np);
|
||||||
|
NormalMap normal_map = NP_helper::get_normal_map(points, np);
|
||||||
|
|
||||||
|
CGAL_precondition(points.begin() != points.end());
|
||||||
|
|
||||||
|
if(!os)
|
||||||
|
{
|
||||||
|
std::cerr << "Error: cannot open file" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
set_stream_precision_from_NP(os, np);
|
||||||
|
|
||||||
|
// Write header
|
||||||
|
if (has_normals)
|
||||||
|
os << "NOFF" << std::endl;
|
||||||
|
else
|
||||||
|
os << "OFF" << std::endl;
|
||||||
|
os << points.size() << " 0 0" << std::endl;
|
||||||
|
|
||||||
|
// Write positions + normals
|
||||||
|
for(typename PointRange::const_iterator it = points.begin(); it != points.end(); it++)
|
||||||
|
{
|
||||||
|
os << get(point_map, *it);
|
||||||
|
if (has_normals)
|
||||||
|
os << " " << get(normal_map, *it);
|
||||||
|
os << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
os << std::flush;
|
||||||
|
|
||||||
|
return !os.fail();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
} // namespace Point_set_processing_3
|
||||||
|
|
||||||
|
namespace IO {
|
||||||
|
|
||||||
|
// // doxygen in ../OFF.h
|
||||||
|
template <typename PointRange, typename CGAL_NP_TEMPLATE_PARAMETERS_NO_DEFAULT>
|
||||||
|
bool write_OFF(std::ostream& os,
|
||||||
|
const PointRange& points,
|
||||||
|
const CGAL_NP_CLASS& np,
|
||||||
|
std::enable_if_t<internal::is_Range<PointRange>::value>*
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return Point_set_processing_3::internal::write_OFF_PSP(os, points, np);
|
||||||
|
}
|
||||||
|
|
||||||
|
// // doxygen in ../OFF.h
|
||||||
|
template <typename PointRange,
|
||||||
|
typename CGAL_NP_TEMPLATE_PARAMETERS_NO_DEFAULT>
|
||||||
|
bool write_OFF(const std::string& filename,
|
||||||
|
const PointRange& points,
|
||||||
|
const CGAL_NP_CLASS& np, std::enable_if_t<internal::is_Range<PointRange>::value>*
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::ofstream os(filename);
|
||||||
|
set_stream_precision_from_NP(os, np);
|
||||||
|
return write_OFF(os, points, np);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // IO namespace
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
#endif // CGAL_IO_OFF_WRITE_OFF_POINTS_H
|
||||||
|
|
@ -14,8 +14,8 @@
|
||||||
|
|
||||||
#include <CGAL/IO/PLY/PLY_reader.h>
|
#include <CGAL/IO/PLY/PLY_reader.h>
|
||||||
#include <CGAL/IO/PLY/PLY_writer.h>
|
#include <CGAL/IO/PLY/PLY_writer.h>
|
||||||
#include <CGAL/IO/helpers.h>
|
|
||||||
|
|
||||||
|
#include <CGAL/IO/helpers.h>
|
||||||
#include <CGAL/Named_function_parameters.h>
|
#include <CGAL/Named_function_parameters.h>
|
||||||
#include <CGAL/boost/graph/named_params_helper.h>
|
#include <CGAL/boost/graph/named_params_helper.h>
|
||||||
#include <CGAL/property_map.h>
|
#include <CGAL/property_map.h>
|
||||||
|
|
@ -549,7 +549,7 @@ bool write_PLY(const std::string& fname,
|
||||||
const CGAL_NP_CLASS& np = parameters::default_values()
|
const CGAL_NP_CLASS& np = parameters::default_values()
|
||||||
#ifndef DOXYGEN_RUNNING
|
#ifndef DOXYGEN_RUNNING
|
||||||
, std::enable_if_t<internal::is_Range<PolygonRange>::value>* = nullptr
|
, std::enable_if_t<internal::is_Range<PolygonRange>::value>* = nullptr
|
||||||
#endif
|
#endif // DOXYGEN_RUNNING
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
const bool binary = CGAL::parameters::choose_parameter(CGAL::parameters::get_parameter(np, internal_np::use_binary_mode), true);
|
const bool binary = CGAL::parameters::choose_parameter(CGAL::parameters::get_parameter(np, internal_np::use_binary_mode), true);
|
||||||
|
|
@ -567,8 +567,429 @@ bool write_PLY(const std::string& fname,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef DOXYGEN_RUNNING
|
||||||
|
/**
|
||||||
|
\ingroup PkgStreamSupportIoFuncsPLY
|
||||||
|
|
||||||
|
Class used to identify a %PLY property as a type and a name.
|
||||||
|
|
||||||
|
\sa `read_PLY_with_properties()`
|
||||||
|
*/
|
||||||
|
template <typename T>
|
||||||
|
struct PLY_property
|
||||||
|
{
|
||||||
|
typedef T type;
|
||||||
|
const char* name;
|
||||||
|
PLY_property(const char* name) : name(name) { }
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
\ingroup PkgStreamSupportIoFuncsPLY
|
||||||
|
|
||||||
|
Generates a %PLY property handler to read 3D points. Points are
|
||||||
|
constructed from the input using 3 %PLY properties of type `FT`
|
||||||
|
and named `x`, `y` and `z`. `FT` is `float` if the points use
|
||||||
|
`CGAL::Simple_cartesian<float>` and `double` otherwise.
|
||||||
|
|
||||||
|
\tparam PointMap the property map used to store points.
|
||||||
|
|
||||||
|
\sa `read_PLY_with_properties()`
|
||||||
|
\sa \ref IOStreamPLY
|
||||||
|
*/
|
||||||
|
template <typename PointMap>
|
||||||
|
std::tuple<PointMap,
|
||||||
|
typename Kernel_traits<typename PointMap::value_type>::Kernel::Construct_point_3,
|
||||||
|
PLY_property<FT>, PLY_property<FT>, PLY_property<FT> >
|
||||||
|
make_ply_point_reader(PointMap point_map);
|
||||||
|
|
||||||
|
/**
|
||||||
|
\ingroup PkgStreamSupportIoFuncsPLY
|
||||||
|
|
||||||
|
Generates a %PLY property handler to read 3D normal
|
||||||
|
vectors. Vectors are constructed from the input using 3 PLY
|
||||||
|
properties of type `FT` and named `nx`, `ny` and `nz`. `FT`
|
||||||
|
is `float` if the points use `CGAL::Simple_cartesian<float>` and
|
||||||
|
`double` otherwise.
|
||||||
|
|
||||||
|
\tparam VectorMap the property map used to store vectors.
|
||||||
|
|
||||||
|
\sa `read_PLY_with_properties()`
|
||||||
|
\sa \ref IOStreamPLY
|
||||||
|
*/
|
||||||
|
template <typename VectorMap>
|
||||||
|
std::tuple<VectorMap,
|
||||||
|
typename Kernel_traits<typename VectorMap::value_type>::Kernel::Construct_vector_3,
|
||||||
|
PLY_property<FT>, PLY_property<FT>, PLY_property<FT> >
|
||||||
|
make_ply_normal_reader(VectorMap normal_map);
|
||||||
|
|
||||||
|
#endif // DOXYGEN_RUNNING
|
||||||
|
|
||||||
|
/**
|
||||||
|
\ingroup PkgStreamSupportIoFuncsPLY
|
||||||
|
|
||||||
|
\brief reads user-selected points properties from a .ply stream (ASCII or binary).
|
||||||
|
|
||||||
|
Potential additional point properties and faces are ignored.
|
||||||
|
|
||||||
|
Properties are handled through a variadic list of property
|
||||||
|
handlers. A `PropertyHandler` can either be:
|
||||||
|
|
||||||
|
- A `std::pair<PropertyMap, PLY_property<T> >` if the user wants
|
||||||
|
to read a %PLY property as a scalar value T (for example, storing
|
||||||
|
an `int` %PLY property into an `int` variable).
|
||||||
|
|
||||||
|
- A `std::tuple<PropertyMap, Constructor,
|
||||||
|
PLY_property<T>...>` if the user wants to use one or several PLY
|
||||||
|
properties to construct a complex object (for example, storing 3
|
||||||
|
`uchar` %PLY properties into a %Color object that can for example
|
||||||
|
be a `std::array<unsigned char, 3>`). In that case, the
|
||||||
|
second element of the tuple should be a functor that constructs
|
||||||
|
the value type of `PropertyMap` from N objects of types `T`.
|
||||||
|
|
||||||
|
\attention To read a binary file, the flag `std::ios::binary` must be set during the creation of the `ifstream`.
|
||||||
|
|
||||||
|
\tparam OutputIteratorValueType type of objects that can be put in `PointOutputIterator`.
|
||||||
|
It must be a model of `DefaultConstructible` and defaults to `value_type_traits<PointOutputIterator>::%type`.
|
||||||
|
It can be omitted when the default is fine.
|
||||||
|
\tparam PointOutputIterator iterator over output points.
|
||||||
|
\tparam PropertyHandler handlers to recover properties.
|
||||||
|
|
||||||
|
\returns `true` if reading was successful, `false` otherwise.
|
||||||
|
|
||||||
|
\sa \ref IOStreamPLY
|
||||||
|
\sa `make_ply_point_reader()`
|
||||||
|
\sa `make_ply_normal_reader()`
|
||||||
|
*/
|
||||||
|
template <typename OutputIteratorValueType,
|
||||||
|
typename PointOutputIterator,
|
||||||
|
typename ... PropertyHandler>
|
||||||
|
bool read_PLY_with_properties(std::istream& is,
|
||||||
|
PointOutputIterator output,
|
||||||
|
PropertyHandler&& ... properties);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\ingroup PkgStreamSupportIoFuncsPLY
|
||||||
|
|
||||||
|
\brief reads points (positions + normals, if available), using the \ref IOStreamPLY.
|
||||||
|
|
||||||
|
Potential additional point properties and faces are ignored.
|
||||||
|
|
||||||
|
\attention To read a binary file, the flag `std::ios::binary` must be set during the creation of the `ifstream`.
|
||||||
|
|
||||||
|
\tparam OutputIteratorValueType type of objects that can be put in `PointOutputIterator`.
|
||||||
|
It must be a model of `DefaultConstructible` and defaults to `value_type_traits<PointOutputIterator>::%type`.
|
||||||
|
It can be omitted when the default is fine.
|
||||||
|
\tparam PointOutputIterator iterator over output points.
|
||||||
|
\tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters"
|
||||||
|
|
||||||
|
\param is input stream.
|
||||||
|
\param output output iterator over points.
|
||||||
|
\param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below
|
||||||
|
|
||||||
|
\cgalNamedParamsBegin
|
||||||
|
\cgalParamNBegin{point_map}
|
||||||
|
\cgalParamDescription{a property map associating points to the elements of the point range}
|
||||||
|
\cgalParamType{a model of `WritablePropertyMap` with value type `geom_traits::Point_3`}
|
||||||
|
\cgalParamDefault{`CGAL::Identity_property_map<geom_traits::Point_3>`}
|
||||||
|
\cgalParamNEnd
|
||||||
|
|
||||||
|
\cgalParamNBegin{normal_map}
|
||||||
|
\cgalParamDescription{a property map associating normals to the elements of the point range}
|
||||||
|
\cgalParamType{a model of `WritablePropertyMap` with value type `geom_traits::Vector_3`}
|
||||||
|
\cgalParamDefault{If this parameter is omitted, normals in the input stream are ignored.}
|
||||||
|
\cgalParamNEnd
|
||||||
|
|
||||||
|
\cgalParamNBegin{geom_traits}
|
||||||
|
\cgalParamDescription{an instance of a geometric traits class}
|
||||||
|
\cgalParamType{a model of `Kernel`}
|
||||||
|
\cgalParamDefault{a \cgal Kernel deduced from the point type, using `CGAL::Kernel_traits`}
|
||||||
|
\cgalParamNEnd
|
||||||
|
\cgalNamedParamsEnd
|
||||||
|
|
||||||
|
\returns `true` if reading was successful, `false` otherwise.
|
||||||
|
|
||||||
|
\sa `read_PLY_with_properties()`
|
||||||
|
*/
|
||||||
|
template <typename OutputIteratorValueType,
|
||||||
|
typename PointOutputIterator,
|
||||||
|
typename CGAL_NP_TEMPLATE_PARAMETERS>
|
||||||
|
bool read_PLY(std::istream& is,
|
||||||
|
PointOutputIterator output,
|
||||||
|
const CGAL_NP_CLASS& np = parameters::default_values()
|
||||||
|
#ifndef DOXYGEN_RUNNING
|
||||||
|
, std::enable_if_t<CGAL::is_iterator<PointOutputIterator>::value>* = nullptr
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\ingroup PkgStreamSupportIoFuncsPLY
|
||||||
|
|
||||||
|
\brief reads points (positions + normals, if available), using the \ref IOStreamPLY.
|
||||||
|
|
||||||
|
Potential additional point properties and faces are ignored.
|
||||||
|
|
||||||
|
\tparam OutputIteratorValueType type of objects that can be put in `PointOutputIterator`.
|
||||||
|
It must be a model of `DefaultConstructible` and defaults to `value_type_traits<PointOutputIterator>::%type`.
|
||||||
|
It can be omitted when the default is fine.
|
||||||
|
\tparam PointOutputIterator iterator over output points.
|
||||||
|
\tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters"
|
||||||
|
|
||||||
|
\param fname input file name.
|
||||||
|
\param output output iterator over points.
|
||||||
|
\param np optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below.
|
||||||
|
|
||||||
|
\cgalNamedParamsBegin
|
||||||
|
\cgalParamNBegin{use_binary_mode}
|
||||||
|
\cgalParamDescription{indicates whether data should be read in binary (`true`) or in \ascii (`false`)}
|
||||||
|
\cgalParamType{Boolean}
|
||||||
|
\cgalParamDefault{`true`}
|
||||||
|
\cgalParamNEnd
|
||||||
|
|
||||||
|
\cgalParamNBegin{point_map}
|
||||||
|
\cgalParamDescription{a property map associating points to the elements of the point range}
|
||||||
|
\cgalParamType{a model of `WritablePropertyMap` with value type `geom_traits::Point_3`}
|
||||||
|
\cgalParamDefault{`CGAL::Identity_property_map<geom_traits::Point_3>`}
|
||||||
|
\cgalParamNEnd
|
||||||
|
|
||||||
|
\cgalParamNBegin{normal_map}
|
||||||
|
\cgalParamDescription{a property map associating normals to the elements of the point range}
|
||||||
|
\cgalParamType{a model of `WritablePropertyMap` with value type `geom_traits::Vector_3`}
|
||||||
|
\cgalParamDefault{If this parameter is omitted, normals in the input stream are ignored.}
|
||||||
|
\cgalParamNEnd
|
||||||
|
|
||||||
|
\cgalParamNBegin{geom_traits}
|
||||||
|
\cgalParamDescription{an instance of a geometric traits class}
|
||||||
|
\cgalParamType{a model of `Kernel`}
|
||||||
|
\cgalParamDefault{a \cgal Kernel deduced from the point type, using `CGAL::Kernel_traits`}
|
||||||
|
\cgalParamNEnd
|
||||||
|
\cgalNamedParamsEnd
|
||||||
|
|
||||||
|
\returns `true` if reading was successful, `false` otherwise.
|
||||||
|
|
||||||
|
\sa \ref IOStreamPLY
|
||||||
|
\sa `read_PLY_with_properties()`
|
||||||
|
*/
|
||||||
|
template <typename OutputIteratorValueType,
|
||||||
|
typename PointOutputIterator,
|
||||||
|
typename CGAL_NP_TEMPLATE_PARAMETERS>
|
||||||
|
bool read_PLY(const std::string& fname,
|
||||||
|
PointOutputIterator output,
|
||||||
|
const CGAL_NP_CLASS& np = parameters::default_values()
|
||||||
|
#ifndef DOXYGEN_RUNNING
|
||||||
|
, std::enable_if_t<CGAL::is_iterator<PointOutputIterator>::value>* = nullptr
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef DOXYGEN_RUNNING // Document some parts from Stream_support here for convenience
|
||||||
|
/**
|
||||||
|
\ingroup PkgStreamSupportIoFuncsPLY
|
||||||
|
|
||||||
|
Generates a %PLY property handler to write 3D points. Points are
|
||||||
|
written as 3 %PLY properties of type `FT` and named `x`, `y` and
|
||||||
|
`z`. `FT` is `float` if the points use
|
||||||
|
`CGAL::Simple_cartesian<float>` and `double` otherwise.
|
||||||
|
|
||||||
|
\tparam PointMap the property map used to store points.
|
||||||
|
|
||||||
|
\sa `write_PLY_with_properties()`
|
||||||
|
\sa \ref IOStreamPLY
|
||||||
|
*/
|
||||||
|
template <typename PointMap>
|
||||||
|
std::tuple<PointMap, PLY_property<FT>, PLY_property<FT>, PLY_property<FT> >
|
||||||
|
make_ply_point_writer(PointMap point_map);
|
||||||
|
|
||||||
|
/**
|
||||||
|
\ingroup PkgStreamSupportIoFuncsPLY
|
||||||
|
|
||||||
|
Generates a %PLY property handler to write 3D normal
|
||||||
|
vectors. Vectors are written as 3 %PLY properties of type `FT`
|
||||||
|
and named `nx`, `ny` and `nz`. `FT` is `float` if the vectors use
|
||||||
|
`CGAL::Simple_cartesian<float>` and `double` otherwise.
|
||||||
|
|
||||||
|
\tparam VectorMap the property map used to store vectors.
|
||||||
|
|
||||||
|
\sa `write_PLY_with_properties()`
|
||||||
|
\sa \ref IOStreamPLY
|
||||||
|
*/
|
||||||
|
template <typename VectorMap>
|
||||||
|
std::tuple<VectorMap, PLY_property<FT>, PLY_property<FT>, PLY_property<FT> >
|
||||||
|
make_ply_normal_writer(VectorMap normal_map);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\ingroup PkgStreamSupportIoFuncsPLY
|
||||||
|
|
||||||
|
\brief writes the range of `points` with properties using \ref IOStreamPLY.
|
||||||
|
|
||||||
|
Properties are handled through a variadic list of property
|
||||||
|
handlers. A `PropertyHandler` can either be:
|
||||||
|
|
||||||
|
- A `std::pair<PropertyMap, PLY_property<T> >` if the user wants
|
||||||
|
to write a scalar value T as a %PLY property (for example, writing
|
||||||
|
an `int` variable as an `int` %PLY property).
|
||||||
|
|
||||||
|
- A `std::tuple<PropertyMap, PLY_property<T>...>` if the
|
||||||
|
user wants to write a complex object as several %PLY
|
||||||
|
properties. In that case, a specialization of `Output_rep` must
|
||||||
|
be provided for `PropertyMap::value_type` that handles both ASCII
|
||||||
|
and binary output (see `CGAL::IO::get_mode()`).
|
||||||
|
|
||||||
|
\attention To write to a binary file, the flag `std::ios::binary` must be set during the creation
|
||||||
|
of the `ofstream`, and the \link PkgStreamSupportEnumRef `IO::Mode` \endlink
|
||||||
|
of the stream must be set to `BINARY`.
|
||||||
|
|
||||||
|
\tparam PointRange is a model of `ConstRange`. The value type of
|
||||||
|
its iterator is the key type of the `PropertyMap` objects provided
|
||||||
|
within the `PropertyHandler` parameter.
|
||||||
|
\tparam PropertyHandler handlers to recover properties.
|
||||||
|
|
||||||
|
\returns `true` if writing was successful, `false` otherwise.
|
||||||
|
|
||||||
|
\sa \ref IOStreamPLY
|
||||||
|
\sa `make_ply_point_writer()`
|
||||||
|
\sa `make_ply_normal_writer()`
|
||||||
|
*/
|
||||||
|
template <typename PointRange,
|
||||||
|
typename ... PropertyHandler>
|
||||||
|
bool write_PLY_with_properties(std::ostream& os, ///< output stream.
|
||||||
|
const PointRange& points, ///< input point range.
|
||||||
|
PropertyHandler&& ... properties); ///< parameter pack of property handlers
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\ingroup PkgStreamSupportIoFuncsPLY
|
||||||
|
|
||||||
|
\brief writes the range of `points` (positions + normals, if available) using \ref IOStreamPLY.
|
||||||
|
|
||||||
|
\attention To write to a binary file, the flag `std::ios::binary` must be set during the creation
|
||||||
|
of the `ofstream`, and the \link PkgStreamSupportEnumRef `IO::Mode` \endlink
|
||||||
|
of the stream must be set to `BINARY`.
|
||||||
|
|
||||||
|
\tparam PointRange is a model of `ConstRange`. The value type of
|
||||||
|
its iterator is the key type of the named parameter `point_map`.
|
||||||
|
\tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters"
|
||||||
|
|
||||||
|
\param os output stream
|
||||||
|
\param points input point range
|
||||||
|
\param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below
|
||||||
|
|
||||||
|
\cgalNamedParamsBegin
|
||||||
|
\cgalParamNBegin{point_map}
|
||||||
|
\cgalParamDescription{a property map associating points to the elements of the point range}
|
||||||
|
\cgalParamType{a model of `ReadablePropertyMap` with value type `geom_traits::Point_3`}
|
||||||
|
\cgalParamDefault{`CGAL::Identity_property_map<geom_traits::Point_3>`}
|
||||||
|
\cgalParamNEnd
|
||||||
|
|
||||||
|
\cgalParamNBegin{normal_map}
|
||||||
|
\cgalParamDescription{a property map associating normals to the elements of the point range}
|
||||||
|
\cgalParamType{a model of `ReadablePropertyMap` with value type `geom_traits::Vector_3`}
|
||||||
|
\cgalParamDefault{If this parameter is omitted, normals are not written in the output stream.}
|
||||||
|
\cgalParamNEnd
|
||||||
|
|
||||||
|
\cgalParamNBegin{geom_traits}
|
||||||
|
\cgalParamDescription{an instance of a geometric traits class}
|
||||||
|
\cgalParamType{a model of `Kernel`}
|
||||||
|
\cgalParamDefault{a \cgal Kernel deduced from the point type, using `CGAL::Kernel_traits`}
|
||||||
|
\cgalParamNEnd
|
||||||
|
|
||||||
|
\cgalParamNBegin{stream_precision}
|
||||||
|
\cgalParamDescription{a parameter used to set the precision (i.e. how many digits are generated) of the output stream}
|
||||||
|
\cgalParamType{int}
|
||||||
|
\cgalParamDefault{the precision of the stream `os`}
|
||||||
|
\cgalParamExtra{This parameter is only meaningful while using \ascii encoding.}
|
||||||
|
\cgalParamNEnd
|
||||||
|
\cgalNamedParamsEnd
|
||||||
|
|
||||||
|
\returns `true` if writing was successful, `false` otherwise.
|
||||||
|
|
||||||
|
\sa `write_PLY_with_properties()`
|
||||||
|
*/
|
||||||
|
template <typename PointRange, typename CGAL_NP_TEMPLATE_PARAMETERS>
|
||||||
|
bool write_PLY(std::ostream& os,
|
||||||
|
const PointRange& points,
|
||||||
|
const CGAL_NP_CLASS& np = parameters::default_values()
|
||||||
|
#ifndef DOXYGEN_RUNNING
|
||||||
|
, std::enable_if_t<internal::is_Range<PointRange>::value>* = nullptr
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\ingroup PkgStreamSupportIoFuncsPLY
|
||||||
|
|
||||||
|
\brief writes the range of `points` (positions + normals, if available) using \ref IOStreamPLY.
|
||||||
|
|
||||||
|
\tparam PointRange is a model of `ConstRange`. The value type of
|
||||||
|
its iterator is the key type of the named parameter `point_map`.
|
||||||
|
\tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters"
|
||||||
|
|
||||||
|
\param filename the path to the output file
|
||||||
|
\param points input point range
|
||||||
|
\param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below
|
||||||
|
|
||||||
|
\cgalNamedParamsBegin
|
||||||
|
\cgalParamNBegin{use_binary_mode}
|
||||||
|
\cgalParamDescription{indicates whether data should be written in binary (`true`) or in \ascii (`false`)}
|
||||||
|
\cgalParamType{Boolean}
|
||||||
|
\cgalParamDefault{`true`}
|
||||||
|
\cgalParamNEnd
|
||||||
|
|
||||||
|
\cgalParamNBegin{point_map}
|
||||||
|
\cgalParamDescription{a property map associating points to the elements of the point range}
|
||||||
|
\cgalParamType{a model of `ReadablePropertyMap` with value type `geom_traits::Point_3`}
|
||||||
|
\cgalParamDefault{`CGAL::Identity_property_map<geom_traits::Point_3>`}
|
||||||
|
\cgalParamNEnd
|
||||||
|
|
||||||
|
\cgalParamNBegin{normal_map}
|
||||||
|
\cgalParamDescription{a property map associating normals to the elements of the point range}
|
||||||
|
\cgalParamType{a model of `ReadablePropertyMap` with value type `geom_traits::Vector_3`}
|
||||||
|
\cgalParamDefault{If this parameter is omitted, normals are not written in the output file.}
|
||||||
|
\cgalParamNEnd
|
||||||
|
|
||||||
|
\cgalParamNBegin{geom_traits}
|
||||||
|
\cgalParamDescription{an instance of a geometric traits class}
|
||||||
|
\cgalParamType{a model of `Kernel`}
|
||||||
|
\cgalParamDefault{a \cgal Kernel deduced from the point type, using `CGAL::Kernel_traits`}
|
||||||
|
\cgalParamNEnd
|
||||||
|
|
||||||
|
\cgalParamNBegin{stream_precision}
|
||||||
|
\cgalParamDescription{a parameter used to set the precision (i.e. how many digits are generated) of the output stream}
|
||||||
|
\cgalParamType{int}
|
||||||
|
\cgalParamDefault{`6`}
|
||||||
|
\cgalParamExtra{This parameter is only meaningful while using \ascii encoding.}
|
||||||
|
\cgalParamNEnd
|
||||||
|
\cgalNamedParamsEnd
|
||||||
|
|
||||||
|
\returns `true` if writing was successful, `false` otherwise.
|
||||||
|
|
||||||
|
\sa `write_PLY_with_properties()`
|
||||||
|
*/
|
||||||
|
template <typename PointRange, typename CGAL_NP_TEMPLATE_PARAMETERS>
|
||||||
|
bool write_PLY(const std::string& filename,
|
||||||
|
const PointRange& points,
|
||||||
|
const CGAL_NP_CLASS& np = parameters::default_values()
|
||||||
|
#ifndef DOXYGEN_RUNNING
|
||||||
|
, std::enable_if_t<internal::is_Range<PointRange>::value>* = nullptr
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
|
||||||
} // namespace IO
|
} // namespace IO
|
||||||
|
|
||||||
} // namespace CGAL
|
} // namespace CGAL
|
||||||
|
|
||||||
|
#include <CGAL/IO/PLY/read_ply_points.h>
|
||||||
|
#include <CGAL/IO/PLY/write_ply_points.h>
|
||||||
|
|
||||||
|
|
||||||
#endif // CGAL_IO_PLY_H
|
#endif // CGAL_IO_PLY_H
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
#ifndef CGAL_IO_PLY_PLY_READER_H
|
#ifndef CGAL_IO_PLY_PLY_READER_H
|
||||||
#define CGAL_IO_PLY_PLY_READER_H
|
#define CGAL_IO_PLY_PLY_READER_H
|
||||||
|
|
||||||
|
#include <CGAL/IO/PLY.h>
|
||||||
#include <CGAL/Container_helper.h>
|
#include <CGAL/Container_helper.h>
|
||||||
#include <CGAL/IO/io.h>
|
#include <CGAL/IO/io.h>
|
||||||
#include <CGAL/type_traits/is_iterator.h>
|
#include <CGAL/type_traits/is_iterator.h>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,181 @@
|
||||||
|
// Copyright (c) 2017 GeometryFactory
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org);
|
||||||
|
//
|
||||||
|
// $URL$
|
||||||
|
// $Id$
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
|
//
|
||||||
|
// Author(s) : Simon Giraudot
|
||||||
|
|
||||||
|
#ifndef CGAL_IO_PLY_READ_PLY_POINTS_H
|
||||||
|
#define CGAL_IO_PLY_READ_PLY_POINTS_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <CGAL/config.h>
|
||||||
|
|
||||||
|
#include <CGAL/IO/PLY.h>
|
||||||
|
#include <CGAL/property_map.h>
|
||||||
|
#include <CGAL/value_type_traits.h>
|
||||||
|
#include <CGAL/Kernel_traits.h>
|
||||||
|
#include <CGAL/IO/io.h>
|
||||||
|
|
||||||
|
#include <CGAL/Named_function_parameters.h>
|
||||||
|
#include <CGAL/boost/graph/named_params_helper.h>
|
||||||
|
|
||||||
|
#include <boost/version.hpp>
|
||||||
|
#include <boost/cstdint.hpp>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
|
||||||
|
namespace IO {
|
||||||
|
|
||||||
|
// documentation in ../PLY.h
|
||||||
|
template <typename OutputIteratorValueType,
|
||||||
|
typename PointOutputIterator,
|
||||||
|
typename ... PropertyHandler>
|
||||||
|
bool read_PLY_with_properties(std::istream& is,
|
||||||
|
PointOutputIterator output,
|
||||||
|
PropertyHandler&& ... properties)
|
||||||
|
{
|
||||||
|
if(!is)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
internal::PLY_reader reader(true);
|
||||||
|
|
||||||
|
if(!(reader.init(is)))
|
||||||
|
{
|
||||||
|
is.setstate(std::ios::failbit);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(std::size_t i = 0; i < reader.number_of_elements(); ++ i)
|
||||||
|
{
|
||||||
|
internal::PLY_element& element = reader.element(i);
|
||||||
|
|
||||||
|
for(std::size_t j = 0; j < element.number_of_items(); ++ j)
|
||||||
|
{
|
||||||
|
for(std::size_t k = 0; k < element.number_of_properties(); ++ k)
|
||||||
|
{
|
||||||
|
internal::PLY_read_number* property = element.property(k);
|
||||||
|
property->get(is);
|
||||||
|
|
||||||
|
if(is.fail())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(element.name() == "vertex" || element.name() == "vertices")
|
||||||
|
{
|
||||||
|
OutputIteratorValueType new_element;
|
||||||
|
internal::process_properties(element, new_element, std::forward<PropertyHandler>(properties)...);
|
||||||
|
*(output ++) = new_element;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \cond SKIP_IN_MANUAL
|
||||||
|
|
||||||
|
template <typename OutputIterator,
|
||||||
|
typename ... PropertyHandler>
|
||||||
|
bool read_PLY_with_properties(std::istream& is,
|
||||||
|
OutputIterator output,
|
||||||
|
PropertyHandler&& ... properties)
|
||||||
|
{
|
||||||
|
typedef typename value_type_traits<OutputIterator>::type OutputValueType;
|
||||||
|
|
||||||
|
return read_PLY_with_properties<OutputValueType>(is, output, std::forward<PropertyHandler>(properties)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \endcond
|
||||||
|
|
||||||
|
|
||||||
|
// documented in ../PLY.h
|
||||||
|
template <typename OutputIteratorValueType,
|
||||||
|
typename PointOutputIterator,
|
||||||
|
typename CGAL_NP_TEMPLATE_PARAMETERS_NO_DEFAULT>
|
||||||
|
bool read_PLY(std::istream& is,
|
||||||
|
PointOutputIterator output,
|
||||||
|
const CGAL_NP_CLASS& np ,
|
||||||
|
std::enable_if_t<CGAL::is_iterator<PointOutputIterator>::value>*
|
||||||
|
)
|
||||||
|
{
|
||||||
|
using parameters::choose_parameter;
|
||||||
|
using parameters::get_parameter;
|
||||||
|
|
||||||
|
typedef Point_set_processing_3::Fake_point_range<OutputIteratorValueType> PointRange;
|
||||||
|
|
||||||
|
// basic geometric types
|
||||||
|
typedef Point_set_processing_3_np_helper<PointRange, CGAL_NP_CLASS> NP_helper;
|
||||||
|
typedef typename NP_helper::Point_map PointMap;
|
||||||
|
typedef typename NP_helper::Normal_map NormalMap;
|
||||||
|
|
||||||
|
PointMap point_map = NP_helper::get_point_map(np);
|
||||||
|
NormalMap normal_map = NP_helper::get_normal_map(np);
|
||||||
|
|
||||||
|
return read_PLY_with_properties(is, output,
|
||||||
|
make_ply_point_reader(point_map),
|
||||||
|
make_ply_normal_reader(normal_map));
|
||||||
|
}
|
||||||
|
|
||||||
|
// documentation in ../PLY.h
|
||||||
|
template <typename OutputIteratorValueType,
|
||||||
|
typename PointOutputIterator,
|
||||||
|
typename CGAL_NP_TEMPLATE_PARAMETERS_NO_DEFAULT>
|
||||||
|
bool read_PLY(const std::string& fname,
|
||||||
|
PointOutputIterator output,
|
||||||
|
const CGAL_NP_CLASS& np,
|
||||||
|
std::enable_if_t<CGAL::is_iterator<PointOutputIterator>::value>*
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const bool binary = CGAL::parameters::choose_parameter(CGAL::parameters::get_parameter(np, internal_np::use_binary_mode), true);
|
||||||
|
if(binary)
|
||||||
|
{
|
||||||
|
std::ifstream is(fname, std::ios::binary);
|
||||||
|
CGAL::IO::set_mode(is, CGAL::IO::BINARY);
|
||||||
|
return read_PLY<OutputIteratorValueType>(is, output, np);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::ifstream is(fname);
|
||||||
|
CGAL::IO::set_mode(is, CGAL::IO::ASCII);
|
||||||
|
return read_PLY<OutputIteratorValueType>(is, output, np);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \cond SKIP_IN_MANUAL
|
||||||
|
|
||||||
|
// variants with default output iterator value type
|
||||||
|
template <typename OutputIterator, typename CGAL_NP_TEMPLATE_PARAMETERS>
|
||||||
|
bool read_PLY(std::istream& is, OutputIterator output, const CGAL_NP_CLASS& np = parameters::default_values(),
|
||||||
|
std::enable_if_t<CGAL::is_iterator<OutputIterator>::value>* = nullptr)
|
||||||
|
{
|
||||||
|
return read_PLY<typename value_type_traits<OutputIterator>::type>(is, output, np);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename OutputIterator,typename CGAL_NP_TEMPLATE_PARAMETERS>
|
||||||
|
bool read_PLY(const std::string& fname, OutputIterator output, const CGAL_NP_CLASS& np = parameters::default_values(),
|
||||||
|
std::enable_if_t<CGAL::is_iterator<OutputIterator>::value>* = nullptr)
|
||||||
|
{
|
||||||
|
return read_PLY<typename value_type_traits<OutputIterator>::type>(fname, output, np);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \endcond
|
||||||
|
|
||||||
|
} // namespace IO
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
#undef TRY_TO_GENERATE_POINT_PROPERTY
|
||||||
|
#undef TRY_TO_GENERATE_SIZED_FACE_PROPERTY
|
||||||
|
#undef TRY_TO_GENERATE_FACE_PROPERTY
|
||||||
|
|
||||||
|
#endif // CGAL_IO_PLY_READ_PLY_POINTS_H
|
||||||
|
|
@ -0,0 +1,137 @@
|
||||||
|
// Copyright (c) 1997
|
||||||
|
// Utrecht University (The Netherlands),
|
||||||
|
// ETH Zurich (Switzerland),
|
||||||
|
// INRIA Sophia-Antipolis (France),
|
||||||
|
// Max-Planck-Institute Saarbruecken (Germany),
|
||||||
|
// and Tel-Aviv University (Israel). 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) : Simon Giraudot
|
||||||
|
|
||||||
|
#ifndef CGAL_IO_PLY_WRITE_PLY_POINTS_H
|
||||||
|
#define CGAL_IO_PLY_WRITE_PLY_POINTS_H
|
||||||
|
|
||||||
|
#include <CGAL/IO/helpers.h>
|
||||||
|
#include <CGAL/IO/PLY.h>
|
||||||
|
|
||||||
|
#include <CGAL/property_map.h>
|
||||||
|
#include <CGAL/assertions.h>
|
||||||
|
#include <CGAL/Iterator_range.h>
|
||||||
|
|
||||||
|
#include <CGAL/Named_function_parameters.h>
|
||||||
|
#include <CGAL/boost/graph/named_params_helper.h>
|
||||||
|
|
||||||
|
#include <boost/version.hpp>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <iterator>
|
||||||
|
#include <tuple>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
|
||||||
|
namespace IO {
|
||||||
|
|
||||||
|
// documented in ../PLY.h
|
||||||
|
template <typename PointRange,
|
||||||
|
typename ... PropertyHandler>
|
||||||
|
bool write_PLY_with_properties(std::ostream& os, ///< output stream.
|
||||||
|
const PointRange& points, ///< input point range.
|
||||||
|
PropertyHandler&& ... properties) ///< parameter pack of property handlers
|
||||||
|
{
|
||||||
|
CGAL_precondition(points.begin() != points.end());
|
||||||
|
|
||||||
|
if(!os)
|
||||||
|
{
|
||||||
|
std::cerr << "Error: cannot open file" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write header
|
||||||
|
os << "ply" << std::endl
|
||||||
|
<< ((get_mode(os) == BINARY) ? "format binary_little_endian 1.0" : "format ascii 1.0") << std::endl
|
||||||
|
<< "comment Generated by the CGAL library" << std::endl
|
||||||
|
<< "element vertex " << points.size() << std::endl;
|
||||||
|
|
||||||
|
internal::output_property_header (os, std::forward<PropertyHandler>(properties)...);
|
||||||
|
|
||||||
|
os << "end_header" << std::endl;
|
||||||
|
|
||||||
|
// Write positions + normals
|
||||||
|
for(typename PointRange::const_iterator it = points.begin(); it != points.end(); it++)
|
||||||
|
internal::output_properties (os, it, std::forward<PropertyHandler>(properties)...);
|
||||||
|
|
||||||
|
return !os.fail();
|
||||||
|
}
|
||||||
|
|
||||||
|
// documented in ../PLY.h
|
||||||
|
template <typename PointRange, typename CGAL_NP_TEMPLATE_PARAMETERS_NO_DEFAULT>
|
||||||
|
bool write_PLY(std::ostream& os,
|
||||||
|
const PointRange& points,
|
||||||
|
const CGAL_NP_CLASS& np
|
||||||
|
, std::enable_if_t<internal::is_Range<PointRange>::value>*
|
||||||
|
)
|
||||||
|
{
|
||||||
|
using parameters::choose_parameter;
|
||||||
|
using parameters::get_parameter;
|
||||||
|
|
||||||
|
// basic geometric types
|
||||||
|
typedef Point_set_processing_3_np_helper<PointRange, CGAL_NP_CLASS> NP_helper;
|
||||||
|
typedef typename NP_helper::Const_point_map PointMap;
|
||||||
|
typedef typename NP_helper::Normal_map NormalMap;
|
||||||
|
|
||||||
|
const bool has_normals = NP_helper::has_normal_map(points, np);
|
||||||
|
|
||||||
|
PointMap point_map = NP_helper::get_const_point_map(points, np);
|
||||||
|
NormalMap normal_map = NP_helper::get_normal_map(points, np);
|
||||||
|
|
||||||
|
if(!os)
|
||||||
|
{
|
||||||
|
std::cerr << "Error: cannot open file" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
set_stream_precision_from_NP(os, np);
|
||||||
|
|
||||||
|
if(has_normals)
|
||||||
|
return write_PLY_with_properties(os, points,
|
||||||
|
make_ply_point_writer(point_map),
|
||||||
|
make_ply_normal_writer(normal_map));
|
||||||
|
|
||||||
|
return write_PLY_with_properties(os, points, make_ply_point_writer(point_map));
|
||||||
|
}
|
||||||
|
|
||||||
|
// documented in ../PLY.h
|
||||||
|
template <typename PointRange, typename CGAL_NP_TEMPLATE_PARAMETERS_NO_DEFAULT>
|
||||||
|
bool write_PLY(const std::string& filename,
|
||||||
|
const PointRange& points,
|
||||||
|
const CGAL_NP_CLASS& np,
|
||||||
|
std::enable_if_t<internal::is_Range<PointRange>::value>*
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const bool binary = CGAL::parameters::choose_parameter(CGAL::parameters::get_parameter(np, internal_np::use_binary_mode), true);
|
||||||
|
if(binary)
|
||||||
|
{
|
||||||
|
std::ofstream os(filename, std::ios::binary);
|
||||||
|
CGAL::IO::set_mode(os, CGAL::IO::BINARY);
|
||||||
|
return write_PLY(os, points, np);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::ofstream os(filename);
|
||||||
|
CGAL::IO::set_mode(os, CGAL::IO::ASCII);
|
||||||
|
return write_PLY(os, points, np);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace IO
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
#endif // CGAL_IO_PLY_WRITE_PLY_POINTS_H
|
||||||
|
|
@ -0,0 +1,236 @@
|
||||||
|
// Copyright (c) 2017 GeometryFactory
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org);
|
||||||
|
//
|
||||||
|
// $URL$
|
||||||
|
// $Id$
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
|
//
|
||||||
|
// Author(s) : Simon Giraudot
|
||||||
|
|
||||||
|
#ifndef CGAL_IO_XYZ_H
|
||||||
|
#define CGAL_IO_XYZ_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <CGAL/IO/helpers.h>
|
||||||
|
#include <CGAL/Named_function_parameters.h>
|
||||||
|
#include <CGAL/boost/graph/named_params_helper.h>
|
||||||
|
#include <CGAL/Kernel_traits.h>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Read
|
||||||
|
|
||||||
|
namespace IO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
\ingroup PkgStreamSupportIoFuncsXYZ
|
||||||
|
|
||||||
|
\brief reads points (positions + normals, if available), using the \ref IOStreamXYZ.
|
||||||
|
|
||||||
|
\tparam OutputIteratorValueType type of objects that can be put in `OutputIterator`.
|
||||||
|
It must be a model of `DefaultConstructible` and defaults to `value_type_traits<OutputIterator>::%type`.
|
||||||
|
It can be omitted when the default is fine.
|
||||||
|
\tparam OutputIterator iterator over output points.
|
||||||
|
\tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters"
|
||||||
|
|
||||||
|
\param is input stream.
|
||||||
|
\param output output iterator over points.
|
||||||
|
\param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below
|
||||||
|
|
||||||
|
\cgalNamedParamsBegin
|
||||||
|
\cgalParamNBegin{point_map}
|
||||||
|
\cgalParamDescription{a property map associating points to the elements of the point range}
|
||||||
|
\cgalParamType{a model of `WritablePropertyMap` with value type `geom_traits::Point_3`}
|
||||||
|
\cgalParamDefault{`CGAL::Identity_property_map<geom_traits::Point_3>`}
|
||||||
|
\cgalParamNEnd
|
||||||
|
|
||||||
|
\cgalParamNBegin{normal_map}
|
||||||
|
\cgalParamDescription{a property map associating normals to the elements of the point range}
|
||||||
|
\cgalParamType{a model of `WritablePropertyMap` with value type `geom_traits::Vector_3`}
|
||||||
|
\cgalParamDefault{If this parameter is omitted, normals in the input stream are ignored.}
|
||||||
|
\cgalParamNEnd
|
||||||
|
|
||||||
|
\cgalParamNBegin{geom_traits}
|
||||||
|
\cgalParamDescription{an instance of a geometric traits class}
|
||||||
|
\cgalParamType{a model of `Kernel`}
|
||||||
|
\cgalParamDefault{a \cgal Kernel deduced from the point type, using `CGAL::Kernel_traits`}
|
||||||
|
\cgalParamNEnd
|
||||||
|
\cgalNamedParamsEnd
|
||||||
|
|
||||||
|
\returns `true` if reading was successful, `false` otherwise.
|
||||||
|
|
||||||
|
\sa \ref IOStreamXYZ
|
||||||
|
*/
|
||||||
|
template <typename OutputIteratorValueType,
|
||||||
|
typename OutputIterator,
|
||||||
|
typename CGAL_NP_TEMPLATE_PARAMETERS>
|
||||||
|
bool read_XYZ(std::istream& is,
|
||||||
|
OutputIterator output,
|
||||||
|
const CGAL_NP_CLASS& np = parameters::default_values());
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\ingroup PkgStreamSupportIoFuncsXYZ
|
||||||
|
|
||||||
|
\brief reads points (positions + normals, if available), using the \ref IOStreamXYZ.
|
||||||
|
|
||||||
|
\tparam OutputIteratorValueType type of objects that can be put in `OutputIterator`.
|
||||||
|
It must be a model of `DefaultConstructible` and defaults to `value_type_traits<OutputIterator>::%type`.
|
||||||
|
It can be omitted when the default is fine.
|
||||||
|
\tparam OutputIterator iterator over output points.
|
||||||
|
\tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters"
|
||||||
|
|
||||||
|
\param fname input file name.
|
||||||
|
\param output output iterator over points.
|
||||||
|
\param np optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below.
|
||||||
|
|
||||||
|
\cgalNamedParamsBegin
|
||||||
|
\cgalParamNBegin{point_map}
|
||||||
|
\cgalParamDescription{a property map associating points to the elements of the point range}
|
||||||
|
\cgalParamType{a model of `WritablePropertyMap` with value type `geom_traits::Point_3`}
|
||||||
|
\cgalParamDefault{`CGAL::Identity_property_map<geom_traits::Point_3>`}
|
||||||
|
\cgalParamNEnd
|
||||||
|
|
||||||
|
\cgalParamNBegin{normal_map}
|
||||||
|
\cgalParamDescription{a property map associating normals to the elements of the point range}
|
||||||
|
\cgalParamType{a model of `WritablePropertyMap` with value type `geom_traits::Vector_3`}
|
||||||
|
\cgalParamDefault{If this parameter is omitted, normals in the input stream are ignored.}
|
||||||
|
\cgalParamNEnd
|
||||||
|
|
||||||
|
\cgalParamNBegin{geom_traits}
|
||||||
|
\cgalParamDescription{an instance of a geometric traits class}
|
||||||
|
\cgalParamType{a model of `Kernel`}
|
||||||
|
\cgalParamDefault{a \cgal Kernel deduced from the point type, using `CGAL::Kernel_traits`}
|
||||||
|
\cgalParamNEnd
|
||||||
|
\cgalNamedParamsEnd
|
||||||
|
|
||||||
|
\returns `true` if reading was successful, `false` otherwise.
|
||||||
|
|
||||||
|
\sa \ref IOStreamXYZ
|
||||||
|
*/
|
||||||
|
template <typename OutputIteratorValueType,
|
||||||
|
typename OutputIterator,
|
||||||
|
typename CGAL_NP_TEMPLATE_PARAMETERS>
|
||||||
|
bool read_XYZ(const std::string& fname,
|
||||||
|
OutputIterator output,
|
||||||
|
const CGAL_NP_CLASS& np = parameters::default_values());
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\ingroup PkgStreamSupportIoFuncsXYZ
|
||||||
|
|
||||||
|
\brief writes the range of `points` (positions + normals, if available), using the \ref IOStreamXYZ.
|
||||||
|
|
||||||
|
\tparam PointRange is a model of `ConstRange`. The value type of
|
||||||
|
its iterator is the key type of the named parameter `point_map`.
|
||||||
|
\tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters"
|
||||||
|
|
||||||
|
\param os output stream
|
||||||
|
\param points input point range
|
||||||
|
\param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below
|
||||||
|
|
||||||
|
\cgalNamedParamsBegin
|
||||||
|
\cgalParamNBegin{point_map}
|
||||||
|
\cgalParamDescription{a property map associating points to the elements of the point range}
|
||||||
|
\cgalParamType{a model of `ReadablePropertyMap` with value type `geom_traits::Point_3`}
|
||||||
|
\cgalParamDefault{`CGAL::Identity_property_map<geom_traits::Point_3>`}
|
||||||
|
\cgalParamNEnd
|
||||||
|
|
||||||
|
\cgalParamNBegin{normal_map}
|
||||||
|
\cgalParamDescription{a property map associating normals to the elements of the point range}
|
||||||
|
\cgalParamType{a model of `ReadablePropertyMap` with value type `geom_traits::Vector_3`}
|
||||||
|
\cgalParamDefault{If this parameter is omitted, normals are not written in the output stream.}
|
||||||
|
\cgalParamNEnd
|
||||||
|
|
||||||
|
\cgalParamNBegin{geom_traits}
|
||||||
|
\cgalParamDescription{an instance of a geometric traits class}
|
||||||
|
\cgalParamType{a model of `Kernel`}
|
||||||
|
\cgalParamDefault{a \cgal Kernel deduced from the point type, using `CGAL::Kernel_traits`}
|
||||||
|
\cgalParamNEnd
|
||||||
|
|
||||||
|
\cgalParamNBegin{stream_precision}
|
||||||
|
\cgalParamDescription{a parameter used to set the precision (i.e. how many digits are generated) of the output stream}
|
||||||
|
\cgalParamType{int}
|
||||||
|
\cgalParamDefault{the precision of the stream `os`}
|
||||||
|
\cgalParamNEnd
|
||||||
|
\cgalNamedParamsEnd
|
||||||
|
|
||||||
|
\returns `true` if writing was successful, `false` otherwise.
|
||||||
|
*/
|
||||||
|
template <typename PointRange, typename CGAL_NP_TEMPLATE_PARAMETERS>
|
||||||
|
bool write_XYZ(std::ostream& os,
|
||||||
|
const PointRange& points,
|
||||||
|
const CGAL_NP_CLASS& np = parameters::default_values()
|
||||||
|
#ifndef DOXYGEN_RUNNING
|
||||||
|
, std::enable_if_t<internal::is_Range<PointRange>::value>* = nullptr
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\ingroup PkgStreamSupportIoFuncsXYZ
|
||||||
|
|
||||||
|
\brief writes the range of `points` (positions + normals, if available), using the \ref IOStreamXYZ.
|
||||||
|
|
||||||
|
\tparam PointRange is a model of `ConstRange`. The value type of
|
||||||
|
its iterator is the key type of the named parameter `point_map`.
|
||||||
|
\tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters"
|
||||||
|
|
||||||
|
\param filename path to the output file
|
||||||
|
\param points input point range
|
||||||
|
\param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below
|
||||||
|
|
||||||
|
\cgalNamedParamsBegin
|
||||||
|
\cgalParamNBegin{point_map}
|
||||||
|
\cgalParamDescription{a property map associating points to the elements of the point range}
|
||||||
|
\cgalParamType{a model of `ReadablePropertyMap` with value type `geom_traits::Point_3`}
|
||||||
|
\cgalParamDefault{`CGAL::Identity_property_map<geom_traits::Point_3>`}
|
||||||
|
\cgalParamNEnd
|
||||||
|
|
||||||
|
\cgalParamNBegin{normal_map}
|
||||||
|
\cgalParamDescription{a property map associating normals to the elements of the point range}
|
||||||
|
\cgalParamType{a model of `ReadablePropertyMap` with value type `geom_traits::Vector_3`}
|
||||||
|
\cgalParamDefault{If this parameter is omitted, normals are not written in the output file.}
|
||||||
|
\cgalParamNEnd
|
||||||
|
|
||||||
|
\cgalParamNBegin{geom_traits}
|
||||||
|
\cgalParamDescription{an instance of a geometric traits class}
|
||||||
|
\cgalParamType{a model of `Kernel`}
|
||||||
|
\cgalParamDefault{a \cgal Kernel deduced from the point type, using `CGAL::Kernel_traits`}
|
||||||
|
\cgalParamNEnd
|
||||||
|
|
||||||
|
\cgalParamNBegin{stream_precision}
|
||||||
|
\cgalParamDescription{a parameter used to set the precision (i.e. how many digits are generated) of the output stream}
|
||||||
|
\cgalParamType{int}
|
||||||
|
\cgalParamDefault{`6`}
|
||||||
|
\cgalParamNEnd
|
||||||
|
\cgalNamedParamsEnd
|
||||||
|
|
||||||
|
\returns `true` if writing was successful, `false` otherwise.
|
||||||
|
*/
|
||||||
|
template <typename PointRange, typename CGAL_NP_TEMPLATE_PARAMETERS>
|
||||||
|
bool write_XYZ(const std::string& filename,
|
||||||
|
const PointRange& points,
|
||||||
|
const CGAL_NP_CLASS& np = parameters::default_values()
|
||||||
|
#ifndef DOXYGEN_RUNNING
|
||||||
|
, std::enable_if_t<internal::is_Range<PointRange>::value>* = nullptr
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
|
||||||
|
} // namespace IO
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
|
||||||
|
#include <CGAL/IO/XYZ/read_xyz_points.h>
|
||||||
|
#include <CGAL/IO/XYZ/write_xyz_points.h>
|
||||||
|
|
||||||
|
#endif // CGAL_IO_XYZ_H
|
||||||
|
|
@ -1,19 +1,22 @@
|
||||||
// Copyright (c) 2007-09 INRIA Sophia-Antipolis (France).
|
// Copyright (c) 1997
|
||||||
// All rights reserved.
|
// Utrecht University (The Netherlands),
|
||||||
|
// ETH Zurich (Switzerland),
|
||||||
|
// INRIA Sophia-Antipolis (France),
|
||||||
|
// Max-Planck-Institute Saarbruecken (Germany),
|
||||||
|
// and Tel-Aviv University (Israel). All rights reserved.
|
||||||
//
|
//
|
||||||
// This file is part of CGAL (www.cgal.org).
|
// This file is part of CGAL (www.cgal.org);
|
||||||
//
|
//
|
||||||
// $URL$
|
// $URL$
|
||||||
// $Id$
|
// $Id$
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
//
|
//
|
||||||
// Author(s) : Pierre Alliez and Laurent Saboret
|
// Author(s) : Pierre Alliez and Laurent Saboret
|
||||||
|
|
||||||
#ifndef CGAL_POINT_SET_PROCESSING_READ_XYZ_POINTS_H
|
#ifndef CGAL_IO_PLY_READ_XYZ_POINTS_H
|
||||||
#define CGAL_POINT_SET_PROCESSING_READ_XYZ_POINTS_H
|
#define CGAL_IO_PLY_READ_XYZ_POINTS_H
|
||||||
|
|
||||||
#include <CGAL/license/Point_set_processing_3.h>
|
|
||||||
|
|
||||||
|
#include <CGAL/IO/XYZ.h>
|
||||||
#include <CGAL/property_map.h>
|
#include <CGAL/property_map.h>
|
||||||
#include <CGAL/value_type_traits.h>
|
#include <CGAL/value_type_traits.h>
|
||||||
#include <CGAL/Origin.h>
|
#include <CGAL/Origin.h>
|
||||||
|
|
@ -32,51 +35,13 @@ namespace CGAL {
|
||||||
|
|
||||||
namespace IO {
|
namespace IO {
|
||||||
|
|
||||||
/**
|
// doxygen in ../XYZ.h
|
||||||
\ingroup PkgPointSetProcessing3IOXyz
|
|
||||||
|
|
||||||
\brief reads points (positions + normals, if available), using the \ref IOStreamXYZ.
|
|
||||||
|
|
||||||
\tparam OutputIteratorValueType type of objects that can be put in `OutputIterator`.
|
|
||||||
It must be a model of `DefaultConstructible` and defaults to `value_type_traits<OutputIterator>::%type`.
|
|
||||||
It can be omitted when the default is fine.
|
|
||||||
\tparam OutputIterator iterator over output points.
|
|
||||||
\tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters"
|
|
||||||
|
|
||||||
\param is input stream.
|
|
||||||
\param output output iterator over points.
|
|
||||||
\param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below
|
|
||||||
|
|
||||||
\cgalNamedParamsBegin
|
|
||||||
\cgalParamNBegin{point_map}
|
|
||||||
\cgalParamDescription{a property map associating points to the elements of the point range}
|
|
||||||
\cgalParamType{a model of `WritablePropertyMap` with value type `geom_traits::Point_3`}
|
|
||||||
\cgalParamDefault{`CGAL::Identity_property_map<geom_traits::Point_3>`}
|
|
||||||
\cgalParamNEnd
|
|
||||||
|
|
||||||
\cgalParamNBegin{normal_map}
|
|
||||||
\cgalParamDescription{a property map associating normals to the elements of the point range}
|
|
||||||
\cgalParamType{a model of `WritablePropertyMap` with value type `geom_traits::Vector_3`}
|
|
||||||
\cgalParamDefault{If this parameter is omitted, normals in the input stream are ignored.}
|
|
||||||
\cgalParamNEnd
|
|
||||||
|
|
||||||
\cgalParamNBegin{geom_traits}
|
|
||||||
\cgalParamDescription{an instance of a geometric traits class}
|
|
||||||
\cgalParamType{a model of `Kernel`}
|
|
||||||
\cgalParamDefault{a \cgal Kernel deduced from the point type, using `CGAL::Kernel_traits`}
|
|
||||||
\cgalParamNEnd
|
|
||||||
\cgalNamedParamsEnd
|
|
||||||
|
|
||||||
\returns `true` if reading was successful, `false` otherwise.
|
|
||||||
|
|
||||||
\sa \ref IOStreamXYZ
|
|
||||||
*/
|
|
||||||
template <typename OutputIteratorValueType,
|
template <typename OutputIteratorValueType,
|
||||||
typename OutputIterator,
|
typename OutputIterator,
|
||||||
typename CGAL_NP_TEMPLATE_PARAMETERS>
|
typename CGAL_NP_TEMPLATE_PARAMETERS_NO_DEFAULT>
|
||||||
bool read_XYZ(std::istream& is,
|
bool read_XYZ(std::istream& is,
|
||||||
OutputIterator output,
|
OutputIterator output,
|
||||||
const CGAL_NP_CLASS& np = parameters::default_values())
|
const CGAL_NP_CLASS& np)
|
||||||
{
|
{
|
||||||
using parameters::choose_parameter;
|
using parameters::choose_parameter;
|
||||||
using parameters::get_parameter;
|
using parameters::get_parameter;
|
||||||
|
|
@ -178,51 +143,13 @@ bool read_XYZ(std::istream& is,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// documentation in ../XYZ.h
|
||||||
\ingroup PkgPointSetProcessing3IOXyz
|
|
||||||
|
|
||||||
\brief reads points (positions + normals, if available), using the \ref IOStreamXYZ.
|
|
||||||
|
|
||||||
\tparam OutputIteratorValueType type of objects that can be put in `OutputIterator`.
|
|
||||||
It must be a model of `DefaultConstructible` and defaults to `value_type_traits<OutputIterator>::%type`.
|
|
||||||
It can be omitted when the default is fine.
|
|
||||||
\tparam OutputIterator iterator over output points.
|
|
||||||
\tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters"
|
|
||||||
|
|
||||||
\param fname input file name.
|
|
||||||
\param output output iterator over points.
|
|
||||||
\param np optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below.
|
|
||||||
|
|
||||||
\cgalNamedParamsBegin
|
|
||||||
\cgalParamNBegin{point_map}
|
|
||||||
\cgalParamDescription{a property map associating points to the elements of the point range}
|
|
||||||
\cgalParamType{a model of `WritablePropertyMap` with value type `geom_traits::Point_3`}
|
|
||||||
\cgalParamDefault{`CGAL::Identity_property_map<geom_traits::Point_3>`}
|
|
||||||
\cgalParamNEnd
|
|
||||||
|
|
||||||
\cgalParamNBegin{normal_map}
|
|
||||||
\cgalParamDescription{a property map associating normals to the elements of the point range}
|
|
||||||
\cgalParamType{a model of `WritablePropertyMap` with value type `geom_traits::Vector_3`}
|
|
||||||
\cgalParamDefault{If this parameter is omitted, normals in the input stream are ignored.}
|
|
||||||
\cgalParamNEnd
|
|
||||||
|
|
||||||
\cgalParamNBegin{geom_traits}
|
|
||||||
\cgalParamDescription{an instance of a geometric traits class}
|
|
||||||
\cgalParamType{a model of `Kernel`}
|
|
||||||
\cgalParamDefault{a \cgal Kernel deduced from the point type, using `CGAL::Kernel_traits`}
|
|
||||||
\cgalParamNEnd
|
|
||||||
\cgalNamedParamsEnd
|
|
||||||
|
|
||||||
\returns `true` if reading was successful, `false` otherwise.
|
|
||||||
|
|
||||||
\sa \ref IOStreamXYZ
|
|
||||||
*/
|
|
||||||
template <typename OutputIteratorValueType,
|
template <typename OutputIteratorValueType,
|
||||||
typename OutputIterator,
|
typename OutputIterator,
|
||||||
typename CGAL_NP_TEMPLATE_PARAMETERS>
|
typename CGAL_NP_TEMPLATE_PARAMETERS_NO_DEFAULT>
|
||||||
bool read_XYZ(const std::string& fname,
|
bool read_XYZ(const std::string& fname,
|
||||||
OutputIterator output,
|
OutputIterator output,
|
||||||
const CGAL_NP_CLASS& np = parameters::default_values())
|
const CGAL_NP_CLASS& np)
|
||||||
{
|
{
|
||||||
std::ifstream is(fname);
|
std::ifstream is(fname);
|
||||||
return read_XYZ<OutputIteratorValueType>(is, output, np);
|
return read_XYZ<OutputIteratorValueType>(is, output, np);
|
||||||
|
|
@ -253,4 +180,4 @@ bool read_XYZ(const std::string& fname, OutputIterator output, const CGAL_NP_CLA
|
||||||
|
|
||||||
} // namespace CGAL
|
} // namespace CGAL
|
||||||
|
|
||||||
#endif // CGAL_POINT_SET_PROCESSING_READ_XYZ_POINTS_H
|
#endif // CGAL_IO_PLY_READ_XYZ_POINTS_H
|
||||||
|
|
@ -0,0 +1,113 @@
|
||||||
|
// Copyright (c) 1997
|
||||||
|
// Utrecht University (The Netherlands),
|
||||||
|
// ETH Zurich (Switzerland),
|
||||||
|
// INRIA Sophia-Antipolis (France),
|
||||||
|
// Max-Planck-Institute Saarbruecken (Germany),
|
||||||
|
// and Tel-Aviv University (Israel). 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) : Pierre Alliez and Laurent Saboret
|
||||||
|
|
||||||
|
#ifndef CGAL_POINT_SET_PROCESSING_WRITE_XYZ_POINTS_H
|
||||||
|
#define CGAL_POINT_SET_PROCESSING_WRITE_XYZ_POINTS_H
|
||||||
|
|
||||||
|
#include <CGAL/IO/helpers.h>
|
||||||
|
|
||||||
|
#include <CGAL/IO/XYZ.h>
|
||||||
|
#include <CGAL/property_map.h>
|
||||||
|
#include <CGAL/assertions.h>
|
||||||
|
#include <CGAL/Kernel_traits.h>
|
||||||
|
#include <CGAL/Iterator_range.h>
|
||||||
|
|
||||||
|
#include <CGAL/Named_function_parameters.h>
|
||||||
|
#include <CGAL/boost/graph/named_params_helper.h>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <iterator>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
namespace Point_set_processing_3 {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
template <typename PointRange, typename CGAL_NP_TEMPLATE_PARAMETERS>
|
||||||
|
bool write_XYZ_PSP(std::ostream& os,
|
||||||
|
const PointRange& points,
|
||||||
|
const CGAL_NP_CLASS& np = CGAL::parameters::default_values())
|
||||||
|
{
|
||||||
|
using CGAL::parameters::choose_parameter;
|
||||||
|
using CGAL::parameters::get_parameter;
|
||||||
|
|
||||||
|
// basic geometric types
|
||||||
|
typedef Point_set_processing_3_np_helper<PointRange, CGAL_NP_CLASS> NP_helper;
|
||||||
|
typedef typename NP_helper::Const_point_map PointMap;
|
||||||
|
typedef typename NP_helper::Normal_map NormalMap;
|
||||||
|
|
||||||
|
const bool has_normals = NP_helper::has_normal_map(points, np);
|
||||||
|
|
||||||
|
PointMap point_map = NP_helper::get_const_point_map(points, np);
|
||||||
|
NormalMap normal_map = NP_helper::get_normal_map(points, np);
|
||||||
|
|
||||||
|
CGAL_precondition(points.begin() != points.end());
|
||||||
|
|
||||||
|
if(!os)
|
||||||
|
{
|
||||||
|
std::cerr << "Error: cannot open file" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
set_stream_precision_from_NP(os, np);
|
||||||
|
|
||||||
|
// Write positions + normals
|
||||||
|
for(typename PointRange::const_iterator it = points.begin(); it != points.end(); it++)
|
||||||
|
{
|
||||||
|
os << get(point_map, *it);
|
||||||
|
if(has_normals)
|
||||||
|
os << " " << get(normal_map, *it);
|
||||||
|
os << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
os << std::flush;
|
||||||
|
|
||||||
|
return !os.fail();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
} // Point_set_processing_3
|
||||||
|
|
||||||
|
namespace IO {
|
||||||
|
|
||||||
|
// documented in ../XYZ.h
|
||||||
|
template <typename PointRange, typename CGAL_NP_TEMPLATE_PARAMETERS_NO_DEFAULT>
|
||||||
|
bool write_XYZ(std::ostream& os,
|
||||||
|
const PointRange& points,
|
||||||
|
const CGAL_NP_CLASS& np,
|
||||||
|
std::enable_if_t<internal::is_Range<PointRange>::value>*
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return Point_set_processing_3::internal::write_XYZ_PSP(os, points, np);
|
||||||
|
}
|
||||||
|
|
||||||
|
// documented in ../XYZ.h
|
||||||
|
template <typename PointRange, typename CGAL_NP_TEMPLATE_PARAMETERS_NO_DEFAULT>
|
||||||
|
bool write_XYZ(const std::string& filename,
|
||||||
|
const PointRange& points,
|
||||||
|
const CGAL_NP_CLASS& np,
|
||||||
|
std::enable_if_t<internal::is_Range<PointRange>::value>*
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::ofstream os(filename);
|
||||||
|
return write_XYZ(os, points, np);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace IO
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
#endif // CGAL_POINT_SET_PROCESSING_WRITE_XYZ_POINTS_H
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
// Copyright (c) 2017 GeometryFactory
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org);
|
||||||
|
//
|
||||||
|
// $URL$
|
||||||
|
// $Id$
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
|
//
|
||||||
|
// Author(s) : Simon Giraudot
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef CGAL_IO_READ_LAS_POINTS_H
|
||||||
|
#define CGAL_IO_READ_LAS_POINTS_H
|
||||||
|
|
||||||
|
#include <CGAL/IO/LAS.h>
|
||||||
|
|
||||||
|
#endif // CGAL_IO_READ_LAS_POINTS_H
|
||||||
|
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
// Copyright (c) 2017 GeometryFactory
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org);
|
||||||
|
//
|
||||||
|
// $URL$
|
||||||
|
// $Id$
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
|
//
|
||||||
|
// Author(s) : Simon Giraudot
|
||||||
|
|
||||||
|
#ifndef CGAL_IO_READ_OFF_POINTS_H
|
||||||
|
#define CGAL_IO_READ_OFF_POINTS_H
|
||||||
|
|
||||||
|
#include <CGAL/IO/OFF.h>
|
||||||
|
|
||||||
|
#endif // CGAL_IO_READ_OFF_POINTS_H
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
// Copyright (c) 2017 GeometryFactory
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org);
|
||||||
|
//
|
||||||
|
// $URL$
|
||||||
|
// $Id$
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
|
//
|
||||||
|
// Author(s) : Simon Giraudot
|
||||||
|
|
||||||
|
#ifndef CGAL_IO_READ_PLY_POINTS_H
|
||||||
|
#define CGAL_IO_READ_PLY_POINTS_H
|
||||||
|
|
||||||
|
#include <CGAL/IO/PLY.h>
|
||||||
|
|
||||||
|
#endif // CGAL_IO_READ_PLY_POINTS_H
|
||||||
|
|
@ -1,26 +1,24 @@
|
||||||
// Copyright (c) 2020 Geometry Factory
|
// Copyright (c) 2020 Geometry Factory
|
||||||
// All rights reserved.
|
|
||||||
//
|
//
|
||||||
// This file is part of CGAL (www.cgal.org).
|
// This file is part of CGAL (www.cgal.org);
|
||||||
//
|
//
|
||||||
// $URL$
|
// $URL$
|
||||||
// $Id$
|
// $Id$
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
//
|
//
|
||||||
// Author(s) : Maxime Gimeno
|
// Author(s) : Maxime Gimeno
|
||||||
|
|
||||||
#ifndef CGAL_POINT_SET_PROCESSING_READ_POINTS_H
|
#ifndef CGAL_STREAM_SUPPORT_IO_READ_POINTS_H
|
||||||
#define CGAL_POINT_SET_PROCESSING_READ_POINTS_H
|
#define CGAL_STREAM_SUPPORT_IO_READ_POINTS_H
|
||||||
|
|
||||||
#include <CGAL/license/Point_set_processing_3.h>
|
|
||||||
|
|
||||||
#include <CGAL/IO/helpers.h>
|
#include <CGAL/IO/helpers.h>
|
||||||
#include <CGAL/IO/read_off_points.h>
|
#include <CGAL/IO/OFF/read_off_points.h>
|
||||||
#include <CGAL/IO/read_ply_points.h>
|
#include <CGAL/IO/PLY/read_ply_points.h>
|
||||||
#include <CGAL/IO/read_xyz_points.h>
|
#include <CGAL/IO/XYZ/read_xyz_points.h>
|
||||||
|
|
||||||
#ifdef CGAL_LINKED_WITH_LASLIB
|
#ifdef CGAL_LINKED_WITH_LASLIB
|
||||||
#include <CGAL/IO/read_las_points.h>
|
#include <CGAL/IO/LAS/read_las_points.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
@ -31,7 +29,7 @@ namespace CGAL {
|
||||||
namespace IO {
|
namespace IO {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\ingroup PkgPointSetProcessing3IO
|
\ingroup IOstreamFunctions
|
||||||
|
|
||||||
\brief reads the point set from an input file.
|
\brief reads the point set from an input file.
|
||||||
|
|
||||||
|
|
@ -120,4 +118,4 @@ bool read_points(const std::string& fname, OutputIterator output, const NamedPar
|
||||||
|
|
||||||
} } // namespace CGAL::IO
|
} } // namespace CGAL::IO
|
||||||
|
|
||||||
#endif // CGAL_POINT_SET_PROCESSING_READ_POINTS_H
|
#endif // CGAL_STREAM_SUPPORT_IO_READ_POINTS_H
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
// Copyright (c) 2017 GeometryFactory
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org);
|
||||||
|
//
|
||||||
|
// $URL$
|
||||||
|
// $Id$
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
|
//
|
||||||
|
// Author(s) : Simon Giraudot
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef CGAL_IO_READ_XYZ_POINTS_H
|
||||||
|
#define CGAL_IO_READ_XYZ_POINTS_H
|
||||||
|
|
||||||
|
#include <CGAL/IO/XYZ.h>
|
||||||
|
|
||||||
|
#endif // CGAL_IO_READ_XYZ_POINTS_H
|
||||||
|
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
// Copyright (c) 2017 GeometryFactory
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org);
|
||||||
|
//
|
||||||
|
// $URL$
|
||||||
|
// $Id$
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
|
//
|
||||||
|
// Author(s) : Simon Giraudot
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef CGAL_IO_WRITE_LAS_POINTS_H
|
||||||
|
#define CGAL_IO_WRITE_LAS_POINTS_H
|
||||||
|
|
||||||
|
#include <CGAL/IO/LAS.h>
|
||||||
|
|
||||||
|
#endif // CGAL_IO_WRITE_LAS_POINTS_H
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
// Copyright (c) 2017 GeometryFactory
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org);
|
||||||
|
//
|
||||||
|
// $URL$
|
||||||
|
// $Id$
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
|
//
|
||||||
|
// Author(s) : Simon Giraudot
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef CGAL_IO_WRITE_OFF_POINTS_H
|
||||||
|
#define CGAL_IO_WRITE_OFF_POINTS_H
|
||||||
|
|
||||||
|
#include <CGAL/IO/OFF.h>
|
||||||
|
|
||||||
|
#endif // CGAL_IO_WRITE_OFF_POINTS_H
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
// Copyright (c) 2017 GeometryFactory
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org);
|
||||||
|
//
|
||||||
|
// $URL$
|
||||||
|
// $Id$
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
|
//
|
||||||
|
// Author(s) : Simon Giraudot
|
||||||
|
|
||||||
|
|
||||||
|
#include <CGAL/IO/PLY/write_ply_points.h>
|
||||||
|
|
@ -1,26 +1,23 @@
|
||||||
// Copyright (c) 2020 Geometry Factory
|
// Copyright (c) 2020 Geometry Factory
|
||||||
// All rights reserved.
|
|
||||||
//
|
//
|
||||||
// This file is part of CGAL (www.cgal.org).
|
// This file is part of CGAL (www.cgal.org);
|
||||||
//
|
//
|
||||||
// $URL$
|
// $URL$
|
||||||
// $Id$
|
// $Id$
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
//
|
//
|
||||||
// Author(s) : Maxime Gimeno
|
// Author(s) : Maxime Gimeno
|
||||||
|
|
||||||
#ifndef CGAL_POINT_SET_PROCESSING_WRITE_POINTS_H
|
#ifndef CGAL_STREAM_SUPPORT_IO_WRITE_POINTS_H
|
||||||
#define CGAL_POINT_SET_PROCESSING_WRITE_POINTS_H
|
#define CGAL_STREAM_SUPPORT_IO_WRITE_POINTS_H
|
||||||
|
|
||||||
#include <CGAL/license/Point_set_processing_3.h>
|
|
||||||
|
|
||||||
#include <CGAL/IO/helpers.h>
|
#include <CGAL/IO/helpers.h>
|
||||||
|
|
||||||
#include <CGAL/IO/write_off_points.h>
|
#include <CGAL/IO/OFF/write_off_points.h>
|
||||||
#include <CGAL/IO/write_ply_points.h>
|
#include <CGAL/IO/PLY/write_ply_points.h>
|
||||||
#include <CGAL/IO/write_xyz_points.h>
|
#include <CGAL/IO/XYZ/write_xyz_points.h>
|
||||||
#ifdef CGAL_LINKED_WITH_LASLIB
|
#ifdef CGAL_LINKED_WITH_LASLIB
|
||||||
#include <CGAL/IO/write_las_points.h>
|
#include <CGAL/IO/LAS/write_las_points.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
@ -31,7 +28,7 @@ namespace CGAL {
|
||||||
namespace IO {
|
namespace IO {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\ingroup PkgPointSetProcessing3IO
|
\ingroup IOstreamFunctions
|
||||||
|
|
||||||
\brief writes the range of `points` with properties to a file.
|
\brief writes the range of `points` with properties to a file.
|
||||||
|
|
||||||
|
|
@ -115,4 +112,4 @@ bool write_points(const std::string& fname,
|
||||||
|
|
||||||
} } // namespace CGAL::IO
|
} } // namespace CGAL::IO
|
||||||
|
|
||||||
#endif // CGAL_POINT_SET_PROCESSING_WRITE_POINTS_H
|
#endif // CGAL_STREAM_SUPPORT_IO_WRITE_POINTS_H
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
// Copyright (c) 2017 GeometryFactory
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org);
|
||||||
|
//
|
||||||
|
// $URL$
|
||||||
|
// $Id$
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
|
//
|
||||||
|
// Author(s) : Simon Giraudot
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef CGAL_IO_WRITE_XYZ_POINTS_H
|
||||||
|
#define CGAL_IO_WRITE_XYZ_POINTS_H
|
||||||
|
|
||||||
|
#include <CGAL/IO/XYZ.h>
|
||||||
|
|
||||||
|
#endif // CGAL_IO_WRITE_XYZ_POINTS_H
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue