Cleaned up; Pacify MSVC; suppressed warnings.

This commit is contained in:
Efi Fogel 2025-10-23 12:11:31 +03:00
parent 6314299598
commit 5ed29f9173
12 changed files with 334 additions and 423 deletions

View File

@ -15,6 +15,7 @@
#ifndef CGAL_DRAW_AOS_ARR_APPROXIMATION_CACHE_H
#define CGAL_DRAW_AOS_ARR_APPROXIMATION_CACHE_H
#include <boost/range/iterator_range.hpp>
#include <CGAL/Arr_enums.h>
@ -24,16 +25,14 @@
namespace CGAL {
namespace draw_aos {
/**
* @brief Cache class for approximating arrangement on surface.
/** @brief Cache class for approximating arrangement on surface.
*
* When iterating over the arrangement dcel, a feature(vertex, halfedge, face) might be visited multiple times.
* This cache stores the approximated geometry for each feature to avoid redundant calculations.
* @tparam Arrangement
*/
template <typename Arrangement>
class Arr_approximation_cache
{
class Arr_approximation_cache {
using Geom_traits = typename Arrangement::Geometry_traits_2;
using Approx_traits = Arr_approximate_traits<Geom_traits>;
@ -67,4 +66,5 @@ private:
} // namespace draw_aos
} // namespace CGAL
#endif

View File

@ -15,6 +15,7 @@
#ifndef CGAL_DRAW_AOS_ARR_BOUNDED_APPROXIMATE_FACE_H
#define CGAL_DRAW_AOS_ARR_BOUNDED_APPROXIMATE_FACE_H
#include <iterator>
#include <optional>
#include <utility>

View File

@ -15,6 +15,7 @@
#ifndef CGAL_DRAW_AOS_ARR_BOUNDED_APPROXIMATE_HALFEDGE_H
#define CGAL_DRAW_AOS_ARR_BOUNDED_APPROXIMATE_HALFEDGE_H
#include <algorithm>
#include <array>
#include <cstdlib>
@ -32,16 +33,14 @@
namespace CGAL {
namespace draw_aos {
/**
* @brief Functor to approximate an x-monotone curve within an bounding box.
/** @brief Functor to approximate an x-monotone curve within an bounding box.
*
* The Approximation is done from xmin to xmax with a given step. For parts outbound the y limits and precedes or
* succeeds a part within, the approximation may be skipped but there will be at least one point outside the bbox
* for indication.
*/
template <typename Arrangement>
class Arr_bounded_approximate_halfedge
{
class Arr_bounded_approximate_halfedge {
using Geom_traits = typename Arrangement::Geometry_traits_2;
using Halfedge_const_handle = typename Arrangement::Halfedge_const_handle;
using Gt_point = typename Geom_traits::Point_2;
@ -61,19 +60,18 @@ class Arr_bounded_approximate_halfedge
has_approximate_xcv_with_bounds_v<Geom_traits, typename Geom_traits::Approximate_2>;
private:
struct Context : public Bounded_render_context
{
Context(const Bounded_render_context& ctx, const X_monotone_curve_2& curve, Polyline& polyline)
: Bounded_render_context(ctx)
, m_polyline(polyline)
, m_curve(curve) {}
struct Context : public Bounded_render_context {
Context(const Bounded_render_context& ctx, const X_monotone_curve_2& curve, Polyline& polyline) :
Bounded_render_context(ctx),
m_polyline(polyline), m_curve(curve)
{}
// Prevent accidental copying.
Context(const Context&) = delete;
Context& operator=(const Context&) = delete;
public:
/*!
* \brief Insert a point to the polyline if it is within the x-range of the curve
/*! \brief Insert a point to the polyline if it is within the x-range of the curve
* \note Will be replaced after AosApproximateUnboundedTraits_2 is fully available.
* \param pt
*/
@ -82,8 +80,8 @@ private:
// We need the last point if not yet x-inbound.
m_last_pt = pt;
return;
} else if(pt.x() > this->xmax())
return;
}
else if (pt.x() > this->xmax()) return;
m_polyline.push_back(pt);
m_last_pt = pt;
@ -99,12 +97,11 @@ private:
const X_monotone_curve_2& m_curve;
};
/*!
* \brief Computes the intersection point between the given boundary side and the line segment from last_pt to pt.
/*! \brief Computes the intersection point between the given boundary side and the line segment from last_pt to pt.
*/
Point boundary_intersection(const Context& ctx, Point pt, Boundary_side side) const {
std::optional<double> x, y;
const Approx_line_2* line;
const Approx_line_2* line = nullptr;
switch(side) {
case Boundary_side::Left:
x = ctx.xmin();
@ -130,8 +127,7 @@ private:
return Point(inter.x(), *y);
}
/*!
* \brief Trace approximated curve point in ltr ordering, adding boundary intersections if necessary.
/*! \brief Trace approximated curve point in ltr ordering, adding boundary intersections if necessary.
*
* \note This method will eventually be replaced by AosApproximateUnboundedTraits_2.
*/
@ -145,10 +141,12 @@ private:
if (ctx.last_pt()->y() < ctx.ymin()) {
if (pt.y() > ctx.ymin()) ctx.insert(boundary_intersection(ctx, pt, Boundary_side::Bottom));
if (pt.y() > ctx.ymax()) ctx.insert(boundary_intersection(ctx, pt, Boundary_side::Top));
} else if(ctx.last_pt()->y() > ctx.ymax()) {
}
else if (ctx.last_pt()->y() > ctx.ymax()) {
if (pt.y() < ctx.ymax()) ctx.insert(boundary_intersection(ctx, pt, Boundary_side::Top));
if (pt.y() < ctx.ymin()) ctx.insert(boundary_intersection(ctx, pt, Boundary_side::Bottom));
} else {
}
else {
if (pt.y() < ctx.ymin())
ctx.insert(boundary_intersection(ctx, pt, Boundary_side::Bottom));
else if (pt.y() > ctx.ymax())
@ -159,8 +157,7 @@ private:
ctx.insert(pt);
}
/*!
* \brief Check if the point is within the x-range of the curve.
/*! \brief Check if the point is within the x-range of the curve.
*/
static bool is_in_x_range(const Context& ctx, const Gt_point& pt) {
const Geom_traits& traits = ctx.m_traits;
@ -170,8 +167,8 @@ private:
if constexpr(!has_parameter_space_in_x_2<Geom_traits>::value) {
const auto& min_pt = traits.construct_min_vertex_2_object()(curve);
const auto& max_pt = traits.construct_max_vertex_2_object()(curve);
return traits.compare_x_2_object()(pt, min_pt) != CGAL::SMALLER &&
traits.compare_x_2_object()(pt, max_pt) != CGAL::LARGER;
return ((traits.compare_x_2_object()(pt, min_pt) != CGAL::SMALLER) &&
(traits.compare_x_2_object()(pt, max_pt) != CGAL::LARGER));
}
Comparison_result left_cmp;
@ -194,13 +191,11 @@ private:
return right_cmp != CGAL::LARGER;
}
/*!
* \brief transform approximated curve points(ltr ordering) in place based on the halfedge, giving correct
/*! \brief transform approximated curve points(ltr ordering) in place based on the halfedge, giving correct
* ordering, continuity, etc.
*/
static void transform_polyline(Context& ctx, Polyline& polyline, const Halfedge_const_handle& he) {
transform_polyline_impl<Geom_traits>(ctx, polyline, he);
}
static void transform_polyline(Context& ctx, Polyline& polyline, const Halfedge_const_handle& he)
{ transform_polyline_impl<Geom_traits>(ctx, polyline, he); }
// For planar arrangements, we only need to reverse the polyline if the halfedge is rtl.
template <typename Gt, std::enable_if_t<!is_or_derived_from_curved_surf_traits_v<Gt>, int> = 0>
@ -224,7 +219,8 @@ private:
if (azimuth == 0 && he->direction() == ARR_LEFT_TO_RIGHT) azimuth = 2 * CGAL_PI;
std::transform(polyline.begin(), polyline.end(), polyline.begin(),
[azimuth](Point pt) { return Point(azimuth, pt.y()); });
} else if(polyline.back().x() == 0) {
}
else if (polyline.back().x() == 0) {
// For strictly x-monotone arcs whose target point sits on the boundary, the x should be set to 2 * CGAL_PI
polyline.back() = Point(2 * CGAL_PI, polyline.back().y());
}
@ -245,19 +241,20 @@ private:
if (is_in_x_range(ctx, m_top_left)) {
if (compare_y_at_x_2(m_top_left, curve) == CGAL::SMALLER) {
polyline.insert(polyline.end(), {Approx_traits::Null_point, Point(ctx.xmin(), ctx.ymax())});
} else if(compare_y_at_x_2(m_bottom_left, curve) == CGAL::LARGER) {
}
else if (compare_y_at_x_2(m_bottom_left, curve) == CGAL::LARGER) {
polyline.insert(polyline.end(), {Approx_traits::Null_point, Point(ctx.xmin(), ctx.ymin())});
}
}
traits.approximate_2_object()(curve, ctx.m_approx_error,
boost::make_function_output_iterator([&ctx, this](Approx_point approx_pt) {
ctx.m_polyline.push_back(snap_to_boundary(ctx, ctx.to_uv(approx_pt)));
}),
boost::make_function_output_iterator([&ctx, this](Approx_point approx_pt)
{ ctx.m_polyline.push_back(snap_to_boundary(ctx, ctx.to_uv(approx_pt))); }),
ctx.bbox(), true);
if (is_in_x_range(ctx, m_top_right)) {
if (compare_y_at_x_2(m_top_right, curve) == CGAL::SMALLER) {
polyline.insert(polyline.end(), {Point(ctx.xmax(), ctx.ymax()), Approx_traits::Null_point});
} else if(compare_y_at_x_2(m_bottom_right, curve) == CGAL::LARGER) {
}
else if (compare_y_at_x_2(m_bottom_right, curve) == CGAL::LARGER) {
polyline.insert(polyline.end(), {Point(ctx.xmax(), ctx.ymin()), Approx_traits::Null_point});
}
}
@ -266,36 +263,31 @@ private:
// If Approximate_2 does not support curve approximation with bounding box
template <typename Gt, std::enable_if_t<!has_approximate_xcv_with_bounds_v<Gt, typename Gt::Approximate_2>, int> = 0>
void approximate_curve_impl(Context& ctx) const {
m_ctx.m_traits.approximate_2_object()(
ctx.m_curve, ctx.m_approx_error,
auto approx = m_ctx.m_traits.approximate_2_object();
approx(ctx.m_curve, ctx.m_approx_error,
boost::make_function_output_iterator([&ctx, this](Approx_point pt) { trace_add(ctx, ctx.to_uv(pt)); }), true);
}
/*!
* \brief Adjusts a point by snapping it to the nearest boundary to reduce floating-point error.
/*! \brief Adjusts a point by snapping it to the nearest boundary to reduce floating-point error.
*
* \return The adjusted (snapped) point if it lies within snapping tolerance, or the original point otherwise.
*/
Point snap_to_boundary(const Context& ctx, Point pt) const {
Approx_nt x = pt.x(), y = pt.y();
if(std::abs(x - ctx.xmin()) < m_ep_left)
x = ctx.xmin();
else if(std::abs(x - ctx.xmax()) < m_ep_right)
x = ctx.xmax();
if(std::abs(y - ctx.ymin()) < m_ep_bottom)
y = ctx.ymin();
else if(std::abs(y - ctx.ymax()) < m_ep_top)
y = ctx.ymax();
if (std::abs(x - ctx.xmin()) < m_ep_left) x = ctx.xmin();
else if (std::abs(x - ctx.xmax()) < m_ep_right) x = ctx.xmax();
if (std::abs(y - ctx.ymin()) < m_ep_bottom) y = ctx.ymin();
else if (std::abs(y - ctx.ymax()) < m_ep_top) y = ctx.ymax();
return Point(x, y);
}
public:
Arr_bounded_approximate_halfedge(const Bounded_render_context& ctx)
: m_ctx(ctx)
, m_top(ctx.top_left(), ctx.top_right())
, m_bottom(ctx.bottom_left(), ctx.bottom_right())
, m_left(ctx.bottom_left(), ctx.top_left())
, m_right(ctx.bottom_right(), ctx.top_right()) {
Arr_bounded_approximate_halfedge(const Bounded_render_context& ctx) :
m_ctx(ctx),
m_left(ctx.bottom_left(), ctx.top_left()),
m_right(ctx.bottom_right(), ctx.top_right()),
m_bottom(ctx.bottom_left(), ctx.bottom_right()),
m_top(ctx.top_left(), ctx.top_right()) {
Construct_gt_point_2<Geom_traits> ctr_p;
m_top_left = ctr_p(ctx.to_cartesian(ctx.top_left()));
m_top_right = ctr_p(ctx.to_cartesian(ctx.top_right()));
@ -332,11 +324,12 @@ public:
private:
const Bounded_render_context& m_ctx;
Approx_line_2 m_left, m_right, m_top, m_bottom;
Approx_line_2 m_left, m_right, m_bottom, m_top;
Gt_point m_top_left, m_top_right, m_bottom_left, m_bottom_right;
Approx_nt m_ep_left, m_ep_right, m_ep_bottom, m_ep_top;
};
} // namespace draw_aos
} // namespace CGAL
#endif

View File

@ -23,8 +23,7 @@ namespace CGAL {
namespace draw_aos {
template <typename Arrangement>
class Arr_bounded_approximate_vertex
{
class Arr_bounded_approximate_vertex {
using Geom_traits = typename Arrangement::Geometry_traits_2;
using Point_2 = typename Geom_traits::Point_2;
using Vertex_const_handle = typename Arrangement::Vertex_const_handle;
@ -32,11 +31,9 @@ class Arr_bounded_approximate_vertex
using Bounded_render_context = Arr_bounded_render_context<Arrangement>;
public:
Arr_bounded_approximate_vertex(const Bounded_render_context& ctx)
: m_ctx(ctx) {}
Arr_bounded_approximate_vertex(const Bounded_render_context& ctx) : m_ctx(ctx) {}
/**
* @brief Approximate a vertex within the x-bounded range.
/** @brief Approximate a vertex within the x-bounded range.
*
* The function uses cached values if available.
* @precondition: The vertex must have an associated point.

View File

@ -54,8 +54,7 @@ namespace draw_aos {
* @brief Triangulator for a face of an arrangement within a bounding box.
*/
template <typename Arrangement>
class Arr_bounded_face_triangulator
{
class Arr_bounded_face_triangulator {
using Geom_traits = typename Arrangement::Geometry_traits_2;
constexpr static bool Is_on_curved_surface = is_or_derived_from_curved_surf_traits_v<Geom_traits>;
@ -74,15 +73,12 @@ class Arr_bounded_face_triangulator
enum Point_type { Vertex_only, Constraint_only, Vertex_and_constraint };
/*!
* \brief A index wrapper defaulted to invalid.
/*! \brief A index wrapper defaulted to invalid.
*/
class Index
{
class Index {
public:
Index() = default;
Index(int idx)
: m_index(idx) {}
Index(int idx) : m_index(idx) {}
bool is_valid() const { return m_index != Invalid_index; }
operator int() const { return m_index; }
@ -111,8 +107,7 @@ public:
private:
static KPoint to_kpoint(Point pt) { return KPoint(pt.x(), pt.y()); }
/*!
* \brief Offset a point on a specific boundary outward by a given offset.
/*! \brief Offset a point on a specific boundary outward by a given offset.
*
* \pre side != Boundary_side::None
*/
@ -120,21 +115,15 @@ private:
CGAL_precondition(side != Boundary_side::None);
switch(side) {
case Boundary_side::Left:
return Point(pt.x() - offset, pt.y());
case Boundary_side::Right:
return Point(pt.x() + offset, pt.y());
case Boundary_side::Top:
return Point(pt.x(), pt.y() + offset);
case Boundary_side::Bottom:
return Point(pt.x(), pt.y() - offset);
default:
return pt; // Should not reach here
case Boundary_side::Left: return Point(pt.x() - offset, pt.y());
case Boundary_side::Right: return Point(pt.x() + offset, pt.y());
case Boundary_side::Top: return Point(pt.x(), pt.y() + offset);
case Boundary_side::Bottom: return Point(pt.x(), pt.y() - offset);
default: return pt; // Should not reach here
}
}
/*!
* \brief Find the shared boundary side of two points, or None if they are not on the same boundary.
/*! \brief Find the shared boundary side of two points, or None if they are not on the same boundary.
*/
Boundary_side shared_boundary(const Point& pt1, const Point& pt2) const {
if (m_ctx.is_on_left(pt1) && m_ctx.is_on_left(pt2)) return Boundary_side::Left;
@ -144,8 +133,7 @@ private:
return Boundary_side::None;
}
/*!
* \brief Add a helper point on the shared boundary of two points if they are on the same boundary side.
/*! \brief Add a helper point on the shared boundary of two points if they are on the same boundary side.
*
* When triangulating a arrangement face within a bounding box, curves outside the bounding box are projected on the
* four sides of the bbox. Topological errors could be introduced if several segments are lying on the same side.
@ -197,9 +185,10 @@ private:
}
public:
Arr_bounded_face_triangulator(const Bounded_render_context& ctx, Face_const_handle fh)
: m_ctx(ctx)
, m_fh(fh) {}
Arr_bounded_face_triangulator(const Bounded_render_context& ctx, Face_const_handle fh) :
m_ctx(ctx),
m_fh(fh)
{}
void push_back(Point pt) {
CGAL_assertion_msg(m_curr_cst_begin.has_value(), "Call start_constraint() before push_back().");
@ -225,8 +214,7 @@ public:
m_cst_ranges.emplace_back(cst_begin, m_points.size());
}
/*!
* \brief Converts the triangulator to a triangulated face, moving internal data to the result.
/*! \brief Converts the triangulator to a triangulated face, moving internal data to the result.
*
* \return Triangulated_face
*/

View File

@ -25,21 +25,20 @@
namespace CGAL {
namespace draw_aos {
/**
* @brief Render arrangement on surface within a bounding box.
/** @brief Render arrangement on surface within a bounding box.
*/
template <typename Arrangement>
class Arr_bounded_renderer
{
class Arr_bounded_renderer {
using Geom_traits = typename Arrangement::Geometry_traits_2;
using Face_const_handle = typename Arrangement::Face_const_handle;
using Render_context = Arr_render_context<Arrangement>;
using Approx_cache = Arr_approximation_cache<Arrangement>;
public:
Arr_bounded_renderer(const Render_context& ctx, Bbox_2 bbox)
: m_ctx(ctx)
, m_bbox(bbox) {}
Arr_bounded_renderer(const Render_context& ctx, Bbox_2 bbox) :
m_ctx(ctx),
m_bbox(bbox)
{}
Approx_cache render() const {
Approx_cache cache;

View File

@ -15,6 +15,7 @@
#ifndef CGAL_DRAW_AOS_ARR_COORDINATE_CONVERTER_H
#define CGAL_DRAW_AOS_ARR_COORDINATE_CONVERTER_H
#include <cmath>
#include <CGAL/number_type_config.h>
@ -24,33 +25,28 @@
namespace CGAL {
namespace draw_aos {
/*!
* \brief class handling coordinate conversion between 2D parameterized surface coordinates and cartesian coordinates.
/*! \brief class handling coordinate conversion between 2D parameterized surface coordinates and cartesian coordinates.
*
* \tparam GeomTraits
*/
template <typename GeomTraits>
class Arr_coordinate_converter
{
class Arr_coordinate_converter {
using Geom_traits = GeomTraits;
using Approx_traits = Arr_approximate_traits<Geom_traits>;
using Approx_point = typename Approx_traits::Approx_point;
using Point = typename Approx_traits::Point;
public:
Arr_coordinate_converter(const GeomTraits& traits)
: m_traits(traits) {}
Arr_coordinate_converter(const GeomTraits& traits) : m_traits(traits) {}
/*!
* \brief Converts a point in cartesian coordinates to parameterized surface coordinates.
/*! \brief converts a point in cartesian coordinates to parameterized surface coordinates.
*
* \param pt
* \return Point
*/
Point to_uv(Approx_point pt) const { return pt; }
/*!
* \brief Converts a point in parameterized surface coordinates to cartesian coordinates.
/*! \brief Converts a point in parameterized surface coordinates to cartesian coordinates.
*
* \param pt
* \return Approx_point
@ -61,10 +57,9 @@ private:
const GeomTraits& m_traits;
};
/*!
* \brief Converter specialization for geodesic arc on sphere traits.
/*! \brief Converter specialization for geodesic arc on sphere traits.
*
* Provides conversions between spherical coordinates and right-handed Cartesian coordinates. Sphercial coordinates are
* provides conversions between spherical coordinates and right-handed Cartesian coordinates. Sphercial coordinates are
* represented as azimuth ( [0, 2 Pi) ) and polar ( [0, Pi] ) angle in radians. Points on the identification curve have
* azimuth == 0. The south pole has polar == 0.
*
@ -73,8 +68,7 @@ private:
* \tparam atanY
*/
template <typename Kernel, int atanX, int atanY>
class Arr_coordinate_converter<Arr_geodesic_arc_on_sphere_traits_2<Kernel, atanX, atanY>>
{
class Arr_coordinate_converter<Arr_geodesic_arc_on_sphere_traits_2<Kernel, atanX, atanY>> {
using Geom_traits = Arr_geodesic_arc_on_sphere_traits_2<Kernel>;
using Approx_traits = Arr_approximate_traits<Geom_traits>;
using Approx_point = typename Approx_traits::Approx_point;
@ -82,8 +76,7 @@ class Arr_coordinate_converter<Arr_geodesic_arc_on_sphere_traits_2<Kernel, atanX
using Point = typename Approx_traits::Point;
public:
Arr_coordinate_converter(const Geom_traits& traits)
: m_traits(traits) {}
Arr_coordinate_converter(const Geom_traits& traits) : m_traits(traits) {}
Point to_uv(Approx_point point) const {
if(point.location() == Approx_point::MAX_BOUNDARY_LOC) return Point(0, CGAL_PI);

View File

@ -15,6 +15,7 @@
#ifndef CGAL_DRAW_AOS_ARR_FACE_POINT_GENERATOR_H
#define CGAL_DRAW_AOS_ARR_FACE_POINT_GENERATOR_H
#include <utility>
#include <variant>
#include <vector>
@ -30,8 +31,7 @@
namespace CGAL {
namespace draw_aos {
/*!
* \brief Generate face interior points.
/*! \brief Generate face interior points.
*
* \tparam Arrangement
*/
@ -39,10 +39,9 @@ template <typename Arrangement, typename = void>
class Arr_face_point_generator;
template <typename Arrangement>
class Arr_face_point_generator<
Arrangement,
std::enable_if_t<!is_or_derived_from_curved_surf_traits_v<typename Arrangement::Geometry_traits_2>>>
{
class Arr_face_point_generator<Arrangement,
std::enable_if_t<!is_or_derived_from_curved_surf_traits_v
<typename Arrangement::Geometry_traits_2>>> {
using Point_geom = typename Arr_approximate_traits<typename Arrangement::Geometry_traits_2>::Point;
using Face_const_handle = typename Arrangement::Face_const_handle;
@ -55,8 +54,7 @@ public:
template <typename Arrangement>
class Arr_face_point_generator<Arrangement,
std::enable_if_t<is_or_derived_from_agas_v<typename Arrangement::Geometry_traits_2>>>
{
std::enable_if_t<is_or_derived_from_agas_v<typename Arrangement::Geometry_traits_2>>> {
using Geom_traits = typename Arrangement::Geometry_traits_2;
using Approx_traits = Arr_approximate_traits<Geom_traits>;
using Approx_nt = typename Approx_traits::Approx_nt;

View File

@ -15,6 +15,7 @@
#ifndef CGAL_DRAW_AOS_ARR_RENDER_CONTEXT_H
#define CGAL_DRAW_AOS_ARR_RENDER_CONTEXT_H
#include <cstdlib>
#include <memory>
#include <atomic>
@ -36,23 +37,22 @@
namespace CGAL {
namespace draw_aos {
/**
* @brief A cancellable context mixin for asynchronous operations. It also tracks elapsed time for performance
/** @brief A cancellable context mixin for asynchronous operations. It also tracks elapsed time for performance
* profiling.
*
* The idea is borrowed from golang with a simple implementation.
* @see https://pkg.go.dev/context
*/
class Arr_cancellable_context_mixin
{
class Arr_cancellable_context_mixin {
using Clock = std::chrono::steady_clock;
using Duration = Clock::duration;
using Time_point = std::chrono::time_point<Clock, Duration>;
protected:
Arr_cancellable_context_mixin()
: m_start_time(Clock::now())
, m_cancelled(std::make_shared<std::atomic<bool>>(false)) {}
Arr_cancellable_context_mixin() :
m_start_time(Clock::now()),
m_cancelled(std::make_shared<std::atomic<bool>>(false))
{}
public:
Time_point start_time() const { return m_start_time; }
@ -70,23 +70,20 @@ private:
std::shared_ptr<std::atomic<bool>> m_cancelled;
};
/**
* @brief Boundary context mixin for rendering arrangements within a bounding box.
/** @brief Boundary context mixin for rendering arrangements within a bounding box.
* Provides extended functionality for checking point-bbox relations.
*
* @tparam GeomTraits the geometry traits class.
*/
template <typename GeomTraits>
class Arr_bounds_context_mixin
{
class Arr_bounds_context_mixin {
using Geom_traits = GeomTraits;
using Approx_traits = Arr_approximate_traits<Geom_traits>;
using Point = typename Approx_traits::Point;
using Approx_nt = typename Approx_traits::Approx_nt;
protected:
Arr_bounds_context_mixin(const Bbox_2& bbox)
: m_bbox(bbox) {}
Arr_bounds_context_mixin(const Bbox_2& bbox) : m_bbox(bbox) {}
public:
double xmin() const { return m_bbox.xmin(); }
@ -118,22 +115,22 @@ template <typename GeomTraits>
using Arr_parameterization_context_mixin = Arr_coordinate_converter<GeomTraits>;
template <typename Arrangement>
class Arr_render_context : public Arr_cancellable_context_mixin,
public Arr_parameterization_context_mixin<typename Arrangement::Geometry_traits_2>
{
class Arr_render_context :
public Arr_cancellable_context_mixin,
public Arr_parameterization_context_mixin<typename Arrangement::Geometry_traits_2> {
using Cancellable_context_mixin = Arr_cancellable_context_mixin;
using Param_context_mixin = Arr_parameterization_context_mixin<typename Arrangement::Geometry_traits_2>;
using Geom_traits = typename Arrangement::Geometry_traits_2;
using Face_points_map = typename Arr_face_point_generator<Arrangement>::Face_points_map;
public:
Arr_render_context(const Arrangement& arr, double approx_error, Face_points_map& face_points)
: Cancellable_context_mixin()
, Param_context_mixin(*arr.geometry_traits())
, m_arr(arr)
, m_traits(*arr.geometry_traits())
, m_approx_error(approx_error)
, m_face_points(face_points) {
Arr_render_context(const Arrangement& arr, double approx_error, Face_points_map& face_points) :
Cancellable_context_mixin(),
Param_context_mixin(*arr.geometry_traits()),
m_arr(arr),
m_traits(*arr.geometry_traits()),
m_approx_error(approx_error),
m_face_points(face_points) {
#if defined(CGAL_DRAW_AOS_DEBUG) && defined(CGAL_DRAW_AOS_TRIANGULATOR_DEBUG_FILE_DIR)
std::filesystem::path debug_file_dir(CGAL_DRAW_AOS_TRIANGULATOR_DEBUG_FILE_DIR);
// clear the index file.
@ -142,9 +139,9 @@ public:
}
public:
const double m_approx_error;
const Arrangement& m_arr;
const Geom_traits& m_traits;
const double m_approx_error;
const Face_points_map& m_face_points;
#if defined(CGAL_DRAW_AOS_DEBUG)
@ -153,9 +150,9 @@ public:
};
template <typename Arrangement>
class Arr_bounded_render_context : public Arr_render_context<Arrangement>,
public Arr_bounds_context_mixin<typename Arrangement::Geometry_traits_2>
{
class Arr_bounded_render_context :
public Arr_render_context<Arrangement>,
public Arr_bounds_context_mixin<typename Arrangement::Geometry_traits_2> {
using Geom_traits = typename Arrangement::Geometry_traits_2;
using Approx_point = typename Geom_traits::Approximate_point_2;
using Render_context = Arr_render_context<Arrangement>;
@ -163,10 +160,11 @@ class Arr_bounded_render_context : public Arr_render_context<Arrangement>,
using Approx_cache = Arr_approximation_cache<Arrangement>;
public:
Arr_bounded_render_context(const Render_context& ctx, const Bbox_2& bbox, Approx_cache& cache)
: Render_context(ctx)
, Bounds_context_mixin(bbox)
, m_cache(cache) {}
Arr_bounded_render_context(const Render_context& ctx, const Bbox_2& bbox, Approx_cache& cache) :
Render_context(ctx),
Bounds_context_mixin(bbox),
m_cache(cache)
{}
public:
Approx_cache& m_cache;
@ -174,4 +172,5 @@ public:
} // namespace draw_aos
} // namespace CGAL
#endif

View File

@ -21,12 +21,7 @@
#include <cstdlib>
#include <type_traits>
#include <QtWidgets/QApplication>
#include <QtWidgets/QWidget>
#include <QtOpenGLWidgets/QtOpenGLWidgets>
#include <QtGui/QOpenGLFunctions>
#include <QtGui/QMouseEvent>
#include <QtGui/QKeyEvent>
#include <QWidget>
#include <CGAL/Qt/Basic_viewer.h>
#include <CGAL/Qt/camera.h>
@ -48,8 +43,7 @@
namespace CGAL {
namespace draw_aos {
/*!
* \brief Viewport helper functions
/*! \brief Viewport helper functions
*
* \tparam Arrangement
*/
@ -58,10 +52,9 @@ class Arr_viewport_helpers;
// Specialization for planar arrangements
template <typename Arrangement>
class Arr_viewport_helpers<
Arrangement,
std::enable_if_t<!is_or_derived_from_curved_surf_traits_v<typename Arrangement::Geometry_traits_2>>>
{
class Arr_viewport_helpers<Arrangement,
std::enable_if_t<! is_or_derived_from_curved_surf_traits_v
<typename Arrangement::Geometry_traits_2>>> {
using Geom_traits = typename Arrangement::Geometry_traits_2;
using Approx_traits = Arr_approximate_traits<Geom_traits>;
using Approx_point = typename Approx_traits::Approx_point;
@ -70,22 +63,18 @@ class Arr_viewport_helpers<
using Local_point = Buffer_for_vao::Local_point;
protected:
Arr_viewport_helpers(const Arrangement& arr)
: m_arr(arr) {}
Arr_viewport_helpers(const Arrangement& arr) : m_arr(arr) {}
/*!
* \brief Computes a subpixel-level approximation error based on the bounding box and viewport width.
/*! \brief Computes a subpixel-level approximation error based on the bounding box and viewport width.
*
* \param bbox
* \param viewport_width width of the viewport in pixels
* \return double
*/
double approximation_error(const Bbox_2& bbox, int viewport_width) const {
return bbox.x_span() / viewport_width;
}
double approximation_error(const Bbox_2& bbox, int viewport_width) const
{ return bbox.x_span() / viewport_width; }
/*!
* \brief Computes a parameter space bounding box that contains everything in the arrangement with some margin.
/*! \brief Computes a parameter space bounding box that contains everything in the arrangement with some margin.
*
* \note For arrangement induced by unbounded curves, the bounding box only fits all vertices.
* \return Bbox_2
@ -94,15 +83,15 @@ protected:
const auto& traits = *m_arr.geometry_traits();
Bbox_2 bbox;
// Computes a rough bounding box from the vertices.
for(const auto& vh : m_arr.vertex_handles()) {
for (const auto& vh : m_arr.vertex_handles())
bbox += traits.approximate_2_object()(vh->point()).bbox();
}
double approx_error = approximation_error(bbox, 100);
// Computes a more precise bounding box from the halfedges.
auto approx = traits.approximate_2_object();
for (const auto& he : m_arr.halfedge_handles()) {
traits.approximate_2_object()(
he->curve(), approx_error,
boost::make_function_output_iterator([this, &bbox](Approx_point pt) { bbox += pt.bbox(); }));
approx(he->curve(), approx_error,
boost::make_function_output_iterator([&bbox](Approx_point pt) { bbox += pt.bbox(); }));
}
// Place margin around the bbox.
double dx = bbox.x_span() * 0.1;
@ -114,8 +103,7 @@ protected:
return bbox;
}
/*!
* \brief Fits the camera to bbox.
/*! \brief Fits the camera to bbox.
*
* \param bbox
* \param camera
@ -125,8 +113,7 @@ protected:
cam.fitBoundingBox(Vec(bbox.xmin(), bbox.ymin(), 0.0), Vec(bbox.xmax(), bbox.ymax(), 0.0));
}
/*!
* \brief Computes parameter space axis aligned bounding box from camera parameters.
/*! \brief Computes parameter space axis aligned bounding box from camera parameters.
*
* \param cam
* \return Bbox_2
@ -155,8 +142,7 @@ protected:
return Bbox_2(xmin, ymin, xmax, ymax);
}
/*!
* \brief Converts a parameter space point to a local point of the buffer object.
/*! \brief Converts a parameter space point to a local point of the buffer object.
*
* \param pt
* \return Local_point
@ -170,8 +156,7 @@ private:
// Spherical arrangement specialization
template <typename Arrangement>
class Arr_viewport_helpers<Arrangement,
std::enable_if_t<is_or_derived_from_agas_v<typename Arrangement::Geometry_traits_2>>>
{
std::enable_if_t<is_or_derived_from_agas_v<typename Arrangement::Geometry_traits_2>>> {
using Geom_traits = typename Arrangement::Geometry_traits_2;
using Approx_traits = Arr_approximate_traits<Geom_traits>;
using Approx_point = typename Approx_traits::Approx_point;
@ -180,8 +165,7 @@ class Arr_viewport_helpers<Arrangement,
using Local_point = Buffer_for_vao::Local_point;
protected:
Arr_viewport_helpers(const Arrangement& arr)
: m_arr(arr) {}
Arr_viewport_helpers(const Arrangement& arr) : m_arr(arr) {}
Bbox_2 arr_bbox() const { return Bbox_2(0, 0, 2 * CGAL_PI, CGAL_PI); }
@ -217,8 +201,7 @@ private:
* \tparam GSOptions
*/
template <typename Arrangement, typename GSOptions>
class Arr_viewer : public Qt::Basic_viewer, Arr_viewport_helpers<Arrangement>
{
class Arr_viewer : public Qt::Basic_viewer, Arr_viewport_helpers<Arrangement> {
using Basic_viewer = Qt::Basic_viewer;
using Helpers = Arr_viewport_helpers<Arrangement>;
using Vertex_const_handle = typename Arrangement::Vertex_const_handle;
@ -231,11 +214,10 @@ class Arr_viewer : public Qt::Basic_viewer, Arr_viewport_helpers<Arrangement>
using Point_generator = Arr_face_point_generator<Arrangement>;
using Faces_point_map = typename Point_generator::Face_points_map;
struct Render_params
{
bool operator==(const Render_params& other) const {
return bbox == other.bbox && approx_error == other.approx_error;
}
struct Render_params {
bool operator==(const Render_params& other) const
{ return bbox == other.bbox && approx_error == other.approx_error; }
Bbox_2 bbox;
double approx_error{0};
};
@ -243,9 +225,8 @@ class Arr_viewer : public Qt::Basic_viewer, Arr_viewport_helpers<Arrangement>
constexpr static bool Is_on_curved_surface = is_or_derived_from_curved_surf_traits_v<Geom_traits>;
private:
static bool contains(const Bbox_2& bbox, const Point& pt) {
return bbox.xmin() <= pt.x() && pt.x() <= bbox.xmax() && bbox.ymin() <= pt.y() && pt.y() <= bbox.ymax();
}
static bool contains(const Bbox_2& bbox, const Point& pt)
{ return bbox.xmin() <= pt.x() && pt.x() <= bbox.xmax() && bbox.ymin() <= pt.y() && pt.y() <= bbox.ymax(); }
int viewport_width() const {
std::array<GLint, 4> viewport;
@ -273,10 +254,8 @@ private:
bool colored_face = m_gso.colored_face(m_arr, fh);
auto color = colored_face ? m_gso.face_color(m_arr, fh) : CGAL::IO::Color();
for (const auto& tri : tf.triangles) {
if(colored_face)
m_gs.face_begin(color);
else
m_gs.face_begin();
if (colored_face) m_gs.face_begin(color);
else m_gs.face_begin();
for (const auto i : tri) m_gs.add_point_in_face(this->to_local_point(tf.points[i]));
m_gs.face_end();
}
@ -311,9 +290,8 @@ private:
}
}
/*!
* \brief Rerender scene within the given bounding box.
/*! \brief Rerender scene within the given bounding box.
*
* \param bbox
*/
void rerender(const Render_params& params) {
@ -325,13 +303,13 @@ private:
}
public:
Arr_viewer(QWidget* parent, const Arrangement& arr, const GSOptions& gso, const char* title, Bbox_2 initial_bbox)
: Basic_viewer(parent, m_gs, title)
, Helpers(arr)
, m_gso(gso)
, m_arr(arr)
, m_coords(*arr.geometry_traits()) {
if(initial_bbox.x_span() == 0 || initial_bbox.y_span() == 0 || Is_on_curved_surface)
Arr_viewer(QWidget* parent, const Arrangement& arr, const GSOptions& gso, const char* title, Bbox_2 initial_bbox) :
Basic_viewer(parent, m_gs, title),
Helpers(arr),
m_gso(gso),
m_arr(arr),
m_coords(*arr.geometry_traits()) {
if ((initial_bbox.x_span() == 0) || (initial_bbox.y_span() == 0) || (Is_on_curved_surface))
m_initial_bbox = this->arr_bbox();
else
m_initial_bbox = initial_bbox;

View File

@ -15,6 +15,7 @@
#ifndef CGAL_DRAW_AOS_TYPE_UTILS_H
#define CGAL_DRAW_AOS_TYPE_UTILS_H
#include <limits>
#include <vector>
#include <type_traits>
@ -34,8 +35,7 @@ enum class Boundary_side {
};
template <typename, typename = std::void_t<>>
struct has_approximate_2_object : std::false_type
{};
struct has_approximate_2_object : std::false_type {};
template <typename Gt>
struct has_approximate_2_object<Gt, std::void_t<decltype(std::declval<Gt>().approximate_2_object())>> : std::true_type
@ -46,14 +46,13 @@ template <typename Gt>
inline constexpr bool has_approximate_2_object_v = has_approximate_2_object<Gt>::value;
template <typename, typename, typename = std::void_t<>>
struct has_approximate_point : std::false_type
{};
struct has_approximate_point : std::false_type {};
template <typename Gt, typename A>
struct has_approximate_point<Gt,
A,
std::void_t<decltype(std::declval<A>()(std::declval<const typename Gt::Point_2&>()))>>
: std::true_type
std::void_t<decltype(std::declval<A>()(std::declval<const typename Gt::Point_2&>()))>> :
std::true_type
{};
// Detect whether A has operator()(const Gt::Point_2&)
@ -61,12 +60,11 @@ template <typename Gt, typename A>
inline constexpr bool has_approximate_point_v = has_approximate_point<Gt, A>::value;
template <typename, typename, typename, typename = std::void_t<>>
struct has_approximate_xcv : std::false_type
{};
struct has_approximate_xcv : std::false_type {};
template <typename Gt, typename A, typename O>
struct has_approximate_xcv<
Gt,
struct has_approximate_xcv
<Gt,
A,
O,
std::void_t<decltype(std::declval<A&>()(std::declval<const typename Gt::X_monotone_curve_2&>(),
@ -84,8 +82,8 @@ struct has_approximate_xcv_with_bounds : std::false_type
{};
template <typename Gt, typename A, typename O>
struct has_approximate_xcv_with_bounds<
Gt,
struct has_approximate_xcv_with_bounds
<Gt,
A,
O,
std::void_t<decltype(std::declval<A&>()(std::declval<const typename Gt::X_monotone_curve_2&>(),
@ -112,8 +110,8 @@ struct has_is_in_x_range : std::false_type
template <typename Gt>
struct has_is_in_x_range<Gt,
std::void_t<decltype(std::declval<typename Gt::X_monotone_curve_2>().is_in_x_range(
std::declval<const typename Gt::Point_2&>()))>> : std::true_type
std::void_t<decltype(std::declval<typename Gt::X_monotone_curve_2>().is_in_x_range
(std::declval<const typename Gt::Point_2&>()))>> : std::true_type
{};
// Detect whether Gt::X_monotone_curve_2 has a member function bool is_in_x_range(const Gt::Point_2&)
@ -122,8 +120,7 @@ inline constexpr bool has_is_in_x_range_v = has_is_in_x_range<Gt>::value;
// Detect whether Gt is or derives from Arr_geodesic_arc_on_sphere_traits_2<*, *, *>
template <typename Gt>
struct is_or_derived_from_agas
{
struct is_or_derived_from_agas {
private:
template <typename Kernel_, int AtanX, int AtanY>
static std::true_type test(const Arr_geodesic_arc_on_sphere_traits_2<Kernel_, AtanX, AtanY>*);
@ -143,30 +140,25 @@ inline constexpr bool is_or_derived_from_curved_surf_traits_v = is_or_derived_fr
// Static helpers to get template arguments from a geometry traits
template <typename Gt>
struct tmpl_args
{};
struct tmpl_args {};
template <typename Kernel_, int AtanX, int AtanY>
struct tmpl_args<Arr_geodesic_arc_on_sphere_traits_2<Kernel_, AtanX, AtanY>>
{
struct tmpl_args<Arr_geodesic_arc_on_sphere_traits_2<Kernel_, AtanX, AtanY>> {
using Kernel = Kernel_;
static constexpr int atan_x = AtanX;
static constexpr int atan_y = AtanY;
};
/*!
* \brief Approximation data types
/*! \brief Approximation data types
*
* \tparam Gt Geometry traits
*/
template <typename Gt>
class Arr_approximate_traits
{
class Arr_approximate_traits {
using Geom_traits = Gt;
template <typename P, typename I>
struct Triangle_soup_
{
struct Triangle_soup_ {
using Index = I;
using Triangle = std::array<Index, 3>;
using Point = P;
@ -198,8 +190,7 @@ public:
* \tparam Gt Geometry traits
*/
template <typename Gt>
class Construct_gt_point_2
{
class Construct_gt_point_2 {
using Approx_traits = Arr_approximate_traits<Gt>;
using Approx_point = typename Approx_traits::Approx_point;
using Gt_point = typename Gt::Point_2;
@ -210,8 +201,7 @@ public:
// Specialization for Arr_geodesic_arc_on_sphere_traits_2
template <typename Kernel, int AtanX, int AtanY>
class Construct_gt_point_2<Arr_geodesic_arc_on_sphere_traits_2<Kernel, AtanX, AtanY>>
{
class Construct_gt_point_2<Arr_geodesic_arc_on_sphere_traits_2<Kernel, AtanX, AtanY>> {
using Geom_traits = Arr_geodesic_arc_on_sphere_traits_2<Kernel, AtanX, AtanY>;
using Approx_traits = Arr_approximate_traits<Arr_geodesic_arc_on_sphere_traits_2<Kernel, AtanX, AtanY>>;
using Approx_point = typename Approx_traits::Approx_point;
@ -220,7 +210,8 @@ class Construct_gt_point_2<Arr_geodesic_arc_on_sphere_traits_2<Kernel, AtanX, At
public:
Gt_point operator()(const Approx_point& pt) const {
using Direction_3 = typename Kernel::Direction_3;
return Gt_point(Direction_3(pt.dx(), pt.dy(), pt.dz()), static_cast<typename Gt_point::Location_type>(pt.location()));
return Gt_point(Direction_3(pt.dx(), pt.dy(), pt.dz()),
static_cast<typename Gt_point::Location_type>(pt.location()));
}
};

View File

@ -26,6 +26,8 @@
#include <unordered_map>
#include <utility>
#include <QApplication>
#include <CGAL/Arr_geodesic_arc_on_sphere_traits_2.h>
#include <CGAL/Arrangement_2.h>
#include <CGAL/Arrangement_on_surface_2.h>
@ -132,29 +134,24 @@ public:
//!
template <typename T, typename A, std::enable_if_t<!has_approximate_point_v<T, A>, int> = 0>
void draw_region_impl2(const T& /* traits */, const A& /* approximate */, Halfedge_const_handle curr) {
draw_exact_region(curr);
}
void draw_region_impl2(const T& /* traits */, const A& /* approximate */, Halfedge_const_handle curr)
{ draw_exact_region(curr); }
//!
template <typename T, typename A, std::enable_if_t<has_approximate_point_v<T, A>, int> = 0>
auto draw_region_impl2(const T& /* traits */, const A& approx, Halfedge_const_handle curr) {
draw_approximate_region(curr, approx);
}
auto draw_region_impl2(const T& /* traits */, const A& approx, Halfedge_const_handle curr)
{ draw_approximate_region(curr, approx); }
/*! draws a region, where the traits does not has approximate_2_object.
*/
template <typename T, std::enable_if_t<!has_approximate_2_object_v<T> && !is_or_derived_from_agas_v<T>, int> = 0>
void draw_region_impl1(const T& /* traits */, Halfedge_const_handle curr) {
draw_exact_region(curr);
}
void draw_region_impl1(const T& /* traits */, Halfedge_const_handle curr)
{ draw_exact_region(curr); }
///
template <typename T, std::enable_if_t<has_approximate_2_object_v<T> && !is_or_derived_from_agas_v<T>, int> = 0>
auto draw_region_impl1(const T& traits, Halfedge_const_handle curr) {
using Approximate = typename Gt::Approximate_2;
draw_region_impl2(traits, traits.approximate_2_object(), curr);
}
auto draw_region_impl1(const T& traits, Halfedge_const_handle curr)
{ draw_region_impl2(traits, traits.approximate_2_object(), curr); }
/*! draws a geodesic region
*/
@ -191,10 +188,8 @@ public:
auto ctr_min = traits->construct_min_vertex_2_object();
auto ctr_max = traits->construct_max_vertex_2_object();
m_gs.add_segment(ctr_min(curve), ctr_max(curve));
if (colored)
m_gs.add_segment(ctr_min(curve), ctr_max(curve), c);
else
m_gs.add_segment(ctr_min(curve), ctr_max(curve));
if (colored) m_gs.add_segment(ctr_min(curve), ctr_max(curve), c);
else m_gs.add_segment(ctr_min(curve), ctr_max(curve));
}
/*! draws a region in an exact manner.
@ -204,9 +199,8 @@ public:
//! Add all faces.
template <typename Traits>
void add_faces(const Traits&) {
for (auto it = m_aos.unbounded_faces_begin(); it != m_aos.unbounded_faces_end(); ++it) add_face(it);
}
void add_faces(const Traits&)
{ for (auto it = m_aos.unbounded_faces_begin(); it != m_aos.unbounded_faces_end(); ++it) add_face(it); }
//! Compile time dispatching
@ -214,47 +208,39 @@ public:
*/
template <typename Approximate>
void draw_approximate_point(const Point& p, const Approximate& approx, bool colored, const CGAL::IO::Color& color) {
if (colored)
m_gs.add_point(approx(p), color);
else
m_gs.add_point(approx(p));
if (colored) m_gs.add_point(approx(p), color);
else m_gs.add_point(approx(p));
}
//!
void draw_exact_point(const Point& p, bool colored, const CGAL::IO::Color& color) {
if (colored)
m_gs.add_point(p, color);
else
m_gs.add_point(p);
if (colored) m_gs.add_point(p, color);
else m_gs.add_point(p);
}
//!
template <typename T, typename A, std::enable_if_t<!has_approximate_point_v<T, A>, int> = 0>
void draw_point_impl2(
const T& /* traits */, const A& /* approximate */, const Point& p, bool colored, const CGAL::IO::Color& c) {
draw_exact_point(p, colored, c);
}
void draw_point_impl2(const T& /* traits */, const A& /* approximate */, const Point& p, bool colored,
const CGAL::IO::Color& c)
{ draw_exact_point(p, colored, c); }
//!
template <typename T, typename A, std::enable_if_t<has_approximate_point_v<T, A>, int> = 0>
auto
draw_point_impl2(const T& /* traits */, const A& approx, const Point& p, bool colored, const CGAL::IO::Color& c) {
draw_approximate_point(p, approx, colored, c);
}
draw_point_impl2(const T& /* traits */, const A& approx, const Point& p, bool colored, const CGAL::IO::Color& c)
{ draw_approximate_point(p, approx, colored, c); }
/*! draws a point, where the traits does not has approximate_2_object.
*/
template <typename T, std::enable_if_t<!has_approximate_2_object_v<T> && !is_or_derived_from_agas_v<T>, int> = 0>
void draw_point_impl1(const T& /* traits */, const Point& p, bool colored, const CGAL::IO::Color& c) {
draw_exact_point(p, colored, c);
}
void draw_point_impl1(const T& /* traits */, const Point& p, bool colored, const CGAL::IO::Color& c)
{ draw_exact_point(p, colored, c); }
/*! draws a point, where the traits does have approximate_2_object.
*/
template <typename T, std::enable_if_t<has_approximate_2_object_v<T> && !is_or_derived_from_agas_v<T>, int> = 0>
auto draw_point_impl1(const T& traits, const Point& p, bool colored, const CGAL::IO::Color& c) {
draw_point_impl2(traits, traits.approximate_2_object(), p, colored, c);
}
auto draw_point_impl1(const T& traits, const Point& p, bool colored, const CGAL::IO::Color& c)
{ draw_point_impl2(traits, traits.approximate_2_object(), p, colored, c); }
/*! draws a geodesic point.
*/
@ -271,10 +257,8 @@ public:
auto z = ap.dz();
auto l = std::sqrt(x * x + y * y + z * z);
Approx_point_3 p3(x / l, y / l, z / l);
if (colored)
m_gs.add_point(p3, color);
else
m_gs.add_point(p3);
if (colored) m_gs.add_point(p3, color);
else m_gs.add_point(p3);
}
//! draws a point.
@ -386,10 +370,8 @@ public:
auto it = polyline.begin();
auto prev = it++;
for (; it != polyline.end(); prev = it++) {
if (colored)
m_gs.add_segment(*prev, *it, c);
else
m_gs.add_segment(*prev, *it);
if (colored) m_gs.add_segment(*prev, *it, c);
else m_gs.add_segment(*prev, *it);
}
}
@ -399,23 +381,20 @@ public:
const A& /* approximate */,
const X_monotone_curve& xcv,
bool colored,
const CGAL::IO::Color& c) {
draw_exact_curve(xcv, colored, c);
}
const CGAL::IO::Color& c)
{ draw_exact_curve(xcv, colored, c); }
///
template <typename T, typename A, std::enable_if_t<has_approximate_point_v<T, A>, int> = 0>
auto draw_curve_impl2(
const T& /* traits */, const A& approx, const X_monotone_curve& xcv, bool colored, const CGAL::IO::Color& c) {
draw_approximate_curve(xcv, approx, colored, c);
}
auto draw_curve_impl2(const T& /* traits */, const A& approx, const X_monotone_curve& xcv, bool colored,
const CGAL::IO::Color& c)
{ draw_approximate_curve(xcv, approx, colored, c); }
/*! draws a curve, where the traits does not has approximate_2_object.
*/
template <typename T, std::enable_if_t<!has_approximate_2_object_v<T> && !is_or_derived_from_agas_v<T>, int> = 0>
void draw_curve_impl1(const T& /* traits */, const X_monotone_curve& xcv, bool colored, const CGAL::IO::Color& c) {
draw_exact_curve(xcv, colored, c);
}
void draw_curve_impl1(const T& /* traits */, const X_monotone_curve& xcv, bool colored, const CGAL::IO::Color& c)
{ draw_exact_curve(xcv, colored, c); }
/*! draws a curve, where the traits does have approximate_2_object.
*/
@ -431,7 +410,6 @@ public:
void draw_curve_impl1(const T& traits, const X_monotone_curve& xcv, bool colored, const CGAL::IO::Color& c) {
// std::cout << "draw_curve (geodesic)\n";
using Traits = T;
using Kernel = typename Traits::Kernel;
using Ak = typename Traits::Approximate_kernel;
using Ap = typename Traits::Approximate_point_2;
using Approx_point_3 = typename Ak::Point_3;
@ -452,10 +430,8 @@ public:
auto z = it->dz();
auto l = std::sqrt(x * x + y * y + z * z);
Approx_point_3 next(x / l, y / l, z / l);
if (colored)
m_gs.add_segment(prev, next, c);
else
m_gs.add_segment(prev, next);
if (colored) m_gs.add_segment(prev, next, c);
else m_gs.add_segment(prev, next);
prev = next;
}
}
@ -535,11 +511,10 @@ protected:
m_halfedge_map[e->twin()] = Halfedge_const_handle(); // twin is created as well
}
virtual void before_split_edge(Halfedge_handle e, Vertex_handle v,
const X_monotone_curve_2& c1,
const X_monotone_curve_2& c2) override {
if (m_vertex_map.find(v) == m_vertex_map.end()) m_vertex_map[v] = Vertex_const_handle(); // v is newly created
}
virtual void before_split_edge(Halfedge_handle /* e */, Vertex_handle v,
const X_monotone_curve_2& /* c1 */,
const X_monotone_curve_2& /* c2 */) override
{ if (m_vertex_map.find(v) == m_vertex_map.end()) m_vertex_map[v] = Vertex_const_handle(); }
virtual void after_split_edge(Halfedge_handle e1, Halfedge_handle e2) override {
if (auto it = m_halfedge_map.find(e1); it == m_halfedge_map.end())
@ -597,8 +572,7 @@ public:
}
private:
/*!
* Maps tracking the changes between the original arrangement and modified arrangement.
/*! maps tracking the changes between the original arrangement and modified arrangement.
* The key is the current feature, and the value is the corresponding feature before modification.
* If there is no entry about a feature, the corresponding feature is itself.
* If the value is a invalid handle, it means that the feature is newly created and thus has no corresponding
@ -774,15 +748,15 @@ void draw(const Arrangement& arr,
gso.enable_vertices();
gso.draw_vertex = [](const Arrangement&, const Vertex_const_handle&) { return true; };
gso.colored_vertex = [](const Arrangement&, const Vertex_const_handle&) { return true; };
gso.vertex_color = [](const Arrangement&, const Vertex_const_handle& vh) -> CGAL::IO::Color {
return CGAL::IO::Color(255, 0, 0);
};
gso.vertex_color = [](const Arrangement&, const Vertex_const_handle& /* vh */) -> CGAL::IO::Color
{ return CGAL::IO::Color(255, 0, 0); };
gso.enable_edges();
gso.draw_edge = [](const Arrangement&, const Halfedge_const_handle&) { return true; };
gso.colored_edge = [](const Arrangement&, const Halfedge_const_handle&) { return true; };
gso.edge_color = [](const Arrangement&, const Halfedge_const_handle& heh) -> CGAL::IO::Color {
return CGAL::IO::Color(0, 0, 0);
};
gso.edge_color = [](const Arrangement&, const Halfedge_const_handle& /* heh */) -> CGAL::IO::Color
{ return CGAL::IO::Color(0, 0, 0); };
gso.enable_faces();
gso.draw_face = [](const Arrangement&, const Face_const_handle&) { return true; };
gso.colored_face = [](const Arrangement&, const Face_const_handle&) { return true; };
@ -807,8 +781,8 @@ void add_to_graphics_scene(const CGAL_ARR_TYPE& aos, CGAL::Graphics_scene& graph
template <typename GeometryTraits_2, typename TopologyTraits>
void add_to_graphics_scene(const CGAL_ARR_TYPE& aos, CGAL::Graphics_scene& graphics_scene) {
CGAL::Graphics_scene_options<CGAL_ARR_TYPE, typename CGAL_ARR_TYPE::Vertex_const_handle,
typename CGAL_ARR_TYPE::Halfedge_const_handle, typename CGAL_ARR_TYPE::Face_const_handle>
gso;
typename CGAL_ARR_TYPE::Halfedge_const_handle,
typename CGAL_ARR_TYPE::Face_const_handle> gso;
// colored face?
gso.colored_face = [](const CGAL_ARR_TYPE&, typename CGAL_ARR_TYPE::Face_const_handle) -> bool { return true; };