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 #ifndef CGAL_DRAW_AOS_ARR_APPROXIMATION_CACHE_H
#define CGAL_DRAW_AOS_ARR_APPROXIMATION_CACHE_H #define CGAL_DRAW_AOS_ARR_APPROXIMATION_CACHE_H
#include <boost/range/iterator_range.hpp> #include <boost/range/iterator_range.hpp>
#include <CGAL/Arr_enums.h> #include <CGAL/Arr_enums.h>
@ -24,16 +25,14 @@
namespace CGAL { namespace CGAL {
namespace draw_aos { 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. * 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. * This cache stores the approximated geometry for each feature to avoid redundant calculations.
* @tparam Arrangement * @tparam Arrangement
*/ */
template <typename Arrangement> template <typename Arrangement>
class Arr_approximation_cache class Arr_approximation_cache {
{
using Geom_traits = typename Arrangement::Geometry_traits_2; using Geom_traits = typename Arrangement::Geometry_traits_2;
using Approx_traits = Arr_approximate_traits<Geom_traits>; using Approx_traits = Arr_approximate_traits<Geom_traits>;
@ -67,4 +66,5 @@ private:
} // namespace draw_aos } // namespace draw_aos
} // namespace CGAL } // namespace CGAL
#endif #endif

View File

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

View File

@ -15,6 +15,7 @@
#ifndef CGAL_DRAW_AOS_ARR_BOUNDED_APPROXIMATE_HALFEDGE_H #ifndef CGAL_DRAW_AOS_ARR_BOUNDED_APPROXIMATE_HALFEDGE_H
#define CGAL_DRAW_AOS_ARR_BOUNDED_APPROXIMATE_HALFEDGE_H #define CGAL_DRAW_AOS_ARR_BOUNDED_APPROXIMATE_HALFEDGE_H
#include <algorithm> #include <algorithm>
#include <array> #include <array>
#include <cstdlib> #include <cstdlib>
@ -32,16 +33,14 @@
namespace CGAL { namespace CGAL {
namespace draw_aos { 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 * 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 * succeeds a part within, the approximation may be skipped but there will be at least one point outside the bbox
* for indication. * for indication.
*/ */
template <typename Arrangement> template <typename Arrangement>
class Arr_bounded_approximate_halfedge class Arr_bounded_approximate_halfedge {
{
using Geom_traits = typename Arrangement::Geometry_traits_2; using Geom_traits = typename Arrangement::Geometry_traits_2;
using Halfedge_const_handle = typename Arrangement::Halfedge_const_handle; using Halfedge_const_handle = typename Arrangement::Halfedge_const_handle;
using Gt_point = typename Geom_traits::Point_2; 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>; has_approximate_xcv_with_bounds_v<Geom_traits, typename Geom_traits::Approximate_2>;
private: private:
struct Context : public Bounded_render_context struct Context : public Bounded_render_context {
{ Context(const Bounded_render_context& ctx, const X_monotone_curve_2& curve, Polyline& polyline) :
Context(const Bounded_render_context& ctx, const X_monotone_curve_2& curve, Polyline& polyline) Bounded_render_context(ctx),
: Bounded_render_context(ctx) m_polyline(polyline), m_curve(curve)
, m_polyline(polyline) {}
, m_curve(curve) {}
// Prevent accidental copying. // Prevent accidental copying.
Context(const Context&) = delete; Context(const Context&) = delete;
Context& operator=(const Context&) = delete; Context& operator=(const Context&) = delete;
public: 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. * \note Will be replaced after AosApproximateUnboundedTraits_2 is fully available.
* \param pt * \param pt
*/ */
@ -82,8 +80,8 @@ private:
// We need the last point if not yet x-inbound. // We need the last point if not yet x-inbound.
m_last_pt = pt; m_last_pt = pt;
return; return;
} else if(pt.x() > this->xmax()) }
return; else if (pt.x() > this->xmax()) return;
m_polyline.push_back(pt); m_polyline.push_back(pt);
m_last_pt = pt; m_last_pt = pt;
@ -99,12 +97,11 @@ private:
const X_monotone_curve_2& m_curve; 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 { Point boundary_intersection(const Context& ctx, Point pt, Boundary_side side) const {
std::optional<double> x, y; std::optional<double> x, y;
const Approx_line_2* line; const Approx_line_2* line = nullptr;
switch(side) { switch(side) {
case Boundary_side::Left: case Boundary_side::Left:
x = ctx.xmin(); x = ctx.xmin();
@ -130,8 +127,7 @@ private:
return Point(inter.x(), *y); 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. * \note This method will eventually be replaced by AosApproximateUnboundedTraits_2.
*/ */
@ -145,10 +141,12 @@ private:
if (ctx.last_pt()->y() < ctx.ymin()) { 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.ymin()) ctx.insert(boundary_intersection(ctx, pt, Boundary_side::Bottom));
if (pt.y() > ctx.ymax()) ctx.insert(boundary_intersection(ctx, pt, Boundary_side::Top)); 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.ymax()) ctx.insert(boundary_intersection(ctx, pt, Boundary_side::Top));
if (pt.y() < ctx.ymin()) ctx.insert(boundary_intersection(ctx, pt, Boundary_side::Bottom)); if (pt.y() < ctx.ymin()) ctx.insert(boundary_intersection(ctx, pt, Boundary_side::Bottom));
} else { }
else {
if (pt.y() < ctx.ymin()) if (pt.y() < ctx.ymin())
ctx.insert(boundary_intersection(ctx, pt, Boundary_side::Bottom)); ctx.insert(boundary_intersection(ctx, pt, Boundary_side::Bottom));
else if (pt.y() > ctx.ymax()) else if (pt.y() > ctx.ymax())
@ -159,8 +157,7 @@ private:
ctx.insert(pt); 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) { static bool is_in_x_range(const Context& ctx, const Gt_point& pt) {
const Geom_traits& traits = ctx.m_traits; const Geom_traits& traits = ctx.m_traits;
@ -170,8 +167,8 @@ private:
if constexpr(!has_parameter_space_in_x_2<Geom_traits>::value) { if constexpr(!has_parameter_space_in_x_2<Geom_traits>::value) {
const auto& min_pt = traits.construct_min_vertex_2_object()(curve); const auto& min_pt = traits.construct_min_vertex_2_object()(curve);
const auto& max_pt = traits.construct_max_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 && return ((traits.compare_x_2_object()(pt, min_pt) != CGAL::SMALLER) &&
traits.compare_x_2_object()(pt, max_pt) != CGAL::LARGER; (traits.compare_x_2_object()(pt, max_pt) != CGAL::LARGER));
} }
Comparison_result left_cmp; Comparison_result left_cmp;
@ -194,13 +191,11 @@ private:
return right_cmp != CGAL::LARGER; 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. * ordering, continuity, etc.
*/ */
static void transform_polyline(Context& ctx, Polyline& polyline, const Halfedge_const_handle& he) { static void transform_polyline(Context& ctx, Polyline& polyline, const Halfedge_const_handle& he)
transform_polyline_impl<Geom_traits>(ctx, polyline, he); { transform_polyline_impl<Geom_traits>(ctx, polyline, he); }
}
// For planar arrangements, we only need to reverse the polyline if the halfedge is rtl. // 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> 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; if (azimuth == 0 && he->direction() == ARR_LEFT_TO_RIGHT) azimuth = 2 * CGAL_PI;
std::transform(polyline.begin(), polyline.end(), polyline.begin(), std::transform(polyline.begin(), polyline.end(), polyline.begin(),
[azimuth](Point pt) { return Point(azimuth, pt.y()); }); [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 // 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()); polyline.back() = Point(2 * CGAL_PI, polyline.back().y());
} }
@ -245,19 +241,20 @@ private:
if (is_in_x_range(ctx, m_top_left)) { if (is_in_x_range(ctx, m_top_left)) {
if (compare_y_at_x_2(m_top_left, curve) == CGAL::SMALLER) { 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())}); 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())}); polyline.insert(polyline.end(), {Approx_traits::Null_point, Point(ctx.xmin(), ctx.ymin())});
} }
} }
traits.approximate_2_object()(curve, ctx.m_approx_error, traits.approximate_2_object()(curve, ctx.m_approx_error,
boost::make_function_output_iterator([&ctx, this](Approx_point 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.m_polyline.push_back(snap_to_boundary(ctx, ctx.to_uv(approx_pt))); }),
}),
ctx.bbox(), true); ctx.bbox(), true);
if (is_in_x_range(ctx, m_top_right)) { if (is_in_x_range(ctx, m_top_right)) {
if (compare_y_at_x_2(m_top_right, curve) == CGAL::SMALLER) { 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}); 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}); 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 // 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> 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 { void approximate_curve_impl(Context& ctx) const {
m_ctx.m_traits.approximate_2_object()( auto approx = m_ctx.m_traits.approximate_2_object();
ctx.m_curve, ctx.m_approx_error, 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); 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. * \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 { Point snap_to_boundary(const Context& ctx, Point pt) const {
Approx_nt x = pt.x(), y = pt.y(); Approx_nt x = pt.x(), y = pt.y();
if(std::abs(x - ctx.xmin()) < m_ep_left) if (std::abs(x - ctx.xmin()) < m_ep_left) x = ctx.xmin();
x = ctx.xmin(); else if (std::abs(x - ctx.xmax()) < m_ep_right) x = ctx.xmax();
else if(std::abs(x - ctx.xmax()) < m_ep_right) if (std::abs(y - ctx.ymin()) < m_ep_bottom) y = ctx.ymin();
x = ctx.xmax(); else if (std::abs(y - ctx.ymax()) < m_ep_top) y = ctx.ymax();
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); return Point(x, y);
} }
public: public:
Arr_bounded_approximate_halfedge(const Bounded_render_context& ctx) Arr_bounded_approximate_halfedge(const Bounded_render_context& ctx) :
: m_ctx(ctx) m_ctx(ctx),
, m_top(ctx.top_left(), ctx.top_right()) m_left(ctx.bottom_left(), ctx.top_left()),
, m_bottom(ctx.bottom_left(), ctx.bottom_right()) m_right(ctx.bottom_right(), ctx.top_right()),
, m_left(ctx.bottom_left(), ctx.top_left()) m_bottom(ctx.bottom_left(), ctx.bottom_right()),
, m_right(ctx.bottom_right(), ctx.top_right()) { m_top(ctx.top_left(), ctx.top_right()) {
Construct_gt_point_2<Geom_traits> ctr_p; Construct_gt_point_2<Geom_traits> ctr_p;
m_top_left = ctr_p(ctx.to_cartesian(ctx.top_left())); m_top_left = ctr_p(ctx.to_cartesian(ctx.top_left()));
m_top_right = ctr_p(ctx.to_cartesian(ctx.top_right())); m_top_right = ctr_p(ctx.to_cartesian(ctx.top_right()));
@ -332,11 +324,12 @@ public:
private: private:
const Bounded_render_context& m_ctx; 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; 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; Approx_nt m_ep_left, m_ep_right, m_ep_bottom, m_ep_top;
}; };
} // namespace draw_aos } // namespace draw_aos
} // namespace CGAL } // namespace CGAL
#endif #endif

