Cleaned up

This commit is contained in:
Efi Fogel 2025-10-23 10:00:43 +03:00
parent 5df526f70c
commit 8e11587719
1 changed files with 380 additions and 416 deletions

View File

@ -37,12 +37,11 @@
namespace CGAL { namespace CGAL {
namespace draw_function_for_arrangement_2 namespace draw_aos {
{
template<typename Arr, typename GSOptions> template<typename Arr, typename GSOptions>
class Draw_arr_tool class Draw_arr_tool {
{ public:
public:
using Halfedge_const_handle=typename Arr::Halfedge_const_handle; using Halfedge_const_handle=typename Arr::Halfedge_const_handle;
using Vertex_const_handle=typename Arr::Vertex_const_handle; using Vertex_const_handle=typename Arr::Vertex_const_handle;
using Face_const_handle=typename Arr::Face_const_handle; using Face_const_handle=typename Arr::Face_const_handle;
@ -57,27 +56,24 @@ namespace draw_function_for_arrangement_2
m_aos(a_aos), m_gs(a_gs), m_gso(a_gso) m_aos(a_aos), m_gs(a_gs), m_gso(a_gso)
{} {}
/// Add a face. //! adds a face.
void add_face(Face_const_handle face) void add_face(Face_const_handle face) {
{
// std::cout << "add_face()\n"; // std::cout << "add_face()\n";
for (Inner_ccb_const_iterator it = face->inner_ccbs_begin(); for (Inner_ccb_const_iterator it = face->inner_ccbs_begin();
it != face->inner_ccbs_end(); ++it) it != face->inner_ccbs_end(); ++it)
{ add_ccb(*it); } add_ccb(*it);
if (! face->is_unbounded()) { if (! face->is_unbounded()) {
for (Outer_ccb_const_iterator it = face->outer_ccbs_begin(); for (Outer_ccb_const_iterator it = face->outer_ccbs_begin();
it != face->outer_ccbs_end(); ++it) it != face->outer_ccbs_end(); ++it) {
{
add_ccb(*it); add_ccb(*it);
draw_region(*it); draw_region(*it);
} }
} }
} }
/// Add a Connected Component of the Boundary. //! adds a Connected Component of the Boundary.
void add_ccb(Ccb_halfedge_const_circulator circ) void add_ccb(Ccb_halfedge_const_circulator circ) {
{
// std::cout << "add_ccb()\n"; // std::cout << "add_ccb()\n";
auto curr = circ; auto curr = circ;
do { do {
@ -88,9 +84,8 @@ namespace draw_function_for_arrangement_2
} while (++curr != circ); } while (++curr != circ);
} }
///! Draw a region. //! draws a region.
void draw_region(Ccb_halfedge_const_circulator circ) void draw_region(Ccb_halfedge_const_circulator circ) {
{
// std::cout << "draw_region()\n"; // std::cout << "draw_region()\n";
/* Check whether the traits has a member function called /* Check whether the traits has a member function called
* approximate_2_object() and if so check whether the return type, namely * approximate_2_object() and if so check whether the return type, namely
@ -107,10 +102,10 @@ namespace draw_function_for_arrangement_2
* *
* For now we use C++14 features. * For now we use C++14 features.
*/ */
if(m_gso.colored_face(m_aos, circ->face())) if (m_gso.colored_face(m_aos, circ->face()))
{ m_gs.face_begin(m_gso.face_color(m_aos, circ->face())); } m_gs.face_begin(m_gso.face_color(m_aos, circ->face()));
else else
{ m_gs.face_begin(); } m_gs.face_begin();
const auto* traits = this->m_aos.geometry_traits(); const auto* traits = this->m_aos.geometry_traits();
auto ext = find_smallest(circ, *traits); auto ext = find_smallest(circ, *traits);
@ -126,7 +121,7 @@ namespace draw_function_for_arrangement_2
m_gs.face_end(); m_gs.face_end();
} }
/// Compile time dispatching //! Compile time dispatching
#if 0 #if 0
template <typename T, typename I = void> template <typename T, typename I = void>
void draw_region_impl2(Halfedge_const_handle curr, T const&, long) void draw_region_impl2(Halfedge_const_handle curr, T const&, long)
@ -160,8 +155,7 @@ namespace draw_function_for_arrangement_2
Arr_geodesic_arc_on_sphere_traits_2<Kernel_, AtanX, AtanY> const& traits, Arr_geodesic_arc_on_sphere_traits_2<Kernel_, AtanX, AtanY> const& traits,
int) int)
{ {
if(!m_gso.draw_edge(m_aos, curr)) if (! m_gso.draw_edge(m_aos, curr)) return;
{ return; }
// std::cout << "draw_region_impl1()\n"; // std::cout << "draw_region_impl1()\n";
auto approx = traits.approximate_2_object(); auto approx = traits.approximate_2_object();
@ -189,17 +183,17 @@ namespace draw_function_for_arrangement_2
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(m_gso.colored_edge(m_aos, curr)) if (m_gso.colored_edge(m_aos, curr))
{ m_gs.add_segment(prev, next, m_gso.edge_color(m_aos, curr)); } m_gs.add_segment(prev, next, m_gso.edge_color(m_aos, curr));
else else
{ m_gs.add_segment(prev, next); } m_gs.add_segment(prev, next);
prev = next; prev = next;
// m_gs.add_point_in_face(*prev); // m_gs.add_point_in_face(*prev);
} }
} }
/*! Draw a region using approximate coordinates. /*! draws a region using approximate coordinates.
* Call this member function only if the geometry traits is equipped with * Call this member function only if the geometry traits is equipped with
* the coordinate-approximation functionality of a curve. * the coordinate-approximation functionality of a curve.
* This function must be inlined (e.g., a template) to enable the * This function must be inlined (e.g., a template) to enable the
@ -207,8 +201,7 @@ namespace draw_function_for_arrangement_2
*/ */
template <typename Approximate> template <typename Approximate>
void draw_approximate_region(Halfedge_const_handle curr, void draw_approximate_region(Halfedge_const_handle curr,
const Approximate& approx) const Approximate& approx) {
{
// std::cout << "draw_approximate_region()\n"; // std::cout << "draw_approximate_region()\n";
std::vector<typename Gt::Approximate_point_2> polyline; std::vector<typename Gt::Approximate_point_2> polyline;
double error(0.01); // TODO? (this->pixel_ratio()); double error(0.01); // TODO? (this->pixel_ratio());
@ -218,48 +211,44 @@ namespace draw_function_for_arrangement_2
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(m_gso.draw_edge(m_aos, curr)) if (m_gso.draw_edge(m_aos, curr)) {
{ if (m_gso.colored_edge(m_aos, curr))
if(m_gso.colored_edge(m_aos, curr)) m_gs.add_segment(*prev, *it, m_gso.edge_color(m_aos, curr));
{ m_gs.add_segment(*prev, *it, m_gso.edge_color(m_aos, curr)); }
else else
{ m_gs.add_segment(*prev, *it); } m_gs.add_segment(*prev, *it);
} }
m_gs.add_point_in_face(*prev); m_gs.add_point_in_face(*prev);
} }
} }
/// Draw an exact curve. //! draws an exact curve.
template <typename XMonotoneCurve> template <typename XMonotoneCurve>
void draw_exact_curve(const XMonotoneCurve& curve) void draw_exact_curve(const XMonotoneCurve& curve) {
{
const auto* traits = this->m_aos.geometry_traits(); const auto* traits = this->m_aos.geometry_traits();
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));
} }
/// Draw an exact region. //! draws an exact region.
void draw_exact_region(Halfedge_const_handle curr) void draw_exact_region(Halfedge_const_handle curr) {
{
// this->add_point_in_face(curr->source()->point()); // this->add_point_in_face(curr->source()->point());
draw_exact_curve(curr->curve()); draw_exact_curve(curr->curve());
} }
/// Add all faces. //! adds 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)
for (auto it=m_aos.unbounded_faces_begin(); it!=m_aos.unbounded_faces_end(); ++it) add_face(it);
{ add_face(it); }
} }
/// Add all faces. //! adds all faces.
template <typename Kernel_, int AtanX, int AtanY> template <typename Kernel_, int AtanX, int AtanY>
void add_faces(Arr_geodesic_arc_on_sphere_traits_2<Kernel_, AtanX, AtanY> const&) void add_faces(Arr_geodesic_arc_on_sphere_traits_2<Kernel_, AtanX, AtanY> const&)
{ add_face(m_aos.faces_begin()); } { add_face(m_aos.faces_begin()); }
/// Compile time dispatching //! Compile time dispatching
#if 0 #if 0
template <typename T> template <typename T>
void draw_point_impl2(const Point& p, T const&, long) { m_gs.add_point(p); } void draw_point_impl2(const Point& p, T const&, long) { m_gs.add_point(p); }
@ -281,9 +270,8 @@ namespace draw_function_for_arrangement_2
#else #else
template <typename T> template <typename T>
void draw_point_impl1(const Point& p, T const& traits, int, void draw_point_impl1(const Point& p, T const& traits, int,
bool colored, const CGAL::IO::Color& color) bool colored, const CGAL::IO::Color& color) {
{ if (colored)
if(colored)
{ m_gs.add_point(traits.approximate_2_object()(p), color); } { m_gs.add_point(traits.approximate_2_object()(p), color); }
else else
{ m_gs.add_point(traits.approximate_2_object()(p)); } { m_gs.add_point(traits.approximate_2_object()(p)); }
@ -296,8 +284,7 @@ namespace draw_function_for_arrangement_2
Arr_geodesic_arc_on_sphere_traits_2<Kernel_, AtanX, AtanY> const& traits, Arr_geodesic_arc_on_sphere_traits_2<Kernel_, AtanX, AtanY> const& traits,
int, int,
bool colored, bool colored,
const CGAL::IO::Color& color) const CGAL::IO::Color& color) {
{
auto approx = traits.approximate_2_object(); auto approx = traits.approximate_2_object();
using Traits = Arr_geodesic_arc_on_sphere_traits_2<Kernel_, AtanX, AtanY>; using Traits = Arr_geodesic_arc_on_sphere_traits_2<Kernel_, AtanX, AtanY>;
using Ak = typename Traits::Approximate_kernel; using Ak = typename Traits::Approximate_kernel;
@ -308,23 +295,19 @@ namespace draw_function_for_arrangement_2
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); }
} }
/// Draw a point. //! draws a point.
void draw_point(Vertex_const_handle vh) void draw_point(Vertex_const_handle vh) {
{
const auto* traits = m_aos.geometry_traits(); const auto* traits = m_aos.geometry_traits();
if(m_gso.draw_vertex(m_aos, vh)) if (m_gso.draw_vertex(m_aos, vh)) {
{ if (m_gso.colored_vertex(m_aos, vh))
if(m_gso.colored_vertex(m_aos, vh)) draw_point_impl1(vh->point(), *traits, 0, true,
{ draw_point_impl1(vh->point(), *traits, 0, true, m_gso.vertex_color(m_aos, vh));
m_gso.vertex_color(m_aos, vh)); }
else else
{ draw_point_impl1(vh->point(), *traits, 0, false, CGAL::IO::Color()); } // color will be unused draw_point_impl1(vh->point(), *traits, 0, false, CGAL::IO::Color()); // color will be unused
} }
} }
@ -334,13 +317,12 @@ namespace draw_function_for_arrangement_2
Arr_geodesic_arc_on_sphere_traits_2<Kernel, AtanX, AtanY> const&) Arr_geodesic_arc_on_sphere_traits_2<Kernel, AtanX, AtanY> const&)
{ return circ; } { return circ; }
/*! Find the halfedge incident to the lexicographically smallest vertex /*! finds the halfedge incident to the lexicographically smallest vertex
* along the CCB, such that there is no other halfedge underneath. * along the CCB, such that there is no other halfedge underneath.
*/ */
template <typename Traits> template <typename Traits>
Halfedge_const_handle find_smallest(Ccb_halfedge_const_circulator circ, Halfedge_const_handle find_smallest(Ccb_halfedge_const_circulator circ,
const Traits&) const Traits&) {
{
// std::cout << "find_smallest()\n"; // std::cout << "find_smallest()\n";
const auto* traits = this->m_aos.geometry_traits(); const auto* traits = this->m_aos.geometry_traits();
auto cmp_xy = traits->compare_xy_2_object(); auto cmp_xy = traits->compare_xy_2_object();
@ -379,46 +361,41 @@ namespace draw_function_for_arrangement_2
return ext; return ext;
} }
/// Add all elements to be drawn. //! adds all elements to be drawn.
void add_elements() void add_elements() {
{
// std::cout << "add_elements()\n"; // std::cout << "add_elements()\n";
// std::cout << "ratio: " << this->pixel_ratio() << std::endl; // std::cout << "ratio: " << this->pixel_ratio() << std::endl;
m_visited.clear(); m_visited.clear();
if (m_aos.is_empty()) return; if (m_aos.is_empty()) return;
if(m_gso.are_faces_enabled()) if (m_gso.are_faces_enabled())
{ add_faces(*(this->m_aos.geometry_traits())); } { add_faces(*(this->m_aos.geometry_traits())); }
// Add edges that do not separate faces. // Add edges that do not separate faces.
if(m_gso.are_edges_enabled()) if (m_gso.are_edges_enabled()) {
{ for (auto it = m_aos.edges_begin(); it != m_aos.edges_end(); ++it) {
for (auto it = m_aos.edges_begin(); it != m_aos.edges_end(); ++it) if (it->face()==it->twin()->face()) {
{ if (it->face()==it->twin()->face()) if (m_gso.draw_edge(m_aos, it)) {
{ if (m_gso.colored_edge(m_aos, it))
if(m_gso.draw_edge(m_aos, it)) draw_curve(it->curve(), true, m_gso.edge_color(m_aos, it));
{
if(m_gso.colored_edge(m_aos, it))
{ draw_curve(it->curve(), true, m_gso.edge_color(m_aos, it)); }
else else
{ draw_curve(it->curve(), false, CGAL::IO::Color()); } draw_curve(it->curve(), false, CGAL::IO::Color());
} }
} }
} }
} }
// Add all points // Add all points
if(m_gso.are_vertices_enabled()) if (m_gso.are_vertices_enabled()) {
{
for (auto it = m_aos.vertices_begin(); it != m_aos.vertices_end(); ++it) for (auto it = m_aos.vertices_begin(); it != m_aos.vertices_end(); ++it)
{ draw_point(it); } draw_point(it);
} }
m_visited.clear(); m_visited.clear();
} }
/*! Draw a curve using approximate coordinates. /*! draws a curve using approximate coordinates.
* Call this member function only of the geometry traits is equipped with * Call this member function only of the geometry traits is equipped with
* the coordinate-aproximation functionality of a curve. * the coordinate-aproximation functionality of a curve.
* This function must be inlined (e.g., a template) to enable the * This function must be inlined (e.g., a template) to enable the
@ -427,22 +404,17 @@ namespace draw_function_for_arrangement_2
template <typename XMonotoneCurve, typename Approximate> template <typename XMonotoneCurve, typename Approximate>
void draw_approximate_curve(const XMonotoneCurve& curve, void draw_approximate_curve(const XMonotoneCurve& curve,
const Approximate& approx, const Approximate& approx,
bool colored, const CGAL::IO::Color& c) bool colored, const CGAL::IO::Color& c) {
{
std::vector<typename Gt::Approximate_point_2> polyline; std::vector<typename Gt::Approximate_point_2> polyline;
double error(0.01); // TODO? (this->pixel_ratio()); double error(0.01); // TODO? (this->pixel_ratio());
approx(curve, error, std::back_inserter(polyline)); approx(curve, error, std::back_inserter(polyline));
if (polyline.empty()) return; if (polyline.empty()) return;
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) m_gs.add_segment(*prev, *it, c);
if(colored) else m_gs.add_segment(*prev, *it);
{ m_gs.add_segment(*prev, *it, c); }
else
{ m_gs.add_segment(*prev, *it); }
} }
} }
/*! Compile time dispatching /*! Compile time dispatching
@ -503,19 +475,16 @@ namespace draw_function_for_arrangement_2
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;
} }
} }
/// Draw a curve. //! draws a curve.
template <typename XMonotoneCurve> template <typename XMonotoneCurve>
void draw_curve(const XMonotoneCurve& curve, void draw_curve(const XMonotoneCurve& curve,
bool colored, const CGAL::IO::Color& c) bool colored, const CGAL::IO::Color& c) {
{
/* Check whether the traits has a member function called /* Check whether the traits has a member function called
* approximate_2_object() and if so check whether the return type, namely * approximate_2_object() and if so check whether the return type, namely
* `Approximate_2` has an appropriate operator. * `Approximate_2` has an appropriate operator.
@ -532,8 +501,7 @@ namespace draw_function_for_arrangement_2
* For now we use C++14 features. * For now we use C++14 features.
*/ */
#if 0 #if 0
if constexpr (std::experimental::is_detected_v<approximate_2_object_t, Gt>) if constexpr (std::experimental::is_detected_v<approximate_2_object_t, Gt>) {
{
const auto* traits = this->m_aos.geometry_traits(); const auto* traits = this->m_aos.geometry_traits();
auto approx = traits->approximate_2_object(); auto approx = traits->approximate_2_object();
draw_approximate_curve(curve, approx); draw_approximate_curve(curve, approx);
@ -546,30 +514,28 @@ namespace draw_function_for_arrangement_2
#endif #endif
} }
protected: protected:
Arr& m_aos; Arr& m_aos;
CGAL::Graphics_scene& m_gs; CGAL::Graphics_scene& m_gs;
const GSOptions& m_gso; const GSOptions& m_gso;
std::unordered_map<Face_const_handle, bool> m_visited; std::unordered_map<Face_const_handle, bool> m_visited;
}; };
} // namespace draw_function_for_arrangement_2 } // namespace draw_aos
#define CGAL_ARR_TYPE CGAL::Arrangement_on_surface_2<GeometryTraits_2, TopologyTraits> #define CGAL_ARR_TYPE CGAL::Arrangement_on_surface_2<GeometryTraits_2, TopologyTraits>
template <typename GeometryTraits_2, typename TopologyTraits, class GSOptions> template <typename GeometryTraits_2, typename TopologyTraits, class GSOptions>
void add_to_graphics_scene(const CGAL_ARR_TYPE& aos, void add_to_graphics_scene(const CGAL_ARR_TYPE& aos,
CGAL::Graphics_scene& graphics_scene, CGAL::Graphics_scene& graphics_scene,
const GSOptions& gso) const GSOptions& gso) {
{ draw_aos::Draw_arr_tool dar(aos, graphics_scene, gso);
draw_function_for_arrangement_2::Draw_arr_tool dar(aos, graphics_scene, gso);
dar.add_elements(); dar.add_elements();
} }
template <typename GeometryTraits_2, typename TopologyTraits> template <typename GeometryTraits_2, typename TopologyTraits>
void add_to_graphics_scene(const CGAL_ARR_TYPE& aos, void add_to_graphics_scene(const CGAL_ARR_TYPE& aos,
CGAL::Graphics_scene& graphics_scene) CGAL::Graphics_scene& graphics_scene) {
{
CGAL::Graphics_scene_options<CGAL_ARR_TYPE, CGAL::Graphics_scene_options<CGAL_ARR_TYPE,
typename CGAL_ARR_TYPE::Vertex_const_handle, typename CGAL_ARR_TYPE::Vertex_const_handle,
typename CGAL_ARR_TYPE::Halfedge_const_handle, typename CGAL_ARR_TYPE::Halfedge_const_handle,
@ -589,11 +555,10 @@ void add_to_graphics_scene(const CGAL_ARR_TYPE& aos,
add_to_graphics_scene(aos, graphics_scene, gso); add_to_graphics_scene(aos, graphics_scene, gso);
} }
/// Draw an arrangement on surface. //! draws an arrangement on surface.
template <typename GeometryTraits_2, typename TopologyTraits, class GSOptions> template <typename GeometryTraits_2, typename TopologyTraits, class GSOptions>
void draw(const CGAL_ARR_TYPE& aos, const GSOptions& gso, void draw(const CGAL_ARR_TYPE& aos, const GSOptions& gso,
const char* title = "2D Arrangement on Surface Basic Viewer") const char* title = "2D Arrangement on Surface Basic Viewer") {
{
CGAL::Graphics_scene graphics_scene; CGAL::Graphics_scene graphics_scene;
add_to_graphics_scene(aos, graphics_scene, gso); add_to_graphics_scene(aos, graphics_scene, gso);
draw_graphics_scene(graphics_scene, title); draw_graphics_scene(graphics_scene, title);
@ -602,8 +567,7 @@ void draw(const CGAL_ARR_TYPE& aos, const GSOptions& gso,
template <typename GeometryTraits_2, typename TopologyTraits> template <typename GeometryTraits_2, typename TopologyTraits>
void draw(const CGAL_ARR_TYPE& aos, void draw(const CGAL_ARR_TYPE& aos,
const char* title = "2D Arrangement on Surface Basic Viewer") const char* title = "2D Arrangement on Surface Basic Viewer") {
{
CGAL::Graphics_scene graphics_scene; CGAL::Graphics_scene graphics_scene;
add_to_graphics_scene(aos, graphics_scene); add_to_graphics_scene(aos, graphics_scene);
draw_graphics_scene(graphics_scene, title); draw_graphics_scene(graphics_scene, title);