Compare commits

..

1 Commits

Author SHA1 Message Date
SOUHARDYA TOLA f1d5ec16dd
Merge 2096d66b3d into dbcace69e6 2025-11-26 12:00:23 +01:00
102 changed files with 5762 additions and 10062 deletions

View File

@ -30,7 +30,7 @@
#include <CGAL/tags.h>
#include <CGAL/Arr_tags.h>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Cartesian.h>
#include <CGAL/Arr_geometry_traits/Circle_segment_2.h>
namespace CGAL {
@ -41,31 +41,31 @@ namespace CGAL {
template <typename Kernel_, bool Filter = true>
class Arr_circle_segment_traits_2 {
public:
using Kernel = Kernel_;
using NT = typename Kernel::FT;
using Rational_point_2 = typename Kernel::Point_2;
using Rational_segment_2 = typename Kernel::Segment_2;
using Rational_circle_2 = typename Kernel::Circle_2;
using Point_2 = _One_root_point_2<NT, Filter>;
using CoordNT = typename Point_2::CoordNT;
using Curve_2 = _Circle_segment_2<Kernel, Filter>;
using X_monotone_curve_2 = _X_monotone_circle_segment_2<Kernel, Filter>;
using Multiplicity = std::size_t;
using Self = Arr_circle_segment_traits_2<Kernel, Filter>;
typedef Kernel_ Kernel;
typedef typename Kernel::FT NT;
typedef typename Kernel::Point_2 Rational_point_2;
typedef typename Kernel::Segment_2 Rational_segment_2;
typedef typename Kernel::Circle_2 Rational_circle_2;
typedef _One_root_point_2<NT, Filter> Point_2;
typedef typename Point_2::CoordNT CoordNT;
typedef _Circle_segment_2<Kernel, Filter> Curve_2;
typedef _X_monotone_circle_segment_2<Kernel, Filter> X_monotone_curve_2;
typedef unsigned int Multiplicity;
typedef Arr_circle_segment_traits_2<Kernel, Filter> Self;
// Category tags:
using Has_left_category = Tag_true;
using Has_merge_category = Tag_true;
using Has_do_intersect_category = Tag_false;
typedef Tag_true Has_left_category;
typedef Tag_true Has_merge_category;
typedef Tag_false Has_do_intersect_category;
using Left_side_category = Arr_oblivious_side_tag;
using Bottom_side_category = Arr_oblivious_side_tag;
using Top_side_category = Arr_oblivious_side_tag;
using Right_side_category = Arr_oblivious_side_tag;
typedef Arr_oblivious_side_tag Left_side_category;
typedef Arr_oblivious_side_tag Bottom_side_category;
typedef Arr_oblivious_side_tag Top_side_category;
typedef Arr_oblivious_side_tag Right_side_category;
protected:
// Type definition for the intersection points mapping.
using Intersection_map = typename X_monotone_curve_2::Intersection_map;
typedef typename X_monotone_curve_2::Intersection_map Intersection_map;
mutable Intersection_map inter_map; // Mapping pairs of curve IDs to their
// intersection points.
@ -78,7 +78,8 @@ public:
{}
/*! obtains the next curve index. */
static unsigned int get_index() {
static unsigned int get_index ()
{
#ifdef CGAL_NO_ATOMIC
static unsigned int index;
#else
@ -90,7 +91,8 @@ public:
/// \name Basic functor definitions.
//@{
class Compare_x_2 {
class Compare_x_2
{
public:
/*! compares the \f$x\f$-coordinates of two points.
* \param p1 The first point.
@ -99,17 +101,23 @@ public:
* SMALLER if x(p1) < x(p2);
* EQUAL if x(p1) = x(p2).
*/
Comparison_result operator() (const Point_2& p1, const Point_2& p2) const {
if (p1.identical (p2)) return (EQUAL);
Comparison_result operator() (const Point_2& p1, const Point_2& p2) const
{
if (p1.identical (p2))
return (EQUAL);
return (CGAL::compare (p1.x(), p2.x()));
}
};
/*! obtains a `Compare_x_2` functor object. */
Compare_x_2 compare_x_2_object () const { return Compare_x_2(); }
Compare_x_2 compare_x_2_object () const
{
return Compare_x_2();
}
class Compare_xy_2 {
class Compare_xy_2
{
public:
/*! compares two points lexigoraphically: by x, then by y.
* \param p1 The first point.
@ -118,11 +126,15 @@ public:
* SMALLER if x(p1) < x(p2), or if x(p1) = x(p2) and y(p1) < y(p2);
* EQUAL if the two points are equal.
*/
Comparison_result operator() (const Point_2& p1, const Point_2& p2) const {
if (p1.identical (p2)) return (EQUAL);
Comparison_result operator() (const Point_2& p1, const Point_2& p2) const
{
if (p1.identical (p2))
return (EQUAL);
Comparison_result res = CGAL::compare(p1.x(), p2.x());
if (res != EQUAL) return (res);
Comparison_result res = CGAL::compare (p1.x(), p2.x());
if (res != EQUAL)
return (res);
return (CGAL::compare (p1.y(), p2.y()));
}
@ -130,51 +142,69 @@ public:
/*! obtains a Compare_xy_2 functor object. */
Compare_xy_2 compare_xy_2_object () const
{ return Compare_xy_2(); }
{
return Compare_xy_2();
}
class Construct_min_vertex_2 {
class Construct_min_vertex_2
{
public:
/*! obtains the left endpoint of the \f$x\f$-monotone curve (segment).
* \param cv The curve.
* \return The left endpoint.
*/
const Point_2& operator() (const X_monotone_curve_2 & cv) const
{ return (cv.left()); }
{
return (cv.left());
}
};
/*! obtains a `Construct_min_vertex_2` functor object. */
Construct_min_vertex_2 construct_min_vertex_2_object () const
{ return Construct_min_vertex_2(); }
{
return Construct_min_vertex_2();
}
class Construct_max_vertex_2 {
class Construct_max_vertex_2
{
public:
/*! obtains the right endpoint of the \f$x\f$-monotone curve (segment).
* \param cv The curve.
* \return The right endpoint.
*/
const Point_2& operator() (const X_monotone_curve_2 & cv) const
{ return (cv.right()); }
{
return (cv.right());
}
};
/*! obtains a Construct_max_vertex_2 functor object. */
Construct_max_vertex_2 construct_max_vertex_2_object () const
{ return Construct_max_vertex_2(); }
{
return Construct_max_vertex_2();
}
class Is_vertical_2 {
class Is_vertical_2
{
public:
/*! checks whether the given \f$x\f$-monotone curve is a vertical segment.
* \param cv The curve.
* \return (true) if the curve is a vertical segment; (false) otherwise.
*/
bool operator() (const X_monotone_curve_2& cv) const
{ return (cv.is_vertical()); }
{
return (cv.is_vertical());
}
};
/*! obtains an `Is_vertical_2` functor object. */
Is_vertical_2 is_vertical_2_object () const
{ return Is_vertical_2(); }
{
return Is_vertical_2();
}
class Compare_y_at_x_2 {
class Compare_y_at_x_2
{
public:
/*! returns the location of the given point with respect to the input curve.
* \param cv The curve.
@ -184,19 +214,23 @@ public:
* LARGER if y(p) > cv(x(p)), i.e. the point is above the curve;
* EQUAL if p lies on the curve.
*/
Comparison_result operator()(const Point_2& p,
const X_monotone_curve_2& cv) const {
CGAL_precondition (cv.is_in_x_range(p));
Comparison_result operator() (const Point_2& p,
const X_monotone_curve_2& cv) const
{
CGAL_precondition (cv.is_in_x_range (p));
return (cv.point_position(p));
return (cv.point_position (p));
}
};
/*! obtains a `Compare_y_at_x_2` functor object. */
Compare_y_at_x_2 compare_y_at_x_2_object () const
{ return Compare_y_at_x_2(); }
{
return Compare_y_at_x_2();
}
class Compare_y_at_x_right_2 {
class Compare_y_at_x_right_2
{
public:
/*! compares the y value of two \f$x\f$-monotone curves immediately to the
* right of their intersection point.
@ -210,29 +244,30 @@ public:
*/
Comparison_result operator() (const X_monotone_curve_2& cv1,
const X_monotone_curve_2& cv2,
const Point_2& p) const {
const Point_2& p) const
{
// Make sure that p lies on both curves, and that both are defined to its
// right (so their right endpoint is lexicographically larger than p).
CGAL_precondition (cv1.point_position (p) == EQUAL &&
cv2.point_position (p) == EQUAL);
if ((CGAL::compare (cv1.left().x(),cv1.right().x()) == EQUAL) &&
(CGAL::compare (cv2.left().x(),cv2.right().x()) == EQUAL)) {
//both cv1 and cv2 are vertical
(CGAL::compare (cv2.left().x(),cv2.right().x()) == EQUAL))
{ //both cv1 and cv2 are vertical
CGAL_precondition (!(cv1.right()).equals(p) && !(cv2.right()).equals(p));
}
else if ((CGAL::compare (cv1.left().x(),cv1.right().x()) != EQUAL) &&
(CGAL::compare (cv2.left().x(),cv2.right().x()) == EQUAL)) {
//only cv1 is vertical
(CGAL::compare (cv2.left().x(),cv2.right().x()) == EQUAL))
{ //only cv1 is vertical
CGAL_precondition (!(cv1.right()).equals(p));
}
else if ((CGAL::compare (cv1.left().x(),cv1.right().x()) == EQUAL) &&
(CGAL::compare (cv2.left().x(),cv2.right().x()) != EQUAL)) {
//only cv2 is vertical
(CGAL::compare (cv2.left().x(),cv2.right().x()) != EQUAL))
{ //only cv2 is vertical
CGAL_precondition (!(cv2.right()).equals(p));
}
else {
//both cv1 and cv2 are non vertical
else
{ //both cv1 and cv2 are non vertical
CGAL_precondition (CGAL::compare (cv1.right().x(),p.x()) == LARGER &&
CGAL::compare (cv2.right().x(),p.x()) == LARGER);
}
@ -243,9 +278,12 @@ public:
/*! obtains a `Compare_y_at_x_right_2` functor object. */
Compare_y_at_x_right_2 compare_y_at_x_right_2_object () const
{ return Compare_y_at_x_right_2(); }
{
return Compare_y_at_x_right_2();
}
class Compare_y_at_x_left_2 {
class Compare_y_at_x_left_2
{
public:
/*! compares the \f$y\f$-value of two \f$x\f$-monotone curves immediately to
* the left of their intersection point.
@ -259,7 +297,8 @@ public:
*/
Comparison_result operator() (const X_monotone_curve_2& cv1,
const X_monotone_curve_2& cv2,
const Point_2& p) const {
const Point_2& p) const
{
// Make sure that p lies on both curves, and that both are defined to its
// left (so their left endpoint is lexicographically smaller than p).
@ -267,25 +306,25 @@ public:
cv2.point_position (p) == EQUAL);
if ((CGAL::compare (cv1.left().x(),cv1.right().x()) == EQUAL) &&
(CGAL::compare (cv2.left().x(),cv2.right().x()) == EQUAL)) {
//both cv1 and cv2 are vertical
CGAL_precondition (!(cv1.left()).equals(p) && !(cv2.left()).equals(p));
}
else if ((CGAL::compare (cv1.left().x(),cv1.right().x()) != EQUAL) &&
(CGAL::compare (cv2.left().x(),cv2.right().x()) == EQUAL)) {
//only cv1 is vertical
CGAL_precondition (!(cv1.left()).equals(p));
}
else if ((CGAL::compare (cv1.left().x(),cv1.right().x()) == EQUAL) &&
(CGAL::compare (cv2.left().x(),cv2.right().x()) != EQUAL)) {
//only cv2 is vertical
CGAL_precondition (!(cv2.left()).equals(p));
}
else {
//both cv1 and cv2 are non vertical
(CGAL::compare (cv2.left().x(),cv2.right().x()) == EQUAL))
{ //both cv1 and cv2 are vertical
CGAL_precondition (!(cv1.left()).equals(p) && !(cv2.left()).equals(p));
}
else if ((CGAL::compare (cv1.left().x(),cv1.right().x()) != EQUAL) &&
(CGAL::compare (cv2.left().x(),cv2.right().x()) == EQUAL))
{ //only cv1 is vertical
CGAL_precondition (!(cv1.left()).equals(p));
}
else if ((CGAL::compare (cv1.left().x(),cv1.right().x()) == EQUAL) &&
(CGAL::compare (cv2.left().x(),cv2.right().x()) != EQUAL))
{ //only cv2 is vertical
CGAL_precondition (!(cv2.left()).equals(p));
}
else
{ //both cv1 and cv2 are non vertical
CGAL_precondition (CGAL::compare (cv1.left().x(),p.x()) == SMALLER &&
CGAL::compare (cv2.left().x(),p.x()) == SMALLER);
}
}
// Compare the two curves immediately to the left of p:
return (cv1.compare_to_left (cv2, p));
}
@ -293,9 +332,12 @@ public:
/*! obtains a `Compare_y_at_x_left_2` functor object. */
Compare_y_at_x_left_2 compare_y_at_x_left_2_object () const
{ return Compare_y_at_x_left_2(); }
{
return Compare_y_at_x_left_2();
}
class Equal_2 {
class Equal_2
{
public:
/*! checks if the two \f$x\f$-monotone curves are the same (have the same
* graph).
@ -304,8 +346,10 @@ public:
* \return (true) if the two curves are the same; (false) otherwise.
*/
bool operator() (const X_monotone_curve_2& cv1,
const X_monotone_curve_2& cv2) const {
if (&cv1 == &cv2) return (true);
const X_monotone_curve_2& cv2) const
{
if (&cv1 == &cv2)
return (true);
return (cv1.equals (cv2));
}
@ -316,20 +360,24 @@ public:
* \return (true) if the two point are the same; (false) otherwise.
*/
bool operator() (const Point_2& p1, const Point_2& p2) const
{ return (p1.equals (p2)); }
{
return (p1.equals (p2));
}
};
/*! obtains an `Equal_2` functor object. */
Equal_2 equal_2_object () const
{ return Equal_2(); }
{
return Equal_2();
}
//@}
/// \name Functor definitions for approximations. Used by the landmarks
// point-location strategy and the drawing procedure.
//@{
using Approximate_number_type = double;
using Approximate_kernel = CGAL::Simple_cartesian<Approximate_number_type>;
using Approximate_point_2 = Approximate_kernel::Point_2;
typedef double Approximate_number_type;
typedef CGAL::Cartesian<Approximate_number_type> Approximate_kernel;
typedef Approximate_kernel::Point_2 Approximate_point_2;
class Approximate_2 {
protected:
@ -509,7 +557,7 @@ public:
*/
class Make_x_monotone_2 {
private:
using Self = Arr_circle_segment_traits_2<Kernel_, Filter>;
typedef Arr_circle_segment_traits_2<Kernel_, Filter> Self;
bool m_use_cache;
@ -525,7 +573,8 @@ public:
* \return the past-the-end iterator.
*/
template <typename OutputIterator>
OutputIterator operator()(const Curve_2& cv, OutputIterator oi) const {
OutputIterator operator()(const Curve_2& cv, OutputIterator oi) const
{
// Increment the serial number of the curve cv, which will serve as its
// unique identifier.
unsigned int index = 0;
@ -542,7 +591,7 @@ public:
// Check the case of a degenerate circle (a point).
const typename Kernel::Circle_2& circ = cv.supporting_circle();
CGAL::Sign sign_rad = CGAL::sign (circ.squared_radius());
CGAL::Sign sign_rad = CGAL::sign (circ.squared_radius());
CGAL_precondition (sign_rad != NEGATIVE);
if (sign_rad == ZERO) {
@ -554,8 +603,8 @@ public:
// The curve is circular: compute the to vertical tangency points
// of the supporting circle.
Point_2 vpts[2];
unsigned int n_vpts = cv.vertical_tangency_points (vpts);
Point_2 vpts[2];
unsigned int n_vpts = cv.vertical_tangency_points (vpts);
if (cv.is_full()) {
CGAL_assertion (n_vpts == 2);
@ -625,7 +674,8 @@ public:
Make_x_monotone_2 make_x_monotone_2_object() const
{ return Make_x_monotone_2(m_use_cache); }
class Split_2 {
class Split_2
{
public:
/*! splits a given \f$x\f$-monotone curve at a given point into two
@ -637,7 +687,8 @@ public:
* \pre `p` lies on cv but is not one of its end-points.
*/
void operator() (const X_monotone_curve_2& cv, const Point_2& p,
X_monotone_curve_2& c1, X_monotone_curve_2& c2) const {
X_monotone_curve_2& c1, X_monotone_curve_2& c2) const
{
CGAL_precondition (cv.point_position(p)==EQUAL &&
! p.equals (cv.source()) &&
! p.equals (cv.target()));
@ -648,7 +699,10 @@ public:
};
/*! obtains a `Split_2` functor object. */
Split_2 split_2_object () const { return Split_2(); }
Split_2 split_2_object () const
{
return Split_2();
}
class Intersect_2 {
private:
@ -676,7 +730,8 @@ public:
/*! obtains an `Intersect_2` functor object. */
Intersect_2 intersect_2_object() const { return (Intersect_2(inter_map)); }
class Are_mergeable_2 {
class Are_mergeable_2
{
public:
/*! checks whether it is possible to merge two given \f$x\f$-monotone curves.
* \param cv1 The first curve.
@ -687,19 +742,24 @@ public:
*/
bool operator() (const X_monotone_curve_2& cv1,
const X_monotone_curve_2& cv2) const
{ return (cv1.can_merge_with (cv2)); }
{
return (cv1.can_merge_with (cv2));
}
};
/*! obtains an `Are_mergeable_2` functor object. */
Are_mergeable_2 are_mergeable_2_object () const
{ return Are_mergeable_2(); }
{
return Are_mergeable_2();
}
/*! \class Merge_2
* A functor that merges two \f$x\f$-monotone arcs into one.
*/
class Merge_2 {
class Merge_2
{
protected:
using Traits = Arr_circle_segment_traits_2<Kernel, Filter>;
typedef Arr_circle_segment_traits_2<Kernel, Filter> Traits;
/*! The traits (in case it has state) */
const Traits* m_traits;
@ -720,7 +780,8 @@ public:
*/
void operator() (const X_monotone_curve_2& cv1,
const X_monotone_curve_2& cv2,
X_monotone_curve_2& c) const {
X_monotone_curve_2& c) const
{
CGAL_precondition(m_traits->are_mergeable_2_object()(cv2, cv1));
c = cv1;
@ -729,15 +790,20 @@ public:
};
/*! obtains a `Merge_2` functor object. */
Merge_2 merge_2_object () const { return Merge_2(this); }
Merge_2 merge_2_object () const
{
return Merge_2(this);
}
class Compare_endpoints_xy_2 {
class Compare_endpoints_xy_2
{
public:
/*! compares lexicogrphic the endpoints of a \f$x\f$-monotone curve.
* \param cv the curve
* \return `SMALLER` if the curve is directed right, else return `LARGER`.
*/
Comparison_result operator()(const X_monotone_curve_2& cv) const {
Comparison_result operator()(const X_monotone_curve_2& cv) const
{
if(cv.is_directed_right())
return(SMALLER);
return (LARGER);
@ -746,25 +812,32 @@ public:
/*! obtains a `Compare_endpoints_xy_2` functor object. */
Compare_endpoints_xy_2 compare_endpoints_xy_2_object() const
{ return Compare_endpoints_xy_2(); }
{
return Compare_endpoints_xy_2();
}
class Construct_opposite_2 {
class Construct_opposite_2
{
public:
/*! constructs an opposite \f$x\f$-monotone curve.
* \param cv the curve
* \return an opposite \f$x\f$-monotone curve.
*/
X_monotone_curve_2 operator()(const X_monotone_curve_2& cv) const
{ return cv.construct_opposite(); }
{
return cv.construct_opposite();
}
};
/*! obtains a `Construct_opposite_2` functor object. */
Construct_opposite_2 construct_opposite_2_object() const
{ return Construct_opposite_2(); }
{
return Construct_opposite_2();
}
class Trim_2 {
protected:
using Traits = Arr_circle_segment_traits_2<Kernel, Filter>;
typedef Arr_circle_segment_traits_2<Kernel, Filter> Traits;
/*! The traits (in case it has state) */
const Traits& m_traits;
@ -787,7 +860,8 @@ public:
*/
X_monotone_curve_2 operator()(const X_monotone_curve_2& xcv,
const Point_2& src,
const Point_2& tgt)const {
const Point_2& tgt)const
{
// make functor objects
CGAL_precondition_code(Compare_y_at_x_2 compare_y_at_x_2 =
m_traits.compare_y_at_x_2_object());
@ -811,6 +885,7 @@ public:
Trim_2 trim_2_object() const { return Trim_2(*this); }
// @}
};
} // namespace CGAL

View File

@ -40,54 +40,55 @@
namespace CGAL {
namespace internal{
template <class CircularKernel>
class Non_x_monotonic_Circular_arc_2
: public CircularKernel::Circular_arc_2
{
typedef typename CircularKernel::FT FT;
typedef typename CircularKernel::Point_2 Point_2;
typedef typename CircularKernel::Line_2 Line_2;
typedef typename CircularKernel::Circle_2 Circle_2;
typedef typename CircularKernel::Circular_arc_point_2
Circular_arc_point_2;
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;
typedef typename CircularKernel::Circular_arc_2 Base;
public:
Non_x_monotonic_Circular_arc_2(): Base(){}
Non_x_monotonic_Circular_arc_2(const Circle_2& c): Base(c){}
Non_x_monotonic_Circular_arc_2(const Circle_2 &c): Base(c){}
// Not Documented
Non_x_monotonic_Circular_arc_2(const Circle_2& support,
const Line_2& l1, const bool b_l1,
const Line_2& l2, const bool b_l2) :
Base(support,l1,b_l1,l2,b_l2){}
Non_x_monotonic_Circular_arc_2(const Circle_2 &support,
const Line_2 &l1, const bool b_l1,
const Line_2 &l2, const bool b_l2)
: Base(support,l1,b_l1,l2,b_l2){}
// Not Documented
Non_x_monotonic_Circular_arc_2(const Circle_2& c,
const Circle_2& c1, const bool b_1,
const Circle_2& c2, const bool b_2) :
Base(c,c1,b_1,c2,b_2)
Non_x_monotonic_Circular_arc_2(const Circle_2 &c,
const Circle_2 &c1, const bool b_1,
const Circle_2 &c2, const bool b_2)
: Base(c,c1,b_1,c2,b_2)
{}
Non_x_monotonic_Circular_arc_2(const Point_2& start,
const Point_2& middle,
const Point_2& end) :
Base(start,middle,end)
Non_x_monotonic_Circular_arc_2(const Point_2 &start,
const Point_2 &middle,
const Point_2 &end)
: Base(start,middle,end)
{}
Non_x_monotonic_Circular_arc_2(const Circle_2& support,
const Circular_arc_point_2& begin,
const Circular_arc_point_2& end) :
Base(support,begin,end)
Non_x_monotonic_Circular_arc_2(const Circle_2 &support,
const Circular_arc_point_2 &begin,
const Circular_arc_point_2 &end)
: Base(support,begin,end)
{}
Non_x_monotonic_Circular_arc_2(const Point_2& start,
const Point_2& end,
const FT& bulge) :
Base(start,end,bulge)
Non_x_monotonic_Circular_arc_2(const Point_2 &start,
const Point_2 &end,
const FT &bulge)
: Base(start,end,bulge)
{}
Non_x_monotonic_Circular_arc_2(const Base& a) : Base(a) {}
Non_x_monotonic_Circular_arc_2(const Base& a) : Base(a) {}
};
} //namespace internal
@ -97,40 +98,45 @@ public:
template < typename CircularKernel >
class Arr_circular_arc_traits_2 {
CircularKernel ck;
public:
using Kernel = CircularKernel;
using Curve_2 = internal::Non_x_monotonic_Circular_arc_2<CircularKernel>;
using X_monotone_curve_2 = typename CircularKernel::Circular_arc_2;
using Point = typename CircularKernel::Circular_arc_point_2;
using Point_2 = typename CircularKernel::Circular_arc_point_2;
typedef CircularKernel Kernel;
typedef internal::Non_x_monotonic_Circular_arc_2<CircularKernel> Curve_2;
typedef typename CircularKernel::Circular_arc_2 X_monotone_curve_2;
using Multiplicity = std::size_t;
typedef typename CircularKernel::Circular_arc_point_2 Point;
typedef typename CircularKernel::Circular_arc_point_2 Point_2;
using Has_left_category = CGAL::Tag_false;
using Has_merge_category = CGAL::Tag_false;
using Has_do_intersect_category = CGAL::Tag_false;
typedef unsigned int Multiplicity;
using Left_side_category = Arr_oblivious_side_tag;
using Bottom_side_category = Arr_oblivious_side_tag;
using Top_side_category = Arr_oblivious_side_tag;
using Right_side_category = Arr_oblivious_side_tag;
typedef CGAL::Tag_false Has_left_category;
typedef CGAL::Tag_false Has_merge_category;
typedef CGAL::Tag_false Has_do_intersect_category;
Arr_circular_arc_traits_2(const CircularKernel& k = CircularKernel()) : ck(k) {}
typedef Arr_oblivious_side_tag Left_side_category;
typedef Arr_oblivious_side_tag Bottom_side_category;
typedef Arr_oblivious_side_tag Top_side_category;
typedef Arr_oblivious_side_tag Right_side_category;
using Compare_x_2 = typename CircularKernel::Compare_x_2;
using Compare_xy_2 = typename CircularKernel::Compare_xy_2;
using Compare_y_at_x_2 = typename CircularKernel::Compare_y_at_x_2;
using Compare_y_at_x_right_2 = typename CircularKernel::Compare_y_to_right_2;
using Construct_max_vertex_2 = typename CircularKernel::Construct_circular_max_vertex_2;
using Construct_min_vertex_2 = typename CircularKernel::Construct_circular_min_vertex_2;
using Equal_2 = typename CircularKernel::Equal_2;
Arr_circular_arc_traits_2(const CircularKernel &k = CircularKernel())
: ck(k) {}
typedef typename CircularKernel::Compare_x_2 Compare_x_2;
typedef typename CircularKernel::Compare_xy_2 Compare_xy_2;
typedef typename CircularKernel::Compare_y_at_x_2 Compare_y_at_x_2;
typedef typename CircularKernel::Compare_y_to_right_2 Compare_y_at_x_right_2;
typedef typename CircularKernel::Construct_circular_max_vertex_2
Construct_max_vertex_2;
typedef typename CircularKernel::Construct_circular_min_vertex_2
Construct_min_vertex_2;
typedef typename CircularKernel::Equal_2 Equal_2;
// typedef typename CircularKernel::Make_x_monotone_2 Make_x_monotone_2;
using Split_2 = typename CircularKernel::Split_2;
using Intersect_2 = typename CircularKernel::Intersect_2;
using Is_vertical_2 = typename CircularKernel::Is_vertical_2;
typedef typename CircularKernel::Split_2 Split_2;
typedef typename CircularKernel::Intersect_2 Intersect_2;
typedef typename CircularKernel::Is_vertical_2 Is_vertical_2;
Compare_x_2 compare_x_2_object() const
{ return ck.compare_x_2_object(); }
@ -154,23 +160,26 @@ public:
{ return ck.split_2_object(); }
Intersect_2 intersect_2_object() const
{ return ck.intersect_2_object(); }
{ return ck.intersect_2_object(); }
Construct_max_vertex_2 construct_max_vertex_2_object() const
{ return ck.construct_circular_max_vertex_2_object(); }
{ return ck.construct_circular_max_vertex_2_object(); }
Construct_min_vertex_2 construct_min_vertex_2_object() const
{ return ck.construct_circular_min_vertex_2_object(); }
{ return ck.construct_circular_min_vertex_2_object(); }
Is_vertical_2 is_vertical_2_object() const
{ return ck.is_vertical_2_object(); }
{ return ck.is_vertical_2_object(); }
//! A functor for subdividing curves into x-monotone curves.
class Make_x_monotone_2 {
public:
template <typename OutputIterator>
OutputIterator operator()(const Curve_2& arc, OutputIterator oi) const {
using Make_x_monotone_result = std::variant<Point_2, X_monotone_curve_2>;
OutputIterator operator()(const Curve_2& arc, OutputIterator oi) const
{
typedef std::variant<Point_2, X_monotone_curve_2>
Make_x_monotone_result;
std::vector<Make_x_monotone_result> objs;
CircularKernel().make_x_monotone_2_object()(arc, std::back_inserter(objs));

View File

@ -41,395 +41,515 @@
#include <CGAL/Arr_tags.h>
namespace CGAL {
namespace VariantFunctors{
namespace VariantFunctors {
// Takes an iterator range of Object(Line/Circular_arc/Point),
// returns a variant of Line, Circular_arc, and Point_2.
template <class CK, class Arc1, class Arc2, class OutputIterator>
OutputIterator
object_to_object_variant(const std::vector<CGAL::Object>& res1,
OutputIterator res2)
{
typedef typename CK::Circular_arc_point_2 Point_2;
typedef std::variant<Arc1, Arc2> X_monotone_curve_2;
typedef std::variant<Point_2, X_monotone_curve_2>
Make_x_monotone_result;
// Takes an iterator range of Object(Line/Circular_arc/Point),
// returns a variant of Line, Circular_arc, and Point_2.
template <typename CK, typename Arc1, typename Arc2, typename OutputIterator>
OutputIterator object_to_object_variant(const std::vector<CGAL::Object>& res1,
OutputIterator res2) {
using Point_2 = typename CK::Circular_arc_point_2;
using X_monotone_curve_2 = std::variant<Arc1, Arc2>;
using Make_x_monotone_result = std::variant<Point_2, X_monotone_curve_2>;
for (auto it = res1.begin(); it != res1.end(); ++it) {
if (const Arc1* arc = CGAL::object_cast<Arc1>(&*it)) {
std::variant<Arc1, Arc2> v = *arc;
*res2++ = Make_x_monotone_result(v);
}
else if (const Arc2* line = CGAL::object_cast<Arc2>(&*it)) {
std::variant<Arc1, Arc2> v = *line;
*res2++ = Make_x_monotone_result(v);
}
else if (const Point_2* p = CGAL::object_cast<Point_2>(&*it)) {
*res2++ = Make_x_monotone_result(*p);
}
else CGAL_error();
}
return res2;
}
template <typename CircularKernel, typename Arc1, typename Arc2>
class Compare_y_to_right_2 {
public:
using result_type = CGAL::Comparison_result;
using Circular_arc_point_2 = typename CircularKernel::Circular_arc_point_2;
result_type operator()(const std::variant<Arc1, Arc2>& a1,
const std::variant<Arc1, Arc2>& a2,
const Circular_arc_point_2& p) const {
if (const Arc1* arc1 = std::get_if<Arc1>(&a1)) {
if (const Arc1* arc2 = std::get_if<Arc1>(&a2)) {
return CircularKernel().compare_y_to_right_2_object()(*arc1, *arc2, p);
for (auto it = res1.begin(); it != res1.end(); ++it) {
if (const Arc1* arc = CGAL::object_cast<Arc1>(&*it)) {
std::variant<Arc1, Arc2> v = *arc;
*res2++ = Make_x_monotone_result(v);
}
else if (const Arc2* line = CGAL::object_cast<Arc2>(&*it)) {
std::variant<Arc1, Arc2> v = *line;
*res2++ = Make_x_monotone_result(v);
}
else if (const Point_2* p = CGAL::object_cast<Point_2>(&*it)) {
*res2++ = Make_x_monotone_result(*p);
}
else CGAL_error();
}
else {
const Arc2* arc2e = std::get_if<Arc2>(&a2);
return CircularKernel().compare_y_to_right_2_object()(*arc1, *arc2e, p);
return res2;
}
template <class CircularKernel, class Arc1, class Arc2>
class Compare_y_to_right_2
{
public:
typedef CGAL::Comparison_result result_type;
typedef typename CircularKernel::Circular_arc_point_2
Circular_arc_point_2;
result_type
operator()(const std::variant< Arc1, Arc2 > &a1,
const std::variant< Arc1, Arc2 > &a2,
const Circular_arc_point_2 &p) const
{
if ( const Arc1* arc1 = std::get_if<Arc1>( &a1 ) ){
if ( const Arc1* arc2 = std::get_if<Arc1>( &a2 ) ){
return CircularKernel()
.compare_y_to_right_2_object()(*arc1, *arc2, p);
}
else {
const Arc2* arc2e = std::get_if<Arc2>( &a2 );
return CircularKernel()
.compare_y_to_right_2_object()(*arc1, *arc2e, p);
}
}
const Arc2* arc1 = std::get_if<Arc2>( &a1 );
if ( const Arc1* arc2 = std::get_if<Arc1>( &a2 ) ){
return CircularKernel()
.compare_y_to_right_2_object()(*arc1, *arc2, p);
}
const Arc2* arc2e = std::get_if<Arc2>( &a2 );
return CircularKernel()
.compare_y_to_right_2_object()(*arc1, *arc2e, p);
}
}
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 <class CircularKernel>
class Variant_Equal_2
{
public :
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);
template < typename T >
bool
operator()(const T &a0, const T &a1) const
{
return CircularKernel().equal_2_object()(a0,a1);
}
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 < 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;
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 ;
}
// an empty class used to have different types between Curve_2 and X_monotone_curve_2
// in Arr_circular_line_arc_traits_2.
namespace internal_Argt_traits {
struct Not_X_Monotone{};
inline std::ostream& operator << (std::ostream& os, const Not_X_Monotone&)
{return os;}
}
};
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& ;
/// Traits class for CGAL::Arrangement_2 (and similar) based on a CircularKernel.
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 < typename CircularKernel>
class Arr_circular_line_arc_traits_2 {
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 Arr_circular_line_arc_traits_2< CircularKernel > Self;
public:
using result_type = Point_2;
// using qualified_result_type = const result_type&;
typedef typename CircularKernel::Line_arc_2 Arc1;
typedef typename CircularKernel::Circular_arc_2 Arc2;
//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); }
};
public:
template <typename CircularKernel>
class Variant_Construct_max_vertex_2 {
using Circular_arc_point_2 = typename CircularKernel::Circular_arc_point_2;
public:
using result_type = Circular_arc_point_2;
// using qualified_result_type = const result_type&;
typedef CircularKernel Kernel;
typedef typename CircularKernel::Circular_arc_point_2
Circular_arc_point_2;
template <typename T>
//std::remove_reference_t<qualified_result_type>
Circular_arc_point_2 operator()(const T& a) const {
//CGAL_kernel_precondition(CircularKernel().compare_xy_2_object()(a.left(), a.right())==CGAL::SMALLER);
return (CircularKernel().construct_circular_max_vertex_2_object()(a));
}
};
typedef typename CircularKernel::Circular_arc_point_2 Point;
typedef typename CircularKernel::Circular_arc_point_2 Point_2;
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 unsigned int Multiplicity;
public:
/*! obtains the right endpoint of the x-monotone curve (segment).
* \param cv The curve.
* \return The right endpoint.
*/
using result_type = Point_2;
// using qualified_result_type = const result_type&;
typedef CGAL::Tag_false Has_left_category;
typedef CGAL::Tag_false Has_merge_category;
typedef CGAL::Tag_false Has_do_intersect_category;
//std::remove_reference<qualified_result_type>
result_type operator() (const std::variant<Arc1, Arc2>& cv) const
{ return std::visit(Variant_Construct_max_vertex_2<CircularKernel>(), cv); }
};
typedef Arr_oblivious_side_tag Left_side_category;
typedef Arr_oblivious_side_tag Bottom_side_category;
typedef Arr_oblivious_side_tag Top_side_category;
typedef Arr_oblivious_side_tag Right_side_category;
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 internal_Argt_traits::Not_X_Monotone Not_X_Monotone;
template <typename CircularKernel, typename Arc1, typename Arc2>
class Is_vertical_2 {
public:
using result_type = bool;
typedef std::variant< Arc1, Arc2, Not_X_Monotone > Curve_2;
typedef std::variant< Arc1, Arc2 > X_monotone_curve_2;
bool operator() (const std::variant<Arc1, Arc2>& cv) const
{ return std::visit(Variant_Is_vertical_2<CircularKernel>(), cv); }
};
private:
CircularKernel ck;
public:
}
Arr_circular_line_arc_traits_2(const CircularKernel &k = CircularKernel())
: ck(k) {}
// an empty class used to have different types between Curve_2 and X_monotone_curve_2
// in Arr_circular_line_arc_traits_2.
namespace internal_Argt_traits {
typedef typename CircularKernel::Compare_x_2 Compare_x_2;
typedef typename CircularKernel::Compare_xy_2 Compare_xy_2;
typedef typename
VariantFunctors::Construct_min_vertex_2<CircularKernel, Arc1, Arc2>
Construct_min_vertex_2;
typedef
VariantFunctors::Construct_max_vertex_2<CircularKernel, Arc1, Arc2>
Construct_max_vertex_2;
typedef VariantFunctors::Is_vertical_2<CircularKernel, Arc1, Arc2>
Is_vertical_2;
typedef VariantFunctors::Compare_y_at_x_2<CircularKernel, Arc1, Arc2>
Compare_y_at_x_2;
typedef VariantFunctors::Compare_y_to_right_2<CircularKernel, Arc1, Arc2>
Compare_y_at_x_right_2;
typedef VariantFunctors::Equal_2<CircularKernel, Arc1, Arc2>
Equal_2;
typedef VariantFunctors::Make_x_monotone_2<CircularKernel, Arc1, Arc2>
Make_x_monotone_2;
typedef VariantFunctors::Split_2<CircularKernel, Arc1, Arc2>
Split_2;
typedef VariantFunctors::Intersect_2<CircularKernel, Arc1, Arc2>
Intersect_2;
struct Not_X_Monotone{};
Compare_x_2 compare_x_2_object() const
{ return ck.compare_x_2_object(); }
inline std::ostream& operator << (std::ostream& os, const Not_X_Monotone&) { return os; }
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(); }
/// Traits class for CGAL::Arrangement_2 (and similar) based on a CircularKernel.
Compare_y_at_x_right_2 compare_y_at_x_right_2_object() const
{ return Compare_y_at_x_right_2(); }
template <typename CircularKernel>
class Arr_circular_line_arc_traits_2 {
using Self = Arr_circular_line_arc_traits_2<CircularKernel>;
Equal_2 equal_2_object() const
{ return Equal_2(); }
using Arc1 = typename CircularKernel::Line_arc_2;
using Arc2 = typename CircularKernel::Circular_arc_2;
Make_x_monotone_2 make_x_monotone_2_object() const
{ return Make_x_monotone_2(); }
public:
using Kernel = CircularKernel;
using Circular_arc_point_2 = typename CircularKernel::Circular_arc_point_2;
Split_2 split_2_object() const
{ return Split_2(); }
using Point = typename CircularKernel::Circular_arc_point_2;
using Point_2 = typename CircularKernel::Circular_arc_point_2;
Intersect_2 intersect_2_object() const
{ return Intersect_2(); }
using Multiplicity = std::size_t;
Construct_min_vertex_2 construct_min_vertex_2_object() const
{ return Construct_min_vertex_2(); }
using Has_left_category = CGAL::Tag_false;
using Has_merge_category = CGAL::Tag_false;
using Has_do_intersect_category = CGAL::Tag_false;
Construct_max_vertex_2 construct_max_vertex_2_object() const
{ return Construct_max_vertex_2(); }
using Left_side_category = Arr_oblivious_side_tag;
using Bottom_side_category = Arr_oblivious_side_tag;
using Top_side_category = Arr_oblivious_side_tag;
using Right_side_category = Arr_oblivious_side_tag;
using Not_X_Monotone = internal_Argt_traits::Not_X_Monotone;
using Curve_2 = std::variant<Arc1, Arc2, Not_X_Monotone>;
using X_monotone_curve_2 = std::variant<Arc1, Arc2>;
private:
CircularKernel ck;
public:
Arr_circular_line_arc_traits_2(const CircularKernel& k = CircularKernel()) : ck(k) {}
using Compare_x_2 = typename CircularKernel::Compare_x_2;
using Compare_xy_2 = typename CircularKernel::Compare_xy_2;
using Construct_min_vertex_2 = typename VariantFunctors::Construct_min_vertex_2<CircularKernel, Arc1, Arc2>;
using Construct_max_vertex_2 = VariantFunctors::Construct_max_vertex_2<CircularKernel, Arc1, Arc2>;
using Is_vertical_2 = VariantFunctors::Is_vertical_2<CircularKernel, Arc1, Arc2>;
using Compare_y_at_x_2 = VariantFunctors::Compare_y_at_x_2<CircularKernel, Arc1, Arc2>;
using Compare_y_at_x_right_2 = VariantFunctors::Compare_y_to_right_2<CircularKernel, Arc1, Arc2>;
using Equal_2 = VariantFunctors::Equal_2<CircularKernel, Arc1, Arc2>;
using Make_x_monotone_2 = VariantFunctors::Make_x_monotone_2<CircularKernel, Arc1, Arc2>;
using Split_2 = VariantFunctors::Split_2<CircularKernel, Arc1, Arc2>;
using Intersect_2 = VariantFunctors::Intersect_2<CircularKernel, Arc1, Arc2>;
Compare_x_2 compare_x_2_object() const
{ return ck.compare_x_2_object(); }
Compare_xy_2 compare_xy_2_object() const
{ return ck.compare_xy_2_object(); }
Compare_y_at_x_2 compare_y_at_x_2_object() const
{ return Compare_y_at_x_2(); }
Compare_y_at_x_right_2 compare_y_at_x_right_2_object() const
{ return Compare_y_at_x_right_2(); }
Equal_2 equal_2_object() const
{ return Equal_2(); }
Make_x_monotone_2 make_x_monotone_2_object() const
{ return Make_x_monotone_2(); }
Split_2 split_2_object() const
{ return Split_2(); }
Intersect_2 intersect_2_object() const
{ return Intersect_2(); }
Construct_min_vertex_2 construct_min_vertex_2_object() const
{ return Construct_min_vertex_2(); }
Construct_max_vertex_2 construct_max_vertex_2_object() const
{ return Construct_max_vertex_2(); }
Is_vertical_2 is_vertical_2_object() const
{ return Is_vertical_2();}
Is_vertical_2 is_vertical_2_object() const
{ return Is_vertical_2();}
};
} // namespace CGAL

View File

@ -32,7 +32,7 @@
#include <boost/math/constants/constants.hpp>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Cartesian.h>
#include <CGAL/tags.h>
#include <CGAL/Arr_tags.h>
#include <CGAL/Arr_enums.h>
@ -59,37 +59,37 @@ namespace CGAL {
template <typename RatKernel, typename AlgKernel, typename NtTraits>
class Arr_conic_traits_2 {
public:
using Rat_kernel = RatKernel;
using Alg_kernel = AlgKernel;
using Nt_traits = NtTraits;
typedef RatKernel Rat_kernel;
typedef AlgKernel Alg_kernel;
typedef NtTraits Nt_traits;
using Rational = typename Rat_kernel::FT;
using Rat_point_2 = typename Rat_kernel::Point_2;
using Rat_segment_2 = typename Rat_kernel::Segment_2;
using Rat_line_2 = typename Rat_kernel::Line_2;
using Rat_circle_2 = typename Rat_kernel::Circle_2;
typedef typename Rat_kernel::FT Rational;
typedef typename Rat_kernel::Point_2 Rat_point_2;
typedef typename Rat_kernel::Segment_2 Rat_segment_2;
typedef typename Rat_kernel::Line_2 Rat_line_2;
typedef typename Rat_kernel::Circle_2 Rat_circle_2;
using Algebraic = typename Alg_kernel::FT;
using Alg_point_2 = typename Alg_kernel::Point_2;
typedef typename Alg_kernel::FT Algebraic;
typedef typename Alg_kernel::Point_2 Alg_point_2;
using Integer = typename Nt_traits::Integer;
typedef typename Nt_traits::Integer Integer;
// Category tags:
using Has_left_category = Tag_true;
using Has_merge_category = Tag_true;
using Has_do_intersect_category = Tag_false;
typedef Tag_true Has_left_category;
typedef Tag_true Has_merge_category;
typedef Tag_false Has_do_intersect_category;
//typedef std::true_type Has_line_segment_constructor;
using Left_side_category = Arr_oblivious_side_tag;
using Bottom_side_category = Arr_oblivious_side_tag;
using Top_side_category = Arr_oblivious_side_tag;
using Right_side_category = Arr_oblivious_side_tag;
typedef Arr_oblivious_side_tag Left_side_category;
typedef Arr_oblivious_side_tag Bottom_side_category;
typedef Arr_oblivious_side_tag Top_side_category;
typedef Arr_oblivious_side_tag Right_side_category;
// Traits objects:
using Curve_2 = Conic_arc_2<Rat_kernel, Alg_kernel, Nt_traits>;
using X_monotone_curve_2 = Conic_x_monotone_arc_2<Curve_2>;
using Point_2 = Conic_point_2<Alg_kernel>;
using Multiplicity = std::size_t;
typedef Conic_arc_2<Rat_kernel, Alg_kernel, Nt_traits> Curve_2;
typedef Conic_x_monotone_arc_2<Curve_2> X_monotone_curve_2;
typedef Conic_point_2<Alg_kernel> Point_2;
typedef size_t Multiplicity;
private:
// Type definition for the intersection points mapping.
@ -106,14 +106,16 @@ private:
}
};
using Intersection_point = std::pair<Point_2, Multiplicity>;
using Intersection_list = std::list<Intersection_point>;
using Intersection_map = std::map<Conic_pair, Intersection_list, Less_conic_pair>;
using Intersection_map_iterator = typename Intersection_map::iterator;
typedef std::pair<Point_2, Multiplicity> Intersection_point;
typedef std::list<Intersection_point> Intersection_list;
typedef std::map<Conic_pair, Intersection_list, Less_conic_pair>
Intersection_map;
typedef typename Intersection_map::iterator Intersection_map_iterator;
using Shared_rat_kernel = std::shared_ptr<Rat_kernel>;
using Shared_alg_kernel = std::shared_ptr<Alg_kernel>;
using Shared_nt_traits = std::shared_ptr<Nt_traits>;
typedef std::shared_ptr<Rat_kernel> Shared_rat_kernel;
typedef std::shared_ptr<Alg_kernel> Shared_alg_kernel;
typedef std::shared_ptr<Nt_traits> Shared_nt_traits;
const Shared_rat_kernel m_rat_kernel;
const Shared_alg_kernel m_alg_kernel;
@ -125,10 +127,10 @@ private:
public:
/*! constructs default.
*/
Arr_conic_traits_2() :
m_rat_kernel(std::make_shared<Rat_kernel>()),
m_alg_kernel(std::make_shared<Alg_kernel>()),
m_nt_traits(std::make_shared<Nt_traits>())
Arr_conic_traits_2()
: m_rat_kernel(std::make_shared<Rat_kernel>()),
m_alg_kernel(std::make_shared<Alg_kernel>()),
m_nt_traits(std::make_shared<Nt_traits>())
{}
/*! constructs from resources.
@ -358,7 +360,8 @@ public:
*/
Comparison_result operator()(const X_monotone_curve_2& xcv1,
const X_monotone_curve_2& xcv2,
const Point_2& p) const {
const Point_2& p) const
{
// Make sure that p lies on both curves, and that both are defined to its
// left (so their left endpoint is lexicographically smaller than p).
CGAL_precondition(m_traits.contains_point(xcv1, p) &&
@ -535,7 +538,8 @@ public:
*/
Comparison_result operator()(const X_monotone_curve_2& xcv1,
const X_monotone_curve_2& xcv2,
const Point_2& p) const {
const Point_2& p) const
{
// Make sure that p lies on both curves, and that both are defined to its
// left (so their left endpoint is lexicographically smaller than p).
CGAL_precondition(m_traits.contains_point(xcv1, p) &&
@ -699,7 +703,8 @@ public:
* \return `true` if the two curves are the same; `false` otherwise.
*/
bool operator()(const X_monotone_curve_2& xcv1,
const X_monotone_curve_2& xcv2) const {
const X_monotone_curve_2& xcv2) const
{
if (&xcv1 == &xcv2) return true;
return equals(xcv1, xcv2);
}
@ -919,7 +924,8 @@ public:
if (((cv.orientation() == COUNTERCLOCKWISE) &&
(start_pos == order_vpts)) ||
((cv.orientation() == CLOCKWISE) && (start_pos != order_vpts))) {
((cv.orientation() == CLOCKWISE) && (start_pos != order_vpts)))
{
ind_first = 1;
ind_second = 0;
}
@ -1095,7 +1101,8 @@ public:
else if (m_traits.is_between_endpoints(xcv2, xcv1.source()) &&
m_traits.is_between_endpoints(xcv2, xcv1.target()) &&
(m_traits.is_strictly_between_endpoints(xcv2, xcv1.source()) ||
m_traits.is_strictly_between_endpoints(xcv2, xcv1.target()))) {
m_traits.is_strictly_between_endpoints(xcv2, xcv1.target())))
{
// Case 4 - *this: +----------->
// arc: +================>
overlap = xcv1;
@ -1278,7 +1285,8 @@ public:
for (i = 0; i < n_xs; ++i) {
for (j = 0; j < n_ys; ++j) {
if (xcv1.is_on_supporting_conic(xs[i], ys[j]) &&
xcv2.is_on_supporting_conic(xs[i], ys[j])) {
xcv2.is_on_supporting_conic(xs[i], ys[j]))
{
// Create the intersection point and set its generating conics.
Point_2 ip(xs[i], ys[j]);
@ -1306,7 +1314,8 @@ public:
OutputIterator intersect(const X_monotone_curve_2& xcv1,
const X_monotone_curve_2& xcv2,
Intersection_map& inter_map,
OutputIterator oi) const {
OutputIterator oi) const
{
if (m_traits.has_same_supporting_conic(xcv1, xcv2)) {
// Check for overlaps between the two arcs.
X_monotone_curve_2 overlap;
@ -1383,7 +1392,8 @@ public:
// both \f$x\f$-monotone arcs.
for (auto iter = inter_list.begin(); iter != inter_list.end(); ++iter) {
if (m_traits.is_between_endpoints(xcv1, (*iter).first) &&
m_traits.is_between_endpoints(xcv2, (*iter).first)) {
m_traits.is_between_endpoints(xcv2, (*iter).first))
{
*oi++ = *iter;
}
}
@ -1471,7 +1481,8 @@ public:
*/
void operator()(const X_monotone_curve_2& xcv1,
const X_monotone_curve_2& xcv2,
X_monotone_curve_2& xcv) const {
X_monotone_curve_2& xcv) const
{
CGAL_precondition(m_traits.are_mergeable_2_object()(xcv2, xcv1));
xcv = xcv1;
merge(xcv, xcv2);
@ -1512,11 +1523,11 @@ public:
* point-location strategy and the drawing function.
*/
//@{
using Approximate_number_type = double;
using Approximate_kernel = CGAL::Simple_cartesian<Approximate_number_type>;
using Approximate_point_2 = Approximate_kernel::Point_2;
typedef double Approximate_number_type;
typedef CGAL::Cartesian<Approximate_number_type> Approximate_kernel;
typedef Approximate_kernel::Point_2 Approximate_point_2;
class Approximate_length_2 {
class Approximate_curve_length_2 {
protected:
using Traits = Arr_conic_traits_2<Rat_kernel, Alg_kernel, Nt_traits>;
@ -1526,7 +1537,7 @@ public:
/*! constructs
* \param traits the traits.
*/
Approximate_length_2(const Traits& traits) : m_traits(traits) {}
Approximate_curve_length_2(const Traits& traits) : m_traits(traits) {}
friend class Arr_conic_traits_2<Rat_kernel, Alg_kernel, Nt_traits>;
@ -1546,7 +1557,7 @@ public:
private:
/*! obtains the segment length.
*/
double segment_length(const X_monotone_curve_2& xcv) const {
double segment_length(const X_monotone_curve_2& xcv) {
auto min_vertex = m_traits.construct_min_vertex_2_object();
auto max_vertex = m_traits.construct_max_vertex_2_object();
const auto& minv = min_vertex(xcv);
@ -1586,7 +1597,7 @@ public:
/*! obtains the parabolic arc length.
*/
double parabola_length(const X_monotone_curve_2& xcv) const {
double parabola_length(const X_monotone_curve_2& xcv) {
double r_m, t_m, s_m, u_m, v_m, w_m;
double cost, sint;
double xs_t, ys_t, xt_t, yt_t;
@ -1606,7 +1617,7 @@ public:
return d;
}
double ellipse_length(const X_monotone_curve_2& xcv) const {
double ellipse_length(const X_monotone_curve_2& xcv) {
double r_m, t_m, s_m, u_m, v_m, w_m;
double cost, sint;
double xs_t, ys_t, xt_t, yt_t;
@ -1627,7 +1638,7 @@ public:
return d;
}
double hyperbola_length(const X_monotone_curve_2& /* xcv */) const {
double hyperbola_length(const X_monotone_curve_2& /* xcv */) {
CGAL_error_msg("Not implemented yet!");
double l(0.0);
return l;
@ -1890,7 +1901,8 @@ public:
template <typename OutputIterator>
OutputIterator approximate_parabola(const X_monotone_curve_2& xcv,
double error, OutputIterator oi,
bool l2r = true) const {
bool l2r = true)
const {
// std::cout << "PARABOLA\n";
auto min_vertex = m_traits.construct_min_vertex_2_object();
auto max_vertex = m_traits.construct_max_vertex_2_object();
@ -2092,7 +2104,8 @@ public:
*/
X_monotone_curve_2 operator()(const Curve_2& cv,
const Point_2& source, const Point_2& target,
const Conic_id& id) const {
const Conic_id& id) const
{
// Set the two endpoints.
X_monotone_curve_2 xcv(cv, id);
xcv.set_source(source);
@ -2109,7 +2122,8 @@ public:
* \return A segment connecting `source` and `target`.
*/
X_monotone_curve_2 operator()(const Point_2& source, const Point_2& target)
const {
const
{
X_monotone_curve_2 xcv;
// Set the basic properties.
@ -2143,7 +2157,8 @@ public:
X_monotone_curve_2 operator()(const Algebraic& a, const Algebraic& b,
const Algebraic& c,
const Point_2& source, const Point_2& target)
const {
const
{
auto cmp_xy = m_traits.m_alg_kernel->compare_xy_2_object();
Comparison_result res = cmp_xy(source, target);
CGAL_precondition(res != EQUAL);
@ -2223,7 +2238,8 @@ public:
*/
Curve_2 operator()(const Rational& r, const Rational& s, const Rational& t,
const Rational& u, const Rational& v, const Rational& w)
const {
const
{
// Ensure that the given curve is an ellipse (4rs - t^2 is positive).
CGAL_precondition(CGAL::sign(4*r*s - t*t) == POSITIVE);
@ -2429,7 +2445,8 @@ public:
if (! m_traits.is_strictly_between_endpoints(arc, mp2) ||
! m_traits.is_strictly_between_endpoints(arc, mp3) ||
! m_traits.is_strictly_between_endpoints(arc, mp4)) {
! m_traits.is_strictly_between_endpoints(arc, mp4))
{
arc.reset_flags(); // invalid arc
return arc;
}
@ -2836,7 +2853,8 @@ public:
* \pre both points must be interior and must lie on \c cv
*/
X_monotone_curve_2 operator()(const X_monotone_curve_2& xcv,
const Point_2& src, const Point_2& tgt) const {
const Point_2& src, const Point_2& tgt) const
{
// make functor objects
CGAL_precondition_code(Compare_y_at_x_2 compare_y_at_x_2 =
m_traits.compare_y_at_x_2_object());
@ -3066,14 +3084,16 @@ public:
const auto& target = cv.target();
// Make sure both endpoint lie on the supporting conic.
if (! is_on_supporting_conic(cv, source) ||
! is_on_supporting_conic(cv, target)) {
! is_on_supporting_conic(cv, target))
{
cv.reset_flags(); // invalid arc
return;
}
// Check whether we have a degree 2 curve.
if ((CGAL::sign(r) != ZERO) || (CGAL::sign(s) != ZERO) ||
(CGAL::sign(t) != ZERO)) {
(CGAL::sign(t) != ZERO))
{
if (cv.orientation() == COLLINEAR) {
// Make sure the midpoint is on the line pair (thus making sure that
// the two points are not taken from different lines).
@ -3085,7 +3105,8 @@ public:
m_nt_traits->convert(u)) * p_mid.x() +
(m_nt_traits->convert(s)*p_mid.y() +
m_nt_traits->convert(v)) * p_mid.y() +
m_nt_traits->convert(w)) != ZERO) {
m_nt_traits->convert(w)) != ZERO)
{
cv.reset_flags(); // invalid arc
return;
}
@ -3624,7 +3645,8 @@ public:
// Compute the degree of the underlying conic.
if ((CGAL::sign(xcv.r()) != ZERO) ||
(CGAL::sign(xcv.s()) != ZERO) ||
(CGAL::sign(xcv.t()) != ZERO)) {
(CGAL::sign(xcv.t()) != ZERO))
{
xcv.set_flag(X_monotone_curve_2::DEGREE_2);
xcv.set_flag(X_monotone_curve_2::IS_SPECIAL_SEGMENT);
}
@ -3834,7 +3856,8 @@ public:
for (int j = 0; j < n_ys; ++j) {
if (CGAL::compare(m_nt_traits->convert(Integer(two*s)) * ys[j],
-(m_nt_traits->convert(t) * xs[i] +
m_nt_traits->convert(v))) == EQUAL) {
m_nt_traits->convert(v))) == EQUAL)
{
ps[n++] = Point_2(xs[i], ys[j]);
break;
}
@ -4105,7 +4128,8 @@ public:
double& xs_t, double& ys_t, double& ts,
double& xt_t, double& yt_t, double& tt,
double& a, double& b, double& cx, double& cy,
bool l2r = true) const {
bool l2r = true)
const {
auto min_vertex = construct_min_vertex_2_object();
auto max_vertex = construct_max_vertex_2_object();
const auto& src = (l2r) ? min_vertex(xcv) : max_vertex(xcv);
@ -4182,7 +4206,8 @@ public:
double& xs_t, double& ys_t, double& ts,
double& xt_t, double& yt_t, double& tt,
double& a, double& b, double& cx, double& cy,
bool l2r = true) const {
bool l2r = true)
const {
auto min_vertex = construct_min_vertex_2_object();
auto max_vertex = construct_max_vertex_2_object();
const auto& src = (l2r) ? min_vertex(xcv) : max_vertex(xcv);

View File

@ -28,7 +28,7 @@
#include <variant>
#include <CGAL/config.h>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Cartesian.h>
#include <CGAL/tags.h>
#include <CGAL/tss.h>
#include <CGAL/intersections.h>
@ -2856,7 +2856,7 @@ public:
/// \name Functor definitions for the landmarks point-location strategy.
//@{
using Approximate_number_type = double;
using Approximate_kernel = CGAL::Simple_cartesian<Approximate_number_type>;
using Approximate_kernel = CGAL::Cartesian<Approximate_number_type>;
using Approximate_point_2 = Arr_extended_direction_3<Approximate_kernel>;
using Approximate_kernel_vector_3 = Approximate_kernel::Vector_3;
using Approximate_kernel_direction_3 = Approximate_kernel::Direction_3;

View File

@ -21,6 +21,7 @@
* Definition of the Bezier_bounding_rational_traits<Kernel> class.
*/
#include <CGAL/Cartesian.h>
#include <CGAL/Polygon_2_algorithms.h>
#include <CGAL/Arr_geometry_traits/de_Casteljau_2.h>

View File

@ -41,9 +41,9 @@ class _One_root_point_2_rep {
friend class _One_root_point_2<NumberType_, Filter_>;
public:
using NT = NumberType_;
using Self = _One_root_point_2_rep<NT, Filter_>;
using CoordNT = Sqrt_extension<NT, NT, Tag_true,Boolean_tag<Filter_> >;
typedef NumberType_ NT;
typedef _One_root_point_2_rep<NT, Filter_> Self;
typedef Sqrt_extension<NT, NT, Tag_true,Boolean_tag<Filter_> > CoordNT;
private:
CoordNT _x; // The coordinates.
@ -70,17 +70,18 @@ public:
*/
template <typename NumberType_, bool Filter_>
class _One_root_point_2 :
public Handle_for<_One_root_point_2_rep<NumberType_, Filter_>> {
public Handle_for<_One_root_point_2_rep<NumberType_, Filter_> >
{
public:
using NT = NumberType_;
using Self = _One_root_point_2<NT, Filter_>;
typedef NumberType_ NT;
typedef _One_root_point_2<NT, Filter_> Self;
private:
using Point_rep = _One_root_point_2_rep<NT, Filter_>;
using Point_handle = Handle_for<Point_rep>;
typedef _One_root_point_2_rep<NT, Filter_> Point_rep;
typedef Handle_for<Point_rep> Point_handle;
public:
using CoordNT = typename Point_rep::CoordNT;
typedef typename Point_rep::CoordNT CoordNT;
/*! constructs default. */
_One_root_point_2() : Point_handle(Point_rep()) {}
@ -105,7 +106,8 @@ public:
const CoordNT& y() const { return (this->ptr()->_y); }
/*! checks for equality. */
bool equals(const Self& p) const {
bool equals(const Self& p) const
{
if (this->identical(p)) return (true);
return (CGAL::compare(this->ptr()->_x, p.ptr()->_x) == EQUAL &&
@ -117,7 +119,8 @@ public:
bool operator == (const Self& p) const { return equals(p); }
/*! sets the point coordinates. */
void set(const NT& x, const NT& y) {
void set(const NT& x, const NT& y)
{
this->copy_on_write();
this->ptr()->_x = CoordNT(x);
this->ptr()->_y = CoordNT(y);
@ -125,7 +128,8 @@ public:
}
/*! sets the point coordinates. */
void set(const CoordNT& x, const CoordNT& y) {
void set(const CoordNT& x, const CoordNT& y)
{
this->copy_on_write();
this->ptr()->_x = x;
this->ptr()->_y = y;
@ -137,7 +141,8 @@ public:
*/
template <typename NT, bool Filter>
std::ostream& operator<<(std::ostream& os,
const _One_root_point_2<NT, Filter>& p) {
const _One_root_point_2<NT, Filter>& p)
{
os << CGAL::to_double(p.x()) << ' ' << CGAL::to_double(p.y());
return (os);
}
@ -160,15 +165,15 @@ std::istream & operator >> (std::istream & is,
template <typename Kernel_, bool Filter_>
class _Circle_segment_2 {
public:
using Kernel = Kernel_;
using NT = typename Kernel::FT;
using Point_2 = _One_root_point_2<NT, Filter_>;
using Circle_2 = typename Kernel::Circle_2;
using Segment_2 = typename Kernel::Segment_2;
using Line_2 = typename Kernel::Line_2;
typedef Kernel_ Kernel;
typedef typename Kernel::FT NT;
typedef _One_root_point_2<NT, Filter_> Point_2;
typedef typename Kernel::Circle_2 Circle_2;
typedef typename Kernel::Segment_2 Segment_2;
typedef typename Kernel::Line_2 Line_2;
protected:
using CoordNT = typename Point_2::CoordNT;
typedef typename Point_2::CoordNT CoordNT;
// Data members:
Line_2 m_line; // The supporting line (for line segments).
@ -229,7 +234,8 @@ public:
m_has_radius(false),
m_source(source),
m_target(target),
m_orient(COLLINEAR) {
m_orient(COLLINEAR)
{
CGAL_precondition(CGAL::compare(source.x() * line.a() + line.c(),
-source.y() * line.b()) == EQUAL);
@ -276,7 +282,8 @@ public:
m_has_radius(false),
m_source(source),
m_target(target),
m_orient(circ.orientation()) {
m_orient(circ.orientation())
{
CGAL_assertion(m_orient != COLLINEAR);
CGAL_precondition
@ -308,7 +315,8 @@ public:
m_radius(r),
m_source(source),
m_target(target),
m_orient(orient) {
m_orient(orient)
{
CGAL_assertion(orient != COLLINEAR);
CGAL_precondition
@ -335,7 +343,8 @@ public:
m_is_full(false),
m_has_radius(false),
m_source(p1.x(), p1.y()),
m_target(p3.x(), p3.y()) {
m_target(p3.x(), p3.y())
{
// Set the source and target.
NT x1 = p1.x();
NT y1 = p1.y();
@ -350,7 +359,7 @@ public:
// Compute the lines: A1*x + B1*y + C1 = 0,
// and: A2*x + B2*y + C2 = 0,
// where:
const NT _two = 2;
const NT _two = 2;
const NT A1 = _two*(x1 - x2);
const NT B1 = _two*(y1 - y2);
@ -414,7 +423,8 @@ public:
/*! obtains the supporting line.
* \pre The curve orientation is COLLINEAR.
*/
const Line_2& supporting_line() const {
const Line_2& supporting_line() const
{
CGAL_precondition(m_orient == COLLINEAR);
return m_line;
}
@ -422,7 +432,8 @@ public:
/*! obtains the supporting circle.
* \pre The curve orientation is not COLLINEAR.
*/
const Circle_2& supporting_circle() const {
const Circle_2& supporting_circle() const
{
CGAL_precondition(m_orient != COLLINEAR);
return m_circ;
}
@ -433,7 +444,8 @@ public:
/*! obtains the source point.
* \pre The curve is not a full circle.
*/
const Point_2& source() const {
const Point_2& source() const
{
CGAL_precondition(! m_is_full);
return (m_source);
}
@ -441,7 +453,8 @@ public:
/*! obtains the target point.
* \pre The curve is not a full circle.
*/
const Point_2& target() const {
const Point_2& target() const
{
CGAL_precondition(! m_is_full);
return (m_target);
}
@ -451,7 +464,8 @@ public:
* \pre The curve is circular.
* \return The number of points (0, 1, or 2).
*/
unsigned int vertical_tangency_points(Point_2* vpts) const {
unsigned int vertical_tangency_points(Point_2* vpts) const
{
CGAL_precondition(m_orient != COLLINEAR);
unsigned int n_vpts = 0;
@ -505,7 +519,8 @@ private:
*/
unsigned int _ccw_vertical_tangency_points(const Point_2& src,
const Point_2& trg,
Point_2* vpts) const {
Point_2* vpts) const
{
unsigned int n_vpts = 0;
const NT& x0 = m_circ.center().x();
const NT& y0 = m_circ.center().y();
@ -532,7 +547,8 @@ private:
if ((qs % 4) == 1) {
// We collect the left tangency point when going from Q[1] to Q[2]:
if (CGAL::compare(x0, trg.x()) != LARGER ||
CGAL::compare(y0, trg.y()) != EQUAL) {
CGAL::compare(y0, trg.y()) != EQUAL)
{
if (m_has_radius)
vpts[n_vpts] = Point_2(CoordNT(x0 - m_radius), y0);
else
@ -545,7 +561,8 @@ private:
else if ((qs % 4) == 3) {
// We collect the right tangency point when going from Q[3] to Q[0]:
if (CGAL::compare(x0, trg.x()) != SMALLER ||
CGAL::compare(y0, trg.y()) != EQUAL) {
CGAL::compare(y0, trg.y()) != EQUAL)
{
if (m_has_radius)
vpts[n_vpts] = Point_2(CoordNT(x0 + m_radius), y0);
else
@ -564,7 +581,8 @@ private:
/*! obtains the index of the quarter-plane containing the given point,
* where the circle center is considered to be the origin.
*/
int _quart_index(const Point_2& p) const {
int _quart_index(const Point_2& p) const
{
// The plane looks like:
//
// Q[1] : | Q[0]:
@ -590,7 +608,8 @@ private:
*/
template <typename Kernel, bool Filter>
std::ostream&
operator<<(std::ostream& os, const _Circle_segment_2<Kernel, Filter>& c) {
operator<<(std::ostream& os, const _Circle_segment_2<Kernel, Filter>& c)
{
if (c.orientation() == COLLINEAR) {
os<< "segment: " << c.source() << " -> " << c.target();
}
@ -613,33 +632,35 @@ operator<<(std::ostream& os, const _Circle_segment_2<Kernel, Filter>& c) {
template <typename Kernel_, bool Filter_>
class _X_monotone_circle_segment_2 {
public:
using Kernel = Kernel_;
using Self = _X_monotone_circle_segment_2<Kernel, Filter_>;
using NT = typename Kernel::FT;
using Point_2 = _One_root_point_2<NT, Filter_>;
using Circle_2 = typename Kernel::Circle_2;
using Line_2 = typename Kernel::Line_2;
using CoordNT = typename Point_2::CoordNT;
typedef Kernel_ Kernel;
typedef _X_monotone_circle_segment_2<Kernel, Filter_> Self;
typedef typename Kernel::FT NT;
typedef _One_root_point_2<NT, Filter_> Point_2;
typedef typename Kernel::Circle_2 Circle_2;
typedef typename Kernel::Line_2 Line_2;
typedef typename Point_2::CoordNT CoordNT;
// Type definition for the intersection points mapping.
using Curve_id_pair = std::pair<unsigned int, unsigned int>;
using Multiplicity = std::size_t;
using Intersection_point = std::pair<Point_2, Multiplicity>;
using Intersection_list = std::list<Intersection_point>;
typedef std::pair<unsigned int, unsigned int> Curve_id_pair;
typedef unsigned int Multiplicity;
typedef std::pair<Point_2, Multiplicity> Intersection_point;
typedef std::list<Intersection_point> Intersection_list;
/*! \struct Less functor for Curve_id_pair.
*/
struct Less_id_pair {
bool operator()(const Curve_id_pair& ip1, const Curve_id_pair& ip2) const {
bool operator()(const Curve_id_pair& ip1, const Curve_id_pair& ip2) const
{
// Compare the pairs of IDs lexicographically.
return (ip1.first < ip2.first ||
(ip1.first == ip2.first && ip1.second < ip2.second));
}
};
using Intersection_map = std::map<Curve_id_pair, Intersection_list, Less_id_pair>;
using Intersection_map_entry = typename Intersection_map::value_type;
using Intersection_map_iterator = typename Intersection_map::iterator;
typedef std::map<Curve_id_pair, Intersection_list, Less_id_pair>
Intersection_map;
typedef typename Intersection_map::value_type Intersection_map_entry;
typedef typename Intersection_map::iterator Intersection_map_iterator;
protected:
NT m_first; // The x-coordinate of the circle center.
@ -692,7 +713,8 @@ public:
m_third(line.c()),
m_source(source),
m_target(target),
m_info(index << INDEX_SHIFT_BITS) {
m_info(index << INDEX_SHIFT_BITS)
{
// Check if the segment is directed left or right:
Comparison_result res = CGAL::compare(source.x(), target.x());
@ -718,7 +740,8 @@ public:
const typename Kernel::Point_2& target) :
m_source(source.x(), source.y()),
m_target(target.x(), target.y()),
m_info(0) {
m_info(0)
{
Line_2 line(source, target);
m_first = line.a();
m_second = line.b();
@ -755,7 +778,8 @@ public:
m_third(circ.squared_radius()),
m_source(source),
m_target(target),
m_info(index << INDEX_SHIFT_BITS) {
m_info(index << INDEX_SHIFT_BITS)
{
// Check if the segment is directed left or right:
Comparison_result res = CGAL::compare (source.x(), target.x());
@ -778,7 +802,8 @@ public:
/*! obtains the supporting line.
* \pre The arc is linear (a line segment).
*/
Line_2 supporting_line() const {
Line_2 supporting_line() const
{
CGAL_precondition (is_linear());
return (Line_2 (a(), b(), c()));
}
@ -786,7 +811,8 @@ public:
/*! obtains the supporting circle.
* \pre The arc is circular.
*/
Circle_2 supporting_circle() const {
Circle_2 supporting_circle() const
{
CGAL_precondition (is_circular());
typename Kernel::Point_2 center(x0(), y0());
@ -817,7 +843,8 @@ public:
/*! checks whether the given point is in the x-range of the arc.
*/
bool is_in_x_range(const Point_2& p) const {
bool is_in_x_range(const Point_2& p) const
{
Comparison_result res = CGAL::compare (p.x(), left().x());
if (res == SMALLER) return false;
@ -831,7 +858,8 @@ public:
{ return ((m_info & IS_VERTICAL_SEGMENT_MASK) != 0); }
/*! obtains the orientation of the arc. */
inline Orientation orientation() const {
inline Orientation orientation() const
{
unsigned int or_ = (m_info & ORIENTATION_MASK);
if (or_ == COUNTERCLOCKWISE_CODE) return (CGAL::COUNTERCLOCKWISE);
else if (or_ == CLOCKWISE_CODE) return (CGAL::CLOCKWISE);
@ -842,14 +870,16 @@ public:
/*! checks the position of a given point with respect to the arc.
*/
Comparison_result point_position(const Point_2& p) const {
Comparison_result point_position(const Point_2& p) const
{
if (is_linear()) return (_line_point_position(p));
else return (_circ_point_position (p));
}
/*! compares the two arcs to the right of their intersection point.
*/
Comparison_result compare_to_right(const Self& cv, const Point_2& p) const {
Comparison_result compare_to_right(const Self& cv, const Point_2& p) const
{
if (is_linear()) {
if (cv.is_linear()) return (_lines_compare_to_right (cv, p));
Comparison_result res = cv._circ_line_compare_to_right (*this, p);
@ -864,7 +894,8 @@ public:
/*! compares the two arcs to the left of their intersection point.
*/
Comparison_result compare_to_left(const Self& cv, const Point_2& p) const {
Comparison_result compare_to_left(const Self& cv, const Point_2& p) const
{
if (is_linear()) {
if (cv.is_linear()) return (_lines_compare_to_left (cv, p));
Comparison_result res = cv._circ_line_compare_to_left(*this, p);
@ -879,7 +910,8 @@ public:
/*! checks whether the two arcs have the same supporting curve.
*/
bool has_same_supporting_curve(const Self& cv) const {
bool has_same_supporting_curve(const Self& cv) const
{
// Check if the curve indices are the same.
if (_index() != 0 && _index() == cv._index()) return true;
@ -918,7 +950,8 @@ public:
/*! checks whether the two curves are equal.
*/
bool equals(const Self& cv) const {
bool equals(const Self& cv) const
{
if (! this->has_same_supporting_curve(cv)) return false;
if (is_linear()) {
@ -936,7 +969,8 @@ public:
/*! splits the curve at a given point into two sub-arcs.
*/
void split(const Point_2& p, Self& c1, Self& c2) const {
void split(const Point_2& p, Self& c1, Self& c2) const
{
// Copy the properties of this arc to the sub-arcs.
c1 = *this;
c2 = *this;
@ -956,7 +990,8 @@ public:
*/
template <typename OutputIterator>
OutputIterator intersect(const Self& cv, OutputIterator oi,
Intersection_map* inter_map = nullptr) const {
Intersection_map* inter_map = nullptr) const
{
// First check whether the two arcs have the same supporting curve.
if (has_same_supporting_curve(cv)) {
// Check for overlaps between the two arcs.
@ -1029,7 +1064,8 @@ public:
// Report only the intersection points that lie on both arcs.
for (auto iter = inter_list.begin(); iter != inter_list.end(); ++iter) {
if (this->_is_between_endpoints (iter->first) &&
cv._is_between_endpoints (iter->first)) {
cv._is_between_endpoints (iter->first))
{
*oi++ = *iter;
}
}
@ -1039,7 +1075,8 @@ public:
/*! checks whether it is possible to merge our arc with the given arc.
*/
bool can_merge_with(const Self& cv) const {
bool can_merge_with(const Self& cv) const
{
// In order to merge the two arcs, they should have the same supporting
// curve.
if (! this->has_same_supporting_curve(cv)) return false;
@ -1052,7 +1089,8 @@ public:
/*! merges our arc with the given arc.
* \pre The two arcs are mergeable.
*/
void merge(const Self& cv) {
void merge(const Self& cv)
{
CGAL_precondition(this->can_merge_with (cv));
// Check if we should extend the arc to the left or to the right.
@ -1071,7 +1109,8 @@ public:
}
/*! constructs an opposite arc. */
Self construct_opposite() const {
Self construct_opposite() const
{
Self opp_cv;
opp_cv.m_first = this->m_first;
opp_cv.m_second = this->m_second;
@ -1088,7 +1127,8 @@ public:
return (opp_cv);
}
Bbox_2 bbox() const {
Bbox_2 bbox() const
{
double x_min = to_double(left().x());
double x_max = to_double(right().x());
double y_min = to_double(left().y());
@ -1127,7 +1167,8 @@ protected:
/*! checks if the circular arc lies on the upper half of the supporting circle.
*/
inline bool _is_upper() const {
inline bool _is_upper() const
{
Orientation orient = orientation();
bool dir_right = ((m_info & IS_DIRECTED_RIGHT_MASK) != 0);
@ -1156,7 +1197,8 @@ protected:
/*! checks the position of a given point with respect to a line segment.
*/
Comparison_result _line_point_position(const Point_2& p) const {
Comparison_result _line_point_position(const Point_2& p) const
{
// Check if we have a vertical segment.
CGAL_precondition(is_in_x_range(p));
@ -1187,17 +1229,20 @@ protected:
/*! checks the position of a given point with respect to a circular arc.
*/
Comparison_result _circ_point_position(const Point_2& p) const {
Comparison_result _circ_point_position(const Point_2& p) const
{
Comparison_result c_res = CGAL::compare (p.y(), y0());
if (_is_upper()) {
// Check if p lies below the "equator" (while the arc lies above it):
if (c_res == SMALLER) return (SMALLER);
if (c_res == SMALLER)
return (SMALLER);
}
else {
// Check if p lies above the "equator" (while the arc lies below it):
if (c_res == LARGER) return (LARGER);
if (c_res == LARGER)
return (LARGER);
}
// Check if p lies inside the supporting circle, namely we have to check
@ -1226,7 +1271,8 @@ protected:
/*! compares two line segments to the right of their intersection point.
*/
Comparison_result _lines_compare_to_right(const Self& cv,
const Point_2& /* p */) const {
const Point_2& /* p */) const
{
if (_index() != 0 && _index() == cv._index()) return (EQUAL);
// Special treatment for vertical segments: a vertical segment is larger
@ -1246,7 +1292,8 @@ protected:
* their intersection point.
*/
Comparison_result _circ_line_compare_to_right(const Self& cv,
const Point_2& p) const {
const Point_2& p) const
{
// A vertical segment lies above any other circle to the right of p:
if (cv.is_vertical()) return (SMALLER);
@ -1287,7 +1334,8 @@ protected:
/*! compares two circular arcs to the right of their intersection point.
*/
Comparison_result _circs_compare_to_right(const Self& cv,
const Point_2& p) const {
const Point_2& p) const
{
if (_index() != 0 && _index() == cv._index()) {
// Check the case of comparing two circular arcs that originate from the
// same supporting circle. Their comparison result is not EQUAL only if
@ -1365,11 +1413,13 @@ protected:
// Compare the slopes of the two tangents to the circles.
Comparison_result slope_res;
if (sign_slope1 == ZERO && sign_slope2 == ZERO) {
if (sign_slope1 == ZERO && sign_slope2 == ZERO)
{
// Special case were both circles have a horizontal tangent:
slope_res = EQUAL;
}
else {
else
{
// Actually compare the slopes.
const bool swap_res = (sign_denom1 != sign_denom2);
const CoordNT A = NT(cv.y0() - y0())*p.x() + (y0()*cv.x0() - cv.y0()*x0());
@ -1416,7 +1466,8 @@ protected:
/*! compares two line segments to the left of their intersection point.
*/
Comparison_result _lines_compare_to_left(const Self& cv,
const Point_2& ) const {
const Point_2& ) const
{
if (_index() != 0 && _index() == cv._index()) return (EQUAL);
// Special treatment for vertical segments: a vertical segment is smaller
@ -1438,7 +1489,8 @@ protected:
* their intersection point.
*/
Comparison_result _circ_line_compare_to_left(const Self& cv,
const Point_2& p) const {
const Point_2& p) const
{
// A vertical segment lies below any other circle to the left of p:
if (cv.is_vertical()) return (LARGER);
@ -1482,7 +1534,8 @@ protected:
/*! compares the two arcs to the left of their intersection point.
*/
Comparison_result _circs_compare_to_left(const Self& cv,
const Point_2& p) const {
const Point_2& p) const
{
if (_index() != 0 && _index() == cv._index()) {
// Check the case of comparing two circular arcs that originate from the
// same supporting circle. Their comparison result is not EQUAL only if
@ -1561,7 +1614,8 @@ protected:
// Compare the slopes of the two tangents to the circles.
Comparison_result slope_res;
if (sign_slope1 == ZERO && sign_slope2 == ZERO) {
if (sign_slope1 == ZERO && sign_slope2 == ZERO)
{
// Special case were both circles have a horizontal tangent:
slope_res = EQUAL;
}
@ -1614,7 +1668,8 @@ protected:
/*! computes the intersections between two line segments.
*/
void _lines_intersect(const Self& cv,
Intersection_list& inter_list) const {
Intersection_list& inter_list) const
{
// The intersection of the lines:
// a1*x + b1*y + c1 = 0 and a2*x + b2*y + c2 = 0 ,
// is given by:
@ -1640,7 +1695,8 @@ protected:
* the supporting line of the segment cv.
*/
void _circ_line_intersect(const Self& cv,
Intersection_list& inter_list) const {
Intersection_list& inter_list) const
{
Point_2 p;
unsigned int mult;
@ -1762,7 +1818,8 @@ protected:
/*! computes the intersections between two circles.
*/
void _circs_intersect(const Self& cv, Intersection_list& inter_list) const {
void _circs_intersect(const Self& cv, Intersection_list& inter_list) const
{
Point_2 p;
unsigned int mult;
@ -1827,7 +1884,8 @@ protected:
/*! checks if the given point lies on the arc.
* \pre p lies on the supporting curve.
*/
bool _is_between_endpoints(const Point_2& p) const {
bool _is_between_endpoints(const Point_2& p) const
{
if (is_linear()) {
if (is_vertical()) {
// Check if the point is in the y-range of the arc.
@ -1850,7 +1908,8 @@ protected:
// Check whether p lies on the upper or on the lower part of the circle.
Comparison_result c_res = CGAL::compare(p.y(), y0());
if ((_is_upper() && c_res == SMALLER) || (! _is_upper() && c_res == LARGER)) {
if ((_is_upper() && c_res == SMALLER) || (! _is_upper() && c_res == LARGER))
{
// The point lies on the other half of the circle:
return false;
}
@ -1862,7 +1921,8 @@ protected:
/*! checks whether the given point lies in the interior of the arc.
* \pre p lies on the supporting curve.
*/
bool _is_strictly_between_endpoints(const Point_2& p) const {
bool _is_strictly_between_endpoints(const Point_2& p) const
{
if (p.equals (m_source) || p.equals (m_target)) return false;
return (_is_between_endpoints(p));
}
@ -1872,7 +1932,8 @@ protected:
* \param overlap Output: The overlapping arc (if any).
* \return Whether we found an overlap.
*/
bool _compute_overlap(const Self& cv, Self& overlap) const {
bool _compute_overlap(const Self& cv, Self& overlap) const
{
// Check if the two arcs are identical.
if (is_linear()) {
// In case of line segments we can swap the source and target:
@ -1938,9 +1999,10 @@ protected:
return false;
}
public:
public:
template <class OutputIterator>
void approximate(OutputIterator oi, unsigned int n) const {
void approximate(OutputIterator oi, unsigned int n) const
{
const double x_left = CGAL::to_double(this->source().x());
const double y_left = CGAL::to_double(this->source().y());
@ -1983,7 +2045,8 @@ public:
* \pre Both ps and pt lies on the arc and must conform with the current
* direction of the arc.
*/
Self trim(const Point_2& ps, const Point_2& pt) const {
Self trim(const Point_2& ps, const Point_2& pt) const
{
Self arc = *this;
arc.m_source = ps;
@ -2000,7 +2063,8 @@ public:
template <class Kernel, bool Filter>
std::ostream&
operator<<(std::ostream& os,
const _X_monotone_circle_segment_2<Kernel, Filter>& arc) {
const _X_monotone_circle_segment_2<Kernel, Filter> & arc)
{
if (! arc.is_linear())
os << "(" << arc.supporting_circle() << ") ";

View File

@ -43,41 +43,46 @@ namespace CGAL {
// Traits class for CGAL::Arrangement_2 (and similar) based on a
// CircularKernel.
template <typename CircularKernel>
template < typename CircularKernel >
class Arr_line_arc_traits_2 {
CircularKernel ck;
public:
using Kernel = CircularKernel;
using Curve_2 = typename CircularKernel::Line_arc_2;
using X_monotone_curve_2 = typename CircularKernel::Line_arc_2;
using Multiplicity = std::size_t;
using Point = typename CircularKernel::Circular_arc_point_2;
using Point_2 = typename CircularKernel::Circular_arc_point_2;
typedef CircularKernel Kernel;
typedef typename CircularKernel::Line_arc_2 Curve_2;
typedef typename CircularKernel::Line_arc_2 X_monotone_curve_2;
typedef unsigned int Multiplicity;
using Has_left_category = CGAL::Tag_false;
using Has_merge_category = CGAL::Tag_false;
using Has_do_intersect_category = CGAL::Tag_false;
typedef typename CircularKernel::Circular_arc_point_2 Point;
typedef typename CircularKernel::Circular_arc_point_2 Point_2;
using Left_side_category = Arr_oblivious_side_tag;
using Bottom_side_category = Arr_oblivious_side_tag;
using Top_side_category = Arr_oblivious_side_tag;
using Right_side_category = Arr_oblivious_side_tag;
typedef CGAL::Tag_false Has_left_category;
typedef CGAL::Tag_false Has_merge_category;
typedef CGAL::Tag_false Has_do_intersect_category;
Arr_line_arc_traits_2(const CircularKernel& k = CircularKernel()) : ck(k) {}
typedef Arr_oblivious_side_tag Left_side_category;
typedef Arr_oblivious_side_tag Bottom_side_category;
typedef Arr_oblivious_side_tag Top_side_category;
typedef Arr_oblivious_side_tag Right_side_category;
using Compare_x_2 = typename CircularKernel::Compare_x_2;
using Compare_xy_2 = typename CircularKernel::Compare_xy_2;
using Compare_y_at_x_2 = typename CircularKernel::Compare_y_at_x_2;
using Compare_y_at_x_right_2 = typename CircularKernel::Compare_y_to_right_2;
using Equal_2 = typename CircularKernel::Equal_2;
// using Make_x_monotone_2 = typename CircularKernel::Make_x_monotone_2;
using Split_2 = typename CircularKernel::Split_2;
using Construct_min_vertex_2 = typename CircularKernel::Construct_circular_min_vertex_2;
using Construct_max_vertex_2 = typename CircularKernel::Construct_circular_max_vertex_2;
using Is_vertical_2 = typename CircularKernel::Is_vertical_2;
using Intersect_2 = typename CircularKernel::Intersect_2;
Arr_line_arc_traits_2(const CircularKernel &k = CircularKernel())
: ck(k) {}
typedef typename CircularKernel::Compare_x_2 Compare_x_2;
typedef typename CircularKernel::Compare_xy_2 Compare_xy_2;
typedef typename CircularKernel::Compare_y_at_x_2 Compare_y_at_x_2;
typedef typename CircularKernel::Compare_y_to_right_2 Compare_y_at_x_right_2;
typedef typename CircularKernel::Equal_2 Equal_2;
// typedef typename CircularKernel::Make_x_monotone_2 Make_x_monotone_2;
typedef typename CircularKernel::Split_2 Split_2;
typedef typename CircularKernel::Construct_circular_min_vertex_2
Construct_min_vertex_2;
typedef typename CircularKernel::Construct_circular_max_vertex_2
Construct_max_vertex_2;
typedef typename CircularKernel::Is_vertical_2 Is_vertical_2;
typedef typename CircularKernel::Intersect_2 Intersect_2;
Compare_x_2 compare_x_2_object() const
{ return ck.compare_x_2_object(); }
@ -101,7 +106,7 @@ public:
{ return ck.split_2_object(); }
Intersect_2 intersect_2_object() const
{ return ck.intersect_2_object(); }
{ return ck.intersect_2_object(); }
Construct_min_vertex_2 construct_min_vertex_2_object() const
{ return ck.construct_circular_min_vertex_2_object(); }
@ -116,8 +121,9 @@ public:
class Make_x_monotone_2 {
public:
template <typename OutputIterator>
OutputIterator operator()(const Curve_2& line, OutputIterator oi) const {
using Make_x_monotone_result = std::variant<Point_2, X_monotone_curve_2>;
OutputIterator operator()(const Curve_2& line, OutputIterator oi) const
{
typedef std::variant<Point_2, X_monotone_curve_2> Make_x_monotone_result;
*oi++ = Make_x_monotone_result(line);
return oi;
}
@ -131,4 +137,4 @@ public:
#include <CGAL/enable_warnings.h>
#endif
#endif // CGAL_CIRCULAR_KERNEL_LINE_ARC_TRAITS_H

View File

@ -28,7 +28,7 @@
#include <variant>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Cartesian.h>
#include <CGAL/tags.h>
#include <CGAL/intersections.h>
#include <CGAL/Arr_tags.h>
@ -49,55 +49,58 @@ class Arr_linear_traits_2 : public Kernel_ {
friend class Arr_linear_object_2<Kernel_>;
public:
using Kernel = Kernel_;
using FT = typename Kernel::FT;
typedef Kernel_ Kernel;
typedef typename Kernel::FT FT;
using Has_exact_division = typename Algebraic_structure_traits<FT>::Is_exact;
typedef typename Algebraic_structure_traits<FT>::Is_exact
Has_exact_division;
// Category tags:
using Has_left_category = Tag_true;
using Has_merge_category = Tag_true;
using Has_do_intersect_category = Tag_false;
typedef Tag_true Has_left_category;
typedef Tag_true Has_merge_category;
typedef Tag_false Has_do_intersect_category;
using Left_side_category = Arr_open_side_tag;
using Bottom_side_category = Arr_open_side_tag;
using Top_side_category = Arr_open_side_tag;
using Right_side_category = Arr_open_side_tag;
typedef Arr_open_side_tag Left_side_category;
typedef Arr_open_side_tag Bottom_side_category;
typedef Arr_open_side_tag Top_side_category;
typedef Arr_open_side_tag Right_side_category;
using Line_2 = typename Kernel::Line_2;
using Ray_2 = typename Kernel::Ray_2;
using Segment_2 = typename Kernel::Segment_2;
typedef typename Kernel::Line_2 Line_2;
typedef typename Kernel::Ray_2 Ray_2;
typedef typename Kernel::Segment_2 Segment_2;
using Segment_assertions = CGAL::Segment_assertions<Arr_linear_traits_2<Kernel>>;
typedef CGAL::Segment_assertions<Arr_linear_traits_2<Kernel> >
Segment_assertions;
/*! \class Representation of a linear with cached data.
*/
class _Linear_object_cached_2 {
public:
using Line_2 = typename Kernel::Line_2;
using Ray_2 = typename Kernel::Ray_2;
using Segment_2 = typename Kernel::Segment_2;
using Point_2 = typename Kernel::Point_2;
typedef typename Kernel::Line_2 Line_2;
typedef typename Kernel::Ray_2 Ray_2;
typedef typename Kernel::Segment_2 Segment_2;
typedef typename Kernel::Point_2 Point_2;
protected:
Line_2 l; // The supporting line.
Point_2 ps; // The source point (if exists).
Point_2 pt; // The target point (if exists).
bool has_source; // Is the source point valid
Line_2 l; // The supporting line.
Point_2 ps; // The source point (if exists).
Point_2 pt; // The target point (if exists).
bool has_source; // Is the source point valid
// (false for a line).
bool has_target; // Is the target point valid
bool has_target; // Is the target point valid
// (false for a line and for a ray).
bool is_right; // Is the object directed to the right
bool is_right; // Is the object directed to the right
// (for segments and rays).
bool is_vert; // Is this a vertical object.
bool is_horiz; // Is this a horizontal object.
bool has_pos_slope; // Does the supporting line has a positive
bool is_vert; // Is this a vertical object.
bool is_horiz; // Is this a horizontal object.
bool has_pos_slope; // Does the supporting line has a positive
// slope (if all three flags is_vert, is_horiz
// and has_pos_slope are false, then the line
// has a negative slope).
bool is_degen; // Is the object degenerate (a single point).
bool is_degen; // Is the object degenerate (a single point).
public:
/*! constructs default.
*/
_Linear_object_cached_2() :
@ -118,7 +121,8 @@ public:
ps(source),
pt(target),
has_source(true),
has_target(true) {
has_target(true)
{
Kernel kernel;
Comparison_result res = kernel.compare_xy_2_object()(source, target);
@ -140,7 +144,8 @@ public:
*/
_Linear_object_cached_2(const Segment_2& seg) :
has_source(true),
has_target(true) {
has_target(true)
{
Kernel kernel;
CGAL_assertion_msg(! kernel.is_degenerate_2_object()(seg),
@ -167,7 +172,8 @@ public:
*/
_Linear_object_cached_2(const Ray_2& ray) :
has_source(true),
has_target(false) {
has_target(false)
{
Kernel kernel;
CGAL_assertion_msg(! kernel.is_degenerate_2_object()(ray),
@ -195,7 +201,8 @@ public:
_Linear_object_cached_2(const Line_2& ln) :
l(ln),
has_source(false),
has_target(false) {
has_target(false)
{
Kernel kernel;
CGAL_assertion_msg(! kernel.is_degenerate_2_object()(ln),
@ -219,7 +226,8 @@ public:
* \return `ARR_LEFT_BOUNDARY` if the left point is near the boundary;
* `ARR_INTERIOR` if the \f$x\f$-coordinate is finite.
*/
Arr_parameter_space left_infinite_in_x() const {
Arr_parameter_space left_infinite_in_x() const
{
if (is_vert || is_degen) return (ARR_INTERIOR);
return (is_right) ?
@ -232,7 +240,8 @@ public:
* `ARR_INTERIOR` if the \f$y\f$-coordinate is finite.
* `ARR_TOP_BOUNDARY` if the left point is at \f$y = +\infty\f$;
*/
Arr_parameter_space left_infinite_in_y() const {
Arr_parameter_space left_infinite_in_y() const
{
if (is_horiz || is_degen) return ARR_INTERIOR;
if (is_vert) {
@ -254,7 +263,8 @@ public:
/*! obtains the (lexicographically) left endpoint.
* \pre The left point is finite.
*/
const Point_2& left() const {
const Point_2& left() const
{
CGAL_precondition(has_left());
return (is_right ? ps : pt);
}
@ -264,7 +274,8 @@ public:
* \pre p lies on the supporting line to the left of the right endpoint.
*/
void set_left(const Point_2& p,
bool CGAL_assertion_code(check_validity) = true) {
bool CGAL_assertion_code(check_validity) = true)
{
CGAL_precondition(! is_degen);
CGAL_precondition_code(Kernel kernel);
@ -285,7 +296,8 @@ public:
/*! sets the (lexicographically) left endpoint as infinite.
*/
void set_left() {
void set_left()
{
CGAL_precondition(! is_degen);
if (is_right) has_source = false;
@ -296,7 +308,8 @@ public:
* \return `ARR_RIGHT_BOUNDARY` if the right point is near the boundary;
* `ARR_INTERIOR` if the \f$x\f$-coordinate is finite.
*/
Arr_parameter_space right_infinite_in_x() const {
Arr_parameter_space right_infinite_in_x() const
{
if (is_vert || is_degen) return ARR_INTERIOR;
return (is_right) ?
@ -309,7 +322,8 @@ public:
* `ARR_INTERIOR` if the \f$y\f$-coordinate is finite.
* `ARR_TOP_BOUNDARY` if the right point is at \f$y = +\infty\f$;
*/
Arr_parameter_space right_infinite_in_y() const {
Arr_parameter_space right_infinite_in_y() const
{
if (is_horiz || is_degen) return ARR_INTERIOR;
if (is_vert) {
@ -331,7 +345,8 @@ public:
/*! obtains the (lexicographically) right endpoint.
* \pre The right endpoint is finite.
*/
const Point_2& right() const {
const Point_2& right() const
{
CGAL_precondition(has_right());
return (is_right ? pt : ps);
}
@ -341,7 +356,8 @@ public:
* \pre p lies on the supporting line to the right of the left endpoint.
*/
void set_right(const Point_2& p,
bool CGAL_assertion_code(check_validity) = true) {
bool CGAL_assertion_code(check_validity) = true)
{
CGAL_precondition(! is_degen);
CGAL_precondition_code(Kernel kernel);
CGAL_precondition
@ -361,7 +377,8 @@ public:
/*! sets the (lexicographically) right endpoint as infinite.
*/
void set_right() {
void set_right()
{
CGAL_precondition(! is_degen);
if (is_right) has_target = false;
@ -370,14 +387,16 @@ public:
/*! obtains the supporting line.
*/
const Line_2& supp_line() const {
const Line_2& supp_line() const
{
CGAL_precondition(! is_degen);
return (l);
}
/*! checks whether the curve is vertical.
*/
bool is_vertical() const {
bool is_vertical() const
{
CGAL_precondition(! is_degen);
return (is_vert);
}
@ -395,7 +414,8 @@ public:
* \return (true) is in the \f$x\f$-range of the segment; (false) if it is
* not.
*/
bool is_in_x_range(const Point_2& p) const {
bool is_in_x_range(const Point_2& p) const
{
Kernel kernel;
typename Kernel_::Compare_x_2 compare_x = kernel.compare_x_2_object();
Comparison_result res1;
@ -434,7 +454,8 @@ public:
* \return (true) is in the \f$y\f$-range of the segment; (false) if it is
* not.
*/
bool is_in_y_range(const Point_2& p) const {
bool is_in_y_range(const Point_2& p) const
{
CGAL_precondition(is_vertical());
Kernel kernel;
@ -462,7 +483,8 @@ public:
private:
/*! determines if the supporting line has a positive slope.
*/
bool _has_positive_slope() const {
bool _has_positive_slope() const
{
if (is_vert) return true;
if (is_horiz) return false;
@ -476,10 +498,10 @@ public:
public:
// Traits objects
using Point_2 = typename Kernel::Point_2;
using X_monotone_curve_2 = Arr_linear_object_2<Kernel>;
using Curve_2 = Arr_linear_object_2<Kernel>;
using Multiplicity = std::size_t;
typedef typename Kernel::Point_2 Point_2;
typedef Arr_linear_object_2<Kernel> X_monotone_curve_2;
typedef Arr_linear_object_2<Kernel> Curve_2;
typedef unsigned int Multiplicity;
public:
/*! constructs default.
@ -492,7 +514,7 @@ public:
/*! A functor that compares the \f$x\f$-coordinates of two points */
class Compare_x_2 {
protected:
using Traits = Arr_linear_traits_2<Kernel>;
typedef Arr_linear_traits_2<Kernel> Traits;
/*! The traits (in case it has state) */
const Traits& m_traits;
@ -516,7 +538,8 @@ public:
* SMALLER if x(p1) < x(p2);
* EQUAL if x(p1) = x(p2).
*/
Comparison_result operator()(const Point_2& p1, const Point_2& p2) const {
Comparison_result operator()(const Point_2& p1, const Point_2& p2) const
{
const Kernel& kernel = m_traits;
return (kernel.compare_x_2_object()(p1, p2));
}
@ -544,7 +567,7 @@ public:
class Trim_2 {
protected:
using Traits = Arr_linear_traits_2<Kernel>;
typedef Arr_linear_traits_2<Kernel> Traits;
/*! The traits (in case it has state) */
const Traits& m_traits;
@ -563,8 +586,10 @@ public:
public:
X_monotone_curve_2 operator()(const X_monotone_curve_2 xcv,
const Point_2 src,
const Point_2 tgt) {
/* "Line_segment, line, and ray" will become line segments
const Point_2 tgt)
{
/*
* "Line_segment, line, and ray" will become line segments
* when trimmed.
*/
Equal_2 equal = Equal_2();
@ -594,7 +619,7 @@ public:
class Construct_opposite_2{
protected:
using Traits = Arr_linear_traits_2<Kernel>;
typedef Arr_linear_traits_2<Kernel> Traits;
/*! The traits (in case it has state) */
const Traits& m_traits;
@ -611,7 +636,8 @@ public:
friend class Arr_linear_traits_2<Kernel>;
public:
X_monotone_curve_2 operator()(const X_monotone_curve_2& xcv) const {
X_monotone_curve_2 operator()(const X_monotone_curve_2& xcv) const
{
CGAL_precondition(! xcv.is_degenerate());
X_monotone_curve_2 opp_xcv;
@ -641,7 +667,8 @@ public:
* SMALLER if x(p1) < x(p2), or if x(p1) = x(p2) and y(p1) < y(p2);
* EQUAL if the two points are equal.
*/
Comparison_result operator()(const Point_2& p1, const Point_2& p2) const {
Comparison_result operator()(const Point_2& p1, const Point_2& p2) const
{
Kernel kernel;
return (kernel.compare_xy_2_object()(p1, p2));
}
@ -658,7 +685,8 @@ public:
* \pre The left end of cv is a valid (bounded) point.
* \return The left endpoint.
*/
const Point_2& operator()(const X_monotone_curve_2& cv) const {
const Point_2& operator()(const X_monotone_curve_2& cv) const
{
CGAL_precondition(! cv.is_degenerate());
CGAL_precondition(cv.has_left());
@ -678,7 +706,8 @@ public:
* \pre The right end of cv is a valid (bounded) point.
* \return The right endpoint.
*/
const Point_2& operator()(const X_monotone_curve_2& cv) const {
const Point_2& operator()(const X_monotone_curve_2& cv) const
{
CGAL_precondition(! cv.is_degenerate());
CGAL_precondition(cv.has_right());
@ -697,7 +726,8 @@ public:
* \param cv The curve.
* \return (true) if the curve is a vertical segment; (false) otherwise.
*/
bool operator()(const X_monotone_curve_2& cv) const {
bool operator()(const X_monotone_curve_2& cv) const
{
CGAL_precondition(! cv.is_degenerate());
return (cv.is_vertical());
}
@ -711,7 +741,7 @@ public:
*/
class Compare_y_at_x_2 {
protected:
using Traits = Arr_linear_traits_2<Kernel>;
typedef Arr_linear_traits_2<Kernel> Traits;
/*! The traits (in case it has state) */
const Traits& m_traits;
@ -737,7 +767,8 @@ public:
* EQUAL if p lies on the curve.
*/
Comparison_result operator()(const Point_2& p,
const X_monotone_curve_2& cv) const {
const X_monotone_curve_2& cv) const
{
CGAL_precondition(! cv.is_degenerate());
CGAL_precondition(cv.is_in_x_range(p));
@ -778,7 +809,8 @@ public:
*/
Comparison_result operator()(const X_monotone_curve_2& cv1,
const X_monotone_curve_2& cv2,
const Point_2& CGAL_precondition_code(p)) const {
const Point_2& CGAL_precondition_code(p)) const
{
CGAL_precondition(! cv1.is_degenerate());
CGAL_precondition(! cv2.is_degenerate());
@ -829,7 +861,8 @@ public:
*/
Comparison_result operator()(const X_monotone_curve_2& cv1,
const X_monotone_curve_2& cv2,
const Point_2& CGAL_precondition_code(p)) const {
const Point_2& CGAL_precondition_code(p)) const
{
CGAL_precondition(! cv1.is_degenerate());
CGAL_precondition(! cv2.is_degenerate());
@ -873,7 +906,8 @@ public:
* \return (true) if the two curves are the same; (false) otherwise.
*/
bool operator()(const X_monotone_curve_2& cv1,
const X_monotone_curve_2& cv2) const {
const X_monotone_curve_2& cv2) const
{
CGAL_precondition(! cv1.is_degenerate());
CGAL_precondition(! cv2.is_degenerate());
@ -884,13 +918,17 @@ public:
if (! equal(cv1.supp_line(), cv2.supp_line()) &&
! equal(cv1.supp_line(),
kernel.construct_opposite_line_2_object()(cv2.supp_line())))
{
return false;
}
// Check that either the two left endpoints are at infinity, or they
// are bounded and equal.
if ((cv1.has_left() != cv2.has_left()) ||
(cv1.has_left() && ! equal(cv1.left(), cv2.left())))
{
return false;
}
// Check that either the two right endpoints are at infinity, or they
// are bounded and equal.
@ -903,7 +941,8 @@ public:
* \param p2 The second point.
* \return (true) if the two point are the same; (false) otherwise.
*/
bool operator()(const Point_2& p1, const Point_2& p2) const {
bool operator()(const Point_2& p1, const Point_2& p2) const
{
Kernel kernel;
return (kernel.equal_2_object()(p1, p2));
}
@ -934,7 +973,8 @@ public:
* the left at the line right end.
*/
Arr_parameter_space operator()(const X_monotone_curve_2 & xcv,
Arr_curve_end ce) const {
Arr_curve_end ce) const
{
CGAL_precondition(! xcv.is_degenerate());
return (ce == ARR_MIN_END) ?
xcv.left_infinite_in_x() : xcv.right_infinite_in_x();
@ -975,7 +1015,8 @@ public:
* right end.
*/
Arr_parameter_space operator()(const X_monotone_curve_2 & xcv,
Arr_curve_end ce) const {
Arr_curve_end ce) const
{
CGAL_precondition(! xcv.is_degenerate());
return (ce == ARR_MIN_END) ?
@ -999,7 +1040,7 @@ public:
*/
class Compare_x_on_boundary_2 {
protected:
using Traits = Arr_linear_traits_2<Kernel>;
typedef Arr_linear_traits_2<Kernel> Traits;
/*! The traits (in case it has state) */
const Traits& m_traits;
@ -1033,7 +1074,8 @@ public:
*/
Comparison_result operator()(const Point_2 & p,
const X_monotone_curve_2 & xcv,
Arr_curve_end ) const {
Arr_curve_end ) const
{
CGAL_precondition(! xcv.is_degenerate());
CGAL_precondition(xcv.is_vertical());
@ -1063,7 +1105,8 @@ public:
Comparison_result operator()(const X_monotone_curve_2 & xcv1,
Arr_curve_end /* ce1 */,
const X_monotone_curve_2 & xcv2,
Arr_curve_end /* ce2 */) const {
Arr_curve_end /* ce2 */) const
{
CGAL_precondition(! xcv1.is_degenerate());
CGAL_precondition(! xcv2.is_degenerate());
CGAL_precondition(xcv1.is_vertical());
@ -1109,7 +1152,8 @@ public:
Comparison_result
operator()(const X_monotone_curve_2& CGAL_precondition_code(xcv1),
const X_monotone_curve_2& CGAL_precondition_code(xcv2),
Arr_curve_end /* ce2 */) const {
Arr_curve_end /* ce2 */) const
{
CGAL_precondition(! xcv1.is_degenerate());
CGAL_precondition(! xcv2.is_degenerate());
CGAL_precondition(xcv1.is_vertical());
@ -1127,7 +1171,7 @@ public:
*/
class Compare_y_near_boundary_2 {
protected:
using Traits = Arr_linear_traits_2<Kernel>;
typedef Arr_linear_traits_2<Kernel> Traits;
/*! The traits (in case it has state) */
const Traits& m_traits;
@ -1155,7 +1199,8 @@ public:
*/
Comparison_result operator()(const X_monotone_curve_2 & xcv1,
const X_monotone_curve_2 & xcv2,
Arr_curve_end ce) const {
Arr_curve_end ce) const
{
// Make sure both curves are defined at \f$x = -\infty\f$ (or at
// \f$x = +\infty\f$).
CGAL_precondition(! xcv1.is_degenerate());
@ -1207,9 +1252,11 @@ public:
* \return The past-the-end iterator.
*/
template <typename OutputIterator>
OutputIterator operator()(const Curve_2& cv, OutputIterator oi) const {
OutputIterator operator()(const Curve_2& cv, OutputIterator oi) const
{
// Wrap the segment with a variant.
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(cv);
return oi;
}
@ -1230,7 +1277,8 @@ public:
* \pre `p` lies on `cv` but is not one of its end-points.
*/
void operator()(const X_monotone_curve_2& cv, const Point_2& p,
X_monotone_curve_2& c1, X_monotone_curve_2& c2) const {
X_monotone_curve_2& c1, X_monotone_curve_2& c2) const
{
CGAL_precondition(! cv.is_degenerate());
// Make sure that p lies on the interior of the curve.
@ -1258,7 +1306,7 @@ public:
class Intersect_2 {
protected:
using Traits = Arr_linear_traits_2<Kernel>;
typedef Arr_linear_traits_2<Kernel> Traits;
/*! The traits (in case it has state) */
const Traits& m_traits;
@ -1282,8 +1330,9 @@ public:
template <typename OutputIterator>
OutputIterator operator()(const X_monotone_curve_2& cv1,
const X_monotone_curve_2& cv2,
OutputIterator oi) const {
using Intersection_point = std::pair<Point_2, Multiplicity>;
OutputIterator oi) const
{
typedef std::pair<Point_2, Multiplicity> Intersection_point;
CGAL_precondition(! cv1.is_degenerate());
CGAL_precondition(! cv2.is_degenerate());
@ -1380,7 +1429,8 @@ public:
* by the same line and share a common endpoint; (false) otherwise.
*/
bool operator()(const X_monotone_curve_2& cv1,
const X_monotone_curve_2& cv2) const {
const X_monotone_curve_2& cv2) const
{
CGAL_precondition(! cv1.is_degenerate());
CGAL_precondition(! cv2.is_degenerate());
@ -1410,7 +1460,7 @@ public:
*/
class Merge_2 {
protected:
using Traits = Arr_linear_traits_2<Kernel>;
typedef Arr_linear_traits_2<Kernel> Traits;
/*! The traits (in case it has state) */
const Traits& m_traits;
@ -1431,7 +1481,8 @@ public:
*/
void operator()(const X_monotone_curve_2& cv1,
const X_monotone_curve_2& cv2,
X_monotone_curve_2& c) const {
X_monotone_curve_2& c) const
{
CGAL_precondition(m_traits.are_mergeable_2_object()(cv2, cv1));
CGAL_precondition(!cv1.is_degenerate());
@ -1441,7 +1492,8 @@ public:
// Check which curve extends to the right of the other.
if (cv1.has_right() && cv2.has_left() &&
equal(cv1.right(), cv2.left())) {
equal(cv1.right(), cv2.left()))
{
// cv2 extends cv1 to the right.
c = cv1;
@ -1467,9 +1519,9 @@ public:
/// \name Functor definitions for the landmarks point-location strategy.
//@{
using Approximate_number_type = double;
using Approximate_kernel = CGAL::Simple_cartesian<Approximate_number_type>;
using Approximate_point_2 = Approximate_kernel::Point_2;
typedef double Approximate_number_type;
typedef CGAL::Cartesian<Approximate_number_type> Approximate_kernel;
typedef Approximate_kernel::Point_2 Approximate_point_2;
class Approximate_2 {
protected:
@ -1493,7 +1545,8 @@ public:
* \return An approximation of `p`'s \f$x\f$-coordinate (if `i` == 0), or an
* approximation of `p`'s \f$y\f$-coordinate (if `i` == 1).
*/
Approximate_number_type operator()(const Point_2& p, int i) const {
Approximate_number_type operator()(const Point_2& p, int i) const
{
CGAL_precondition((i == 0) || (i == 1));
return (i == 0) ? CGAL::to_double(p.x()) : CGAL::to_double(p.y());
}
@ -1513,8 +1566,12 @@ public:
auto max_vertex = m_traits.construct_max_vertex_2_object();
const auto& src = (l2r) ? min_vertex(xcv) : max_vertex(xcv);
const auto& trg = (l2r) ? max_vertex(xcv) : min_vertex(xcv);
*oi++ = operator()(src);
*oi++ = operator()(trg);
auto xs = CGAL::to_double(src.x());
auto ys = CGAL::to_double(src.y());
auto xt = CGAL::to_double(trg.x());
auto yt = CGAL::to_double(trg.y());
*oi++ = Approximate_point_2(xs, ys);
*oi++ = Approximate_point_2(xt, yt);
return oi;
}
@ -1523,7 +1580,8 @@ public:
template <typename OutputIterator>
OutputIterator operator()(const X_monotone_curve_2& xcv, double /* error */,
OutputIterator oi, const Bbox_2& bbox,
bool l2r = true) const {
bool l2r = true) const
{
using Approx_pnt = Approximate_point_2;
using Approx_seg = Approximate_kernel::Segment_2;
using Approx_ray = Approximate_kernel::Ray_2;
@ -1599,7 +1657,8 @@ public:
* \pre p and q must not be the same.
* \return A segment connecting `p` and `q`.
*/
X_monotone_curve_2 operator()(const Point_2& p, const Point_2& q) const {
X_monotone_curve_2 operator()(const Point_2& p, const Point_2& q) const
{
Kernel kernel;
Segment_2 seg = kernel.construct_segment_2_object()(p, q);
@ -1616,7 +1675,7 @@ public:
//@{
//! Functor
using Construct_curve_2 = Construct_x_monotone_curve_2;
typedef Construct_x_monotone_curve_2 Construct_curve_2;
/*! obtains a `Construct_curve_2` functor object. */
Construct_curve_2 construct_curve_2_object() const
@ -1629,16 +1688,18 @@ public:
*/
template <typename Kernel_>
class Arr_linear_object_2 :
public Arr_linear_traits_2<Kernel_>::_Linear_object_cached_2 {
using Base = typename Arr_linear_traits_2<Kernel_>::_Linear_object_cached_2;
public Arr_linear_traits_2<Kernel_>::_Linear_object_cached_2
{
typedef typename Arr_linear_traits_2<Kernel_>::_Linear_object_cached_2
Base;
public:
using Kernel = Kernel_;
typedef Kernel_ Kernel;
using Point_2 = typename Kernel::Point_2;
using Segment_2 = typename Kernel::Segment_2;
using Ray_2 = typename Kernel::Ray_2;
using Line_2 = typename Kernel::Line_2;
typedef typename Kernel::Point_2 Point_2;
typedef typename Kernel::Segment_2 Segment_2;
typedef typename Kernel::Ray_2 Ray_2;
typedef typename Kernel::Line_2 Line_2;
public:
/*! constructs default.
@ -1678,7 +1739,8 @@ public:
/*! casts to a segment.
* \pre The linear object is really a segment.
*/
Segment_2 segment() const {
Segment_2 segment() const
{
CGAL_precondition(is_segment());
Kernel kernel;
@ -1694,7 +1756,8 @@ public:
/*! casts to a ray.
* \pre The linear object is really a ray.
*/
Ray_2 ray() const {
Ray_2 ray() const
{
CGAL_precondition(is_ray());
Kernel kernel;
@ -1713,7 +1776,8 @@ public:
/*! casts to a line.
* \pre The linear object is really a line.
*/
Line_2 line() const {
Line_2 line() const
{
CGAL_precondition(is_line());
return (this->l);
}
@ -1721,7 +1785,8 @@ public:
/*! obtains the supporting line.
* \pre The object is not a point.
*/
const Line_2& supporting_line() const {
const Line_2& supporting_line() const
{
CGAL_precondition(! this->is_degen);
return (this->l);
}
@ -1729,7 +1794,8 @@ public:
/*! obtains the source point.
* \pre The object is a point, a segment or a ray.
*/
const Point_2& source() const {
const Point_2& source() const
{
CGAL_precondition(! is_line());
if (this->is_degen) return (this->ps); // For a point.
@ -1740,14 +1806,16 @@ public:
/*! obtains the target point.
* \pre The object is a point or a segment.
*/
const Point_2& target() const {
const Point_2& target() const
{
CGAL_precondition(! is_line() && ! is_ray());
return (this->pt);
}
/*! creates a bounding box for the linear object.
*/
Bbox_2 bbox() const {
Bbox_2 bbox() const
{
CGAL_precondition(this->is_segment());
Kernel kernel;
Segment_2 seg = kernel.construct_segment_2_object()(this->ps, this->pt);
@ -1766,7 +1834,8 @@ public:
*/
template <typename Kernel, typename OutputStream>
OutputStream& operator<<(OutputStream& os,
const Arr_linear_object_2<Kernel>& lobj) {
const Arr_linear_object_2<Kernel>& lobj)
{
// Print a letter identifying the object type, then the object itself.
if (lobj.is_segment()) os << " S " << lobj.segment();
else if (lobj.is_ray()) os << " R " << lobj.ray();
@ -1777,7 +1846,8 @@ OutputStream& operator<<(OutputStream& os,
/*! Importer for the segment class used by the traits-class.
*/
template <typename Kernel, typename InputStream>
InputStream& operator>>(InputStream& is, Arr_linear_object_2<Kernel>& lobj) {
InputStream& operator>>(InputStream& is, Arr_linear_object_2<Kernel>& lobj)
{
// Read the object type.
char c;
do {

View File

@ -30,7 +30,7 @@
* functors required by the concept it models.
*/
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Cartesian.h>
#include <CGAL/Algebraic_structure_traits.h>
#include <CGAL/number_utils.h>
#include <CGAL/tags.h>
@ -44,28 +44,34 @@ namespace CGAL {
* A model of the AosBasicTraits_2 concept that handles \f$x\f$-monotone
* non-intersecting line segments.
*/
template <typename T_Kernel>
class Arr_non_caching_segment_basic_traits_2 : public T_Kernel {
template <class T_Kernel>
class Arr_non_caching_segment_basic_traits_2 : public T_Kernel
{
public:
using Kernel = T_Kernel;
using FT = typename Kernel::FT;
typedef T_Kernel Kernel;
typedef typename Kernel::FT FT;
private:
using AST = Algebraic_structure_traits<FT>;
using FT_is_exact = typename AST::Is_exact;
typedef Algebraic_structure_traits<FT> AST;
typedef typename AST::Is_exact FT_is_exact;
public:
using Has_exact_division = Boolean_tag<FT_is_exact::value>;
using Segment_assertions = CGAL::Segment_assertions<Arr_non_caching_segment_basic_traits_2<Kernel>>;
typedef Boolean_tag<FT_is_exact::value> Has_exact_division;
typedef
CGAL::Segment_assertions<Arr_non_caching_segment_basic_traits_2<Kernel> >
Segment_assertions;
// Categories:
using Has_left_category = Tag_true;
using Has_do_intersect_category = Tag_false;
typedef Tag_true Has_left_category;
typedef Tag_false Has_do_intersect_category;
using Left_side_category = Arr_oblivious_side_tag;
using Bottom_side_category = Arr_oblivious_side_tag;
using Top_side_category = Arr_oblivious_side_tag;
using Right_side_category = Arr_oblivious_side_tag;
typedef Arr_oblivious_side_tag Left_side_category;
typedef Arr_oblivious_side_tag Bottom_side_category;
typedef Arr_oblivious_side_tag Top_side_category;
typedef Arr_oblivious_side_tag Right_side_category;
/*! constructs default */
Arr_non_caching_segment_basic_traits_2() {}
@ -74,30 +80,30 @@ public:
//@{
// Traits types:
using Point_2 = typename Kernel::Point_2;
using X_monotone_curve_2 = typename Kernel::Segment_2;
using Multiplicity = std::size_t;
typedef typename Kernel::Point_2 Point_2;
typedef typename Kernel::Segment_2 X_monotone_curve_2;
typedef unsigned int Multiplicity;
/*! compares the \f$x\f$-coordinates of two points. */
using Compare_x_2 = typename Kernel::Compare_x_2;
/*! Compare the \f$x\f$-coordinates of two points. */
typedef typename Kernel::Compare_x_2 Compare_x_2;
/*! compares two points lexigoraphically; by \f$x\f$, then by \f$y\f$. */
using Compare_xy_2 = typename Kernel::Compare_xy_2;
/*! Compare two points lexigoraphically; by \f$x\f$, then by \f$y\f$. */
typedef typename Kernel::Compare_xy_2 Compare_xy_2;
/*! obtains the left endpoint of a given segment. */
using Construct_min_vertex_2 = typename Kernel::Construct_min_vertex_2;
/*! Obtain the left endpoint of a given segment. */
typedef typename Kernel::Construct_min_vertex_2 Construct_min_vertex_2;
/*! obtains the right endpoint of a given segment. */
using Construct_max_vertex_2 = typename Kernel::Construct_max_vertex_2;
/*! Obtain the right endpoint of a given segment. */
typedef typename Kernel::Construct_max_vertex_2 Construct_max_vertex_2;
/*! checks whether a given segment is vertical. */
using Is_vertical_2 = typename Kernel::Is_vertical_2;
/*! Check whether a given segment is vertical. */
typedef typename Kernel::Is_vertical_2 Is_vertical_2;
/*! returns the location of a given point with respect to an input segment. */
using Compare_y_at_x_2 = typename Kernel::Compare_y_at_x_2;
/*! Return the location of a given point with respect to an input segment. */
typedef typename Kernel::Compare_y_at_x_2 Compare_y_at_x_2;
/*! checks if two segments or if two points are identical. */
using Equal_2 = typename Kernel::Equal_2;
/*! Check if two segments or if two points are identical. */
typedef typename Kernel::Equal_2 Equal_2;
//@}
@ -121,7 +127,8 @@ public:
*/
Comparison_result operator()(const X_monotone_curve_2& cv1,
const X_monotone_curve_2& cv2,
const Point_2& CGAL_precondition_code(p)) const {
const Point_2& CGAL_precondition_code(p)) const
{
Kernel kernel;
// The two segments must be defined at q and also to its left.
@ -133,13 +140,13 @@ public:
Compare_xy_2 compare_xy = kernel.compare_xy_2_object();
typename Kernel::Construct_vertex_2 construct_vertex =
kernel.construct_vertex_2_object();
const Point_2& source1 = construct_vertex(cv1, 0);
const Point_2& target1 = construct_vertex(cv1, 1);
const Point_2& left1 =
const Point_2 & source1 = construct_vertex(cv1, 0);
const Point_2 & target1 = construct_vertex(cv1, 1);
const Point_2 & left1 =
(kernel.less_xy_2_object()(source1, target1)) ? source1 : target1;
const Point_2& source2 = construct_vertex(cv2, 0);
const Point_2& target2 = construct_vertex(cv2, 1);
const Point_2& left2 =
const Point_2 & source2 = construct_vertex(cv2, 0);
const Point_2 & target2 = construct_vertex(cv2, 1);
const Point_2 & left2 =
(kernel.less_xy_2_object()(source2, target2)) ? source2 : target2;
);
@ -174,9 +181,10 @@ public:
* to the right of `p`: `SMALLER`, `LARGER`, or `EQUAL`.
*/
Comparison_result operator()(const X_monotone_curve_2& cv1,
const X_monotone_curve_2& cv2,
const Point_2& CGAL_precondition_code(p)) const {
Comparison_result operator()(const X_monotone_curve_2 & cv1,
const X_monotone_curve_2 & cv2,
const Point_2 & CGAL_precondition_code(p)) const
{
Kernel kernel;
// The two segments must be defined at q and also to its right.
@ -188,13 +196,13 @@ public:
Compare_xy_2 compare_xy = kernel.compare_xy_2_object();
typename Kernel::Construct_vertex_2 construct_vertex =
kernel.construct_vertex_2_object();
const Point_2& source1 = construct_vertex(cv1, 0);
const Point_2& target1 = construct_vertex(cv1, 1);
const Point_2& right1 =
const Point_2 & source1 = construct_vertex(cv1, 0);
const Point_2 & target1 = construct_vertex(cv1, 1);
const Point_2 & right1 =
(kernel.less_xy_2_object()(source1, target1)) ? target1 : source1;
const Point_2& source2 = construct_vertex(cv2, 0);
const Point_2& target2 = construct_vertex(cv2, 1);
const Point_2& right2 =
const Point_2 & source2 = construct_vertex(cv2, 0);
const Point_2 & target2 = construct_vertex(cv2, 1);
const Point_2 & right2 =
(kernel.less_xy_2_object()(source2, target2)) ? target2 : source2;
);
@ -214,9 +222,9 @@ public:
/// \name Functor definitions for the landmarks point-location strategy.
//@{
using Approximate_number_type = double;
using Approximate_kernel = CGAL::Simple_cartesian<Approximate_number_type>;
using Approximate_point_2 = Approximate_kernel::Point_2;
typedef double Approximate_number_type;
typedef CGAL::Cartesian<Approximate_number_type> Approximate_kernel;
typedef Approximate_kernel::Point_2 Approximate_point_2;
class Approximate_2 {
protected:
@ -259,8 +267,12 @@ public:
auto max_vertex = m_traits.construct_max_vertex_2_object();
const auto& src = (l2r) ? min_vertex(xcv) : max_vertex(xcv);
const auto& trg = (l2r) ? max_vertex(xcv) : min_vertex(xcv);
*oi++ = operator()(src);
*oi++ = operator()(trg);
auto xs = CGAL::to_double(src.x());
auto ys = CGAL::to_double(src.y());
auto xt = CGAL::to_double(trg.x());
auto yt = CGAL::to_double(trg.y());
*oi++ = Approximate_point_2(xs, ys);
*oi++ = Approximate_point_2(xt, yt);
return oi;
}
};
@ -268,7 +280,7 @@ public:
/*! obtains an Approximate_2 functor object. */
Approximate_2 approximate_2_object () const { return Approximate_2(*this); }
using Construct_x_monotone_curve_2 = typename Kernel::Construct_segment_2;
typedef typename Kernel::Construct_segment_2 Construct_x_monotone_curve_2;
/*! obtains a `Construct_x_monotone_curve_2` functor object. */
Construct_x_monotone_curve_2 construct_x_monotone_curve_2_object () const

View File

@ -28,7 +28,7 @@
#include <variant>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Cartesian.h>
#include <CGAL/tags.h>
#include <CGAL/intersections.h>
#include <CGAL/Arr_tags.h>
@ -52,32 +52,35 @@ class Arr_segment_2;
template <typename Kernel_ = Exact_predicates_exact_constructions_kernel>
class Arr_segment_traits_2 : public Kernel_ {
friend class Arr_segment_2<Kernel_>;
public:
using Kernel = Kernel_;
using FT = typename Kernel::FT;
using Has_exact_division = typename Algebraic_structure_traits<FT>::Is_exact;
public:
typedef Kernel_ Kernel;
typedef typename Kernel::FT FT;
typedef typename Algebraic_structure_traits<FT>::Is_exact
Has_exact_division;
// Category tags:
using Has_left_category = Tag_true;
using Has_merge_category = Tag_true;
using Has_do_intersect_category = Tag_false;
typedef Tag_true Has_left_category;
typedef Tag_true Has_merge_category;
typedef Tag_false Has_do_intersect_category;
using Left_side_category = Arr_oblivious_side_tag;
using Bottom_side_category = Arr_oblivious_side_tag;
using Top_side_category = Arr_oblivious_side_tag;
using Right_side_category = Arr_oblivious_side_tag;
typedef Arr_oblivious_side_tag Left_side_category;
typedef Arr_oblivious_side_tag Bottom_side_category;
typedef Arr_oblivious_side_tag Top_side_category;
typedef Arr_oblivious_side_tag Right_side_category;
using Line_2 = typename Kernel::Line_2;
using Segment_assertions = CGAL::Segment_assertions<Arr_segment_traits_2<Kernel>>;
typedef typename Kernel::Line_2 Line_2;
typedef CGAL::Segment_assertions<Arr_segment_traits_2<Kernel> >
Segment_assertions;
/*! \class Representation of a segment with cached data.
*/
class _Segment_cached_2 {
public:
using Line_2 = typename Kernel::Line_2;
using Segment_2 = typename Kernel::Segment_2;
using Point_2 = typename Kernel::Point_2;
typedef typename Kernel::Line_2 Line_2;
typedef typename Kernel::Segment_2 Segment_2;
typedef typename Kernel::Point_2 Point_2;
protected:
mutable Line_2 m_l; // the line that supports the segment.
@ -225,10 +228,10 @@ public:
public:
// Traits objects
using Point_2 = typename Kernel::Point_2;
using X_monotone_curve_2 = Arr_segment_2<Kernel>;
using Curve_2 = Arr_segment_2<Kernel>;
using Multiplicity = std::size_t;
typedef typename Kernel::Point_2 Point_2;
typedef Arr_segment_2<Kernel> X_monotone_curve_2;
typedef Arr_segment_2<Kernel> Curve_2;
typedef unsigned int Multiplicity;
public:
/*! constructs default. */
@ -239,7 +242,7 @@ public:
class Compare_x_2 {
protected:
using Traits = Arr_segment_traits_2<Kernel>;
typedef Arr_segment_traits_2<Kernel> Traits;
//! The traits (in case it has state).
const Traits& m_traits;
@ -259,7 +262,8 @@ public:
* `SMALLER` if x(p1) < x(p2);
* `EQUAL` if x(p1) = x(p2).
*/
Comparison_result operator()(const Point_2& p1, const Point_2& p2) const {
Comparison_result operator()(const Point_2& p1, const Point_2& p2) const
{
const Kernel& kernel = m_traits;
return (kernel.compare_x_2_object()(p1, p2));
}
@ -270,7 +274,7 @@ public:
class Compare_xy_2 {
protected:
using Traits = Arr_segment_traits_2<Kernel>;
typedef Arr_segment_traits_2<Kernel> Traits;
/*! The traits (in case it has state) */
const Traits& m_traits;
@ -290,7 +294,8 @@ public:
* SMALLER if x(p1) < x(p2), or if x(p1) = x(p2) and y(p1) < y(p2);
* EQUAL if the two points are equal.
*/
Comparison_result operator()(const Point_2& p1, const Point_2& p2) const {
Comparison_result operator()(const Point_2& p1, const Point_2& p2) const
{
const Kernel& kernel = m_traits;
return (kernel.compare_xy_2_object()(p1, p2));
}
@ -342,7 +347,7 @@ public:
class Compare_y_at_x_2 {
protected:
using Traits = Arr_segment_traits_2<Kernel>;
typedef Arr_segment_traits_2<Kernel> Traits;
/*! The traits (in case it has state) */
const Traits& m_traits;
@ -364,7 +369,8 @@ public:
* `EQUAL` if `p` lies on the curve.
*/
Comparison_result operator()(const Point_2& p,
const X_monotone_curve_2& cv) const {
const X_monotone_curve_2& cv) const
{
CGAL_precondition(m_traits.is_in_x_range_2_object()(cv, p));
const Kernel& kernel = m_traits;
@ -390,7 +396,7 @@ public:
class Compare_y_at_x_left_2 {
protected:
using Traits = Arr_segment_traits_2<Kernel>;
typedef Arr_segment_traits_2<Kernel> Traits;
/*! The traits (in case it has state) */
const Traits& m_traits;
@ -415,7 +421,8 @@ public:
*/
Comparison_result operator()(const X_monotone_curve_2& cv1,
const X_monotone_curve_2& cv2,
const Point_2& CGAL_assertion_code(p)) const {
const Point_2& CGAL_assertion_code(p)) const
{
const Kernel& kernel = m_traits;
// Make sure that p lies on both curves, and that both are defined to its
@ -443,7 +450,7 @@ public:
class Compare_y_at_x_right_2 {
protected:
using Traits = Arr_segment_traits_2<Kernel>;
typedef Arr_segment_traits_2<Kernel> Traits;
/*! The traits (in case it has state) */
const Traits& m_traits;
@ -468,7 +475,8 @@ public:
*/
Comparison_result operator()(const X_monotone_curve_2& cv1,
const X_monotone_curve_2& cv2,
const Point_2& CGAL_assertion_code(p)) const {
const Point_2& CGAL_assertion_code(p)) const
{
const Kernel& kernel = m_traits;
// Make sure that p lies on both curves, and that both are defined to its
@ -494,7 +502,7 @@ public:
class Equal_2 {
protected:
using Traits = Arr_segment_traits_2<Kernel>;
typedef Arr_segment_traits_2<Kernel> Traits;
/*! The traits (in case it has state) */
const Traits& m_traits;
@ -514,7 +522,8 @@ public:
* \return (true) if the two curves are the same; (false) otherwise.
*/
bool operator()(const X_monotone_curve_2& cv1,
const X_monotone_curve_2& cv2) const {
const X_monotone_curve_2& cv2) const
{
const Kernel& kernel = m_traits;
typename Kernel::Equal_2 equal = kernel.equal_2_object();
@ -527,7 +536,8 @@ public:
* \param p2 the second point.
* \return (true) if the two point are the same; (false) otherwise.
*/
bool operator()(const Point_2& p1, const Point_2& p2) const {
bool operator()(const Point_2& p1, const Point_2& p2) const
{
const Kernel& kernel = m_traits;
return (kernel.equal_2_object()(p1, p2));
}
@ -556,9 +566,11 @@ public:
* \return the past-the-end output iterator.
*/
template <typename OutputIterator>
OutputIterator operator()(const Curve_2& cv, OutputIterator oi) const {
OutputIterator operator()(const Curve_2& cv, OutputIterator oi) const
{
// Wrap the segment with a variant.
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(cv);
return oi;
}
@ -570,7 +582,7 @@ public:
class Split_2 {
protected:
using Traits = Arr_segment_traits_2<Kernel>;
typedef Arr_segment_traits_2<Kernel> Traits;
/*! The traits (in case it has state) */
const Traits& m_traits;
@ -583,7 +595,7 @@ public:
friend class Arr_segment_traits_2<Kernel>;
public:
/*! splits a given \f$x\f$-monotone curve at a given point into two
/*! split a given \f$x\f$-monotone curve at a given point into two
* sub-curves.
* \param cv the curve to split
* \param p the split point.
@ -592,7 +604,8 @@ public:
* \pre `p` lies on cv but is not one of its endpoints.
*/
void operator()(const X_monotone_curve_2& cv, const Point_2& p,
X_monotone_curve_2& c1, X_monotone_curve_2& c2) const {
X_monotone_curve_2& c1, X_monotone_curve_2& c2) const
{
// Make sure that p lies on the interior of the curve.
CGAL_precondition_code(const Kernel& kernel = m_traits;
auto compare_xy = kernel.compare_xy_2_object());
@ -615,7 +628,7 @@ public:
class Intersect_2 {
protected:
using Traits = Arr_segment_traits_2<Kernel>;
typedef Arr_segment_traits_2<Kernel> Traits;
/*! The traits (in case it has state) */
const Traits& m_traits;
@ -631,7 +644,8 @@ public:
// this point, we already know which point is left / right for
// both segments
bool do_intersect(const Point_2& A1, const Point_2& A2,
const Point_2& B1, const Point_2& B2) const {
const Point_2& B1, const Point_2& B2) const
{
const Kernel& kernel = m_traits;
auto compare_xy = kernel.compare_xy_2_object();
namespace interx = CGAL::Intersections::internal;
@ -672,7 +686,8 @@ public:
/*! determines whether the bounding boxes of two segments overlap
*/
bool do_bboxes_overlap(const X_monotone_curve_2& cv1,
const X_monotone_curve_2& cv2) const {
const X_monotone_curve_2& cv2) const
{
const Kernel& kernel = m_traits;
auto construct_bbox = kernel.construct_bbox_2_object();
auto bbox1 = construct_bbox(cv1.source()) + construct_bbox(cv1.target());
@ -692,8 +707,9 @@ public:
template <typename OutputIterator>
OutputIterator operator()(const X_monotone_curve_2& cv1,
const X_monotone_curve_2& cv2,
OutputIterator oi) const {
using Intersection_point = std::pair<Point_2, Multiplicity>;
OutputIterator oi) const
{
typedef std::pair<Point_2, Multiplicity> Intersection_point;
// Early ending with Bbox overlapping test
if (! do_bboxes_overlap(cv1, cv2)) return oi;
@ -771,7 +787,7 @@ public:
class Are_mergeable_2 {
protected:
using Traits = Arr_segment_traits_2<Kernel>;
typedef Arr_segment_traits_2<Kernel> Traits;
/*! The traits (in case it has state) */
const Traits& m_traits;
@ -792,7 +808,8 @@ public:
* \pre `cv1` and `cv2` share a common endpoint.
*/
bool operator()(const X_monotone_curve_2& cv1,
const X_monotone_curve_2& cv2) const {
const X_monotone_curve_2& cv2) const
{
const Kernel& kernel = m_traits;
typename Kernel::Equal_2 equal = kernel.equal_2_object();
if (! equal(cv1.right(), cv2.left()) &&
@ -815,7 +832,7 @@ public:
*/
class Merge_2 {
protected:
using Traits = Arr_segment_traits_2<Kernel>;
typedef Arr_segment_traits_2<Kernel> Traits;
/*! The traits (in case it has state) */
const Traits& m_traits;
@ -836,13 +853,14 @@ public:
*/
void operator()(const X_monotone_curve_2& cv1,
const X_monotone_curve_2& cv2,
X_monotone_curve_2& c) const {
X_monotone_curve_2& c) const
{
CGAL_precondition(m_traits.are_mergeable_2_object()(cv1, cv2));
const Kernel& kernel = m_traits;
auto equal = kernel.equal_2_object();
// checks which curve extends to the right of the other.
// Check which curve extends to the right of the other.
if (equal(cv1.right(), cv2.left())) {
// cv2 extends cv1 to the right.
c = cv1;
@ -864,9 +882,9 @@ public:
/// \name Functor definitions for the landmarks point-location strategy.
//@{
using Approximate_number_type = double;
using Approximate_kernel = CGAL::Simple_cartesian<Approximate_number_type>;
using Approximate_point_2 = Approximate_kernel::Point_2;
typedef double Approximate_number_type;
typedef CGAL::Cartesian<Approximate_number_type> Approximate_kernel;
typedef Approximate_kernel::Point_2 Approximate_point_2;
class Approximate_2 {
protected:
@ -909,8 +927,12 @@ public:
auto max_vertex = m_traits.construct_max_vertex_2_object();
const auto& src = (l2r) ? min_vertex(xcv) : max_vertex(xcv);
const auto& trg = (l2r) ? max_vertex(xcv) : min_vertex(xcv);
*oi++ = operator()(src);
*oi++ = operator()(trg);
auto xs = CGAL::to_double(src.x());
auto ys = CGAL::to_double(src.y());
auto xt = CGAL::to_double(trg.x());
auto yt = CGAL::to_double(trg.y());
*oi++ = Approximate_point_2(xs, ys);
*oi++ = Approximate_point_2(xt, yt);
return oi;
}
};
@ -921,7 +943,7 @@ public:
//! Functor
class Construct_x_monotone_curve_2 {
protected:
using Traits = Arr_segment_traits_2<Kernel>;
typedef Arr_segment_traits_2<Kernel> Traits;
//! The traits (in case it has state).
const Traits& m_traits;
@ -934,7 +956,7 @@ public:
friend class Arr_segment_traits_2<Kernel>;
public:
using Segment_2 = typename Kernel::Segment_2;
typedef typename Kernel::Segment_2 Segment_2;
/*! obtains an \f$x\f$-monotone curve connecting two given endpoints.
* \param source the first point.
@ -943,7 +965,8 @@ public:
* \return a segment connecting `source` and `target`.
*/
X_monotone_curve_2 operator()(const Point_2& source,
const Point_2& target) const {
const Point_2& target) const
{
const Kernel& kernel = m_traits;
auto line = kernel.construct_line_2_object()(source, target);
Comparison_result res = kernel.compare_xy_2_object()(source, target);
@ -962,7 +985,8 @@ public:
* \pre the segment is not degenerate.
* \return a segment that is the same as `seg`..
*/
X_monotone_curve_2 operator()(const Segment_2& seg) const {
X_monotone_curve_2 operator()(const Segment_2& seg) const
{
const Kernel& kernel = m_traits;
auto line = kernel.construct_line_2_object()(seg);
auto vertex_ctr = kernel.construct_vertex_2_object();
@ -987,7 +1011,8 @@ public:
*/
X_monotone_curve_2 operator()(const Line_2& line,
const Point_2& source,
const Point_2& target) const {
const Point_2& target) const
{
const Kernel& kernel = m_traits;
CGAL_precondition
(Segment_assertions::_assert_is_point_on(source, line,
@ -1014,7 +1039,7 @@ public:
//@{
//! Functor
using Construct_curve_2 = Construct_x_monotone_curve_2;
typedef Construct_x_monotone_curve_2 Construct_curve_2;
/*! obtains a `Construct_curve_2` functor object. */
Construct_curve_2 construct_curve_2_object() const
@ -1026,7 +1051,7 @@ public:
class Trim_2 {
protected:
using Traits = Arr_segment_traits_2<Kernel>;
typedef Arr_segment_traits_2<Kernel> Traits;
/*! The traits (in case it has state). */
const Traits& m_traits;
@ -1049,7 +1074,8 @@ public:
public:
X_monotone_curve_2 operator()(const X_monotone_curve_2& xcv,
const Point_2& src,
const Point_2& tgt) const {
const Point_2& tgt)const
{
CGAL_precondition_code(Equal_2 equal = m_traits.equal_2_object());
CGAL_precondition_code(Compare_y_at_x_2 compare_y_at_x =
m_traits.compare_y_at_x_2_object());
@ -1093,7 +1119,7 @@ public:
class Construct_opposite_2 {
public:
/*! constructs an opposite \f$x\f$-monotone (with swapped source and target).
/*! Construct an opposite \f$x\f$-monotone (with swapped source and target).
* \param cv the curve.
* \return the opposite curve.
*/
@ -1111,12 +1137,12 @@ public:
class Is_in_x_range_2 {
protected:
using Traits = Arr_segment_traits_2<Kernel>;
typedef Arr_segment_traits_2<Kernel> Traits;
//! The traits (in case it has state).
const Traits& m_traits;
/*! constructs
/*! Construct
* \param traits the traits (in case it has state)
*/
Is_in_x_range_2(const Traits& traits) : m_traits(traits) {}
@ -1130,7 +1156,8 @@ public:
* \param p the point.
* \return true if p is in the \f$x\f$-range of cv; false otherwise.
*/
bool operator()(const X_monotone_curve_2& cv, const Point_2& p) const {
bool operator()(const X_monotone_curve_2& cv, const Point_2& p) const
{
const Kernel& kernel = m_traits;
auto compare_x = kernel.compare_x_2_object();
Comparison_result res1 = compare_x(p, cv.left());
@ -1149,7 +1176,7 @@ public:
class Is_in_y_range_2 {
protected:
using Traits = Arr_segment_traits_2<Kernel>;
typedef Arr_segment_traits_2<Kernel> Traits;
//! The traits (in case it has state).
const Traits& m_traits;
@ -1168,7 +1195,8 @@ public:
* \param p the point.
* \return true if p is in the \f$y\f$-range of cv; false otherwise.
*/
bool operator()(const X_monotone_curve_2& cv, const Point_2& p) const {
bool operator()(const X_monotone_curve_2& cv, const Point_2& p) const
{
const Kernel& kernel = m_traits;
auto compare_y = kernel.compare_y_2_object();
Comparison_result res1 = compare_y(p, cv.left());
@ -1204,7 +1232,8 @@ template <typename Kernel>
Arr_segment_traits_2<Kernel>::
_Segment_cached_2::_Segment_cached_2(const Segment_2& seg) :
m_is_vert(false),
m_is_computed(false) {
m_is_computed(false)
{
Kernel kernel;
auto vertex_ctr = kernel.construct_vertex_2_object();
@ -1226,7 +1255,8 @@ _Segment_cached_2::_Segment_cached_2(const Point_2& source,
m_ps(source),
m_pt(target),
m_is_vert(false),
m_is_computed(false) {
m_is_computed(false)
{
Kernel kernel;
Comparison_result res = kernel.compare_xy_2_object()(m_ps, m_pt);
@ -1244,7 +1274,8 @@ _Segment_cached_2::_Segment_cached_2(const Line_2& line,
const Point_2& target) :
m_l(line),
m_ps(source),
m_pt(target) {
m_pt(target)
{
Kernel kernel;
CGAL_precondition
@ -1281,7 +1312,8 @@ _Segment_cached_2(const Line_2& line,
//! \brief assigns.
template <typename Kernel>
const typename Arr_segment_traits_2<Kernel>::_Segment_cached_2&
Arr_segment_traits_2<Kernel>::_Segment_cached_2::operator=(const Segment_2& seg) {
Arr_segment_traits_2<Kernel>::_Segment_cached_2::operator=(const Segment_2& seg)
{
Kernel kernel;
auto vertex_ctr = kernel.construct_vertex_2_object();
@ -1306,7 +1338,8 @@ Arr_segment_traits_2<Kernel>::_Segment_cached_2::operator=(const Segment_2& seg)
//! \brief obtains the supporting line.
template <typename Kernel>
const typename Kernel::Line_2&
Arr_segment_traits_2<Kernel>::_Segment_cached_2::line() const {
Arr_segment_traits_2<Kernel>::_Segment_cached_2::line() const
{
if (!m_is_computed) {
Kernel kernel;
m_l = kernel.construct_line_2_object()(m_ps, m_pt);
@ -1318,7 +1351,8 @@ Arr_segment_traits_2<Kernel>::_Segment_cached_2::line() const {
//! \brief determines whether the curve is vertical.
template <typename Kernel>
bool Arr_segment_traits_2<Kernel>::_Segment_cached_2::is_vertical() const {
bool Arr_segment_traits_2<Kernel>::_Segment_cached_2::is_vertical() const
{
// Force computation of line is orientation is still unknown
if (! m_is_computed) line();
CGAL_precondition(!m_is_degen);
@ -1363,7 +1397,8 @@ Arr_segment_traits_2<Kernel>::_Segment_cached_2::right() const
//! \brief sets the (lexicographically) left endpoint.
template <typename Kernel>
void Arr_segment_traits_2<Kernel>::_Segment_cached_2::set_left(const Point_2& p) {
void Arr_segment_traits_2<Kernel>::_Segment_cached_2::set_left(const Point_2& p)
{
CGAL_precondition(! m_is_degen);
CGAL_precondition_code(Kernel kernel);
CGAL_precondition
@ -1376,7 +1411,8 @@ void Arr_segment_traits_2<Kernel>::_Segment_cached_2::set_left(const Point_2& p)
//! \brief sets the (lexicographically) right endpoint.
template <typename Kernel>
void Arr_segment_traits_2<Kernel>::_Segment_cached_2::set_right(const Point_2& p) {
void Arr_segment_traits_2<Kernel>::_Segment_cached_2::set_right(const Point_2& p)
{
CGAL_precondition(! m_is_degen);
CGAL_precondition_code(Kernel kernel);
CGAL_precondition
@ -1392,7 +1428,8 @@ void Arr_segment_traits_2<Kernel>::_Segment_cached_2::set_right(const Point_2& p
*/
template <typename Kernel>
bool Arr_segment_traits_2<Kernel>::_Segment_cached_2::
is_in_x_range(const Point_2& p) const {
is_in_x_range(const Point_2& p) const
{
Kernel kernel;
typename Kernel::Compare_x_2 compare_x = kernel.compare_x_2_object();
const Comparison_result res1 = compare_x(p, left());
@ -1409,7 +1446,8 @@ is_in_x_range(const Point_2& p) const {
*/
template <typename Kernel>
bool Arr_segment_traits_2<Kernel>::_Segment_cached_2::
is_in_y_range(const Point_2& p) const {
is_in_y_range(const Point_2& p) const
{
Kernel kernel;
typename Kernel::Compare_y_2 compare_y = kernel.compare_y_2_object();
const Comparison_result res1 = compare_y(p, left());
@ -1426,31 +1464,31 @@ is_in_y_range(const Point_2& p) const {
*/
template <typename Kernel_>
class Arr_segment_2 : public Arr_segment_traits_2<Kernel_>::_Segment_cached_2 {
using Kernel = Kernel_;
typedef Kernel_ Kernel;
using Base = typename Arr_segment_traits_2<Kernel>::_Segment_cached_2;
using Segment_2 = typename Kernel::Segment_2;
using Point_2 = typename Kernel::Point_2;
using Line_2 = typename Kernel::Line_2;
typedef typename Arr_segment_traits_2<Kernel>::_Segment_cached_2 Base;
typedef typename Kernel::Segment_2 Segment_2;
typedef typename Kernel::Point_2 Point_2;
typedef typename Kernel::Line_2 Line_2;
public:
/*! constructs default. */
/*! Construct default. */
Arr_segment_2();
/*! constructs a segment from a "kernel" segment.
/*! Construct a segment from a "kernel" segment.
* \param seg the segment.
* \pre the segment is not degenerate.
*/
Arr_segment_2(const Segment_2& seg);
/*! constructs a segment from two endpoints.
/*! Construct a segment from two endpoints.
* \param source the source point.
* \param target the target point.
* \pre `source` and `target` are not equal.
*/
Arr_segment_2(const Point_2& source, const Point_2& target);
/*! constructs a segment from a line and two endpoints.
/*! Construct a segment from a line and two endpoints.
* \param line the supporting line.
* \param source the source point.
* \param target the target point.
@ -1460,7 +1498,7 @@ public:
Arr_segment_2(const Line_2& line,
const Point_2& source, const Point_2& target);
/*! constructs a segment from all fields.
/*! Construct a segment from all fields.
* \param line the supporting line.
* \param source the source point.
* \param target the target point.
@ -1472,11 +1510,11 @@ public:
const Point_2& source, const Point_2& target,
bool is_directed_right, bool is_vert, bool is_degen);
/*! casts to a segment.
/*! Cast to a segment.
*/
operator Segment_2() const;
/*! flips the segment (swap its source and target).
/*! Flip the segment (swap its source and target).
*/
Arr_segment_2 flip() const;
@ -1520,7 +1558,8 @@ Arr_segment_2<Kernel>::Arr_segment_2(const Line_2& line,
//! \brief casts to a segment.
template <typename Kernel>
Arr_segment_2<Kernel>::operator typename Kernel::Segment_2() const {
Arr_segment_2<Kernel>::operator typename Kernel::Segment_2() const
{
Kernel kernel;
auto seg_ctr = kernel.construct_segment_2_object();
return seg_ctr(this->source(), this->target());
@ -1528,7 +1567,8 @@ Arr_segment_2<Kernel>::operator typename Kernel::Segment_2() const {
//! \brief flips the segment (swap its source and target).
template <typename Kernel>
Arr_segment_2<Kernel> Arr_segment_2<Kernel>::flip() const {
Arr_segment_2<Kernel> Arr_segment_2<Kernel>::flip() const
{
return Arr_segment_2(this->line(), this->target(), this->source(),
! (this->is_directed_right()), this->is_vertical(),
this->is_degenerate());
@ -1546,7 +1586,8 @@ Bbox_2 Arr_segment_2<Kernel>::bbox() const
/*! Exporter for the segment class used by the traits-class.
*/
template <typename Kernel, typename OutputStream>
OutputStream& operator<<(OutputStream& os, const Arr_segment_2<Kernel>& seg) {
OutputStream& operator<<(OutputStream& os, const Arr_segment_2<Kernel>& seg)
{
os << static_cast<typename Kernel::Segment_2>(seg);
return (os);
}
@ -1554,7 +1595,8 @@ OutputStream& operator<<(OutputStream& os, const Arr_segment_2<Kernel>& seg) {
/*! Importer for the segment class used by the traits-class.
*/
template <typename Kernel, typename InputStream>
InputStream& operator>>(InputStream& is, Arr_segment_2<Kernel>& seg) {
InputStream& operator>>(InputStream& is, Arr_segment_2<Kernel>& seg)
{
typename Kernel::Segment_2 kernel_seg;
is >> kernel_seg;
seg = kernel_seg;

View File

@ -588,7 +588,7 @@ private:
#ifdef CGAL_USE_BASIC_VIEWER
//!
inline void draw_unimplemented() {
void draw_unimplemented() {
CGAL_error_msg("Geometry traits type of arrangement is required to support approximation of Point_2 and "
"X_monotone_curve_2. Traits on curved surfaces needs additional support for parameterization.");
}

View File

@ -8,7 +8,7 @@
#include <CGAL/bounding_box.h>
#include <CGAL/tags.h>
#include <CGAL/IO/read_points.h>
#include <CGAL/IO/PLY.h>
#include <CGAL/IO/write_ply_points.h>
#include <CGAL/Real_timer.h>

View File

@ -1068,18 +1068,8 @@ If \link GenericMap::are_attributes_automatically_managed `are_attributes_automa
template <unsigned int i>
size_type remove_cell(Dart_descriptor d);
/*!
\ingroup PkgCombinatorialMapsRefIO
Writes `amap` in `os`, using our own internal file format in XML. Writes both the topology of the combinatorial map and its enabled attributes.
*/
friend std::ostream& operator<< (std::ostream& os, const GenericMap& amap);
/*!
\ingroup PkgCombinatorialMapsRefIO
Reads `amap` from `is`, using our own internal file format in XML. Reads both the topology of the combinatorial map and its enabled attributes which are present in `is`. Note that if `amap` is not empty before the reading, the new map is added in the previous one.
*/
friend std::ifstream& operator>> (std::ifstream& is, GenericMap& amap);
/// @}
}; /* end GenericMap */

View File

@ -6,9 +6,6 @@
/// \defgroup PkgCombinatorialMapsClasses Classes
/// \ingroup PkgCombinatorialMapsRef
/// \defgroup PkgCombinatorialMapsRefIO IO Functions for CMap
/// \ingroup PkgCombinatorialMapsRef
/*!
\addtogroup PkgCombinatorialMapsRef
\cgalPkgDescriptionBegin{Combinatorial Maps,PkgCombinatorialMaps}
@ -39,9 +36,5 @@
- `CGAL::Cell_attribute_with_id<CMap,Info_,Tag,OnMerge,OnSplit>`
- `CGAL::Generic_map_min_items`
\cgalCRPSubsection{IO Functions for CMap}
- \link PkgCombinatorialMapsRefIO `std::ostream& operator<< (std::ostream& os, const GenericMap& amap)` \endlink
- \link PkgCombinatorialMapsRefIO `std::ifstream& operator>> (std::ifstream& is, GenericMap& amap)` \endlink
*/

View File

@ -255,7 +255,7 @@ namespace CGAL {
}
}
// Creates a mapping between darts of the two maps (originals->copies).
// Create an mapping between darts of the two maps (originals->copies).
// (here we cannot use CGAL::Unique_hash_map because it does not provide
// iterators...
std::unordered_map<Dart_descriptor_2, Dart_descriptor> local_dartmap;
@ -585,7 +585,7 @@ namespace CGAL {
bool copy_perforated_darts=false,
size_type mark_perforated=INVALID_MARK)
{
// Creates a mapping between darts of the two maps (originals->copies).
// Create an mapping between darts of the two maps (originals->copies).
// (here we cannot use CGAL::Unique_hash_map because it does not provide
// iterators...
std::unordered_map
@ -661,7 +661,7 @@ namespace CGAL {
return is;
}
/** Creates a new dart and add it to the map.
/** Create a new dart and add it to the map.
* The marks of the darts are initialized with mmask_marks, i.e. the dart
* is unmarked for all the marks.
* @return a Dart_descriptor on the new dart.
@ -968,7 +968,7 @@ namespace CGAL {
size_type number_of_used_marks() const
{ return mnb_used_marks; }
/** Tests if a given mark is reserved.
/** Test if a given mark is reserved.
* @return true iff the mark is reserved (i.e. in used).
*/
bool is_reserved(size_type amark) const
@ -997,14 +997,14 @@ namespace CGAL {
return number_of_darts() - number_of_marked_darts(amark);
}
/** Tests if all the darts are unmarked for a given mark.
/** Test if all the darts are unmarked for a given mark.
* @param amark the mark index.
* @return true iff all the darts are unmarked for amark.
*/
bool is_whole_map_unmarked(size_type amark) const
{ return number_of_marked_darts(amark) == 0; }
/** Tests if all the darts are marked for a given mark.
/** Test if all the darts are marked for a given mark.
* @param amark the mark index.
* @return true iff all the darts are marked for amark.
*/
@ -1071,7 +1071,7 @@ namespace CGAL {
mmask_marks.flip(amark);
}
/** Tests if a given dart is marked for a given mark.
/** Test if a given dart is marked for a given mark.
* @param adart the dart to test.
* @param amark the given mark.
* @return true iff adart is marked for the mark amark.
@ -1239,7 +1239,7 @@ namespace CGAL {
std::size_t orient(size_type amark) const
{ negate_mark(amark); return number_of_darts(); }
/** Tests if this map is without boundary for a given dimension.
/** Test if this map is without boundary for a given dimension.
* @param i the dimension.
* @return true iff all the darts are not i-free.
* @pre 1<=i<=n
@ -1253,7 +1253,7 @@ namespace CGAL {
return true;
}
/** Tests if this map is without boundary for all the dimensions.
/** Test if this map is without boundary for all the dimensions.
* @return true iff all the darts are non free.
*/
bool is_without_boundary() const
@ -1334,7 +1334,7 @@ namespace CGAL {
return res;
}
/** Tests if the map is valid.
/** Test if the map is valid.
* @return true iff the map is valid.
*/
bool is_valid(bool show_errors=true) const
@ -1579,7 +1579,7 @@ namespace CGAL {
return os;
}
/// Creates a new attribute.
/// Create a new attribute.
/// @return a descriptor on the new attribute.
template<unsigned int i, typename ...Args>
typename Attribute_descriptor<i>::type create_attribute(const Args&... args)
@ -1988,7 +1988,7 @@ namespace CGAL {
else unlink_beta_for_involution(adart, i);
}
/** Tests if it is possible to sew by betai the two given darts
/** Test if it is possible to sew by betai the two given darts
* @param adart1 the first dart.
* @param adart2 the second dart.
* @return true iff \em adart1 can be i-sewn with \em adart2.
@ -3439,7 +3439,7 @@ namespace CGAL {
}
/** Tests if the connected component of cmap containing dart dh1 is
/** Test if the connected component of cmap containing dart dh1 is
* isomorphic to the connected component of map2 containing dart dh2,
* starting from dh1 and dh2.
* @param dh1 initial dart for this map
@ -3648,7 +3648,7 @@ namespace CGAL {
return match;
}
/** Tests if this cmap is isomorphic to map2.
/** Test if this cmap is isomorphic to map2.
* @pre cmap is connected.
* @param map2 the second combinatorial map
* @param testDartInfo Boolean to test the equality of dart info (true)
@ -3687,7 +3687,7 @@ namespace CGAL {
return false;
}
/** Tests if the attributes of this map are automatically updated.
/** Test if the attributes of this map are automatically updated.
* @return true iff the boolean automatic_attributes_management is set to true.
*/
bool are_attributes_automatically_managed() const
@ -3710,13 +3710,13 @@ namespace CGAL {
void set_automatic_attributes_management_without_correction(bool newval)
{ this->automatic_attributes_management = newval; }
/** Creates a halfedge.
* @return a dart of the new half-edge.
/** Create a halfedge.
* @return a dart of the new halfedge.
*/
Dart_descriptor make_half_edge()
{ return create_dart(); }
/** Creates an edge.
/** Create an edge.
* if closed==true, the edge has no 2-free dart.
* (note that for CMap there is no difference between true and false, but
* this is not the case for GMap)
@ -3730,7 +3730,7 @@ namespace CGAL {
return d1;
}
/** Creates an edge given 2 Attribute_descriptor<0>.
/** Create an edge given 2 Attribute_descriptor<0>.
* Note that this function can be used only if 0-attributes are non void
* @param h0 the first vertex descriptor.
* @param h1 the second vertex descriptor.
@ -3751,7 +3751,7 @@ namespace CGAL {
return d1;
}
/** Creates a combinatorial polygon of length alg
/** Create a combinatorial polygon of length alg
* (a cycle of alg darts beta1 links together).
* @return a new dart.
*/
@ -3772,7 +3772,7 @@ namespace CGAL {
return start;
}
/** Tests if a face is a combinatorial polygon of length alg
/** Test if a face is a combinatorial polygon of length alg
* (a cycle of alg darts beta1 links together).
* @param adart an initial dart
* @return true iff the face containing adart is a polygon of length alg.
@ -3794,7 +3794,7 @@ namespace CGAL {
return (nb==alg);
}
/** Creates a triangle given 3 Attribute_descriptor<0>.
/** Create a triangle given 3 Attribute_descriptor<0>.
* @param h0 the first descriptor.
* @param h1 the second descriptor.
* @param h2 the third descriptor.
@ -3814,7 +3814,7 @@ namespace CGAL {
return d1;
}
/** Creates a quadrangle given 4 Vertex_attribute_descriptor.
/** Create a quadrangle given 4 Vertex_attribute_descriptor.
* @param h0 the first vertex descriptor.
* @param h1 the second vertex descriptor.
* @param h2 the third vertex descriptor.
@ -3837,7 +3837,7 @@ namespace CGAL {
return d1;
}
/** Creates a combinatorial tetrahedron from 4 triangles.
/** Create a combinatorial tetrahedron from 4 triangles.
* @param d1 a dart onto a first triangle.
* @param d2 a dart onto a second triangle.
* @param d3 a dart onto a third triangle.
@ -3859,9 +3859,9 @@ namespace CGAL {
return d1;
}
/** Tests if a volume is a combinatorial tetrahedron.
* @param d1 an initial dart
* @return true iff the volume containing d1 is a combinatorial tetrahedron.
/** Test if a volume is a combinatorial tetrahedron.
* @param adart an initial dart
* @return true iff the volume containing adart is a combinatorial tetrahedron.
*/
bool is_volume_combinatorial_tetrahedron(Dart_const_descriptor d1) const
{
@ -3892,7 +3892,7 @@ namespace CGAL {
return true;
}
/** Creates a new combinatorial tetrahedron.
/** Create a new combinatorial tetrahedron.
* @return a new dart.
*/
Dart_descriptor make_combinatorial_tetrahedron()
@ -3905,7 +3905,7 @@ namespace CGAL {
return make_combinatorial_tetrahedron(d1, d2, d3, d4);
}
/** Creates a combinatorial hexahedron from 6 quadrilaterals.
/** Create a combinatorial hexahedron from 6 quadrilaterals.
* @param d1 a dart onto a first quadrilateral.
* @param d2 a dart onto a second quadrilateral.
* @param d3 a dart onto a third quadrilateral.
@ -3952,9 +3952,9 @@ namespace CGAL {
return d1;
}
/** Tests if a volume is a combinatorial hexahedron.
* @param d1 an initial dart
* @return true iff the volume containing d1 is a combinatorial hexahedron.
/** Test if a volume is a combinatorial hexahedron.
* @param adart an initial dart
* @return true iff the volume containing adart is a combinatorial hexahedron.
*/
bool is_volume_combinatorial_hexahedron(Dart_const_descriptor d1) const
{
@ -4004,7 +4004,7 @@ namespace CGAL {
return true;
}
/** Creates a new combinatorial hexahedron.
/** Create a new combinatorial hexahedron.
* @return a new dart.
*/
Dart_descriptor make_combinatorial_hexahedron()
@ -4019,362 +4019,7 @@ namespace CGAL {
return make_combinatorial_hexahedron(d1, d2, d3, d4, d5, d6);
}
/** 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.
/** Test if an i-cell can be removed.
* An i-cell can be removed if i==dimension or i==dimension-1,
* or if there are at most two (i+1)-cell incident to it.
* @param adart a dart of the i-cell.
@ -4396,7 +4041,7 @@ namespace CGAL {
run(*this,adart,update_attributes);
}
/** Tests if an i-cell can be contracted.
/** Test if an i-cell can be contracted.
* An i-cell can be contracted if i==1
* or if there are at most two (i-1)-cell incident to it.
* @param adart a dart of the i-cell.
@ -4762,7 +4407,7 @@ namespace CGAL {
return this->template beta<0>(adart1);
}
/** Tests if an edge can be inserted onto a 2-cell between two given darts.
/** Test if an edge can be inserted onto a 2-cell between two given darts.
* @param adart1 a first dart.
* @param adart2 a second dart.
* @return true iff an edge can be inserted between adart1 and adart2.
@ -4798,7 +4443,7 @@ namespace CGAL {
return generic_insert_cell_1(adart1, adart2, false, update_attributes);
}
/** Tests if an edge can be inserted between two different 2-cells
/** Test if an edge can be inserted between two different 2-cells
* between two given darts.
* @param adart1 a first dart.
* @param adart2 a second dart.
@ -4982,7 +4627,7 @@ namespace CGAL {
return this->template beta<0>(adart1);
}
/** Tests if a 2-cell can be inserted onto a given 3-cell along
/** Test if a 2-cell can be inserted onto a given 3-cell along
* a path of edges.
* @param afirst iterator on the beginning of the path.
* @param alast iterator on the end of the path.

View File

@ -1,208 +0,0 @@
// 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

View File

@ -5,7 +5,6 @@
#include <CGAL/make_conforming_constrained_Delaunay_triangulation_3.h>
#include <vector>
#include <algorithm>
using K = CGAL::Exact_predicates_inexact_constructions_kernel;
@ -30,18 +29,6 @@ int main(int argc, char* argv[])
<< "Number of constrained facets in the CDT: "
<< ccdt.number_of_constrained_facets() << '\n';
// Collect constrained facets per polygon
std::vector<std::size_t> constrained_facets(polygons.size());
for(auto facet : ccdt.constrained_facets())
{
int i = ccdt.face_constraint_index(facet);
++constrained_facets[i];
}
auto it = std::max_element(constrained_facets.begin(), constrained_facets.end());
std::cout << "The polygon with the most constrained facets has index "
<< (it - constrained_facets.begin()) << " and " << *it << " facets.\n";
std::ofstream ofs(argc > 2 ? argv[2] : "out.mesh");
ofs.precision(17);
CGAL::IO::write_MEDIT(ofs, ccdt);

View File

@ -1034,7 +1034,7 @@ public:
*/
CDT_3_signed_index face_constraint_index(typename Triangulation::Cell_handle ch, int i) const
{
return ch->ccdt_3_data().face_constraint_index(i);
return ch->face_id[static_cast<unsigned>(i)];
}
/*!

View File

@ -98,7 +98,7 @@ public:
CGAL::read(is, i);
}
if(!is) return is;
c->ccdt_3_data().set_face_constraint_index(li, i);
c.face_id[li] = i;
}
return is;
}

View File

@ -123,11 +123,11 @@ In the example below, we can see a query where:
</center>
\section subsecFrechetDistanceImageCredits Image Credits
\subsection 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.
\section subsecFrechetDistanceImplementation Implementation History
\subsection subsecFrechetDistanceImplementation Implementation History
An initial version using floating point arithmetic was developed by the authors
while working at the Max-Planck Institute for Informatics in Saarbrücken, Germany.

View File

@ -25,6 +25,7 @@ Modular_arithmetic
Number_types
Orthtree
Point_set_3
Point_set_processing_3
Polygon
Polygon_mesh_processing
Principal_component_analysis

View File

@ -26,6 +26,7 @@ Modular_arithmetic
Number_types
Orthtree
Point_set_3
Point_set_processing_3
Polygon
Polygon_mesh_processing
Principal_component_analysis

View File

@ -1795,8 +1795,8 @@ bool MainWindow::loadScript(QFileInfo info)
QString program;
QString filename = info.absoluteFilePath();
QFile script_file(filename);
bool success = script_file.open(QIODevice::ReadOnly);
if((! success) || (!script_file.isReadable())) {
script_file.open(QIODevice::ReadOnly);
if(!script_file.isReadable()) {
throw std::ios_base::failure(script_file.errorString().toStdString());
}
program = script_file.readAll();
@ -2747,9 +2747,9 @@ void MainWindow::exportStatistics()
if(filename.isEmpty())
return;
QFile output(filename);
bool success = output.open(QIODevice::WriteOnly | QIODevice::Text);
output.open(QIODevice::WriteOnly | QIODevice::Text);
if((! success) || (!output.isOpen())){
if(!output.isOpen()){
qDebug() << "- Error, unable to open" << "outputFilename" << "for output";
}
QTextStream outStream(&output);

View File

@ -93,20 +93,18 @@ bool Camera_positions_list::save(QString filename) {
if(m_model->rowCount() <1)
return false;
QFile file(filename);
if(file.open(QIODevice::WriteOnly)){
QTextStream out(&file);
for(int i = 0; i < m_model->rowCount(); ++i)
{
QStandardItem* item = m_model->item(i);
out << item->data(Qt::DisplayRole).toString()
<< "\n"
<< item->data(Qt::UserRole).toString()
<< "\n";
}
file.close();
return true;
file.open(QIODevice::WriteOnly);
QTextStream out(&file);
for(int i = 0; i < m_model->rowCount(); ++i)
{
QStandardItem* item = m_model->item(i);
out << item->data(Qt::DisplayRole).toString()
<< "\n"
<< item->data(Qt::UserRole).toString()
<< "\n";
}
return false;
file.close();
return true;
}
void Camera_positions_list::on_saveButton_pressed()
@ -131,24 +129,19 @@ void Camera_positions_list::on_openButton_pressed()
void Camera_positions_list::load(QString filename) {
QFile file(filename);
if(file.open(QIODevice::ReadOnly)){
std::clog << "Loading camera positions " << qPrintable(filename) << std::endl;
QTextStream input(&file);
while(!input.atEnd()) {
QString text = input.readLine(1000);
QString coord = input.readLine(1000);
if(text.isNull() || coord.isNull()) return;
CGAL::qglviewer::Frame frame;
if(Three::activeViewer()->readFrame(coord, frame))
{
addItem(text,
Three::activeViewer()->dumpFrame(frame));
}
std::clog << "Loading camera positions " << qPrintable(filename) << std::endl;
file.open(QIODevice::ReadOnly);
QTextStream input(&file);
while(!input.atEnd()) {
QString text = input.readLine(1000);
QString coord = input.readLine(1000);
if(text.isNull() || coord.isNull()) return;
CGAL::qglviewer::Frame frame;
if(Three::activeViewer()->readFrame(coord, frame))
{
addItem(text,
Three::activeViewer()->dumpFrame(frame));
}
}else {
std::clog << "Loading camera positions " << qPrintable(filename) << " failed" << std::endl;
}
}

View File

@ -1,68 +0,0 @@
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

View File

@ -289,18 +289,6 @@ The following example shows the use of \link GenericMap::insert_cell_1_between_t
Result of the run of the linear_cell_complex_3_insert program. A window shows the 3D cube where one face has a hole.
\cgalFigureEnd
\subsection Linear_cell_complexWriteVTK Writing a Linear Cell Complex to a VTK File
\anchor ssecLCCWriteVtK
This example loads a 3D linear cell complex from a `.3map` file (using the `operator>>`). It computes for each 3-cell (volume) the number of incident vertices (0-cells), stores these values in a `std::vector<std::size_t>`, and writes the result to a `.vtk` file using `CGAL::IO::write_VTK()`, with the computed values as scalars for each volume.
\cgalExample{Linear_cell_complex/linear_cell_complex_3_vtk_io.cpp}
\cgalFigureBegin{fig_lcc_export_vtk,lcc-export-vtk.png}
Visualization of the VTK file generated by the `linear_cell_complex_3_vtk_io` program, using Paraview. Each volume is colored depending on its number of vertices.
\cgalFigureEnd
\section Linear_cell_complexDesign Design and Implementation History
This package was developed by Guillaume Damiand, with the help of Andreas Fabri, S&eacute;bastien Loriot and Laurent Rineau. Monique Teillaud and Bernd G&auml;rtner contributed to the manual.

View File

@ -23,14 +23,6 @@
/// \defgroup PkgDrawLinearCellComplex Draw a Linear Cell Complex
/// \ingroup PkgLinearCellComplexRef
/// \defgroup PkgLinearCellComplexRefIO IO Functions for LCC
/// \ingroup PkgLinearCellComplexRef
/*! High-level operations.
\cgalInclude{CGAL/Linear_cell_complex/IO/VTK.h}
*/
/// \defgroup PkgLinearCellComplexRefIOVTK VTK IO Functions for LCC
/// \ingroup PkgLinearCellComplexRefIO
/*!
\addtogroup PkgLinearCellComplexRef
@ -82,10 +74,4 @@
- \link PkgDrawLinearCellComplex CGAL::draw<LCC>() \endlink
- \link PkgDrawLinearCellComplex CGAL::add_in_graphics_scene<LCC, BufferType, DrawingFunctor>() \endlink
\cgalCRPSubsection{IO Functions for LCC}
- \link PkgCombinatorialMapsRefIO `std::ostream& operator<< (std::ostream& os, const GenericMap& amap)` \endlink
- \link PkgCombinatorialMapsRefIO `std::ifstream& operator>> (std::ifstream& is, GenericMap& amap)` \endlink
- \link PkgLinearCellComplexRefIOVTK `CGAL::IO::Read_VTK<LCC>()` \endlink
- \link PkgLinearCellComplexRefIOVTK `CGAL::IO::Write_VTK<LCC>()` \endlink
*/

View File

@ -6,5 +6,4 @@
\example Linear_cell_complex/linear_cell_complex_3_incremental_builder.cpp
\example Linear_cell_complex/draw_linear_cell_complex.cpp
\example Linear_cell_complex/linear_cell_complex_3_insert.cpp
\example Linear_cell_complex/linear_cell_complex_3_vtk_io.cpp
*/

Binary file not shown.

Before

Width:  |  Height:  |  Size: 89 KiB

View File

@ -27,7 +27,6 @@ create_single_source_cgal_program("linear_cell_complex_4.cpp")
create_single_source_cgal_program("read_plane_graph_in_lcc_2.cpp")
create_single_source_cgal_program("voronoi_2.cpp")
create_single_source_cgal_program("voronoi_3.cpp")
create_single_source_cgal_program("linear_cell_complex_3_vtk_io.cpp")
create_single_source_cgal_program("draw_linear_cell_complex.cpp")
if(CGAL_Qt6_FOUND)

File diff suppressed because one or more lines are too long

View File

@ -1,34 +0,0 @@
#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;
}

View File

@ -1,719 +0,0 @@
// 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

View File

@ -213,7 +213,7 @@ namespace CGAL {
return *this;
}
/** Creates a vertex attribute.
/** Create a vertex attribute.
* @return a handle on the new attribute.
*/
template<typename ...Args>
@ -221,7 +221,7 @@ namespace CGAL {
{ return Base::template create_attribute<0>(args...); }
/**
* Creates a new dart associated with a handle through an attribute.
* Create a new dart associated with a handle through an attribute.
* @param ahandle the point handle to associated with the dart.
* @return a Dart_descriptor on the new dart.
*/
@ -232,7 +232,7 @@ namespace CGAL {
return res;
}
/** Creates a new dart associated with a point.
/** Create a new dart associated with a point.
* @param apoint the point to associated with the dart.
* @return a Dart_descriptor on the new dart.
*/
@ -307,7 +307,7 @@ namespace CGAL {
return point_of_vertex_attribute(this->template attribute<0>(adart));
}
/** Tests if the lcc is valid.
/** Test if the lcc is valid.
* A Linear_cell_complex is valid if it is a valid Combinatorial_map with
* an attribute associated to each dart.
* @return true iff the map is valid.
@ -550,7 +550,7 @@ namespace CGAL {
return res;
}
/** Creates a segment given 2 points.
/** Create a segment given 2 points.
* @param p0 the first point.
* @param p1 the second point.
* if closed==true, the edge has no 2-free dart.
@ -564,7 +564,7 @@ namespace CGAL {
closed);
}
/** Creates a triangle given 3 points.
/** Create a triangle given 3 points.
* @param p0 the first point.
* @param p1 the second point.
* @param p2 the third point.
@ -579,7 +579,7 @@ namespace CGAL {
create_vertex_attribute(p2));
}
/** Creates a quadrangle given 4 points.
/** Create a quadrangle given 4 points.
* @param p0 the first point.
* @param p1 the second point.
* @param p2 the third point.
@ -598,7 +598,7 @@ namespace CGAL {
}
/** Creates a tetrahedron given 4 Vertex_attribute_descriptor.
/** Create a tetrahedron given 4 Vertex_attribute_descriptor.
* @param h0 the first vertex handle.
* @param h1 the second vertex handle.
* @param h2 the third vertex handle.
@ -619,7 +619,7 @@ namespace CGAL {
return this->make_combinatorial_tetrahedron(d1, d2, d3, d4);
}
/** Creates a tetrahedron given 4 points.
/** Create a tetrahedron given 4 points.
* @param p0 the first point.
* @param p1 the second point.
* @param p2 the third point.
@ -638,7 +638,7 @@ namespace CGAL {
create_vertex_attribute(p3));
}
/** Creates an hexahedron given 8 Vertex_attribute_descriptor.
/** Create an hexahedron given 8 Vertex_attribute_descriptor.
* (8 vertices, 12 edges and 6 facets)
* \verbatim
* 4----7
@ -660,13 +660,13 @@ namespace CGAL {
* h0,h5 and to the facet (h0,h5,h6,h1).
*/
Dart_descriptor make_hexahedron(Vertex_attribute_descriptor h0,
Vertex_attribute_descriptor h1,
Vertex_attribute_descriptor h2,
Vertex_attribute_descriptor h3,
Vertex_attribute_descriptor h4,
Vertex_attribute_descriptor h5,
Vertex_attribute_descriptor h6,
Vertex_attribute_descriptor h7)
Vertex_attribute_descriptor h1,
Vertex_attribute_descriptor h2,
Vertex_attribute_descriptor h3,
Vertex_attribute_descriptor h4,
Vertex_attribute_descriptor h5,
Vertex_attribute_descriptor h6,
Vertex_attribute_descriptor h7)
{
Dart_descriptor d1 = make_quadrangle(h0, h5, h6, h1);
Dart_descriptor d2 = make_quadrangle(h1, h6, h7, h2);
@ -678,7 +678,7 @@ namespace CGAL {
return this->make_combinatorial_hexahedron(d1, d2, d3, d4, d5, d6);
}
/** Creates an hexahedron given 8 points.
/** Create an hexahedron given 8 points.
* \verbatim
* 4----7
* /| /|
@ -717,133 +717,6 @@ namespace CGAL {
create_vertex_attribute(p7));
}
/** Creates a prism given 6 Vertex_attribute_descriptor.
* (6 vertices, 9 edges and 5 facets)
* \verbatim
* 3---4
* |\ /|
* 0-5-1
* \|/
* 2
* \endverbatim
* @param h0 the first vertex handle.
* @param h1 the second vertex handle.
* @param h2 the third vertex handle.
* @param h3 the fourth vertex handle.
* @param h4 the fifth vertex handle.
* @param h5 the sixth vertex handle.
* @return the dart of the new prism incident to h0 and to
* the facet (h0,h1,h2).
*/
Dart_descriptor make_prism(Vertex_attribute_descriptor h0,
Vertex_attribute_descriptor h1,
Vertex_attribute_descriptor h2,
Vertex_attribute_descriptor h3,
Vertex_attribute_descriptor h4,
Vertex_attribute_descriptor h5)
{
Dart_descriptor d1=make_triangle(h0, h1, h2);
Dart_descriptor d2=make_quadrangle(h1, h0, h3, h4);
Dart_descriptor d3=make_quadrangle(h2, h1, h4, h5);
Dart_descriptor d4=make_quadrangle(h0, h2, h5, h3);
Dart_descriptor d5=make_triangle(h4, h3, h5);
return make_combinatorial_prism(d1, d2, d3, d4, d5);
}
/** Creates a prism given 6 points.
* \verbatim
* 3---4
* |\ /|
* 0-5-1
* \|/
* 2
* \endverbatim
* @param p0 the first point.
* @param p1 the second point.
* @param p2 the third point.
* @param p3 the fourth point.
* @param p4 the fifth point.
* @param p5 the sixth point.
* @return the dart of the new prism incident to p0 and to
* the facet (p0,p1,p2).
*/
Dart_descriptor make_prism(const Point& p0,
const Point& p1,
const Point& p2,
const Point& p3,
const Point& p4,
const Point& p5)
{
return make_prism(create_vertex_attribute(p0),
create_vertex_attribute(p1),
create_vertex_attribute(p2),
create_vertex_attribute(p3),
create_vertex_attribute(p4),
create_vertex_attribute(p5));
}
/** Creates a pyramid given 5 Vertex_attribute_descriptor.
* (5 vertices, 8 edges and 5 facets)
* \verbatim
* 4
* /|\
* 0-|-1
* | | |
* 3---2
* \endverbatim
* @param h0 the first vertex handle.
* @param h1 the second vertex handle.
* @param h2 the third vertex handle.
* @param h3 the fourth vertex handle.
* @param h4 the fifth vertex handle.
* @return the dart of the new pyramid incident to h0 and to
* the facet (h0,h1,h2,h3).
*/
Dart_descriptor make_pyramid(Vertex_attribute_descriptor h0,
Vertex_attribute_descriptor h1,
Vertex_attribute_descriptor h2,
Vertex_attribute_descriptor h3,
Vertex_attribute_descriptor h4)
{
Dart_descriptor d1=make_quadrangle(h0, h1, h2, h3);
Dart_descriptor d2=make_triangle(h1, h0, h4);
Dart_descriptor d3=make_triangle(h0, h3, h4);
Dart_descriptor d4=make_triangle(h3, h2, h4);
Dart_descriptor d5=make_triangle(h2, h1, h4);
return make_combinatorial_pyramid(d1, d2, d3, d4, d5);
}
/** Creates a pyramid given 5 points.
* \verbatim
* 4
* /|\
* 0-|-1
* | | |
* 3---2
* \endverbatim
* @param p0 the first point.
* @param p1 the second point.
* @param p2 the third point.
* @param p3 the fourth point.
* @param p4 the fifth point.
* @return the dart of the new pyramid incident to p0 and to
* the facet (p0,p1,p2,p3).
*/
Dart_descriptor make_pyramid(const Point& p0,
const Point& p1,
const Point& p2,
const Point& p3,
const Point& p4)
{
return make_pyramid(create_vertex_attribute(p0),
create_vertex_attribute(p1),
create_vertex_attribute(p2),
create_vertex_attribute(p3),
create_vertex_attribute(p4));
}
/** Compute the barycenter of a given cell.
* @param adart a dart incident to the cell.
* @param adim the dimension of the cell.

View File

@ -261,7 +261,7 @@ public:
prev_dart =lcc.null_descriptor;
}
void add_vertex_to_facet(size_type i, std::vector<DH>* tabdarts = nullptr)
void add_vertex_to_facet(size_type i)
{
CGAL_assertion(i<vertex_map.size());
// std::cout<<i<<" "<<std::flush;
@ -289,7 +289,6 @@ public:
{ first_dart=cur_dart; min_vertex=max_vertex=i; min_dart=cur_dart; }
prev_dart=cur_dart;
if(tabdarts != nullptr) { tabdarts->push_back(cur_dart); }
}
// End of the facet. Return the first dart of this facet.
@ -326,12 +325,11 @@ public:
return first_dart;
}
DH add_facet(std::initializer_list<size_type> l, std::vector<DH>* tabdarts = nullptr)
DH add_facet(std::initializer_list<size_type> l)
{
if(tabdarts != nullptr) { tabdarts->reserve(tabdarts->size() + l.size()); }
begin_facet();
for (size_type i:l)
{ add_vertex_to_facet(i, tabdarts); }
{ add_vertex_to_facet(i); }
return end_facet();
}
@ -406,197 +404,5 @@ private:
} //namespace CGAL
///////////////////////////////////////////////////////////////////////////////
/* Create an hexahedron, given the indices of its vertices (in the following
* order), the vertex must already have been added in the incremental builder.
* 3
* /|\
* 0-|-2
* \|/
* 1
*/
template<typename IncrementalBuilder>
typename IncrementalBuilder::LCC::Dart_descriptor
make_tetrahedron_with_builder(IncrementalBuilder& ib,
std::size_t i0,
std::size_t i1,
std::size_t i2,
std::size_t i3,
std::vector<typename IncrementalBuilder::LCC::Dart_descriptor>*
tabdarts=nullptr)
{
ib.begin_surface();
ib.add_facet({i0,i1,i2}, tabdarts);
ib.add_facet({i1,i0,i3}, tabdarts);
ib.add_facet({i2,i1,i3}, tabdarts);
ib.add_facet({i0,i2,i3}, tabdarts);
return ib.end_surface();
}
///////////////////////////////////////////////////////////////////////////////
/* 4
* /|\
* 0-|-3
* | | |
* 1---2
*/
template<typename IncrementalBuilder>
typename IncrementalBuilder::LCC::Dart_descriptor
make_pyramid_with_builder(IncrementalBuilder& ib,
std::size_t i0,
std::size_t i1,
std::size_t i2,
std::size_t i3,
std::size_t i4,
std::vector<typename IncrementalBuilder::LCC::Dart_descriptor>*
tabdarts=nullptr)
{
ib.begin_surface();
ib.add_facet({i0,i1,i2,i3}, tabdarts);
ib.add_facet({i1,i0,i4}, tabdarts);
ib.add_facet({i2,i1,i4}, tabdarts);
ib.add_facet({i3,i2,i4}, tabdarts);
ib.add_facet({i0,i3,i4}, tabdarts);
return ib.end_surface();
}
///////////////////////////////////////////////////////////////////////////////
/* 3
* /|\
* 4---5
* | | |
* | 0 |
* |/ \|
* 1---2
*/
template<typename IncrementalBuilder>
typename IncrementalBuilder::LCC::Dart_descriptor
make_prism_with_builder(IncrementalBuilder& ib,
std::size_t i0,
std::size_t i1,
std::size_t i2,
std::size_t i3,
std::size_t i4,
std::size_t i5,
std::vector<typename IncrementalBuilder::LCC::Dart_descriptor>*
tabdarts=nullptr)
{
ib.begin_surface();
ib.add_facet({i0,i1,i2}, tabdarts);
ib.add_facet({i1,i0,i3,i4}, tabdarts);
ib.add_facet({i2,i1,i4,i5}, tabdarts);
ib.add_facet({i0,i2,i5,i3}, tabdarts);
ib.add_facet({i5,i4,i3}, tabdarts);
return ib.end_surface();
}
///////////////////////////////////////////////////////////////////////////////
/* 7----6
* /| /|
* 4----5 |
* | 3--|-2
* |/ |/
* 0----1
*/
template<typename IncrementalBuilder>
typename IncrementalBuilder::LCC::Dart_descriptor
make_hexahedron_with_builder(IncrementalBuilder& ib,
std::size_t i0,
std::size_t i1,
std::size_t i2,
std::size_t i3,
std::size_t i4,
std::size_t i5,
std::size_t i6,
std::size_t i7,
std::vector<typename IncrementalBuilder::LCC::Dart_descriptor>*
tabdarts=nullptr)
{
ib.begin_surface();
ib.add_facet({i0,i1,i2,i3}, tabdarts);
ib.add_facet({i1,i0,i4,i5}, tabdarts);
ib.add_facet({i2,i1,i5,i6}, tabdarts);
ib.add_facet({i3,i2,i6,i7}, tabdarts);
ib.add_facet({i0,i3,i7,i4}, tabdarts);
ib.add_facet({i7,i6,i5,i4}, tabdarts);
return ib.end_surface();
}
///////////////////////////////////////////////////////////////////////////////
template<typename IncrementalBuilder>
typename IncrementalBuilder::LCC::Dart_descriptor
make_pentagonal_prism_with_builder(IncrementalBuilder& ib,
std::size_t i0,
std::size_t i1,
std::size_t i2,
std::size_t i3,
std::size_t i4,
std::size_t i5,
std::size_t i6,
std::size_t i7,
std::size_t i8,
std::size_t i9,
std::vector<typename IncrementalBuilder::LCC::Dart_descriptor>*
tabdarts=nullptr)
{
ib.begin_surface();
ib.add_facet({i0,i1,i2,i3,i4}, tabdarts);
ib.add_facet({i1,i0,i5,i6}, tabdarts);
ib.add_facet({i2,i1,i6,i7}, tabdarts);
ib.add_facet({i3,i2,i7,i8}, tabdarts);
ib.add_facet({i4,i3,i8,i9}, tabdarts);
ib.add_facet({i0,i4,i9,i5}, tabdarts);
ib.add_facet({i9,i8,i7,i6,i5}, tabdarts);
return ib.end_surface();
}
///////////////////////////////////////////////////////////////////////////////
template<typename IncrementalBuilder>
typename IncrementalBuilder::LCC::Dart_descriptor
make_hexagonal_prism_with_builder(IncrementalBuilder& ib,
std::size_t i0,
std::size_t i1,
std::size_t i2,
std::size_t i3,
std::size_t i4,
std::size_t i5,
std::size_t i6,
std::size_t i7,
std::size_t i8,
std::size_t i9,
std::size_t i10,
std::size_t i11,
std::vector<typename IncrementalBuilder::LCC::Dart_descriptor>*
tabdarts=nullptr)
{
ib.begin_surface();
ib.add_facet({i0,i1,i2,i3,i4,i5}, tabdarts);
ib.add_facet({i1,i0,i6,i7}, tabdarts);
ib.add_facet({i2,i1,i7,i8}, tabdarts);
ib.add_facet({i3,i2,i8,i9}, tabdarts);
ib.add_facet({i4,i3,i9,i10}, tabdarts);
ib.add_facet({i5,i4,i10,i11}, tabdarts);
ib.add_facet({i0,i5,i11,i6}, tabdarts);
ib.add_facet({i11,i10,i9,i8,i7,i6}, tabdarts);
return ib.end_surface();
}
///////////////////////////////////////////////////////////////////////////////
template<typename IncrementalBuilder>
typename IncrementalBuilder::LCC::Dart_descriptor
make_generic_cell_with_builder(IncrementalBuilder& ib,
const std::vector<std::size_t>& faces,
std::vector<typename IncrementalBuilder::LCC::Dart_descriptor>*
tabdarts=nullptr)
{
ib.begin_surface();
std::size_t i=1, end; // Start to 1 because faces[0] is the number of faces
for(; i<faces.size(); )
{
end=i+1+faces[i]; // faces[i] is the number of vertices of the face; +i is the index of the end
++i; // I prefer to increment i after its use!
ib.begin_facet();
for(; i<end; ++i)
{ ib.add_vertex_to_facet(faces[i], tabdarts); }
ib.end_facet();
}
return ib.end_surface();
}
///////////////////////////////////////////////////////////////////////////////
#endif // CGAL_LINEAR_CELL_COMPLEX_INCREMENTAL_BUILDER_3_H //
// EOF //

View File

@ -15,7 +15,6 @@ create_single_source_cgal_program(Linear_cell_complex_3_test.cpp ${hfiles})
create_single_source_cgal_program(Linear_cell_complex_4_test.cpp ${hfiles})
create_single_source_cgal_program(Linear_cell_complex_copy_test.cpp ${hfiles})
create_single_source_cgal_program(LCC_3_incremental_builder_test.cpp ${hfiles})
create_single_source_cgal_program(Linear_cell_complex_vtk_io_test.cpp ${hfiles})
# Same targets, defining USE_COMPACT_CONTAINER_WITH_INDEX to test index version
add_executable(Linear_cell_complex_2_test_index Linear_cell_complex_2_test.cpp ${hfiles})

View File

@ -5,6 +5,104 @@
#include "Linear_cell_complex_3_test.h"
///////////////////////////////////////////////////////////////////////////////
/* 3
* /|\
* 0-|-2
* \|/
* 1
*/
template<typename IncrementalBuilder>
void make_tetrahedron_with_builder(IncrementalBuilder& ib,
std::size_t i0,
std::size_t i1,
std::size_t i2,
std::size_t i3)
{
ib.begin_surface();
ib.add_facet({i0,i1,i2});
ib.add_facet({i1,i0,i3});
ib.add_facet({i2,i1,i3});
ib.add_facet({i0,i2,i3});
ib.end_surface();
}
///////////////////////////////////////////////////////////////////////////////
/* 4
* /|\
* 0-|-3
* | | |
* 1---2
*/
template<typename IncrementalBuilder>
void make_pyramid_with_builder(IncrementalBuilder& ib,
std::size_t i0,
std::size_t i1,
std::size_t i2,
std::size_t i3,
std::size_t i4)
{
ib.begin_surface();
ib.add_facet({i0,i1,i2,i3});
ib.add_facet({i1,i0,i4});
ib.add_facet({i2,i1,i4});
ib.add_facet({i3,i2,i4});
ib.add_facet({i0,i3,i4});
ib.end_surface();
}
///////////////////////////////////////////////////////////////////////////////
/* 3
* /|\
* 4---5
* | | |
* | 0 |
* |/ \|
* 1---2
*/
template<typename IncrementalBuilder>
void make_prism_with_builder(IncrementalBuilder& ib,
std::size_t i0,
std::size_t i1,
std::size_t i2,
std::size_t i3,
std::size_t i4,
std::size_t i5)
{
ib.begin_surface();
ib.add_facet({i0,i1,i2});
ib.add_facet({i1,i0,i3,i4});
ib.add_facet({i2,i1,i4,i5});
ib.add_facet({i0,i2,i5,i3});
ib.add_facet({i5,i4,i3});
ib.end_surface();
}
///////////////////////////////////////////////////////////////////////////////
/* 7----6
* /| /|
* 4----5 |
* | 3--|-2
* |/ |/
* 0----1
*/
template<typename IncrementalBuilder>
void make_hexahedron_with_builder(IncrementalBuilder& ib,
std::size_t i0,
std::size_t i1,
std::size_t i2,
std::size_t i3,
std::size_t i4,
std::size_t i5,
std::size_t i6,
std::size_t i7)
{
ib.begin_surface();
ib.add_facet({i0,i1,i2,i3});
ib.add_facet({i1,i0,i4,i5});
ib.add_facet({i2,i1,i5,i6});
ib.add_facet({i3,i2,i6,i7});
ib.add_facet({i0,i3,i7,i4});
ib.add_facet({i7,i6,i5,i4});
ib.end_surface();
}
///////////////////////////////////////////////////////////////////////////////
template<typename LCC>
bool test_ib(const char* filename)

View File

@ -1,202 +0,0 @@
#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;
}

View File

@ -1,35 +0,0 @@
# 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

View File

@ -1,26 +0,0 @@
# 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

View File

@ -1,30 +0,0 @@
# 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

View File

@ -1,21 +0,0 @@
# 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

View File

@ -1,33 +0,0 @@
# 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 one or more lines are too long

View File

@ -138,12 +138,7 @@ public Q_SLOTS:
private:
void showFileBox(QString title, QString fileName) {
QFile textFile(fileName);
bool b = textFile.open(QIODevice::ReadOnly);
if(!b){
QMessageBox::critical(this, tr("Error"),
tr("Could not open file %1.").arg(fileName));
return;
}
textFile.open(QIODevice::ReadOnly);
QMessageBox mb(QMessageBox::NoIcon,
title,
QTextStream(&textFile).readAll(),

View File

@ -1,7 +1,2 @@
@INCLUDE = ${CGAL_DOC_PACKAGE_DEFAULTS}
PROJECT_NAME = "CGAL ${CGAL_DOC_VERSION} - 3D Point Set"
EXTRACT_ALL = false
HIDE_UNDOC_MEMBERS = true
HIDE_UNDOC_CLASSES = true

View File

@ -43,6 +43,9 @@
/// I/O Functions for the \ref IOStreamXYZ
/// \ingroup PkgPointSet3IO
/// \defgroup PkgPointSet3IODeprecated Input/Output (Deprecated)
/// \ingroup PkgPointSet3IO
/// These I/O functions are deprecated and newer versions should be used.
/*!
\addtogroup PkgPointSet3Ref

View File

@ -13,8 +13,10 @@
#include <CGAL/license/Point_set_3.h>
#include <CGAL/IO/LAS/read_las_points.h>
#include <CGAL/IO/LAS/write_las_points.h>
#ifdef CGAL_LINKED_WITH_LASLIB
#include <CGAL/IO/read_las_points.h>
#include <CGAL/IO/write_las_points.h>
#endif // LAS
#include <fstream>
#include <string>

View File

@ -16,8 +16,8 @@
#include <CGAL/Named_function_parameters.h>
#include <CGAL/boost/graph/named_params_helper.h>
#include <CGAL/IO/helpers.h>
#include <CGAL/IO/OFF/read_off_points.h>
#include <CGAL/IO/OFF/write_off_points.h>
#include <CGAL/IO/read_off_points.h>
#include <CGAL/IO/write_off_points.h>
#include <fstream>
#include <string>

View File

@ -15,8 +15,8 @@
#include <CGAL/Named_function_parameters.h>
#include <CGAL/boost/graph/named_params_helper.h>
#include <CGAL/IO/XYZ/read_xyz_points.h>
#include <CGAL/IO/XYZ/write_xyz_points.h>
#include <CGAL/IO/read_xyz_points.h>
#include <CGAL/IO/write_xyz_points.h>
#include <fstream>
#include <string>

View File

@ -18,6 +18,7 @@ Kernel_d
Modular_arithmetic
Number_types
Point_set_3
Point_set_processing_3
Polygon
Profiling_tools
Property_map

View File

@ -1,6 +1,7 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Point_set_3.h>
#include <CGAL/IO/write_xyz_points.h>
#include <CGAL/grid_simplify_point_set.h>
#include <fstream>

View File

@ -10,6 +10,23 @@ simplification, etc.).
\defgroup PkgPointSetProcessing3IO I/O Functions
\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
\cgalPkgDescriptionBegin{Point Set Processing,PkgPointSetProcessing3}
@ -67,14 +84,14 @@ simplification, etc.).
\cgalCRPSection{I/O (XYZ/OFF Formats)}
- \link PkgStreamSupportIoFuncsOFF OFF I/O Functions (`read_OFF()` and `write_OFF()`)\endlink
- \link PkgStreamSupportIoFuncsXYZ XYZ I/O Functions (`read_XYZ()` and `write_XYZ()`)\endlink
- \link PkgPointSetProcessing3IOOff OFF I/O Functions (`read_OFF()` and `write_OFF()`)\endlink
- \link PkgPointSetProcessing3IOXyz XYZ I/O Functions (`read_XYZ()` and `write_XYZ()`)\endlink
\cgalCRPSection{I/O (PLY Format)}
- \link PkgStreamSupportIoFuncsPLY `CGAL::IO::read_PLY()` \endlink
- \link PkgPointSetProcessing3IOPly `CGAL::IO::read_PLY()` \endlink
- `CGAL::IO::read_PLY_with_properties()`
- \link PkgStreamSupportIoFuncsPLY `CGAL::IO::write_PLY()` \endlink
- \link PkgPointSetProcessing3IOPly `CGAL::IO::write_PLY()` \endlink
- `CGAL::IO::write_PLY_with_properties()`
- `CGAL::IO::PLY_property<T>`
- `CGAL::IO::make_ply_point_reader()`

View File

@ -1,7 +1,6 @@
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Point_set_3/IO/LAS.h>
#include <CGAL/IO/LAS.h>
#include <CGAL/IO/PLY.h>
#include <CGAL/IO/read_las_points.h>
#include <CGAL/IO/write_ply_points.h>
#include <CGAL/jet_estimate_normals.h>
#include <CGAL/scanline_orient_normals.h>

View File

@ -1,7 +1,7 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/property_map.h>
#include <CGAL/IO/LAS.h>
#include <CGAL/IO/read_las_points.h>
#include <utility>
#include <vector>

View File

@ -1,7 +1,7 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/property_map.h>
#include <CGAL/IO/PLY.h>
#include <CGAL/IO/read_ply_points.h>
#include <utility>
#include <vector>

View File

@ -1,7 +1,8 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/property_map.h>
#include <CGAL/IO/XYZ.h>
#include <CGAL/IO/read_xyz_points.h>
#include <CGAL/IO/write_xyz_points.h>
#include <utility> // defines std::pair
#include <vector>

View File

@ -1,7 +1,8 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/property_map.h>
#include <CGAL/IO/LAS.h>
#include <CGAL/IO/read_las_points.h>
#include <CGAL/IO/write_las_points.h>
#include <utility>
#include <vector>

View File

@ -1,7 +1,7 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/property_map.h>
#include <CGAL/IO/PLY.h>
#include <CGAL/IO/write_ply_points.h>
#include <utility>
#include <vector>

View File

@ -1,22 +1,21 @@
// Copyright (c) 2017 GeometryFactory
// Copyright (c) 2017 Geometry Factory
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org);
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
// Author(s) : Simon Giraudot
#ifndef CGAL_IO_LAS_READ_LAS_POINTS_H
#define CGAL_IO_LAS_READ_LAS_POINTS_H
#ifndef CGAL_POINT_SET_PROCESSING_READ_LAS_POINTS_H
#define CGAL_POINT_SET_PROCESSING_READ_LAS_POINTS_H
#ifdef CGAL_LINKED_WITH_LASLIB
#include <CGAL/license/Point_set_processing_3.h>
#include <CGAL/config.h>
#include <CGAL/IO/LAS/Las_property.h>
#include <CGAL/IO/LAS.h>
#include <CGAL/property_map.h>
#include <CGAL/value_type_traits.h>
#include <CGAL/Kernel_traits.h>
@ -60,6 +59,89 @@ namespace CGAL {
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
namespace internal {
@ -227,10 +309,69 @@ void process_properties (const LASpoint& reader, OutputValueType& new_element,
} // namespace LAS
} // namespace internal
/// \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,
typename PointOutputIterator,
typename ... PropertyHandler>
@ -279,13 +420,49 @@ bool read_LAS_with_properties(std::istream& is,
/// \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,
typename PointOutputIterator,
typename CGAL_NP_TEMPLATE_PARAMETERS_NO_DEFAULT>
typename CGAL_NP_TEMPLATE_PARAMETERS>
bool read_LAS(std::istream& is,
PointOutputIterator output,
const CGAL_NP_CLASS& np)
const CGAL_NP_CLASS& np = parameters::default_values())
{
using parameters::choose_parameter;
using parameters::get_parameter;
@ -309,13 +486,47 @@ bool read_LAS(std::istream& is, OutputIterator output, const CGAL_NP_CLASS& np =
/// \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,
typename PointOutputIterator,
typename CGAL_NP_TEMPLATE_PARAMETERS_NO_DEFAULT>
typename CGAL_NP_TEMPLATE_PARAMETERS>
bool read_LAS(const std::string& filename,
PointOutputIterator output,
const CGAL_NP_CLASS& np)
const CGAL_NP_CLASS& np = parameters::default_values())
{
std::ifstream is(filename, std::ios::binary);
CGAL::IO::set_mode(is, CGAL::IO::BINARY);
@ -338,5 +549,4 @@ bool read_LAS(const std::string& fname, OutputIterator output, const CGAL_NP_CLA
} // namespace CGAL
#endif // CGAL_LINKED_WITH_LASLIB
#endif // CGAL_IO_LAS_READ_LAS_POINTS_H
#endif // CGAL_POINT_SET_PROCESSING_READ_LAS_POINTS_H

View File

@ -1,21 +1,18 @@
// 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.
// Copyright (c) 2007-09 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org);
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
// Author(s) : Pierre Alliez and Laurent Saboret
#ifndef CGAL_IO_OFF_READ_OFF_POINTS_H
#define CGAL_IO_OFF_READ_OFF_POINTS_H
#ifndef CGAL_POINT_SET_PROCESSING_READ_OFF_POINTS_H
#define CGAL_POINT_SET_PROCESSING_READ_OFF_POINTS_H
#include <CGAL/license/Point_set_processing_3.h>
#include <CGAL/IO/io.h>
#include <CGAL/property_map.h>
@ -24,12 +21,10 @@
#include <CGAL/Kernel_traits.h>
#include <CGAL/iterator.h>
#include <CGAL/type_traits/is_iterator.h>
#include <CGAL/IO/OFF.h>
#include <CGAL/Named_function_parameters.h>
#include <CGAL/boost/graph/named_params_helper.h>
#include <iostream>
#include <fstream>
#include <sstream>
@ -40,14 +35,54 @@ namespace CGAL {
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,
typename PointOutputIterator,
typename CGAL_NP_TEMPLATE_PARAMETERS_NO_DEFAULT>
typename CGAL_NP_TEMPLATE_PARAMETERS>
bool read_OFF(std::istream& is,
PointOutputIterator output,
const CGAL_NP_CLASS& np,
std::enable_if_t<CGAL::is_iterator<PointOutputIterator>::value>*
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;
@ -159,14 +194,54 @@ bool read_OFF(std::istream& is,
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,
typename PointOutputIterator,
typename CGAL_NP_TEMPLATE_PARAMETERS_NO_DEFAULT>
typename CGAL_NP_TEMPLATE_PARAMETERS>
bool read_OFF(const std::string& fname,
PointOutputIterator output,
const CGAL_NP_CLASS& np,
std::enable_if_t<CGAL::is_iterator<PointOutputIterator>::value>*
const CGAL_NP_CLASS& np = parameters::default_values()
#ifndef DOXYGEN_RUNNING
, std::enable_if_t<CGAL::is_iterator<PointOutputIterator>::value>* = nullptr
#endif
)
{
std::ifstream is(fname);
@ -198,4 +273,4 @@ bool read_OFF(const std::string& fname, OutputIterator output, const CGAL_NP_CLA
} // namespace CGAL
#endif // CGAL_IO_OFF_READ_OFF_POINTS_H
#endif // CGAL_POINT_SET_PROCESSING_READ_OFF_POINTS_H

View File

@ -0,0 +1,367 @@
// 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

View File

@ -1,24 +1,26 @@
// 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$
// $Id$
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
// Author(s) : Maxime Gimeno
#ifndef CGAL_STREAM_SUPPORT_IO_READ_POINTS_H
#define CGAL_STREAM_SUPPORT_IO_READ_POINTS_H
#ifndef CGAL_POINT_SET_PROCESSING_READ_POINTS_H
#define CGAL_POINT_SET_PROCESSING_READ_POINTS_H
#include <CGAL/license/Point_set_processing_3.h>
#include <CGAL/IO/helpers.h>
#include <CGAL/IO/OFF/read_off_points.h>
#include <CGAL/IO/PLY/read_ply_points.h>
#include <CGAL/IO/XYZ/read_xyz_points.h>
#include <CGAL/IO/read_off_points.h>
#include <CGAL/IO/read_ply_points.h>
#include <CGAL/IO/read_xyz_points.h>
#ifdef CGAL_LINKED_WITH_LASLIB
#include <CGAL/IO/LAS/read_las_points.h>
#include <CGAL/IO/read_las_points.h>
#endif
#include <fstream>
@ -29,7 +31,7 @@ namespace CGAL {
namespace IO {
/**
\ingroup IOstreamFunctions
\ingroup PkgPointSetProcessing3IO
\brief reads the point set from an input file.
@ -118,4 +120,4 @@ bool read_points(const std::string& fname, OutputIterator output, const NamedPar
} } // namespace CGAL::IO
#endif // CGAL_STREAM_SUPPORT_IO_READ_POINTS_H
#endif // CGAL_POINT_SET_PROCESSING_READ_POINTS_H

View File

@ -1,22 +1,19 @@
// 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.
// Copyright (c) 2007-09 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org);
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
// Author(s) : Pierre Alliez and Laurent Saboret
#ifndef CGAL_IO_PLY_READ_XYZ_POINTS_H
#define CGAL_IO_PLY_READ_XYZ_POINTS_H
#ifndef CGAL_POINT_SET_PROCESSING_READ_XYZ_POINTS_H
#define CGAL_POINT_SET_PROCESSING_READ_XYZ_POINTS_H
#include <CGAL/license/Point_set_processing_3.h>
#include <CGAL/IO/XYZ.h>
#include <CGAL/property_map.h>
#include <CGAL/value_type_traits.h>
#include <CGAL/Origin.h>
@ -35,13 +32,51 @@ namespace CGAL {
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,
typename OutputIterator,
typename CGAL_NP_TEMPLATE_PARAMETERS_NO_DEFAULT>
typename CGAL_NP_TEMPLATE_PARAMETERS>
bool read_XYZ(std::istream& is,
OutputIterator output,
const CGAL_NP_CLASS& np)
const CGAL_NP_CLASS& np = parameters::default_values())
{
using parameters::choose_parameter;
using parameters::get_parameter;
@ -143,13 +178,51 @@ bool read_XYZ(std::istream& is,
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,
typename OutputIterator,
typename CGAL_NP_TEMPLATE_PARAMETERS_NO_DEFAULT>
typename CGAL_NP_TEMPLATE_PARAMETERS>
bool read_XYZ(const std::string& fname,
OutputIterator output,
const CGAL_NP_CLASS& np)
const CGAL_NP_CLASS& np = parameters::default_values())
{
std::ifstream is(fname);
return read_XYZ<OutputIteratorValueType>(is, output, np);
@ -180,4 +253,4 @@ bool read_XYZ(const std::string& fname, OutputIterator output, const CGAL_NP_CLA
} // namespace CGAL
#endif // CGAL_IO_PLY_READ_XYZ_POINTS_H
#endif // CGAL_POINT_SET_PROCESSING_READ_XYZ_POINTS_H

View File

@ -1,21 +1,21 @@
// Copyright (c) 2017 GeometryFactory
// Copyright (c) 2017 Geometry Factory
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org);
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
// Author(s) : Simon Giraudot
#ifndef CGAL_IO_LAS_WRITE_LAS_POINTS_H
#define CGAL_IO_LAS_WRITE_LAS_POINTS_H
#ifndef CGAL_POINT_SET_PROCESSING_WRITE_LAS_POINTS_H
#define CGAL_POINT_SET_PROCESSING_WRITE_LAS_POINTS_H
#ifdef CGAL_LINKED_WITH_LASLIB
#include <CGAL/license/Point_set_processing_3.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/Named_function_parameters.h>
#include <CGAL/boost/graph/named_params_helper.h>
@ -62,7 +62,16 @@ namespace CGAL {
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>
std::tuple<PointMap, LAS_property::X, LAS_property::Y, LAS_property::Z >
make_las_point_writer(PointMap point_map)
@ -183,7 +192,33 @@ namespace LAS {
/// \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,
typename PointMap,
typename ... PropertyHandler>
@ -245,12 +280,47 @@ bool write_LAS_with_properties(std::ostream& os, ///< output stream.
return !os.fail();
}
// documented in ../LAS.h
template <typename PointRange, typename CGAL_NP_TEMPLATE_PARAMETERS_NO_DEFAULT>
/**
\ingroup PkgPointSetProcessing3IOLas
\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,
std::enable_if_t<internal::is_Range<PointRange>::value>*
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;
@ -268,12 +338,44 @@ bool write_LAS(std::ostream& os,
return write_LAS_with_properties(os, points, make_las_point_writer(point_map));
}
// documented in ../LAS.h
template <typename PointRange, typename CGAL_NP_TEMPLATE_PARAMETERS_NO_DEFAULT>
/**
\ingroup PkgPointSetProcessing3IOLas
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,
std::enable_if_t<internal::is_Range<PointRange>::value>*
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, std::ios::binary);
@ -285,5 +387,4 @@ bool write_LAS(const std::string& filename,
} // namespace CGAL
#endif // CGAL_LINKED_WITH_LASLIB
#endif // CGAL_IO_LAS_WRITE_LAS_POINTS_H
#endif // CGAL_POINT_SET_PROCESSING_WRITE_LAS_POINTS_H

View File

@ -0,0 +1,203 @@
// 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

View File

@ -0,0 +1,303 @@
// 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

View File

@ -1,23 +1,26 @@
// 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$
// $Id$
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
// Author(s) : Maxime Gimeno
#ifndef CGAL_STREAM_SUPPORT_IO_WRITE_POINTS_H
#define CGAL_STREAM_SUPPORT_IO_WRITE_POINTS_H
#ifndef CGAL_POINT_SET_PROCESSING_WRITE_POINTS_H
#define CGAL_POINT_SET_PROCESSING_WRITE_POINTS_H
#include <CGAL/license/Point_set_processing_3.h>
#include <CGAL/IO/helpers.h>
#include <CGAL/IO/OFF/write_off_points.h>
#include <CGAL/IO/PLY/write_ply_points.h>
#include <CGAL/IO/XYZ/write_xyz_points.h>
#include <CGAL/IO/write_off_points.h>
#include <CGAL/IO/write_ply_points.h>
#include <CGAL/IO/write_xyz_points.h>
#ifdef CGAL_LINKED_WITH_LASLIB
#include <CGAL/IO/LAS/write_las_points.h>
#include <CGAL/IO/write_las_points.h>
#endif
#include <iostream>
@ -28,7 +31,7 @@ namespace CGAL {
namespace IO {
/**
\ingroup IOstreamFunctions
\ingroup PkgPointSetProcessing3IO
\brief writes the range of `points` with properties to a file.
@ -112,4 +115,4 @@ bool write_points(const std::string& fname,
} } // namespace CGAL::IO
#endif // CGAL_STREAM_SUPPORT_IO_WRITE_POINTS_H
#endif // CGAL_POINT_SET_PROCESSING_WRITE_POINTS_H

View File

@ -0,0 +1,194 @@
// 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

View File

@ -1,4 +1,4 @@
POLYGON((0 0, 40 0, 40 40, 0 40, 0 0))
POLYGON((10 10 , 30 10, 30 30, 0 30, 10 10))
POLYGON((1 1, 2 1, 2 2, 1 2, 1 1))
POLYGON((11 11, 12 11, 12 12, 11 12, 11 11))
POLYGON((0 0, 40 0, 40 40, 0 40))
POLYGON((10 10 , 30 10, 30 30, 0 30))
POLYGON((1 1, 2 1, 2 2, 1 2))
POLYGON((11 11, 12 11, 12 12, 11 12))

View File

@ -1 +1 @@
POLYGON((0 0, 10 0, 10 6, 6 6, 6 4 , 10 4, 10 10, 0 10, 0 0))
POLYGON((0 0, 10 0, 10 6, 6 6, 6 4 , 10 4, 10 10, 0 10))

View File

@ -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.25)))
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)))

View File

@ -5,8 +5,8 @@
#include <CGAL/Shape_detection/Region_growing/Point_set.h>
#include <CGAL/IO/XYZ.h>
#include <CGAL/IO/PLY.h>
#include <CGAL/IO/read_xyz_points.h>
#include <CGAL/IO/write_ply_points.h>
#include <CGAL/Real_timer.h>

View File

@ -22,7 +22,6 @@ each specific format.
- \ref IOStreamMedit
- \ref IOStreamTetgen
- \ref IOStreamWKT
- \ref IOStreamVTKLCC
\section IOStreamOFF Object File Format (OFF)
@ -62,7 +61,7 @@ The following table lists some \cgal data structures that have I/O functions com
</tr>
<tr>
<td>Any point range</td>
<td>\link PkgStreamSupportIoFuncsOFF CGAL::IO::read_OFF(const std::string&, PointOutputIterator)\endlink</td>
<td>\link PkgPointSetProcessing3IOOff CGAL::IO::read_OFF(const std::string&, PointOutputIterator)\endlink</td>
</tr>
<tr>
<td>Polygon Soup</td>
@ -90,7 +89,7 @@ The following table lists some \cgal data structures that have I/O functions com
</tr>
<tr>
<td>Any point range</td>
<td>\link PkgStreamSupportIoFuncsOFF CGAL::IO::write_OFF(const std::string&, const PointRange&)\endlink</td>
<td>\link PkgPointSetProcessing3IOOff CGAL::IO::write_OFF(const std::string&, const PointRange&)\endlink</td>
</tr>
<tr>
<td>Polygon Soup</td>
@ -240,7 +239,7 @@ A precise specification of those formats is available <a href="https://paulbourk
</tr>
<tr>
<td>Any point range</td>
<td>\link PkgStreamSupportIoFuncsPLY CGAL::IO::read_PLY(const std::string&, PointRange&)\endlink</td>
<td>\link PkgPointSetProcessing3IOPly CGAL::IO::read_PLY(const std::string&, PointRange&)\endlink</td>
</tr>
<tr>
<td>Polygon Soup</td>
@ -264,7 +263,7 @@ A precise specification of those formats is available <a href="https://paulbourk
</tr>
<tr>
<td>Any point range</td>
<td>\link PkgStreamSupportIoFuncsPLY CGAL::IO::write_PLY(const std::string&, const PointRange&)\endlink</td>
<td>\link PkgPointSetProcessing3IOPly CGAL::IO::write_PLY(const std::string&, const PointRange&)\endlink</td>
</tr>
<tr>
<td>Polygon Soup</td>
@ -299,7 +298,7 @@ A precise specification of those formats is available
</tr>
<tr>
<td>Any point range</td>
<td>\link PkgStreamSupportIoFuncsLAS CGAL::IO::read_LAS(const std::string&, PointRange&)\endlink</td>
<td>\link PkgPointSetProcessing3IOLas CGAL::IO::read_LAS(const std::string&, PointRange&)\endlink</td>
</tr>
<tr>
<td rowspan="2">Output</td>
@ -309,7 +308,7 @@ A precise specification of those formats is available
</tr>
<tr>
<td>Any point range</td>
<td>\link PkgStreamSupportIoFuncsLAS CGAL::IO::write_LAS(const std::string&, const PointRange&)\endlink</td>
<td>\link PkgPointSetProcessing3IOLas CGAL::IO::write_LAS(const std::string&, const PointRange&)\endlink</td>
</tr>
</table>
@ -332,7 +331,7 @@ of its coordinates and other properties. Only coordinates and normals are curren
</tr>
<tr>
<td>Any point range</td>
<td>\link PkgStreamSupportIoFuncsXYZ CGAL::IO::read_XYZ(const std::string&, PointRange&)\endlink</td>
<td>\link PkgPointSetProcessing3IOXyz CGAL::IO::read_XYZ(const std::string&, PointRange&)\endlink</td>
</tr>
<tr>
<td rowspan="2">Output</td>
@ -342,7 +341,7 @@ of its coordinates and other properties. Only coordinates and normals are curren
</tr>
<tr>
<td>Any point range</td>
<td>\link PkgStreamSupportIoFuncsXYZ CGAL::IO::write_XYZ(const std::string&, const PointRange&)\endlink</td>
<td>\link PkgPointSetProcessing3IOXyz CGAL::IO::write_XYZ(const std::string&, const PointRange&)\endlink</td>
</tr>
</table>
@ -505,30 +504,6 @@ 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::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

View File

@ -306,23 +306,23 @@ The following table shows which file formats can be read from and written for po
</tr>
<tr>
<th>\ref IOStreamOFF "OFF"</th>
<td>\link PkgStreamSupportIoFuncsOFF `CGAL::IO::read_OFF()` \endlink</td>
<td>\link PkgStreamSupportIoFuncsOFF `CGAL::IO::write_OFF()` \endlink</td>
<td>\link PkgPointSetProcessing3IOOff `CGAL::IO::read_OFF()` \endlink</td>
<td>\link PkgPointSetProcessing3IOOff `CGAL::IO::write_OFF()` \endlink</td>
</tr>
<tr>
<th>\ref IOStreamXYZ "XYZ"</th>
<td>\link PkgStreamSupportIoFuncsXYZ `CGAL::IO::read_XYZ()` \endlink</td>
<td>\link PkgStreamSupportIoFuncsXYZ `CGAL::IO::write_XYZ()` \endlink</td>
<td>\link PkgPointSetProcessing3IOXyz `CGAL::IO::read_XYZ()` \endlink</td>
<td>\link PkgPointSetProcessing3IOXyz `CGAL::IO::write_XYZ()` \endlink</td>
</tr>
<tr>
<th>\ref IOStreamPLY "PLY"</th>
<td>\link PkgStreamSupportIoFuncsPLY `CGAL::IO::read_PLY()` \endlink</td>
<td>\link PkgStreamSupportIoFuncsPLY `CGAL::IO::write_PLY()` \endlink</td>
<td>\link PkgPointSetProcessing3IOPly `CGAL::IO::read_PLY()` \endlink</td>
<td>\link PkgPointSetProcessing3IOPly `CGAL::IO::write_PLY()` \endlink</td>
</tr>
<tr>
<th>\ref IOStreamLAS "LAS"</th>
<td>\link PkgStreamSupportIoFuncsLAS `CGAL::IO::read_LAS()` \endlink</td>
<td>\link PkgStreamSupportIoFuncsLAS `CGAL::IO::write_LAS()` \endlink</td>
<td>\link PkgPointSetProcessing3IOLas `CGAL::IO::read_LAS()` \endlink</td>
<td>\link PkgPointSetProcessing3IOLas `CGAL::IO::write_LAS()` \endlink</td>
</tr>
</table>

View File

@ -36,14 +36,6 @@
/// I/O Functions for the \ref IOStream3MF
/// \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
/// \ingroup PkgStreamSupportRef
@ -107,7 +99,5 @@ the printing mode.
- \link PkgStreamSupportIoFuncsVTK I/O for VTK files \endlink
- \link PkgStreamSupportIoFuncs3MF I/O for 3MF 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
*/

View File

@ -3,7 +3,6 @@ Arrangement_on_surface_2
BGL
Constrained_triangulation_3
Kernel_23
Linear_cell_complex
Manual
Mesh_2
Mesh_3

View File

@ -1,357 +0,0 @@
// 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

View File

@ -1,94 +0,0 @@
// 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

View File

@ -344,213 +344,6 @@ bool write_OFF(const std::string& fname,
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 CGAL

View File

@ -1,119 +0,0 @@
// 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

View File

@ -14,8 +14,8 @@
#include <CGAL/IO/PLY/PLY_reader.h>
#include <CGAL/IO/PLY/PLY_writer.h>
#include <CGAL/IO/helpers.h>
#include <CGAL/Named_function_parameters.h>
#include <CGAL/boost/graph/named_params_helper.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()
#ifndef DOXYGEN_RUNNING
, std::enable_if_t<internal::is_Range<PolygonRange>::value>* = nullptr
#endif // DOXYGEN_RUNNING
#endif
)
{
const bool binary = CGAL::parameters::choose_parameter(CGAL::parameters::get_parameter(np, internal_np::use_binary_mode), true);
@ -567,429 +567,8 @@ 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 CGAL
#include <CGAL/IO/PLY/read_ply_points.h>
#include <CGAL/IO/PLY/write_ply_points.h>
#endif // CGAL_IO_PLY_H

View File

@ -11,7 +11,6 @@
#ifndef 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/IO/io.h>
#include <CGAL/type_traits/is_iterator.h>

View File

@ -1,181 +0,0 @@
// 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

View File

@ -1,137 +0,0 @@
// 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

View File

@ -1,236 +0,0 @@
// 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

View File

@ -1,113 +0,0 @@
// 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

View File

@ -1,18 +0,0 @@
// 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

View File

@ -1,16 +0,0 @@
// 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

View File

@ -1,16 +0,0 @@
// 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

View File

@ -1,18 +0,0 @@
// 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

View File

@ -1,17 +0,0 @@
// 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

View File

@ -1,17 +0,0 @@
// 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

View File

@ -1,12 +0,0 @@
// 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>

View File

@ -1,17 +0,0 @@
// 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

View File

@ -1,7 +1,7 @@
#include <CGAL/Simple_cartesian.h>
#include <CGAL/config.h>
#include <CGAL/IO/PLY.h>
#include <CGAL/IO/read_ply_points.h>
#include <CGAL/property_map.h>
#include <boost/iterator/function_output_iterator.hpp>

Some files were not shown because too many files have changed in this diff Show More