View File

@ -23,8 +23,7 @@ namespace CGAL {
namespace draw_aos { namespace draw_aos {
template <typename Arrangement> template <typename Arrangement>
class Arr_bounded_approximate_vertex class Arr_bounded_approximate_vertex {
{
using Geom_traits = typename Arrangement::Geometry_traits_2; using Geom_traits = typename Arrangement::Geometry_traits_2;
using Point_2 = typename Geom_traits::Point_2; using Point_2 = typename Geom_traits::Point_2;
using Vertex_const_handle = typename Arrangement::Vertex_const_handle; 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>; using Bounded_render_context = Arr_bounded_render_context<Arrangement>;
public: public:
Arr_bounded_approximate_vertex(const Bounded_render_context& ctx) Arr_bounded_approximate_vertex(const Bounded_render_context& ctx) : m_ctx(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. * The function uses cached values if available.
* @precondition: The vertex must have an associated point. * @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. * @brief Triangulator for a face of an arrangement within a bounding box.
*/ */
template <typename Arrangement> template <typename Arrangement>
class Arr_bounded_face_triangulator class Arr_bounded_face_triangulator {
{
using Geom_traits = typename Arrangement::Geometry_traits_2; 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>; 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 }; 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: public:
Index() = default; Index() = default;
Index(int idx) Index(int idx) : m_index(idx) {}
: m_index(idx) {}
bool is_valid() const { return m_index != Invalid_index; } bool is_valid() const { return m_index != Invalid_index; }
operator int() const { return m_index; } operator int() const { return m_index; }
@ -111,8 +107,7 @@ public:
private: private:
static KPoint to_kpoint(Point pt) { return KPoint(pt.x(), pt.y()); } 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 * \pre side != Boundary_side::None
*/ */
@ -120,21 +115,15 @@ private:
CGAL_precondition(side != Boundary_side::None); CGAL_precondition(side != Boundary_side::None);
switch(side) { switch(side) {
case Boundary_side::Left: case Boundary_side::Left: return Point(pt.x() - offset, pt.y());
return Point(pt.x() - offset, pt.y()); case Boundary_side::Right: return Point(pt.x() + offset, pt.y());
case Boundary_side::Right: case Boundary_side::Top: return Point(pt.x(), pt.y() + offset);
return Point(pt.x() + offset, pt.y()); case Boundary_side::Bottom: return Point(pt.x(), pt.y() - offset);
case Boundary_side::Top: default: return pt; // Should not reach here
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 { 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; 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; 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 * 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. * 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: public:
Arr_bounded_face_triangulator(const Bounded_render_context& ctx, Face_const_handle fh) Arr_bounded_face_triangulator(const Bounded_render_context& ctx, Face_const_handle fh) :
: m_ctx(ctx) m_ctx(ctx),
, m_fh(fh) {} m_fh(fh)
{}
void push_back(Point pt) { void push_back(Point pt) {
CGAL_assertion_msg(m_curr_cst_begin.has_value(), "Call start_constraint() before push_back()."); 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()); 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 * \return Triangulated_face
*/ */

View File

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

View File

@ -15,6 +15,7 @@
#ifndef CGAL_DRAW_AOS_ARR_COORDINATE_CONVERTER_H #ifndef CGAL_DRAW_AOS_ARR_COORDINATE_CONVERTER_H
#define CGAL_DRAW_AOS_ARR_COORDINATE_CONVERTER_H #define CGAL_DRAW_AOS_ARR_COORDINATE_CONVERTER_H
#include <cmath> #include <cmath>
#include <CGAL/number_type_config.h> #include <CGAL/number_type_config.h>
@ -24,33 +25,28 @@
namespace CGAL { namespace CGAL {
namespace draw_aos { 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 * \tparam GeomTraits
*/ */
template <typename GeomTraits> template <typename GeomTraits>
class Arr_coordinate_converter class Arr_coordinate_converter {
{
using Geom_traits = GeomTraits; using Geom_traits = GeomTraits;
using Approx_traits = Arr_approximate_traits<Geom_traits>; using Approx_traits = Arr_approximate_traits<Geom_traits>;
using Approx_point = typename Approx_traits::Approx_point; using Approx_point = typename Approx_traits::Approx_point;
using Point = typename Approx_traits::Point; using Point = typename Approx_traits::Point;
public: public:
Arr_coordinate_converter(const GeomTraits& traits) Arr_coordinate_converter(const GeomTraits& traits) : m_traits(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 * \param pt
* \return Point * \return Point
*/ */
Point to_uv(Approx_point pt) const { return pt; } 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 * \param pt
* \return Approx_point * \return Approx_point
@ -61,10 +57,9 @@ private:
const GeomTraits& m_traits; 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 * 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. * azimuth == 0. The south pole has polar == 0.
* *
@ -73,8 +68,7 @@ private:
* \tparam atanY * \tparam atanY
*/ */
template <typename Kernel, int atanX, int 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 Geom_traits = Arr_geodesic_arc_on_sphere_traits_2<Kernel>;
using Approx_traits = Arr_approximate_traits<Geom_traits>; using Approx_traits = Arr_approximate_traits<Geom_traits>;
using Approx_point = typename Approx_traits::Approx_point; 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; using Point = typename Approx_traits::Point;
public: public:
Arr_coordinate_converter(const Geom_traits& traits) Arr_coordinate_converter(const Geom_traits& traits) : m_traits(traits) {}
: m_traits(traits) {}
Point to_uv(Approx_point point) const { Point to_uv(Approx_point point) const {
if(point.location() == Approx_point::MAX_BOUNDARY_LOC) return Point(0, CGAL_PI); 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 #ifndef CGAL_DRAW_AOS_ARR_FACE_POINT_GENERATOR_H
#define CGAL_DRAW_AOS_ARR_FACE_POINT_GENERATOR_H #define CGAL_DRAW_AOS_ARR_FACE_POINT_GENERATOR_H
#include <utility> #include <utility>
#include <variant> #include <variant>
#include <vector> #include <vector>
@ -30,8 +31,7 @@
namespace CGAL { namespace CGAL {
namespace draw_aos { namespace draw_aos {
/*! /*! \brief Generate face interior points.
* \brief Generate face interior points.
* *
* \tparam Arrangement * \tparam Arrangement
*/ */
@ -39,10 +39,9 @@ template <typename Arrangement, typename = void>
class Arr_face_point_generator; class Arr_face_point_generator;
template <typename Arrangement> template <typename Arrangement>
class Arr_face_point_generator< class Arr_face_point_generator<Arrangement,
Arrangement, std::enable_if_t<!is_or_derived_from_curved_surf_traits_v
std::enable_if_t<!is_or_derived_from_curved_surf_traits_v<typename Arrangement::Geometry_traits_2>>> <typename Arrangement::Geometry_traits_2>>> {
{
using Point_geom = typename Arr_approximate_traits<typename Arrangement::Geometry_traits_2>::Point; using Point_geom = typename Arr_approximate_traits<typename Arrangement::Geometry_traits_2>::Point;
using Face_const_handle = typename Arrangement::Face_const_handle; using Face_const_handle = typename Arrangement::Face_const_handle;
@ -55,8 +54,7 @@ public:
template <typename Arrangement> template <typename Arrangement>
class Arr_face_point_generator<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 Geom_traits = typename Arrangement::Geometry_traits_2;
using Approx_traits = Arr_approximate_traits<Geom_traits>; using Approx_traits = Arr_approximate_traits<Geom_traits>;
using Approx_nt = typename Approx_traits::Approx_nt; using Approx_nt = typename Approx_traits::Approx_nt;

View File

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

View File

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

View File

@ -15,6 +15,7 @@
#ifndef CGAL_DRAW_AOS_TYPE_UTILS_H #ifndef CGAL_DRAW_AOS_TYPE_UTILS_H
#define CGAL_DRAW_AOS_TYPE_UTILS_H #define CGAL_DRAW_AOS_TYPE_UTILS_H
#include <limits> #include <limits>
#include <vector> #include <vector>
#include <type_traits> #include <type_traits>
@ -34,8 +35,7 @@ enum class Boundary_side {
}; };
template <typename, typename = std::void_t<>> 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> template <typename Gt>
struct has_approximate_2_object<Gt, std::void_t<decltype(std::declval<Gt>().approximate_2_object())>> : std::true_type 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; inline constexpr bool has_approximate_2_object_v = has_approximate_2_object<Gt>::value;
template <typename, typename, typename = std::void_t<>> 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> template <typename Gt, typename A>
struct has_approximate_point<Gt, struct has_approximate_point<Gt,
A, A,
std::void_t<decltype(std::declval<A>()(std::declval<const typename Gt::Point_2&>()))>> std::void_t<decltype(std::declval<A>()(std::declval<const typename Gt::Point_2&>()))>> :
: std::true_type std::true_type
{}; {};
// Detect whether A has operator()(const Gt::Point_2&) // 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; inline constexpr bool has_approximate_point_v = has_approximate_point<Gt, A>::value;
template <typename, typename, typename, typename = std::void_t<>> 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> template <typename Gt, typename A, typename O>
struct has_approximate_xcv< struct has_approximate_xcv
Gt, <Gt,
A, A,
O, O,
std::void_t<decltype(std::declval<A&>()(std::declval<const typename Gt::X_monotone_curve_2&>(), 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> template <typename Gt, typename A, typename O>
struct has_approximate_xcv_with_bounds< struct has_approximate_xcv_with_bounds
Gt, <Gt,
A, A,
O, O,
std::void_t<decltype(std::declval<A&>()(std::declval<const typename Gt::X_monotone_curve_2&>(), 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> template <typename Gt>
struct has_is_in_x_range<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::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::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&) // 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<*, *, *> // Detect whether Gt is or derives from Arr_geodesic_arc_on_sphere_traits_2<*, *, *>
template <typename Gt> template <typename Gt>
struct is_or_derived_from_agas struct is_or_derived_from_agas {
{
private: private:
template <typename Kernel_, int AtanX, int AtanY> template <typename Kernel_, int AtanX, int AtanY>
static std::true_type test(const Arr_geodesic_arc_on_sphere_traits_2<Kernel_, AtanX, 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 // Static helpers to get template arguments from a geometry traits
template <typename Gt> template <typename Gt>
struct tmpl_args struct tmpl_args {};
{};
template <typename Kernel_, int AtanX, int AtanY> 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_; using Kernel = Kernel_;
static constexpr int atan_x = AtanX; static constexpr int atan_x = AtanX;
static constexpr int atan_y = AtanY; static constexpr int atan_y = AtanY;
}; };
/*! /*! \brief Approximation data types
* \brief Approximation data types
* *
* \tparam Gt Geometry traits * \tparam Gt Geometry traits
*/ */
template <typename Gt> template <typename Gt>
class Arr_approximate_traits class Arr_approximate_traits {
{
using Geom_traits = Gt; using Geom_traits = Gt;
template <typename P, typename I> template <typename P, typename I>
struct Triangle_soup_ struct Triangle_soup_ {
{
using Index = I; using Index = I;
using Triangle = std::array<Index, 3>; using Triangle = std::array<Index, 3>;
using Point = P; using Point = P;
@ -198,8 +190,7 @@ public:
* \tparam Gt Geometry traits * \tparam Gt Geometry traits
*/ */
template <typename Gt> template <typename Gt>
class Construct_gt_point_2 class Construct_gt_point_2 {
{
using Approx_traits = Arr_approximate_traits<Gt>; using Approx_traits = Arr_approximate_traits<Gt>;
using Approx_point = typename Approx_traits::Approx_point; using Approx_point = typename Approx_traits::Approx_point;
using Gt_point = typename Gt::Point_2; using Gt_point = typename Gt::Point_2;
@ -210,8 +201,7 @@ public:
// Specialization for Arr_geodesic_arc_on_sphere_traits_2 // Specialization for Arr_geodesic_arc_on_sphere_traits_2
template <typename Kernel, int AtanX, int AtanY> 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 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_traits = Arr_approximate_traits<Arr_geodesic_arc_on_sphere_traits_2<Kernel, AtanX, AtanY>>;
using Approx_point = typename Approx_traits::Approx_point; 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: public:
Gt_point operator()(const Approx_point& pt) const { Gt_point operator()(const Approx_point& pt) const {
using Direction_3 = typename Kernel::Direction_3; 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 <unordered_map>
#include <utility> #include <utility>
#include <QApplication>
#include <CGAL/Arr_geodesic_arc_on_sphere_traits_2.h> #include <CGAL/Arr_geodesic_arc_on_sphere_traits_2.h>
#include <CGAL/Arrangement_2.h> #include <CGAL/Arrangement_2.h>
#include <CGAL/Arrangement_on_surface_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> 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) { void draw_region_impl2(const T& /* traits */, const A& /* approximate */, Halfedge_const_handle curr)
draw_exact_region(curr); { draw_exact_region(curr); }
}
//! //!
template <typename T, typename A, std::enable_if_t<has_approximate_point_v<T, A>, int> = 0> 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) { auto draw_region_impl2(const T& /* traits */, const A& approx, Halfedge_const_handle curr)
draw_approximate_region(curr, approx); { draw_approximate_region(curr, approx); }
}
/*! draws a region, where the traits does not has approximate_2_object. /*! 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> 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) { void draw_region_impl1(const T& /* traits */, Halfedge_const_handle curr)
draw_exact_region(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> 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) { 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); }
draw_region_impl2(traits, traits.approximate_2_object(), curr);
}
/*! draws a geodesic region /*! draws a geodesic region
*/ */
@ -191,10 +188,8 @@ public:
auto ctr_min = traits->construct_min_vertex_2_object(); auto ctr_min = traits->construct_min_vertex_2_object();
auto ctr_max = traits->construct_max_vertex_2_object(); auto ctr_max = traits->construct_max_vertex_2_object();
m_gs.add_segment(ctr_min(curve), ctr_max(curve)); m_gs.add_segment(ctr_min(curve), ctr_max(curve));
if (colored) if (colored) m_gs.add_segment(ctr_min(curve), ctr_max(curve), c);
m_gs.add_segment(ctr_min(curve), ctr_max(curve), c); else m_gs.add_segment(ctr_min(curve), ctr_max(curve));
else
m_gs.add_segment(ctr_min(curve), ctr_max(curve));
} }
/*! draws a region in an exact manner. /*! draws a region in an exact manner.
@ -204,9 +199,8 @@ public:
//! Add all faces. //! Add all faces.
template <typename Traits> template <typename Traits>
void add_faces(const Traits&) { void add_faces(const Traits&)
for (auto it = m_aos.unbounded_faces_begin(); it != m_aos.unbounded_faces_end(); ++it) add_face(it); { for (auto it = m_aos.unbounded_faces_begin(); it != m_aos.unbounded_faces_end(); ++it) add_face(it); }
}
//! Compile time dispatching //! Compile time dispatching
@ -214,47 +208,39 @@ public:
*/ */
template <typename Approximate> template <typename Approximate>
void draw_approximate_point(const Point& p, const Approximate& approx, bool colored, const CGAL::IO::Color& color) { void draw_approximate_point(const Point& p, const Approximate& approx, bool colored, const CGAL::IO::Color& color) {
if (colored) if (colored) m_gs.add_point(approx(p), color);
m_gs.add_point(approx(p), color); else m_gs.add_point(approx(p));
else
m_gs.add_point(approx(p));
} }
//! //!
void draw_exact_point(const Point& p, bool colored, const CGAL::IO::Color& color) { void draw_exact_point(const Point& p, bool colored, const CGAL::IO::Color& color) {
if (colored) if (colored) m_gs.add_point(p, color);
m_gs.add_point(p, color); else m_gs.add_point(p);
else
m_gs.add_point(p);
} }
//! //!
template <typename T, typename A, std::enable_if_t<!has_approximate_point_v<T, A>, int> = 0> template <typename T, typename A, std::enable_if_t<!has_approximate_point_v<T, A>, int> = 0>
void draw_point_impl2( void draw_point_impl2(const T& /* traits */, const A& /* approximate */, const Point& p, bool colored,
const T& /* traits */, const A& /* approximate */, const Point& p, bool colored, const CGAL::IO::Color& c) { const CGAL::IO::Color& c)
draw_exact_point(p, colored, c); { draw_exact_point(p, colored, c); }
}
//! //!
template <typename T, typename A, std::enable_if_t<has_approximate_point_v<T, A>, int> = 0> template <typename T, typename A, std::enable_if_t<has_approximate_point_v<T, A>, int> = 0>
auto auto
draw_point_impl2(const T& /* traits */, const A& approx, const Point& p, bool colored, const CGAL::IO::Color& 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); { draw_approximate_point(p, approx, colored, c); }
}
/*! draws a point, where the traits does not has approximate_2_object. /*! 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> 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) { void draw_point_impl1(const T& /* traits */, const Point& p, bool colored, const CGAL::IO::Color& c)
draw_exact_point(p, colored, c); { draw_exact_point(p, colored, c); }
}
/*! draws a point, where the traits does have approximate_2_object. /*! 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> 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) { 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); { draw_point_impl2(traits, traits.approximate_2_object(), p, colored, c); }
}
/*! draws a geodesic point. /*! draws a geodesic point.
*/ */
@ -271,10 +257,8 @@ public:
auto z = ap.dz(); auto z = ap.dz();
auto l = std::sqrt(x * x + y * y + z * z); auto l = std::sqrt(x * x + y * y + z * z);
Approx_point_3 p3(x / l, y / l, z / l); Approx_point_3 p3(x / l, y / l, z / l);
if (colored) if (colored) m_gs.add_point(p3, color);
m_gs.add_point(p3, color); else m_gs.add_point(p3);
else
m_gs.add_point(p3);
} }
//! draws a point. //! draws a point.
@ -386,10 +370,8 @@ public:
auto it = polyline.begin(); auto it = polyline.begin();
auto prev = it++; auto prev = it++;
for (; it != polyline.end(); prev = it++) { for (; it != polyline.end(); prev = it++) {
if (colored) if (colored) m_gs.add_segment(*prev, *it, c);
m_gs.add_segment(*prev, *it, c); else m_gs.add_segment(*prev, *it);
else
m_gs.add_segment(*prev, *it);
} }
} }
@ -399,23 +381,20 @@ public:
const A& /* approximate */, const A& /* approximate */,
const X_monotone_curve& xcv, const X_monotone_curve& xcv,
bool colored, bool colored,
const CGAL::IO::Color& c) { const CGAL::IO::Color& c)
draw_exact_curve(xcv, colored, c); { draw_exact_curve(xcv, colored, c); }
}
/// ///
template <typename T, typename A, std::enable_if_t<has_approximate_point_v<T, A>, int> = 0> template <typename T, typename A, std::enable_if_t<has_approximate_point_v<T, A>, int> = 0>
auto draw_curve_impl2( auto draw_curve_impl2(const T& /* traits */, const A& approx, const X_monotone_curve& xcv, bool colored,
const T& /* traits */, const A& approx, const X_monotone_curve& xcv, bool colored, const CGAL::IO::Color& c) { const CGAL::IO::Color& c)
draw_approximate_curve(xcv, approx, colored, c); { draw_approximate_curve(xcv, approx, colored, c); }
}
/*! draws a curve, where the traits does not has approximate_2_object. /*! 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> 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) { 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); { draw_exact_curve(xcv, colored, c); }
}
/*! draws a curve, where the traits does have approximate_2_object. /*! 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) { 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"; // std::cout << "draw_curve (geodesic)\n";
using Traits = T; using Traits = T;
using Kernel = typename Traits::Kernel;
using Ak = typename Traits::Approximate_kernel; using Ak = typename Traits::Approximate_kernel;
using Ap = typename Traits::Approximate_point_2; using Ap = typename Traits::Approximate_point_2;
using Approx_point_3 = typename Ak::Point_3; using Approx_point_3 = typename Ak::Point_3;
@ -452,10 +430,8 @@ public:
auto z = it->dz(); auto z = it->dz();
auto l = std::sqrt(x * x + y * y + z * z); auto l = std::sqrt(x * x + y * y + z * z);
Approx_point_3 next(x / l, y / l, z / l); Approx_point_3 next(x / l, y / l, z / l);
if (colored) if (colored) m_gs.add_segment(prev, next, c);
m_gs.add_segment(prev, next, c); else m_gs.add_segment(prev, next);
else
m_gs.add_segment(prev, next);
prev = next; prev = next;
} }
} }
@ -535,11 +511,10 @@ protected:
m_halfedge_map[e->twin()] = Halfedge_const_handle(); // twin is created as well m_halfedge_map[e->twin()] = Halfedge_const_handle(); // twin is created as well
} }
virtual void before_split_edge(Halfedge_handle e, Vertex_handle v, virtual void before_split_edge(Halfedge_handle /* e */, Vertex_handle v,
const X_monotone_curve_2& c1, const X_monotone_curve_2& /* c1 */,
const X_monotone_curve_2& c2) override { 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 { 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 { 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()) if (auto it = m_halfedge_map.find(e1); it == m_halfedge_map.end())
@ -597,8 +572,7 @@ public:
} }
private: 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. * 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 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 * 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.enable_vertices();
gso.draw_vertex = [](const Arrangement&, const Vertex_const_handle&) { return true; }; gso.draw_vertex = [](const Arrangement&, const Vertex_const_handle&) { return true; };
gso.colored_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 { gso.vertex_color = [](const Arrangement&, const Vertex_const_handle& /* vh */) -> CGAL::IO::Color
return CGAL::IO::Color(255, 0, 0); { return CGAL::IO::Color(255, 0, 0); };
};
gso.enable_edges(); gso.enable_edges();
gso.draw_edge = [](const Arrangement&, const Halfedge_const_handle&) { return true; }; gso.draw_edge = [](const Arrangement&, const Halfedge_const_handle&) { return true; };
gso.colored_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 { gso.edge_color = [](const Arrangement&, const Halfedge_const_handle& /* heh */) -> CGAL::IO::Color
return CGAL::IO::Color(0, 0, 0); { return CGAL::IO::Color(0, 0, 0); };
};
gso.enable_faces(); gso.enable_faces();
gso.draw_face = [](const Arrangement&, const Face_const_handle&) { return true; }; gso.draw_face = [](const Arrangement&, const Face_const_handle&) { return true; };
gso.colored_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> template <typename GeometryTraits_2, typename TopologyTraits>
void add_to_graphics_scene(const CGAL_ARR_TYPE& aos, CGAL::Graphics_scene& graphics_scene) { 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, 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> typename CGAL_ARR_TYPE::Halfedge_const_handle,
gso; typename CGAL_ARR_TYPE::Face_const_handle> gso;
// colored face? // colored face?
gso.colored_face = [](const CGAL_ARR_TYPE&, typename CGAL_ARR_TYPE::Face_const_handle) -> bool { return true; }; gso.colored_face = [](const CGAL_ARR_TYPE&, typename CGAL_ARR_TYPE::Face_const_handle) -> bool { return true; };