diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementDemoGraphicsView.cpp b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementDemoGraphicsView.cpp index b8513207e9f..bc09e4708a5 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementDemoGraphicsView.cpp +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementDemoGraphicsView.cpp @@ -12,39 +12,44 @@ #include "ArrangementDemoGraphicsView.h" -#include -#include -#include -#include -#include -#include #include +#include +#include +#include +#include +#include +#include //! Member function to setup the viewport of the screen /*! \param parent a Qwidget pointer to the class */ -ArrangementDemoGraphicsView::ArrangementDemoGraphicsView(QWidget* parent) - : QGraphicsView(parent) - , maxScale(500000) - , minScale(0.0002) { +ArrangementDemoGraphicsView::ArrangementDemoGraphicsView( QWidget* parent ) : + QGraphicsView( parent ), + maxScale( 500000 ), + minScale( 0.0002 ) +{ this->resetTransform(); this->setResizeAnchor(QGraphicsView::AnchorUnderMouse); this->setViewportUpdateMode(QGraphicsView::FullViewportUpdate); - this->setMouseTracking(true); + this->setMouseTracking( true ); this->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); this->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); // TODO: Make options menu work this->setRenderHint(QPainter::Antialiasing); } -void ArrangementDemoGraphicsView::paintEvent(QPaintEvent* event) { +void ArrangementDemoGraphicsView::paintEvent(QPaintEvent* event) +{ qreal scale = std::sqrt(std::abs(this->transform().determinant())); - if(scale > this->maxScale) + if (scale > this->maxScale) this->scale(this->maxScale / scale, this->maxScale / scale); - else if(scale < this->minScale) + else if (scale < this->minScale) this->scale(this->minScale / scale, this->minScale / scale); QGraphicsView::paintEvent(event); } -void ArrangementDemoGraphicsView::resetTransform() { this->setTransform({1.0, 0.0, 0.0, -1.0, 0.0, 0.0}); } +void ArrangementDemoGraphicsView::resetTransform() +{ + this->setTransform({1.0, 0.0, 0.0, -1.0, 0.0, 0.0}); +} diff --git a/Arrangement_on_surface_2/include/CGAL/Draw_aos/Arr_approximation_cache.h b/Arrangement_on_surface_2/include/CGAL/Draw_aos/Arr_approximation_cache.h index f84f125ab05..e70edb3023e 100644 --- a/Arrangement_on_surface_2/include/CGAL/Draw_aos/Arr_approximation_cache.h +++ b/Arrangement_on_surface_2/include/CGAL/Draw_aos/Arr_approximation_cache.h @@ -84,16 +84,19 @@ public: Vertex_cache_range vertex_cache() const { return boost::make_iterator_range(vertex_cache_begin(), vertex_cache_end()); } + std::size_t vertex_cache_size() const { return m_vertex_cache.size(); } Halfedge_cache_const_iterator halfedge_cache_begin() const { return m_halfedge_cache.begin(); } Halfedge_cache_const_iterator halfedge_cache_end() const { return m_halfedge_cache.end(); } Halfedge_cache_range halfedge_cache() const { return boost::make_iterator_range(halfedge_cache_begin(), halfedge_cache_end()); } + std::size_t halfedge_cache_size() const { return m_halfedge_cache.size(); } Face_cache_const_iterator face_cache_begin() const { return m_face_cache.begin(); } Face_cache_const_iterator face_cache_end() const { return m_face_cache.end(); } Face_cache_range face_cache() const { return boost::make_iterator_range(face_cache_begin(), face_cache_end()); } + std::size_t face_cache_size() const { return m_face_cache.size(); } private: Vertex_cache m_vertex_cache; diff --git a/Arrangement_on_surface_2/include/CGAL/Draw_aos/Arr_bounded_approximate_curve_2.h b/Arrangement_on_surface_2/include/CGAL/Draw_aos/Arr_bounded_approximate_curve_2.h index 83c10aa8d57..3a5169215f8 100644 --- a/Arrangement_on_surface_2/include/CGAL/Draw_aos/Arr_bounded_approximate_curve_2.h +++ b/Arrangement_on_surface_2/include/CGAL/Draw_aos/Arr_bounded_approximate_curve_2.h @@ -3,7 +3,7 @@ #include "CGAL/Arr_enums.h" #include "CGAL/Draw_aos/Arr_bounded_approximate_point_2.h" -#include "CGAL/Draw_aos/Arr_bounded_compute_y_at_x.h" +#include "CGAL/Draw_aos/Arr_compute_y_at_x.h" #include "CGAL/Draw_aos/Arr_construct_curve_end.h" #include "CGAL/Draw_aos/Arr_construct_segments.h" #include "CGAL/Draw_aos/Arr_render_context.h" @@ -48,13 +48,13 @@ class Arr_bounded_approximate_curve_2 Execution_context(const Arr_bounded_render_context& ctx, const X_monotone_curve_2& curve, const Arr_bounded_approximate_point_2& approx_pt, - const Arr_bounded_compute_y_at_x& compute_y_at_x, + const Arr_compute_y_at_x& compute_y_at_x, const Intersections_vector& top_inters, const Intersections_vector& bottom_inters, Polyline_geom& polyline) : Arr_context_delegator(ctx) , curve(curve) - , bounded_compute_y_at_x(compute_y_at_x) + , compute_y_at_x(compute_y_at_x) , bounded_approx_pt(approx_pt) , top_inters(top_inters) , bottom_inters(bottom_inters) @@ -72,7 +72,7 @@ class Arr_bounded_approximate_curve_2 bool is_bounded_curve() const { return is_min_end_bounded() && is_max_end_bounded(); } const X_monotone_curve_2& curve; - const Arr_bounded_compute_y_at_x& bounded_compute_y_at_x; + const Arr_compute_y_at_x& compute_y_at_x; const Arr_bounded_approximate_point_2& bounded_approx_pt; const Intersections_vector &top_inters, bottom_inters; const std::optional min_end, max_end; @@ -132,7 +132,7 @@ private: */ static void approximate_simple_curve_segment(Execution_context& ctx, const FT& start, const FT& end, double step) { for(FT x = start + step; x < end; x += step) { - auto y = ctx.bounded_compute_y_at_x(ctx.curve, x); + auto y = ctx.compute_y_at_x(ctx.curve, x); if(!y.has_value()) { // break as soon as there's no more intersections break; @@ -143,14 +143,14 @@ private: } *ctx.out_it++ = ctx->approx_pt(Point_2(x, y.value())); if(y > ctx->ymax() || y < ctx->ymin()) { - // We are outside the bbox. The dummy point is inserted to indicate the curve is outside the bbox. + // We are outside the bbox. The dummy point was already inserted to indicate that. break; } } }; static void approximate_vertical_curve(Execution_context& ctx) { - if(ctx.is_bounded_curve() && ctx.min_end->x() < ctx->xmin() && ctx.min_end->x() > ctx->xmax()) { + if(ctx.is_bounded_curve() && (ctx.min_end->x() < ctx->xmin() || ctx.min_end->x() > ctx->xmax())) { // The curve is outside the bbox in x direction, no need to approximate return; } @@ -178,7 +178,7 @@ private: public: Arr_bounded_approximate_curve_2(const Arr_bounded_render_context& ctx, const Arr_bounded_approximate_point_2& point_approx) - : m_bounded_compute_y_at_x(ctx) + : m_compute_y_at_x(ctx) , m_approx_pt(point_approx) , m_ctx(ctx) , m_top(ctx.cst_horizontal_segment(ctx.ymax(), ctx.xmin(), ctx.xmax())) @@ -210,7 +210,7 @@ public: auto top_inters = compute_intersections(curve, m_top, m_ctx.intersect_2, m_ctx.cst_curve_end); auto bottom_inters = compute_intersections(curve, m_bottom, m_ctx.intersect_2, m_ctx.cst_curve_end); - Execution_context ctx(m_ctx, curve, m_approx_pt, m_bounded_compute_y_at_x, top_inters, bottom_inters, polyline); + Execution_context ctx(m_ctx, curve, m_approx_pt, m_compute_y_at_x, top_inters, bottom_inters, polyline); if(ctx->is_vertical_2(curve)) { approximate_vertical_curve(ctx); @@ -224,7 +224,7 @@ public: FT last_x; std::optional first_inter = first_intersection(ctx); - if(auto y_at_txmin = ctx.bounded_compute_y_at_x(curve, txmin); + if(auto y_at_txmin = ctx.compute_y_at_x(curve, txmin); y_at_txmin.has_value() && y_at_txmin != ctx->ymin() && y_at_txmin != ctx->ymax()) { // The tight starting point of the curve is within the bbox and @@ -237,16 +237,7 @@ public: } else if(first_inter.has_value()) { last_x = first_inter->x(); } else { - // We assert that the curve is outbound. - // If the min end is bounded, it's obvious. - // - // If the min end is unbounded, we know that the curve has no intersections with top, bottom or left edge(txmin == - // xmin when the min end is unbounded) and the min end of the curve is outbound (it approaches infinity in one or - // both dimension). - // Assume that the curve does has one point within the bbox. Note that it's a contiguous - // x-monotone curve. So it must cross the top, bottom or left edge to reach the min end from right to left, - // which is a contradiction. - return polyline; + return polyline; // The curve is entirely outside the bbox in x direction. } // iterate through the intersections and insert segments in-between. @@ -258,7 +249,7 @@ public: }), [&ctx](const Point_2& pt1, const Point_2& pt2) { return ctx->compare_xy_2(pt1, pt2) == CGAL::SMALLER; }); - if(auto y_at_txmax = ctx.bounded_compute_y_at_x(curve, txmax); + if(auto y_at_txmax = ctx.compute_y_at_x(curve, txmax); y_at_txmax.has_value() && y_at_txmax != ctx->ymin() && y_at_txmax != ctx->ymax()) { approximate_simple_curve_segment(ctx, last_x, txmax, ctx->approx_error); @@ -272,7 +263,7 @@ public: private: const Arr_bounded_render_context& m_ctx; const Arr_bounded_approximate_point_2& m_approx_pt; - const Arr_bounded_compute_y_at_x m_bounded_compute_y_at_x; + const Arr_compute_y_at_x m_compute_y_at_x; const X_monotone_curve_2 m_top; const X_monotone_curve_2 m_bottom; }; diff --git a/Arrangement_on_surface_2/include/CGAL/Draw_aos/Arr_bounded_approximate_face_2.h b/Arrangement_on_surface_2/include/CGAL/Draw_aos/Arr_bounded_approximate_face_2.h index d4cc3163c3c..851ce684c29 100644 --- a/Arrangement_on_surface_2/include/CGAL/Draw_aos/Arr_bounded_approximate_face_2.h +++ b/Arrangement_on_surface_2/include/CGAL/Draw_aos/Arr_bounded_approximate_face_2.h @@ -22,7 +22,6 @@ namespace CGAL { namespace internal { - /** * @brief Patches corners between two boundary points of the bbox * counter-clockwisely. @@ -118,6 +117,7 @@ public: continue; } *out_it++ = corner; + std::cout << "Patching corner: " << corner << std::endl; } return; } @@ -126,6 +126,64 @@ private: const Bbox_2 m_bbox; }; +template +class Geom_simplifier +{ + using Approx_point = Arr_approximation_geometry_traits::Approx_point; + +private: + void dump() { + if(m_start.has_value()) { + *m_out_it++ = m_start.value(); + m_start.reset(); + } + if(m_mid.has_value()) { + *m_out_it++ = m_mid.value(); + m_mid.reset(); + } + } + +public: + Geom_simplifier(OutputIterator& out_it, const Bbox_2& bbox) + : m_out_it(out_it) + , m_bbox(bbox) {} + + decltype(auto) insert_iterator() { + return boost::make_function_output_iterator([this](const Approx_point& p) { + if(m_mid.has_value()) { + if(m_mid.value() == p) { + return; + } + if(p.y() == m_mid->y() && p.y() == m_start->y() || p.x() == m_mid->x() && p.x() == m_start->x()) { + // Three points are collinear horizontally or vertically. + m_mid = p; + } else { + *m_out_it++ = m_start.value(); + m_start = m_mid; + m_mid = p; + } + return; + } + + if(m_start.has_value()) { + if(m_start.value() == p) { + return; + } + m_mid = p; + } else { + m_start = p; + } + }); + } + + ~Geom_simplifier() { dump(); } + +private: + OutputIterator& m_out_it; + std::optional m_start, m_mid; + Bbox_2 m_bbox; +}; + } // namespace internal /** @@ -141,8 +199,11 @@ class Arr_bounded_approximate_face_2 using Polyline_geom = Approx_geom_traits::Polyline_geom; using Ccb_halfedge_const_circulator = Arrangement::Ccb_halfedge_const_circulator; using Approx_point = Approx_geom_traits::Approx_point; - using Patch_boundary = internal::Patch_boundary; using Triangulated_face = Approx_geom_traits::Triangulated_face; + using Patch_boundary = internal::Patch_boundary; + + template + using Geom_simplifier = internal::Geom_simplifier; struct Left_to_right_tag {}; @@ -155,9 +216,9 @@ private: public: Execution_context(const Arr_bounded_render_context& ctx, Arr_bounded_face_triangulator& triangulator, + const Patch_boundary& patch_boundary, const Arr_bounded_approximate_point_2& bounded_approx_pt, - const Arr_bounded_approximate_curve_2& bounded_approx_curve, - const Patch_boundary& patch_boundary) + const Arr_bounded_approximate_curve_2& bounded_approx_curve) : Arr_context_delegator(ctx) , triangulator(triangulator) , patch_boundary(patch_boundary) @@ -167,8 +228,8 @@ private: public: const Arr_bounded_approximate_point_2& bounded_approx_pt; const Arr_bounded_approximate_curve_2& bounded_approx_curve; - const Patch_boundary& patch_boundary; Arr_bounded_face_triangulator& triangulator; + const Patch_boundary& patch_boundary; }; private: @@ -194,46 +255,75 @@ private: } } - template - static void approximate_ccb(Execution_context& ctx, const Ccb_halfedge_const_circulator& start_circ) { - constexpr bool Is_outer_ccb = std::is_same_v; - auto ccb_constraint = ctx.triangulator.make_ccb_constraint(); - auto out_it = ccb_constraint.insert_iterator(); + template + static void approximate_ccb(Execution_context& ctx, Ccb_halfedge_const_circulator start_circ) { + constexpr bool Is_outer_ccb = std::is_same_v; + static_assert(Is_outer_ccb || Bounded, "Inner CCBs are impossible to be unbounded."); - std::optional ccb_last_pt, ccb_first_pt; - auto counter_clockwise_start_circ = Is_outer_ccb ? start_circ : Ccb_halfedge_const_circulator(start_circ->twin()); - auto circ = counter_clockwise_start_circ; - do { - bool is_he_first_pt = true; - auto patch_out_it = boost::make_function_output_iterator([&](const Approx_point& pt) { - if(ccb_last_pt == pt || !ctx->contains(pt)) { - return; - } - if(is_he_first_pt && ccb_last_pt.has_value()) { - ctx.patch_boundary(ccb_last_pt.value(), pt, out_it); - } - - *out_it++ = pt; - ccb_last_pt = pt; - if(!ccb_first_pt.has_value()) { - ccb_first_pt = pt; - } - is_he_first_pt = false; - }); - - approximate_halfedge_of_ccb(ctx, circ, patch_out_it); - approximate_vertex(ctx, circ->target()); - } while(++circ != counter_clockwise_start_circ); - - if(Is_outer_ccb && !ccb_first_pt.has_value()) { - *out_it++ = Approx_point(ctx->xmin(), ctx->ymin()); - *out_it++ = Approx_point(ctx->xmax(), ctx->ymin()); - *out_it++ = Approx_point(ctx->xmax(), ctx->ymax()); - *out_it++ = Approx_point(ctx->xmin(), ctx->ymax()); + // For unbound ccb, we start on a fictitious edge + if constexpr(!Bounded) { + while(!start_circ->is_fictitious()) { + ++start_circ; + } } - if(ccb_first_pt.has_value() && ccb_first_pt != ccb_last_pt) { - // Close the ccb - ctx.patch_boundary(ccb_last_pt.value(), ccb_first_pt.value(), out_it); + + auto ccb_constraint = ctx.triangulator.make_ccb_constraint(); + auto constraint_out_it = ccb_constraint.insert_iterator(); + + auto simplifier = Geom_simplifier(constraint_out_it, ctx->bbox()); + auto simplifier_out_it = simplifier.insert_iterator(); + + auto circ = start_circ; + std::optional last_pt; + + // These vars are used only in unbounded ccb. + std::optional first_pt; + bool passed_fictitious_edge = false; + + auto he_process_out_it = boost::make_function_output_iterator([&](const Approx_point& pt) { + Approx_point regulated_pt(pt.x(), std::clamp(pt.y(), ctx->ymin(), ctx->ymax())); + if(last_pt == regulated_pt) { + return; + } + + *simplifier_out_it++ = regulated_pt; + + if constexpr(!Bounded) { + // TODO: nesting too deep and looks ugly + if(passed_fictitious_edge) { + passed_fictitious_edge = false; + if(last_pt.has_value()) { + ctx.patch_boundary(last_pt.value(), regulated_pt, simplifier_out_it); + } + } + if(!first_pt.has_value()) { + first_pt = regulated_pt; + } + } + + last_pt = regulated_pt; + }); + + do { + if constexpr(!Bounded) { + if(circ->is_fictitious()) { + passed_fictitious_edge = true; + } + } + approximate_halfedge_of_ccb(ctx, circ, he_process_out_it); + approximate_vertex(ctx, circ->target()); + } while(++circ != start_circ); + + if constexpr(!Bounded) { + if(!first_pt.has_value()) { + *simplifier_out_it++ = Approx_point(ctx->xmin(), ctx->ymin()); + *simplifier_out_it++ = Approx_point(ctx->xmin(), ctx->ymax()); + *simplifier_out_it++ = Approx_point(ctx->xmax(), ctx->ymax()); + *simplifier_out_it++ = Approx_point(ctx->xmax(), ctx->ymin()); + + } else { + ctx.patch_boundary(last_pt.value(), first_pt.value(), simplifier_out_it); + } } } @@ -257,18 +347,34 @@ public: } CGAL_assertion_msg(!fh->is_fictitious(), "Cannot approximate a fictitious face."); + if(!fh->has_outer_ccb()) { - // The face is the unbounded face of bounded arrangements + // The face is the unbounded face of bounded arrangements, we skip approximating any non degenerate features. + for(auto inner_ccb = fh->inner_ccbs_begin(); inner_ccb != fh->inner_ccbs_end(); ++inner_ccb) { + if((*inner_ccb)->twin()->face() != (*inner_ccb)->face()) { + continue; + } + m_curve_approx(*inner_ccb); + } + for(auto isolated_vh = fh->isolated_vertices_begin(); isolated_vh != fh->isolated_vertices_end(); ++isolated_vh) { + m_point_approx(isolated_vh); + } return triangulated_face; } Arr_bounded_face_triangulator triangulator(m_ctx); - Execution_context ctx(m_ctx, triangulator, m_point_approx, m_curve_approx, m_patch_boundary); + Execution_context ctx(m_ctx, triangulator, m_patch_boundary, m_point_approx, m_curve_approx); + + if(fh->is_unbounded()) { + approximate_ccb(ctx, fh->outer_ccb()); + } else { + approximate_ccb(ctx, fh->outer_ccb()); + } - approximate_ccb(ctx, fh->outer_ccb()); for(auto inner_ccb = fh->inner_ccbs_begin(); inner_ccb != fh->inner_ccbs_end(); ++inner_ccb) { approximate_ccb(ctx, *inner_ccb); } + for(auto isolated_vh = fh->isolated_vertices_begin(); isolated_vh != fh->isolated_vertices_begin(); ++isolated_vh) { approximate_vertex(ctx, isolated_vh); } diff --git a/Arrangement_on_surface_2/include/CGAL/Draw_aos/Arr_bounded_compute_y_at_x.h b/Arrangement_on_surface_2/include/CGAL/Draw_aos/Arr_bounded_compute_y_at_x.h index 7e87b76e592..27a593cda2c 100644 --- a/Arrangement_on_surface_2/include/CGAL/Draw_aos/Arr_bounded_compute_y_at_x.h +++ b/Arrangement_on_surface_2/include/CGAL/Draw_aos/Arr_bounded_compute_y_at_x.h @@ -7,73 +7,9 @@ #include #include #include +#include #include #include -namespace CGAL { -/** - * @brief Functor to compute the y-coordinate at a given x-coordinate for an x-monotone curve within a bounding box. - */ -class Arr_bounded_compute_y_at_x -{ -public: - using Point_2 = Geom_traits::Point_2; - using X_monotone_curve_2 = Geom_traits::X_monotone_curve_2; - using Intersect_2 = Geom_traits::Intersect_2; - using Construct_min_vertex_2 = Geom_traits::Construct_min_vertex_2; - using FT = Geom_traits::FT; - using Approximate_2 = Geom_traits::Approximate_2; - using Is_vertical_2 = Geom_traits::Is_vertical_2; - - Arr_bounded_compute_y_at_x(const Arr_bounded_render_context& ctx) - : m_ctx(ctx) - // TODO: some traits does not have approximate_2_object. we'll need a specialization for them. - , m_approx(ctx.traits.approximate_2_object()) {} - - /** - * @brief Computes the y-coordinate at a given x-coordinate for an x-monotone curve trimmed - * to the bounding box. - * - * The bounding box here is considered as closed. - * - * @precondition The curve is not verical - * @param curve - * @param x - * @return true if there is an intersection at given x within the bounding box, - * @return false otherwise. - */ - std::optional operator()(const X_monotone_curve_2& curve, const FT& x) const { - CGAL_assertion(!m_ctx.is_vertical_2(curve)); - if(!m_ctx.contains_x(x)) { - return false; - } - - auto min_pt = m_ctx.cst_curve_end(curve, ARR_MIN_END); - auto max_pt = m_ctx.cst_curve_end(curve, ARR_MAX_END); - if(min_pt.has_value() && min_pt->x() == x) { - return min_pt->y(); - } - if(max_pt.has_value() && max_pt->x() == x) { - return max_pt->y(); - } - - using Multiplicity = Geom_traits::Multiplicity; - using Intersect_point = std::pair; - using Intersect_curve = X_monotone_curve_2; - using Intersect_type = std::variant; - - auto vertical_line = m_ctx.cst_vertical_segment(x, m_ctx.ymin(), m_ctx.ymax()); - std::optional y; - auto func_out_iter = boost::make_function_output_iterator( - [&y, this](const Intersect_type& res) { y = std::get(res).first.y(); }); - m_ctx.intersect_2(curve, vertical_line, func_out_iter); - return y; - } - -private: - const Arr_bounded_render_context& m_ctx; - Approximate_2 m_approx; -}; - -} // namespace CGAL +namespace CGAL {} // namespace CGAL #endif // CGAL_DRAW_AOS_ARR_BOUNDED_COMPUTE_Y_AT_X_H \ No newline at end of file diff --git a/Arrangement_on_surface_2/include/CGAL/Draw_aos/Arr_bounded_face_triangulator.h b/Arrangement_on_surface_2/include/CGAL/Draw_aos/Arr_bounded_face_triangulator.h index 618c71323d6..711559c2e89 100644 --- a/Arrangement_on_surface_2/include/CGAL/Draw_aos/Arr_bounded_face_triangulator.h +++ b/Arrangement_on_surface_2/include/CGAL/Draw_aos/Arr_bounded_face_triangulator.h @@ -1,13 +1,15 @@ #ifndef CGAL_DRAW_AOS_ARR_FACE_TRIANGULATOR_H #define CGAL_DRAW_AOS_ARR_FACE_TRIANGULATOR_H -#include "CGAL/Constrained_Delaunay_triangulation_2.h" #include "CGAL/Constrained_triangulation_2.h" #include "CGAL/Constrained_triangulation_face_base_2.h" #include "CGAL/Draw_aos/Arr_approximation_geometry_traits.h" #include "CGAL/Draw_aos/Arr_render_context.h" +#include "CGAL/Exact_predicates_inexact_constructions_kernel.h" #include "CGAL/Triangulation_vertex_base_with_info_2.h" +#include "CGAL/basic.h" #include "CGAL/mark_domain_in_triangulation.h" +#include "CGAL/number_utils.h" #include "CGAL/unordered_flat_map.h" #include #include @@ -49,8 +51,8 @@ class Arr_bounded_face_triangulator using Fb = CGAL::Constrained_triangulation_face_base_2; using Tds = CGAL::Triangulation_data_structure_2; using Ct = Constrained_triangulation_2; - using Point = Epick::Point_2; - using Point_with_info = std::pair; + using KPoint = Epick::Point_2; + using KPoint_with_info = std::pair; std::size_t counter{0}; @@ -63,12 +65,14 @@ class Arr_bounded_face_triangulator class Ccb_constraint { constexpr static bool Is_outer_ccb = std::is_same_v; + friend class Arr_bounded_face_triangulator; + using Side_of_boundary = Arr_bounded_render_context::Side_of_boundary; std::ofstream m_ofs; Ccb_constraint(Arr_bounded_face_triangulator& triangulator) - : m_triangulator(&triangulator) { - m_ccb_start = m_triangulator->m_points.size(); + : m_triangulator(&triangulator) + , m_ccb_start(m_triangulator->m_points.size()) { triangulator.m_has_active_constraint = true; if(Is_outer_ccb) { @@ -80,24 +84,28 @@ class Arr_bounded_face_triangulator } private: - Point offset_boundary_point(const Point& pt) const { - constexpr double offset = 1; // It doesn't matter how much we offset the point - double x = pt.x(), y = pt.y(); - const auto& ctx = m_triangulator->m_ctx; + std::vector& points() { return m_triangulator->m_points; } + const std::vector& points() const { return m_triangulator->m_points; } + auto first_point() const { return points()[m_ccb_start].first; } + auto last_point() const { return points().back().first; } + const Arr_bounded_render_context& ctx() const { return m_triangulator->m_ctx; } + void add_point(const KPoint& pt) { points().emplace_back(pt, points().size()); } + std::size_t ccb_size() const { return m_triangulator->m_points.size() - m_ccb_start - m_helper_indices.size(); } - if(x == ctx.xmin()) { - x -= offset; + KPoint offset_boundary_point(const KPoint& pt, Side_of_boundary side, double offset) const { + CGAL_precondition(side != Side_of_boundary::None); + switch(side) { + case Side_of_boundary::Left: + return KPoint(pt.x() - offset, pt.y()); + case Side_of_boundary::Right: + return KPoint(pt.x() + offset, pt.y()); + case Side_of_boundary::Top: + return KPoint(pt.x(), pt.y() + offset); + case Side_of_boundary::Bottom: + return KPoint(pt.x(), pt.y() - offset); + default: + return pt; // Should not reach here } - if(x == ctx.xmax()) { - x += offset; - } - if(y == ctx.ymin()) { - y -= offset; - } - if(y == ctx.ymax()) { - y += offset; - } - return Point(x, y); } void insert_ccb() { @@ -123,30 +131,39 @@ class Arr_bounded_face_triangulator }; auto index_to_point_with_info = [&points](std::size_t idx) { return points[idx]; }; - auto indexes_begin = boost::make_counting_iterator(m_ccb_start); auto indexes_end = boost::make_counting_iterator(points.size()); auto filtered_begin = boost::make_filter_iterator(concrete_pt_filter, indexes_begin, indexes_end); auto filtered_end = boost::make_filter_iterator(concrete_pt_filter, indexes_end, indexes_end); auto transformed_begin = boost::make_transform_iterator(filtered_begin, index_to_point_with_info); auto transformed_end = boost::make_transform_iterator(filtered_end, index_to_point_with_info); - // { - // std::ofstream ofs_index("/Users/shep/codes/aos_2_js_helper/shapes.txt", std::ios::app); - // auto& ctx = const_cast(m_triangulator->m_ctx); - // ofs_index << "ccb_" << ctx.counter << ".txt" << std::endl; - // std::ofstream ofs("/Users/shep/codes/aos_2_js_helper/ccb_" + std::to_string(ctx.counter++) + ".txt", - // std::ios::out | std::ios::trunc); - // for(auto it = filtered_begin; it != filtered_end; ++it) { - // const auto& pt = it->first; - // ofs << pt.x() << " " << pt.y() << std::endl; - // } - // } - ct.insert_with_info(transformed_begin, transformed_end); + + ct.insert_with_info(transformed_begin, transformed_end); } else { - ct.insert_with_info(begin, end); + ct.insert_with_info(begin, end); } } + void try_add_offset(const KPoint& from, const KPoint& to) { + if(from == to) { + return; + } + auto shared_side = ctx().shared_boundary_side(from, to); + if(shared_side == Arr_bounded_render_context::Side_of_boundary::None) { + return; + } + // m_helper_indices.push_back(points().size()); + // add_point(offset_boundary_point(from, shared_side, m_offset)); + m_helper_indices.push_back(points().size()); + add_point(offset_boundary_point(KPoint((from.x() + to.x()) / 2, (from.y() + to.y()) / 2), shared_side, m_offset)); + + // TODO: we'll come back to find out if we do need to offset the second point. + // m_helper_indices.push_back(points().size()); + // add_point(offset_boundary_point(to, shared_side, m_offset)); + // Doesn't matter how much we increase the offset. + m_offset += 0.5; + } + public: Ccb_constraint(const Ccb_constraint&) = delete; Ccb_constraint& operator=(const Ccb_constraint&) = delete; @@ -162,22 +179,18 @@ class Arr_bounded_face_triangulator return *this; } - decltype(auto) insert_iterator() { - return boost::make_function_output_iterator([&, this](const Approx_point& pt) { - auto& points = m_triangulator->m_points; + auto insert_iterator() { + return boost::make_function_output_iterator([this](const Approx_point& pt) { CGAL_assertion_msg(m_triangulator != nullptr, "Use of destructed or moved Ccb_constraint object."); - CGAL_assertion_msg(m_triangulator->m_ctx.contains(pt), "Outbound point in Ccb_constraint."); + CGAL_assertion_msg(ctx().contains(pt), "Outbound point in Ccb_constraint."); + KPoint kp(pt.x(), pt.y()); - if constexpr(Is_outer_ccb) { - bool is_on_boundary = m_triangulator->m_ctx.is_on_boundary(pt); - if(is_on_boundary && m_is_last_on_boundary) { - m_helper_indices.push_back(points.size()); - points.emplace_back(offset_boundary_point(points.back().first), Point_index()); - } - m_is_last_on_boundary = is_on_boundary; + if(Is_outer_ccb && ccb_size() != 0) { + try_add_offset(last_point(), kp); m_ofs << pt.x() << " " << pt.y() << std::endl; } - points.emplace_back(Point(pt.x(), pt.y()), points.size()); + + add_point(kp); }); } @@ -185,15 +198,9 @@ class Arr_bounded_face_triangulator if(m_triangulator == nullptr) { return; } - if(Is_outer_ccb && m_is_last_on_boundary && m_triangulator->m_points.size() != m_ccb_start) { - auto& points = m_triangulator->m_points; - const auto& first_pt = points[m_ccb_start].first; - const auto& last_pt = points.back().first; - bool is_first_on_boundary = m_triangulator->m_ctx.is_on_boundary(first_pt); - if(m_is_last_on_boundary && is_first_on_boundary) { - m_helper_indices.push_back(points.size()); - points.emplace_back(offset_boundary_point(last_pt), Point_index()); - } + + if(Is_outer_ccb && ccb_size() != 0) { + try_add_offset(last_point(), first_point()); } insert_ccb(); @@ -203,8 +210,10 @@ class Arr_bounded_face_triangulator private: Arr_bounded_face_triangulator* m_triangulator; - std::size_t m_ccb_start; - bool m_is_last_on_boundary = false; + const std::size_t m_ccb_start; + + // These are used only for outer CCBs. + double m_offset = 0.5; // Doesn't matter how much we offset. std::vector m_helper_indices; // The offseted point indices when inserting outer ccb constraint }; @@ -217,12 +226,15 @@ public: operator Triangulated_face() && { CGAL_assertion(!m_has_active_constraint && "There is an active constraint in the triangulator."); CGAL_assertion(m_outer_ccb_processed && "Outer CCB has not been processed yet."); + if(m_points.empty() || m_ct.number_of_faces() == 0) { + return Triangulated_face(); + } // insert_constraint() should be called after insert_with_info(), or info will not be set correctly. - auto first_of_pair = [](const Point_with_info& pt_with_info) { return pt_with_info.first; }; + auto first_of_pair = [](const KPoint_with_info& pt_with_info) { return pt_with_info.first; }; for(std::size_t i = 0; i < m_ccb_start_indices.size(); ++i) { auto begin = m_points.begin() + m_ccb_start_indices[i]; - auto end = m_points.begin() + (i + 1 < m_ccb_start_indices.size() ? m_ccb_start_indices[i + 1] : m_points.size()); + auto end = i + 1 < m_ccb_start_indices.size() ? m_points.begin() + m_ccb_start_indices[i + 1] : m_points.end(); { std::ofstream ofs_index("/Users/shep/codes/aos_2_js_helper/shapes.txt", std::ios::app); auto& ctx = const_cast(m_ctx); @@ -258,12 +270,11 @@ public: tf.triangles.emplace_back(tri); } - auto transform_first_of_pair = [](const Point_with_info& pt_with_info) { - return Approx_point(pt_with_info.first.x(), pt_with_info.first.y()); + auto transform_first_of_pair = [](const KPoint_with_info& pt_with_info) { + return Approx_point(CGAL::to_double(pt_with_info.first.x()), CGAL::to_double(pt_with_info.first.y())); }; tf.points = Point_vec(boost::make_transform_iterator(m_points.begin(), transform_first_of_pair), boost::make_transform_iterator(m_points.end(), transform_first_of_pair)); - m_ct.clear(); return tf; } @@ -286,7 +297,7 @@ public: private: const Arr_bounded_render_context& m_ctx; Ct m_ct; - std::vector m_points; + std::vector m_points; std::vector m_ccb_start_indices; bool m_has_active_constraint = false; bool m_outer_ccb_processed = false; diff --git a/Arrangement_on_surface_2/include/CGAL/Draw_aos/Arr_bounded_renderer.h b/Arrangement_on_surface_2/include/CGAL/Draw_aos/Arr_bounded_renderer.h index bda0d15a9da..8301a59221e 100644 --- a/Arrangement_on_surface_2/include/CGAL/Draw_aos/Arr_bounded_renderer.h +++ b/Arrangement_on_surface_2/include/CGAL/Draw_aos/Arr_bounded_renderer.h @@ -129,11 +129,10 @@ private: auto he = *inner_ccb; auto inner_face = he->twin()->face(); - bool is_degenerate = inner_face == fh; - bool within_bounds = ctx->strictly_contains(inner_face->outer_ccb()->source()->point()); - if(is_degenerate || !within_bounds) { + if(inner_face == fh || !ctx->strictly_contains(inner_face->outer_ccb()->source()->point())) { continue; } + discover_faces(ctx, inner_face); } diff --git a/Arrangement_on_surface_2/include/CGAL/Draw_aos/Arr_compute_y_at_x.h b/Arrangement_on_surface_2/include/CGAL/Draw_aos/Arr_compute_y_at_x.h new file mode 100644 index 00000000000..98610a1dece --- /dev/null +++ b/Arrangement_on_surface_2/include/CGAL/Draw_aos/Arr_compute_y_at_x.h @@ -0,0 +1,77 @@ +#ifndef CGAL_DRAW_AOS_ARR_COMPUTE_Y_AT_X_H +#define CGAL_DRAW_AOS_ARR_COMPUTE_Y_AT_X_H +#include "CGAL/Bbox_2.h" +#include "CGAL/Draw_aos/Arr_render_context.h" +#include "CGAL/Draw_aos/helpers.h" +#include + +namespace CGAL { + +/** + * @brief Functor to compute the y-coordinate at a given x-coordinate for an x-monotone curve within a bounding box. + */ +class Arr_compute_y_at_x +{ +public: + using Point_2 = Geom_traits::Point_2; + using X_monotone_curve_2 = Geom_traits::X_monotone_curve_2; + using Intersect_2 = Geom_traits::Intersect_2; + using Construct_min_vertex_2 = Geom_traits::Construct_min_vertex_2; + using FT = Geom_traits::FT; + using Approximate_2 = Geom_traits::Approximate_2; + using Is_vertical_2 = Geom_traits::Is_vertical_2; + + Arr_compute_y_at_x(const Arr_render_context& ctx) + : m_ctx(ctx) + // TODO: some traits does not have approximate_2_object. we'll need a specialization for them. + , m_approx(ctx.traits.approximate_2_object()) {} + + /** + * @brief Computes the y-coordinate at a given x-coordinate for an x-monotone curve trimmed + * to the bounding box. + * + * The bounding box here is considered as closed. + * + * @precondition The curve is not verical + * @param curve + * @param x + * @return true if there is an intersection at given x within the bounding box, + * @return false otherwise. + */ + std::optional operator()(const X_monotone_curve_2& curve, const FT& x) const { + CGAL_assertion(!m_ctx.is_vertical_2(curve)); + + auto min_pt = m_ctx.cst_curve_end(curve, ARR_MIN_END); + auto max_pt = m_ctx.cst_curve_end(curve, ARR_MAX_END); + if(min_pt.has_value() && min_pt->x() == x) { + return min_pt->y(); + } + if(max_pt.has_value() && max_pt->x() == x) { + return max_pt->y(); + } + + using Multiplicity = Geom_traits::Multiplicity; + using Intersect_point = std::pair; + using Intersect_curve = X_monotone_curve_2; + using Intersect_type = std::variant; + + auto vertical_line = m_ctx.cst_vertical_segment(x, m_ymin, m_ymax); + std::optional y; + auto func_out_iter = boost::make_function_output_iterator( + [&y, this](const Intersect_type& res) { y = std::get(res).first.y(); }); + m_ctx.intersect_2(curve, vertical_line, func_out_iter); + return y; + } + +private: + Approximate_2 m_approx; + const Arr_render_context& m_ctx; + + // Should be enough for visualization purposes. + constexpr static double m_ymin = std::numeric_limits::lowest(); + constexpr static double m_ymax = std::numeric_limits::max(); +}; + +} // namespace CGAL + +#endif // CGAL_DRAW_AOS_ARR_COMPUTE_Y_AT_X_H \ No newline at end of file diff --git a/Arrangement_on_surface_2/include/CGAL/Draw_aos/Arr_render_context.h b/Arrangement_on_surface_2/include/CGAL/Draw_aos/Arr_render_context.h index 5639ead835f..bb5e1e49388 100644 --- a/Arrangement_on_surface_2/include/CGAL/Draw_aos/Arr_render_context.h +++ b/Arrangement_on_surface_2/include/CGAL/Draw_aos/Arr_render_context.h @@ -59,6 +59,14 @@ protected: : m_bbox(bbox) {} public: + enum class Side_of_boundary { + Left, + Right, + Bottom, + Top, + None, + }; + double xmin() const { return m_bbox.xmin(); } double xmax() const { return m_bbox.xmax(); } double ymin() const { return m_bbox.ymin(); } @@ -102,6 +110,20 @@ public: (pt.y() == ymin() || pt.y() == ymax()) && contains_x(pt.x()); } + template + Side_of_boundary shared_boundary_side(const Point& pt1, const Point& pt2) const { + if(pt1.x() == xmin() && pt2.x() == xmin() && contains_y(pt1.y()) && contains_y(pt2.y())) { + return Side_of_boundary::Left; + } else if(pt1.x() == xmax() && pt2.x() == xmax() && contains_y(pt1.y()) && contains_y(pt2.y())) { + return Side_of_boundary::Right; + } else if(pt1.y() == ymin() && pt2.y() == ymin() && contains_x(pt1.x()) && contains_x(pt2.x())) { + return Side_of_boundary::Bottom; + } else if(pt1.y() == ymax() && pt2.y() == ymax() && contains_x(pt1.x()) && contains_x(pt2.x())) { + return Side_of_boundary::Top; + } + return Side_of_boundary::None; + } + private: const Bbox_2 m_bbox; }; diff --git a/Arrangement_on_surface_2/include/CGAL/Draw_aos/Arr_viewer.h b/Arrangement_on_surface_2/include/CGAL/Draw_aos/Arr_viewer.h index f237c2c44fa..efa855e4d5d 100644 --- a/Arrangement_on_surface_2/include/CGAL/Draw_aos/Arr_viewer.h +++ b/Arrangement_on_surface_2/include/CGAL/Draw_aos/Arr_viewer.h @@ -5,12 +5,14 @@ #include #include #include "CGAL/Arr_trapezoid_ric_point_location.h" +#include "CGAL/Arrangement_on_surface_2.h" #include "CGAL/Bbox_2.h" #include "CGAL/Draw_aos/Arr_bounded_renderer.h" #include "CGAL/Draw_aos/Arr_render_context.h" #include "CGAL/Graphics_scene.h" #include "CGAL/Graphics_scene_options.h" #include "CGAL/Qt/camera.h" +#include "CGAL/unordered_flat_map.h" #include #include #include @@ -20,6 +22,10 @@ #include #include #include +#include +#include +#include +#include namespace CGAL { @@ -31,6 +37,7 @@ class Arr_viewer : public Qt::Basic_viewer using Face_const_handle = Arrangement::Face_const_handle; using Graphics_scene_options = Graphics_scene_options; + using Point_location = Arr_trapezoid_ric_point_location; private: // Function to check if the camera's state has changed @@ -48,17 +55,17 @@ private: return true; } - Bbox_2 initial_bbox() const { - Bbox_2 bbox; - for(const auto& vh : m_arr.vertex_handles()) { - bbox += vh->point().bbox(); - } - if(bbox.x_span() == 0 || bbox.y_span() == 0) { - // make a default bbox around the degenrate rect - bbox = Bbox_2(bbox.xmin() - 1, bbox.ymin() - 1, bbox.xmax() + 1, bbox.ymax() + 1); - } - return bbox; - } + // Bbox_2 initial_bbox() const { + // Bbox_2 bbox; + // for(const auto& vh : m_arr.vertex_handles()) { + // bbox += vh->point().bbox(); + // } + // if(bbox.x_span() == 0 || bbox.y_span() == 0) { + // // make a default bbox around the degenrate rect + // bbox = Bbox_2(bbox.xmin() - 1, bbox.ymin() - 1, bbox.xmax() + 1, bbox.ymax() + 1); + // } + // return bbox; + // } /** * @brief Computes the bounding box of the view from orthogonal camera. @@ -101,7 +108,9 @@ private: std::array viewport; camera_->getViewport(viewport.data()); double width = static_cast(viewport[2]); - return 0.5; + // return bbox.x_span() / std::min(600.0, width); + // We are testing linear traits, lets set it to inf + return 10000; } public: @@ -111,26 +120,22 @@ public: const char* title = "Arrangement Viewer") : Basic_viewer(parent, m_scene, title) , m_scene_options(options) - , m_pl(arr) - , m_arr(arr) {} + , m_arr(arr) + , m_pl(arr) {} - void rerender(Bbox_2 bbox) { - Arr_render_context ctx(m_arr, m_pl, get_approx_error(bbox)); + void render_arr(const Arrangement& arr, const Point_location& pl, const Bbox_2& bbox) { + Arr_render_context ctx(arr, pl, get_approx_error(bbox)); Arr_bounded_renderer renderer(ctx, bbox); const auto& cache = renderer.render(); - m_scene.clear(); - - int counter = 0; - // add faces for(const auto& [fh, face_tris] : cache.face_cache()) { const auto& points = face_tris.points; const auto& tris = face_tris.triangles; - bool draw_face = m_scene_options.colored_face(m_arr, fh); + bool draw_face = m_scene_options.colored_face(arr, fh); for(const auto& t : tris) { if(draw_face) { - m_scene.face_begin(m_scene_options.face_color(m_arr, fh)); + m_scene.face_begin(m_scene_options.face_color(arr, fh)); } else { m_scene.face_begin(); } @@ -142,15 +147,13 @@ public: } // add edges - counter = 0; for(const auto& [he, polyline] : cache.halfedge_cache()) { if(polyline.size() < 2) { continue; // skip degenerate edges } - // ofs_index << "polyline_" << counter << ".txt" << std::endl; - // std::ofstream ofs("/Users/shep/codes/aos_2_js_helper/polyline_" + std::to_string(counter++) + ".txt"); - bool draw_colored_edge = m_scene_options.colored_edge(m_arr, he); - auto color = draw_colored_edge ? m_scene_options.edge_color(m_arr, he) : CGAL::IO::Color(); + + bool draw_colored_edge = m_scene_options.colored_edge(arr, he); + auto color = draw_colored_edge ? m_scene_options.edge_color(arr, he) : CGAL::IO::Color(); for(size_t i = 0; i < polyline.size() - 1; ++i) { const auto& cur_pt = polyline[i]; const auto& next_pt = polyline[i + 1]; @@ -160,25 +163,26 @@ public: { continue; } - // ofs << cur_pt << "\n"; if(draw_colored_edge) { m_scene.add_segment(cur_pt, next_pt, color); } else { m_scene.add_segment(cur_pt, next_pt); } } - // ofs << polyline.back() << "\n"; - // ofs << std::endl; } // add vertices for(const auto& [vh, pt] : cache.vertex_cache()) { - // std::cout << pt << std::endl; - if(m_scene_options.colored_vertex(m_arr, vh)) { - m_scene.add_point(pt, m_scene_options.vertex_color(m_arr, vh)); + if(m_scene_options.colored_vertex(arr, vh)) { + m_scene.add_point(pt, m_scene_options.vertex_color(arr, vh)); } else { m_scene.add_point(pt); } } + } + + void rerender(Bbox_2 bbox) { + m_scene.clear(); + render_arr(m_arr, m_pl, bbox); Basic_viewer::redraw(); } @@ -200,8 +204,8 @@ public: private: Graphics_scene m_scene; Graphics_scene_options m_scene_options; - const Arrangement& m_arr; - Arr_trapezoid_ric_point_location m_pl; + Arrangement m_arr; + Point_location m_pl; QMatrix4x4 m_last_proj_matrix; QMatrix4x4 m_last_modelview_matrix; }; @@ -225,7 +229,9 @@ void draw_viewer(const Arrangement& arr) { CGAL::Random random((size_t(&*vh))); return get_random_color(random); }; + // Arr_viewer viewer(app.activeWindow(), move_degenerate_features(arr), gso, "Arrangement Viewer"); Arr_viewer viewer(app.activeWindow(), arr, gso, "Arrangement Viewer"); + std::cout << "Preprocess complete" << std::endl; viewer.show(); app.exec(); } diff --git a/Arrangement_on_surface_2/include/CGAL/Draw_aos/helpers.h b/Arrangement_on_surface_2/include/CGAL/Draw_aos/helpers.h index 677ef1726e5..ebba088d7a5 100644 --- a/Arrangement_on_surface_2/include/CGAL/Draw_aos/helpers.h +++ b/Arrangement_on_surface_2/include/CGAL/Draw_aos/helpers.h @@ -6,7 +6,7 @@ namespace CGAL { using Exact_kernel = CGAL::Exact_predicates_exact_constructions_kernel; -// using Geom_traits = Arr_linear_traits_2; +// using Geom_traits = Arr_segment_traits_2; using Geom_traits = CGAL::Arr_linear_traits_2; using Arrangement = Arrangement_2; diff --git a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/approx_y_at_x.h b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/approx_y_at_x.h deleted file mode 100644 index ae9d6008460..00000000000 --- a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/approx_y_at_x.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef APPROX_Y_AT_X_H -#define APPROX_Y_AT_X_H -#include -#include -#include - -using Exact_kernel = CGAL::Exact_predicates_exact_constructions_kernel; -using Segment_traits_2 = CGAL::Arr_segment_traits_2; -using Arr = CGAL::Arrangement_2; -double approx_y_at_x(const Arr::Traits_2& traits, const Arr::X_monotone_curve_2& curve, double x) {} -#endif // APPROX_Y_AT_X_H \ No newline at end of file diff --git a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/compile.sh b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/compile.sh deleted file mode 100644 index 7b8231bf788..00000000000 --- a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/compile.sh +++ /dev/null @@ -1 +0,0 @@ -/usr/bin/clang++ -DCGAL_DATA_DIR=\\\"/Users/shep/codes/cgal-public-dev/Data/data\\\" -DCGAL_USE_BASIC_VIEWER -DCGAL_USE_CORE=1 -DCGAL_USE_GMPXX=1 -DQT_CORE_LIB -DQT_GUI_LIB -DQT_OPENGLWIDGETS_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -I/Users/shep/codes/cgal-public-dev/AABB_tree/include -I/Users/shep/codes/cgal-public-dev/Advancing_front_surface_reconstruction/include -I/Users/shep/codes/cgal-public-dev/Algebraic_foundations/include -I/Users/shep/codes/cgal-public-dev/Algebraic_kernel_d/include -I/Users/shep/codes/cgal-public-dev/Algebraic_kernel_for_circles/include -I/Users/shep/codes/cgal-public-dev/Algebraic_kernel_for_spheres/include -I/Users/shep/codes/cgal-public-dev/Alpha_shapes_2/include -I/Users/shep/codes/cgal-public-dev/Alpha_shapes_3/include -I/Users/shep/codes/cgal-public-dev/Alpha_wrap_3/include -I/Users/shep/codes/cgal-public-dev/Apollonius_graph_2/include -I/Users/shep/codes/cgal-public-dev/Arithmetic_kernel/include -I/Users/shep/codes/cgal-public-dev/Arrangement_on_surface_2/include -I/Users/shep/codes/cgal-public-dev/BGL/include -I/Users/shep/codes/cgal-public-dev/Barycentric_coordinates_2/include -I/Users/shep/codes/cgal-public-dev/Basic_viewer/include -I/Users/shep/codes/cgal-public-dev/Boolean_set_operations_2/include -I/Users/shep/codes/cgal-public-dev/Bounding_volumes/include -I/Users/shep/codes/cgal-public-dev/Box_intersection_d/include -I/Users/shep/codes/cgal-public-dev/CGAL_Core/include -I/Users/shep/codes/cgal-public-dev/CGAL_ImageIO/include -I/Users/shep/codes/cgal-public-dev/CGAL_ipelets/include -I/Users/shep/codes/cgal-public-dev/Cartesian_kernel/include -I/Users/shep/codes/cgal-public-dev/Circular_kernel_2/include -I/Users/shep/codes/cgal-public-dev/Circular_kernel_3/include -I/Users/shep/codes/cgal-public-dev/Circulator/include -I/Users/shep/codes/cgal-public-dev/Classification/include -I/Users/shep/codes/cgal-public-dev/Combinatorial_map/include -I/Users/shep/codes/cgal-public-dev/Cone_spanners_2/include -I/Users/shep/codes/cgal-public-dev/Convex_decomposition_3/include -I/Users/shep/codes/cgal-public-dev/Convex_hull_2/include -I/Users/shep/codes/cgal-public-dev/Convex_hull_3/include -I/Users/shep/codes/cgal-public-dev/Convex_hull_d/include -I/Users/shep/codes/cgal-public-dev/Distance_2/include -I/Users/shep/codes/cgal-public-dev/Distance_3/include -I/Users/shep/codes/cgal-public-dev/Envelope_2/include -I/Users/shep/codes/cgal-public-dev/Envelope_3/include -I/Users/shep/codes/cgal-public-dev/Filtered_kernel/include -I/Users/shep/codes/cgal-public-dev/Generalized_map/include -I/Users/shep/codes/cgal-public-dev/Generator/include -I/Users/shep/codes/cgal-public-dev/GraphicsView/include -I/Users/shep/codes/cgal-public-dev/HalfedgeDS/include -I/Users/shep/codes/cgal-public-dev/Hash_map/include -I/Users/shep/codes/cgal-public-dev/Heat_method_3/include -I/Users/shep/codes/cgal-public-dev/Homogeneous_kernel/include -I/Users/shep/codes/cgal-public-dev/Hyperbolic_triangulation_2/include -I/Users/shep/codes/cgal-public-dev/Inscribed_areas/include -I/Users/shep/codes/cgal-public-dev/Installation/include -I/Users/shep/codes/cgal-public-dev/Interpolation/include -I/Users/shep/codes/cgal-public-dev/Intersections_2/include -I/Users/shep/codes/cgal-public-dev/Intersections_3/include -I/Users/shep/codes/cgal-public-dev/Interval_skip_list/include -I/Users/shep/codes/cgal-public-dev/Interval_support/include -I/Users/shep/codes/cgal-public-dev/Isosurfacing_3/include -I/Users/shep/codes/cgal-public-dev/Jet_fitting_3/include -I/Users/shep/codes/cgal-public-dev/Kernel_23/include -I/Users/shep/codes/cgal-public-dev/Kernel_d/include -I/Users/shep/codes/cgal-public-dev/Kinetic_space_partition/include -I/Users/shep/codes/cgal-public-dev/Kinetic_surface_reconstruction/include -I/Users/shep/codes/cgal-public-dev/LEDA/include -I/Users/shep/codes/cgal-public-dev/Linear_cell_complex/include -I/Users/shep/codes/cgal-public-dev/Matrix_search/include -I/Users/shep/codes/cgal-public-dev/Mesh_2/include -I/Users/shep/codes/cgal-public-dev/Mesh_3/include -I/Users/shep/codes/cgal-public-dev/Mesher_level/include -I/Users/shep/codes/cgal-public-dev/Minkowski_sum_2/include -I/Users/shep/codes/cgal-public-dev/Minkowski_sum_3/include -I/Users/shep/codes/cgal-public-dev/Modifier/include -I/Users/shep/codes/cgal-public-dev/Modular_arithmetic/include -I/Users/shep/codes/cgal-public-dev/Nef_2/include -I/Users/shep/codes/cgal-public-dev/Nef_3/include -I/Users/shep/codes/cgal-public-dev/Nef_S2/include -I/Users/shep/codes/cgal-public-dev/NewKernel_d/include -I/Users/shep/codes/cgal-public-dev/Number_types/include -I/Users/shep/codes/cgal-public-dev/Optimal_bounding_box/include -I/Users/shep/codes/cgal-public-dev/Optimal_transportation_reconstruction_2/include -I/Users/shep/codes/cgal-public-dev/Optimisation_basic/include -I/Users/shep/codes/cgal-public-dev/Orthtree/include -I/Users/shep/codes/cgal-public-dev/Partition_2/include -I/Users/shep/codes/cgal-public-dev/Periodic_2_triangulation_2/include -I/Users/shep/codes/cgal-public-dev/Periodic_3_mesh_3/include -I/Users/shep/codes/cgal-public-dev/Periodic_3_triangulation_3/include -I/Users/shep/codes/cgal-public-dev/Periodic_4_hyperbolic_triangulation_2/include -I/Users/shep/codes/cgal-public-dev/Point_set_2/include -I/Users/shep/codes/cgal-public-dev/Point_set_3/include -I/Users/shep/codes/cgal-public-dev/Point_set_processing_3/include -I/Users/shep/codes/cgal-public-dev/Poisson_surface_reconstruction_3/include -I/Users/shep/codes/cgal-public-dev/Polygon/include -I/Users/shep/codes/cgal-public-dev/Polygon_mesh_processing/include -I/Users/shep/codes/cgal-public-dev/Polygon_repair/include -I/Users/shep/codes/cgal-public-dev/Polygonal_surface_reconstruction/include -I/Users/shep/codes/cgal-public-dev/Polyhedron/include -I/Users/shep/codes/cgal-public-dev/Polyline_simplification_2/include -I/Users/shep/codes/cgal-public-dev/Polynomial/include -I/Users/shep/codes/cgal-public-dev/Polytope_distance_d/include -I/Users/shep/codes/cgal-public-dev/Principal_component_analysis/include -I/Users/shep/codes/cgal-public-dev/Principal_component_analysis_LGPL/include -I/Users/shep/codes/cgal-public-dev/Profiling_tools/include -I/Users/shep/codes/cgal-public-dev/Property_map/include -I/Users/shep/codes/cgal-public-dev/QP_solver/include -I/Users/shep/codes/cgal-public-dev/Random_numbers/include -I/Users/shep/codes/cgal-public-dev/Ridges_3/include -I/Users/shep/codes/cgal-public-dev/SMDS_3/include -I/Users/shep/codes/cgal-public-dev/STL_Extension/include -I/Users/shep/codes/cgal-public-dev/Scale_space_reconstruction_3/include -I/Users/shep/codes/cgal-public-dev/SearchStructures/include -I/Users/shep/codes/cgal-public-dev/Segment_Delaunay_graph_2/include -I/Users/shep/codes/cgal-public-dev/Segment_Delaunay_graph_Linf_2/include -I/Users/shep/codes/cgal-public-dev/Set_movable_separability_2/include -I/Users/shep/codes/cgal-public-dev/Shape_detection/include -I/Users/shep/codes/cgal-public-dev/Shape_regularization/include -I/Users/shep/codes/cgal-public-dev/Skin_surface_3/include -I/Users/shep/codes/cgal-public-dev/Snap_rounding_2/include -I/Users/shep/codes/cgal-public-dev/Solver_interface/include -I/Users/shep/codes/cgal-public-dev/Spatial_searching/include -I/Users/shep/codes/cgal-public-dev/Spatial_sorting/include -I/Users/shep/codes/cgal-public-dev/Straight_skeleton_2/include -I/Users/shep/codes/cgal-public-dev/Straight_skeleton_extrusion_2/include -I/Users/shep/codes/cgal-public-dev/Stream_lines_2/include -I/Users/shep/codes/cgal-public-dev/Stream_support/include -I/Users/shep/codes/cgal-public-dev/Subdivision_method_3/include -I/Users/shep/codes/cgal-public-dev/Surface_mesh/include -I/Users/shep/codes/cgal-public-dev/Surface_mesh_approximation/include -I/Users/shep/codes/cgal-public-dev/Surface_mesh_deformation/include -I/Users/shep/codes/cgal-public-dev/Surface_mesh_parameterization/include -I/Users/shep/codes/cgal-public-dev/Surface_mesh_segmentation/include -I/Users/shep/codes/cgal-public-dev/Surface_mesh_shortest_path/include -I/Users/shep/codes/cgal-public-dev/Surface_mesh_simplification/include -I/Users/shep/codes/cgal-public-dev/Surface_mesh_skeletonization/include -I/Users/shep/codes/cgal-public-dev/Surface_mesh_topology/include -I/Users/shep/codes/cgal-public-dev/Surface_mesher/include -I/Users/shep/codes/cgal-public-dev/Surface_sweep_2/include -I/Users/shep/codes/cgal-public-dev/TDS_2/include -I/Users/shep/codes/cgal-public-dev/TDS_3/include -I/Users/shep/codes/cgal-public-dev/Testsuite/include -I/Users/shep/codes/cgal-public-dev/Tetrahedral_remeshing/include -I/Users/shep/codes/cgal-public-dev/Three/include -I/Users/shep/codes/cgal-public-dev/Triangulation/include -I/Users/shep/codes/cgal-public-dev/Triangulation_2/include -I/Users/shep/codes/cgal-public-dev/Triangulation_3/include -I/Users/shep/codes/cgal-public-dev/Triangulation_on_hyperbolic_surface_2/include -I/Users/shep/codes/cgal-public-dev/Triangulation_on_sphere_2/include -I/Users/shep/codes/cgal-public-dev/Union_find/include -I/Users/shep/codes/cgal-public-dev/Visibility_2/include -I/Users/shep/codes/cgal-public-dev/Voronoi_diagram_2/include -I/Users/shep/codes/cgal-public-dev/Weights/include -I/Users/shep/codes/cgal-public-dev/Arrangement_on_surface_2/test/Arrangement_on_surface_2/build -isystem /opt/homebrew/include -isystem /opt/homebrew/lib/QtOpenGLWidgets.framework/Headers -iframework /opt/homebrew/lib -isystem /opt/homebrew/lib/QtOpenGL.framework/Headers -isystem /opt/homebrew/lib/QtCore.framework/Headers -isystem /opt/homebrew/share/qt/mkspecs/macx-clang -isystem /opt/homebrew/lib/QtGui.framework/Headers -isystem /opt/homebrew/lib/QtWidgets.framework/Headers -ftemplate-backtrace-limit=0 -g -std=gnu++17 -arch arm64 -o CMakeFiles/test_drawing_planar.dir/test_drawing_planar.cpp.o -c /Users/shep/codes/cgal-public-dev/Arrangement_on_surface_2/test/Arrangement_on_surface_2/test_drawing_planar.cpp diff --git a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/outer_ccb_0.txt b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/outer_ccb_0.txt deleted file mode 100644 index 33b89f89ae6..00000000000 --- a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/outer_ccb_0.txt +++ /dev/null @@ -1,4 +0,0 @@ -0.200004 -1.24026 -3.73824 -1.24026 -3.73824 1.94415 -0.200004 1.94415 diff --git a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/print_arr.h b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/print_arr.h deleted file mode 100644 index a2a229d4dca..00000000000 --- a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/print_arr.h +++ /dev/null @@ -1,122 +0,0 @@ -#ifndef _PRINT_ARR_H_ -#define _PRINT_ARR_H_ -#include -#include -#include - -//----------------------------------------------------------------------------- -// Print all neighboring vertices to a given arrangement vertex. -// -template -void print_neighboring_vertices(typename Arrangement::Vertex_const_handle v) { - if(v->is_isolated()) { - std::cout << "The vertex (" << v->point() << ") is isolated\n"; - return; - } - - std::cout << "The neighbors of the vertex (" << v->point() << ") are:"; - typename Arrangement::Halfedge_around_vertex_const_circulator first, curr; - first = curr = v->incident_halfedges(); - do - std::cout << " (" << curr->source()->point() << ")"; - while(++curr != first); - std::cout << std::endl; -} - -//----------------------------------------------------------------------------- -// Print all vertices (points) and edges (curves) along a connected component -// boundary. -// -template -void print_ccb(typename Arrangement::Ccb_halfedge_const_circulator circ) { - std::cout << "(" << circ->source()->point() << ")"; - typename Arrangement::Ccb_halfedge_const_circulator curr = circ; - do { - typename Arrangement::Halfedge_const_handle e = curr; - std::cout << " [" << e->curve() << "] " - << "(" << e->target()->point() << ")"; - } while(++curr != circ); - std::cout << std::endl; -} - -//----------------------------------------------------------------------------- -// Print the boundary description of an arrangement face. -// -template -void print_face(typename Arrangement::Face_const_handle f) { - // Print the outer boundary. - if(f->is_unbounded()) { - std::cout << "Unbounded face.\n"; - } else { - std::cout << "Outer boundary: "; - print_ccb(f->outer_ccb()); - } - - // Print the boundary of each of the holes. - size_t index = 1; - for(auto hole = f->holes_begin(); hole != f->holes_end(); ++hole, ++index) { - std::cout << " Hole #" << index << ": "; - // The following statement pacifies msvc. - typename Arrangement::Ccb_halfedge_const_circulator circ = *hole; - print_ccb(circ); - } - - // Print the isolated vertices. - index = 1; - for(auto iv = f->isolated_vertices_begin(); iv != f->isolated_vertices_end(); ++iv, ++index) { - std::cout << " Isolated vertex #" << index << ": " - << "(" << iv->point() << ")" << std::endl; - } -} - -//----------------------------------------------------------------------------- -// Print the given arrangement. -// -template -void print_arrangement(const Arrangement& arr) { - CGAL_precondition(arr.is_valid()); - - // Print the arrangement vertices. - std::cout << arr.number_of_vertices() << " vertices:\n"; - for(auto vit = arr.vertices_begin(); vit != arr.vertices_end(); ++vit) { - std::cout << "(" << vit->point() << ")"; - if(vit->is_isolated()) - std::cout << " - Isolated.\n"; - else - std::cout << " - degree " << vit->degree() << std::endl; - } - - // Print the arrangement edges. - std::cout << arr.number_of_edges() << " edges:\n"; - for(auto eit = arr.edges_begin(); eit != arr.edges_end(); ++eit) - std::cout << "[" << eit->curve() << "]\n"; - - // Print the arrangement faces. - std::cout << arr.number_of_faces() << " faces:\n"; - for(auto fit = arr.faces_begin(); fit != arr.faces_end(); ++fit) - print_face(fit); -} - -//----------------------------------------------------------------------------- -// Print the size of the given arrangement. -// -template -void print_arrangement_size(const Arrangement& arr) { - std::cout << "The arrangement size:\n" - << " |V| = " << arr.number_of_vertices() << ", |E| = " << arr.number_of_edges() - << ", |F| = " << arr.number_of_faces() << std::endl; -} - -//----------------------------------------------------------------------------- -// Print the size of the given unbounded arrangement. -// -template -void print_unbounded_arrangement_size(const Arrangement& arr) { - std::cout << "The arrangement size:\n" - << " |V| = " << arr.number_of_vertices() << " (plus " << arr.number_of_vertices_at_infinity() - << " at infinity)" - << ", |E| = " << arr.number_of_edges() << ", |F| = " << arr.number_of_faces() << " (" - << arr.number_of_unbounded_faces() << " unbounded)\n\n"; -} - -#endif diff --git a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/test_draw_aos_arr_bounded_approximate_face_2.cpp b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/test_draw_aos_arr_bounded_approximate_face_2.cpp deleted file mode 100644 index 8f54f158724..00000000000 --- a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/test_draw_aos_arr_bounded_approximate_face_2.cpp +++ /dev/null @@ -1,194 +0,0 @@ -#include "CGAL/Bbox_2.h" -#include "CGAL/Draw_aos/Arr_approximation_geometry_traits.h" -#include -#include -#include -#include - -using Approx_point = CGAL::Arr_approximation_geometry_traits::Approx_point; - -struct Test_case -{ - std::vector points_to_insert; - std::vector expected_points; - CGAL::Bbox_2 bbox; - - Test_case(std::vector points, std::vector expected, CGAL::Bbox_2 b) - : points_to_insert(std::move(points)) - , expected_points(std::move(expected)) - , bbox(b) {} -}; - -void test_geom_fill_corners_output_iterator(const Test_case& test_case) { - std::vector points{}; - auto inserter = std::back_inserter(points); - CGAL::Geom_fill_corners_output_iterator> geom_inserter( - inserter, CGAL::Bbox_2(test_case.bbox)); - - for(const auto& pt : test_case.points_to_insert) { - geom_inserter++ = pt; - } - - if(points != test_case.expected_points) { - std::cerr << "Test failed for bbox: " << test_case.bbox << std::endl; - std::cerr << "Points inserted: \n"; - for(const auto& pt : test_case.points_to_insert) { - std::cerr << pt << "\n"; - } - std::cerr << "\nExpected: \n"; - for(const auto& pt : test_case.expected_points) { - std::cerr << pt << "\n"; - } - std::cerr << "\nGot:\n"; - for(const auto& pt : points) { - std::cerr << pt << "\n"; - } - std::cerr << std::endl; - assert(false); - } -} - -int main() { - CGAL::Bbox_2 bbox(0, 0, 10, 10); - std::vector cases{ - /** - * -------------------- - * | | - * | | - * | | - * | | - * | | - * | | - * 1------------------- - */ - Test_case({Approx_point(0, 0)}, {Approx_point(0, 0)}, bbox), - - /** - * 2------------------- - * | | - * | | - * | | - * | | - * | | - * | | - * 1------------------- - * - * Expected: - * - * 4------------------3 - * | | - * | | - * | | - * | | - * | | - * | | - * 1------------------2 - */ - Test_case({Approx_point(0, 0), Approx_point(0, 10)}, - {Approx_point(0, 0), Approx_point(10, 0), Approx_point(10, 10), Approx_point(0, 10)}, bbox), - /** - * -------------------- - * | | - * | | - * | | - * | | - * | | - * | | - * 1------------------2 - * - * Expected: - * - * 2------------------- - * | | - * | | - * | | - * | | - * | | - * | | - * 1------------------2 - */ - Test_case({Approx_point(0, 0), Approx_point(10, 0)}, {Approx_point(0, 0), Approx_point(10, 0)}, bbox), - /** - * -------------------- - * | | - * | | - * | | - * | | - * | | - * | | - * 1---------2--------- - * - * Expected: - * - * -------------------- - * | | - * | | - * 2 | - * | | - * | | - * | | - * 1------------------- - */ - Test_case({Approx_point(0, 0), Approx_point(5, 0)}, {Approx_point(0, 0), Approx_point(5, 0)}, bbox), - /** - * -------------------- - * | | - * | | - * | 1 - * | | - * | 2 - * | | - * -------------------- - * - * Expected: - * - * 3------------------2 - * | | - * | | - * | 1 - * | | - * | 6 - * | | - * 4------------------5 - */ - Test_case({Approx_point(10, 5), Approx_point(10, 3)}, - {Approx_point(10, 5), Approx_point(10, 10), Approx_point(0, 10), Approx_point(0, 0), - Approx_point(10, 0), Approx_point(10, 3)}, - bbox), - /** - * -------------------1 - * | | - * | | - * | | - * | | - * | 2 - * | | - * -------------------| - * - * Expected: - * - * 2------------------1 - * | | - * | | - * | | - * | | - * | 5 - * | | - * 3------------------4 - */ - Test_case({Approx_point(10, 10), Approx_point(10, 3)}, - { - Approx_point(10, 10), - Approx_point(0, 10), - Approx_point(0, 0), - Approx_point(10, 0), - Approx_point(10, 3), - }, - bbox), - }; - - for(size_t i = 0; i < cases.size(); ++i) { - const auto& test_case = cases[i]; - test_geom_fill_corners_output_iterator(test_case); - } -} \ No newline at end of file diff --git a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/test_drawing_planar.cpp b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/test_drawing_planar.cpp index 1570982f54b..01532380433 100644 --- a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/test_drawing_planar.cpp +++ b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/test_drawing_planar.cpp @@ -18,6 +18,7 @@ #include "CGAL/Exact_predicates_exact_constructions_kernel.h" #include "CGAL/Exact_predicates_inexact_constructions_kernel.h" #include +#include // void draw_segments_arr_1() { // using Exact_kernel = CGAL::Exact_predicates_exact_constructions_kernel; @@ -111,26 +112,120 @@ // // CGAL::draw_viewer(arr); // } -void draw_linear_arr_1() { - using Exact_kernel = CGAL::Exact_predicates_exact_constructions_kernel; - using Traits = CGAL::Arr_linear_traits_2; - using Point_2 = Traits::Point_2; - using Line_2 = Traits::Line_2; - using Ray_2 = Traits::Ray_2; - using Curve_2 = Traits::Curve_2; - using Arrangement = CGAL::Arrangement_2; - using Face_const_handle = Arrangement::Face_const_handle; - using Halfedge_const_handle = Arrangement::Halfedge_const_iterator; - using X_monotone_curve_2 = Traits::X_monotone_curve_2; +// void draw_segments_arr_4() { +// using Exact_kernel = CGAL::Exact_predicates_exact_constructions_kernel; +// using Segment_traits = CGAL::Arr_segment_traits_2; +// using Point_2 = Segment_traits::Point_2; +// using X_monotone_curve_2 = Segment_traits::X_monotone_curve_2; +// using Arrangement = CGAL::Arrangement_2; +// Arrangement arr; +// auto traits = arr.traits(); +// auto cst_x_curve = traits->construct_x_monotone_curve_2_object(); - Arrangement arr; - auto x_axis = X_monotone_curve_2(Ray_2(Point_2(0, 0), Point_2(1, 0))); - auto y_axis = X_monotone_curve_2(Ray_2(Point_2(0, 0), Point_2(0, 1))); - CGAL::insert(arr, x_axis); - CGAL::insert(arr, y_axis); +// std::vector segments; - CGAL::draw_viewer(arr); -} +// std::vector polyline1{ +// {6, -21}, {6, -3}, {13, -3}, {13, -12}, {18, -12}, {18, -4}, {18, -3}, {25, -3}, {25, -21}, {6, -21}, +// }; +// for(size_t i = 0; i < polyline1.size() - 1; ++i) { +// segments.push_back(cst_x_curve(polyline1[i], polyline1[i + 1])); +// } + +// std::vector polyline2{ +// {-27, -14}, {-24, -14}, {-21, -16}, {-19, -18}, {-18, -21}, {-17, -24}, {-18, -28}, {-19, -30}, {-22, -32}, +// {-24, -33}, {-29, -33}, {-34, -33}, {-38, -32}, {-43, -30}, {-46, -29}, {-50, -25}, {-53, -21}, {-53, -17}, +// {-54, -12}, {-53, -7}, {-52, -2}, {-50, 2}, {-45, 5}, {-40, 6}, {-34, 7}, {-29, 7}, {-23, 7}, +// {-20, 6}, {-18, 5}, {-16, 2}, {-15, 0}, {-16, -3}, {-17, -3}, {-18, -1}, {-19, 1}, {-20, 4}, +// {-22, 4}, {-26, 4}, {-28, 4}, {-31, 4}, {-33, 4}, {-37, 4}, {-41, 3}, {-44, 2}, {-47, 1}, +// {-48, 0}, {-49, -2}, {-50, -5}, {-51, -8}, {-51, -13}, {-51, -16}, {-50, -18}, {-49, -22}, {-46, -24}, +// {-42, -27}, {-40, -29}, {-36, -29}, {-32, -30}, {-28, -31}, {-24, -31}, {-21, -30}, {-19, -28}, {-19, -25}, +// {-20, -23}, {-21, -21}, {-24, -18}, {-26, -16}, {-27, -15}, {-27, -14}, +// }; +// for(size_t i = 0; i < polyline2.size() - 1; ++i) { +// segments.push_back(cst_x_curve(polyline2[i], polyline2[i + 1])); +// } + +// CGAL::insert(arr, segments.begin(), segments.end()); + +// CGAL::draw_viewer(arr); +// } + +// void draw_segments_arr_5() { +// using Exact_kernel = CGAL::Exact_predicates_exact_constructions_kernel; +// using Segment_traits = CGAL::Arr_segment_traits_2; +// using Point_2 = Segment_traits::Point_2; +// using X_monotone_curve_2 = Segment_traits::X_monotone_curve_2; +// using Arrangement = CGAL::Arrangement_2; +// Arrangement arr; +// auto traits = arr.traits(); +// auto cst_x_curve = traits->construct_x_monotone_curve_2_object(); + +// std::vector segments; + +// std::vector polyline1{ +// {11, 23}, {12, -13}, {17, -13}, {18, 1}, {18, 16}, {18, 23}, {15, 35}, {15, 44}, {18, 47}, {19, 42}, +// {19, 37}, {20, 28}, {23, 21}, {23, 9}, {24, -7}, {22, -15}, {20, -19}, {15, -19}, {10, -16}, {7, -14}, +// {7, -3}, {5, 11}, {1, 20}, {0, 35}, {1, 45}, {3, 51}, {5, 53}, {11, 53}, {19, 53}, {23, 49}, +// {25, 40}, {28, 31}, {34, 16}, {35, 7}, {38, -11}, {44, -11}, {43, -7}, {43, -5}, {42, 7}, {40, 23}, +// {38, 30}, {35, 49}, {19, 57}, {8, 58}, {-2, 55}, {-2, 30}, {-3, 15}, {-3, -16}, {1, -20}, {12, -22}, +// {20, -22}, {25, -21}, {26, -14}, {28, -3}, {27, 15}, {23, 31}, {22, 44}, {20, 49}, {15, 49}, {10, 46}, +// {8, 39}, {8, 32}, {8, 28}, {11, 23}, +// }; +// for(size_t i = 0; i < polyline1.size() - 1; ++i) { +// segments.push_back(cst_x_curve(polyline1[i], polyline1[i + 1])); +// } + +// CGAL::insert(arr, segments.begin(), segments.end()); + +// CGAL::draw_viewer(arr); +// } + +// void draw_segments_arr_6() { +// using Exact_kernel = CGAL::Exact_predicates_exact_constructions_kernel; +// using Segment_traits = CGAL::Arr_segment_traits_2; +// using Point_2 = Segment_traits::Point_2; +// using X_monotone_curve_2 = Segment_traits::X_monotone_curve_2; +// using Arrangement = CGAL::Arrangement_2; +// Arrangement arr; +// auto traits = arr.traits(); +// auto cst_x_curve = traits->construct_x_monotone_curve_2_object(); + +// std::vector segments; + +// std::vector polyline1{ +// {9, -3}, {11, -34}, {26, -34}, {26, -8}, {26, -34}, {36, -34}, {36, -31}, {36, -27}, {37, -23}, {41, -23}, +// {47, -23}, {49, -16}, {49, -2}, {42, 10}, {41, 0}, {41, -19}, {41, 0}, {42, 10}, {30, 10}, {28, 6}, +// {28, 2}, {29, -30}, {28, 2}, {28, 6}, {30, 10}, {42, 10}, {29, 16}, {18, 12}, {9, -3}, +// }; +// for(size_t i = 0; i < polyline1.size() - 1; ++i) { +// segments.push_back(cst_x_curve(polyline1[i], polyline1[i + 1])); +// } + +// CGAL::insert(arr, segments.begin(), segments.end()); + +// CGAL::draw_viewer(arr); +// } + +// void draw_linear_arr_1() { +// using Exact_kernel = CGAL::Exact_predicates_exact_constructions_kernel; +// using Traits = CGAL::Arr_linear_traits_2; +// using Point_2 = Traits::Point_2; +// using Line_2 = Traits::Line_2; +// using Ray_2 = Traits::Ray_2; +// using Curve_2 = Traits::Curve_2; +// using Arrangement = CGAL::Arrangement_2; +// using Face_const_handle = Arrangement::Face_const_handle; +// using Halfedge_const_handle = Arrangement::Halfedge_const_iterator; +// using X_monotone_curve_2 = Traits::X_monotone_curve_2; + +// Arrangement arr; +// auto x_axis = X_monotone_curve_2(Ray_2(Point_2(0, 0), Point_2(1, 0))); +// auto y_axis = X_monotone_curve_2(Ray_2(Point_2(0, 0), Point_2(0, 1))); +// CGAL::insert(arr, x_axis); +// CGAL::insert(arr, y_axis); + +// CGAL::draw_viewer(arr); +// } void draw_linear_arr_2() { using Exact_kernel = CGAL::Exact_predicates_exact_constructions_kernel; @@ -148,17 +243,17 @@ void draw_linear_arr_2() { Arrangement arr; auto& traits = *arr.traits(); // Insert a n*n grid, each cell is a square of size 5 - int n = 1; - // for(int i = 0; i < n; ++i) { - // Point_2 p1(i * 5, 0); - // Point_2 p2(i * 5, 1); - // CGAL::insert(arr, Curve_2(Line_2(p1, p2))); - // } - // for(int i = 0; i < n; ++i) { - // Point_2 p1(0, i * 5); - // Point_2 p2(1, i * 5); - // CGAL::insert(arr, Curve_2(Line_2(p1, p2))); - // } + int n = 5; + for(int i = 0; i < n; ++i) { + Point_2 p1(i * 5, 0); + Point_2 p2(i * 5, 1); + CGAL::insert(arr, Curve_2(Line_2(p1, p2))); + } + for(int i = 0; i < n; ++i) { + Point_2 p1(0, i * 5); + Point_2 p2(1, i * 5); + CGAL::insert(arr, Curve_2(Line_2(p1, p2))); + } // Generate a inner square(2*2) for all cells // And an inner triangle for each square for(int i = 0; i < n; ++i) { @@ -183,12 +278,49 @@ void draw_linear_arr_2() { CGAL::insert(arr, Curve_2(Segment_2(tri_p1, top))); } } - - auto arr2 = arr; - + std::cout << "Arrangement has " << arr.number_of_faces() << " faces." << std::endl; CGAL::draw_viewer(arr); } +// void draw_linear_arr_3() { +// using Exact_kernel = CGAL::Exact_predicates_exact_constructions_kernel; +// using Traits = CGAL::Arr_linear_traits_2; +// using Point_2 = Traits::Point_2; +// using Line_2 = Traits::Line_2; +// using Segment_2 = Traits::Segment_2; +// using Ray_2 = Traits::Ray_2; +// using Curve_2 = Traits::Curve_2; +// using Arrangement = CGAL::Arrangement_2; +// using Face_const_handle = Arrangement::Face_const_handle; +// using Halfedge_const_handle = Arrangement::Halfedge_const_iterator; +// using X_monotone_curve_2 = Traits::X_monotone_curve_2; + +// std::vector points{ +// {11, 23}, {12, -13}, {17, -13}, {18, 1}, {18, 16}, {18, 23}, {15, 35}, {15, 44}, {18, 47}, {19, 42}, +// {19, 37}, {20, 28}, {23, 21}, {23, 9}, {24, -7}, {22, -15}, {20, -19}, {15, -19}, {10, -16}, {7, -14}, +// {7, -3}, {5, 11}, {1, 20}, {0, 35}, {1, 45}, {3, 51}, {5, 53}, {11, 53}, {19, 53}, {23, 49}, +// {25, 40}, {28, 31}, {34, 16}, {35, 7}, {38, -11}, {44, -11}, {43, -7}, {43, -5}, {42, 7}, {40, 23}, +// {38, 30}, {35, 49}, {19, 57}, {8, 58}, {-2, 55}, {-2, 30}, {-3, 15}, {-3, -16}, {1, -20}, {12, -22}, +// {20, -22}, {25, -21}, {26, -14}, {28, -3}, {27, 15}, {23, 31}, {22, 44}, {20, 49}, {15, 49}, {10, 46}, +// {8, 39}, {8, 32}, {8, 28}, {11, 23}, +// }; + +// Arrangement arr; +// auto& traits = *arr.traits(); +// std::vector segments; +// for(size_t i = 0; i < points.size() - 1; ++i) { +// Point_2 p1 = points[i]; +// Point_2 p2 = points[i + 1]; +// // create a segment +// X_monotone_curve_2 seg = traits.construct_x_monotone_curve_2_object()(p1, p2); +// segments.push_back(seg); +// } + +// // insert segments into the arrangement +// CGAL::insert(arr, segments.begin(), segments.end()); + +// CGAL::draw_viewer(arr); +// } // // supports segments // void draw_circle_segs_arr() { // using Exact_kernel = CGAL::Exact_predicates_exact_constructions_kernel; @@ -311,7 +443,7 @@ using Point = Kernel::Point_2; // } int main() { - // draw_segments_arr_2(); + // draw_segments_arr_6(); draw_linear_arr_2(); // test_zone(); // draw_conic_arcs_arr(); diff --git a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/test_drawing_spherical.cpp b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/test_drawing_spherical.cpp index 536f64e3b0b..1664696b293 100644 --- a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/test_drawing_spherical.cpp +++ b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/test_drawing_spherical.cpp @@ -52,11 +52,30 @@ int main() { using Point = K::Point_2; Cdt cdt; - std::vector outer = {Point(0, 0), Point(5, 0), Point(5, 5), Point(0, 5), Point(0, 0)}; + std::vector outer = {{4, 1}, {4, 4}, {2.5, 4}, {2.32026, 3.28104}, {2.32026, 2.64052}, + {2.5, 3}, {3, 2}, {2.32026, 2}, {2.32026, 3.28104}, {2.5, 4}, + {2.32026, 4}, {2.32026, 1}, {4, 1}}; std::vector inner = {Point(0, 0), Point(0.5, 0), Point(0.5, 0.5), Point(0.5, 0), Point(1, 0), Point(1, 1), Point(0, 1)}; - std::vector outer_constraint = {Point(0, 0), Point(-1, -1), Point(5, 0), Point(6, -1), - Point(5, 5), Point(6, 6), Point(0, 5), Point(-1, 6)}; + std::vector outer_constraint = {{4, 1}, + {4, 4}, + {2.5, 4}, + {2.32026, 3.28104}, + {1.32026, 3.28104}, + {1.32026, 2.64052}, + {2.32026, 2.64052}, + {2.5, 3}, + {3, 2}, + {2.32026, 2}, + {1.32026, 2}, + {1.32026, 3.28104}, + {2.32026, 3.28104}, + {2.5, 4}, + {2.32026, 4}, + {1.32026, 4}, + {1.32026, 1}, + {2.32026, 1}, + {4, 1}}; auto add_info = [](const Point& p) { return std::make_pair(p, 1); }; diff --git a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/zone_exp.h b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/zone_exp.h deleted file mode 100644 index e0702188a81..00000000000 --- a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/zone_exp.h +++ /dev/null @@ -1,71 +0,0 @@ -#ifndef ZONE_EXP_H -#define ZONE_EXP_H -#include "CGAL/Arr_trapezoid_ric_point_location.h" -#include -#include -#include -#include -#include -#include -#include -#include - -void test_zone() { - using Exact_kernel = CGAL::Exact_predicates_exact_constructions_kernel; - using Segment_traits = CGAL::Arr_segment_traits_2; - using Point_2 = Segment_traits::Point_2; - using Arrangement = CGAL::Arrangement_2; - using X_monotone_curve_2 = Segment_traits::X_monotone_curve_2; - using Traits = CGAL::Arr_linear_traits_2; - using Face_const_handle = Arrangement::Face_const_handle; - using Halfedge_const_handle = Arrangement::Halfedge_const_handle; - using Vertex_const_handle = Arrangement::Vertex_const_handle; - using Face_handle = Arrangement::Face_handle; - using Halfedge_handle = Arrangement::Halfedge_handle; - using Vertex_handle = Arrangement::Vertex_handle; - using Halfedge_const_handle = Arrangement::Halfedge_const_handle; - - Arrangement arr; - auto traits = arr.traits(); - - auto cst_x_curve = traits->construct_x_monotone_curve_2_object(); - auto tri = { - cst_x_curve({-1, 0}, {1, 0}), - cst_x_curve({1, 0}, {0, 3}), - cst_x_curve({0, 3}, {-1, 0}), - }; - CGAL::insert(arr, tri.begin(), tri.end()); - - // point location - auto pl = CGAL::Arr_trapezoid_ric_point_location(arr); - - // test zone construction - using Feature = std::variant; - using Feature_vector = std::vector; - using Feature_vector_out_iter = std::back_insert_iterator; - using Zone_visitor = CGAL::Arr_compute_zone_visitor; - - Feature_vector zone_features; - Feature_vector_out_iter out_iter(zone_features); - Zone_visitor zone_visitor(out_iter); - auto cv = cst_x_curve({-1, 0}, {1, 0}); - CGAL::Arrangement_zone_2 zone(arr, &zone_visitor); - - zone.init(cv, pl); - zone.compute_zone(); - - for(const auto& feature : zone_features) { - if(auto* hf = std::get_if(&feature)) { - std::cout << "Halfedge: " << (*hf)->curve() << std::endl; - Halfedge_const_handle che(*hf); - std::cout << " const curve" << che->curve() << std::endl; - } else if(auto* vh = std::get_if(&feature)) { - std::cout << "Vertex: " << (*vh)->point() << std::endl; - } else if(auto* fh = std::get_if(&feature)) { - std::cout << "Face: " << std::endl; - } - } - - CGAL::draw(arr); -} -#endif // ZONE_EXP_H \ No newline at end of file diff --git a/Basic_viewer/include/CGAL/Basic_viewer.h b/Basic_viewer/include/CGAL/Basic_viewer.h index ed8ca7620db..7a3354691c2 100644 --- a/Basic_viewer/include/CGAL/Basic_viewer.h +++ b/Basic_viewer/include/CGAL/Basic_viewer.h @@ -13,8 +13,8 @@ #ifndef CGAL_BASIC_VIEWER_H #define CGAL_BASIC_VIEWER_H -#include #include +#include // compatibility #if defined(CGAL_USE_BASIC_VIEWER) && !defined(CGAL_USE_BASIC_VIEWER_QT) @@ -30,10 +30,14 @@ // #elif defined(CGAL_USE_BASIC_VIEWER_GLFW) // #include #else -namespace CGAL { -inline void draw_graphics_scene(const Graphics_scene&, const char* = "CGAL Basic Viewer") { - std::cerr << "Impossible to draw, CGAL_USE_BASIC_VIEWER is not defined." << std::endl; -} +namespace CGAL +{ + inline + void draw_graphics_scene(const Graphics_scene&, + const char* ="CGAL Basic Viewer") + { + std::cerr<<"Impossible to draw, CGAL_USE_BASIC_VIEWER is not defined."< -#include #include #include -#include #include +#include +#include #ifdef __GNUC__ -#if __GNUC__ >= 9 -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-copy" +#if __GNUC__ >= 9 +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wdeprecated-copy" #endif #endif #include #include -#include #include +#include +#include #include #include -#include #ifdef __GNUC__ #if __GNUC__ >= 9 -#pragma GCC diagnostic pop +# pragma GCC diagnostic pop #endif #endif -#include -#include #include +#include +#include #include #include #include -#include #include +#include #define CGAL_BASIC_VIEWER_INIT_SIZE_X 500 #define CGAL_BASIC_VIEWER_INIT_SIZE_Y 450 @@ -66,48 +64,49 @@ namespace Qt { class Basic_viewer : public CGAL::QGLViewer { public: - using BufferType = float; + using BufferType=float; typedef CGAL::Exact_predicates_inexact_constructions_kernel Local_kernel; - typedef Local_kernel::Point_3 Local_point; + typedef Local_kernel::Point_3 Local_point; typedef Local_kernel::Vector_3 Local_vector; - using GS = Graphics_scene; + using GS=Graphics_scene; // Constructor/Destructor Basic_viewer(QWidget* parent, const Graphics_scene& buf, - const char* title = "", - bool draw_vertices = false, - bool draw_edges = true, - bool draw_faces = true, - bool use_default_color = false, - bool inverse_normal = false, - bool draw_rays = true, - bool draw_lines = true, - bool draw_text = true, - bool no_2D_mode = false) - : CGAL::QGLViewer(parent) - , m_scene(buf) - , m_draw_vertices(draw_vertices) - , m_draw_edges(draw_edges) - , m_draw_rays(draw_rays) - , m_draw_lines(draw_lines) - , m_draw_faces(draw_faces) - , m_draw_text(draw_text) - , m_draw_normals(false) - , m_draw_cylinder_edge(false) - , m_draw_sphere_vertex(false) - , m_draw_mesh_triangles(false) - , m_flat_shading(true) - , m_use_default_color(use_default_color) - , m_use_default_color_normal(false) - , m_display_face_normal(false) - , m_inverse_normal(inverse_normal) - , m_no_2D_mode(no_2D_mode) - , m_geometry_feature_enabled(true) - , m_prev_scene_empty(true) - , m_default_color_normal(220, 60, 20) - , m_ambient_color(0.6f, 0.5f, 0.5f, 0.5f) - , m_are_buffers_initialized(false) { + const char* title="", + bool draw_vertices=false, + bool draw_edges=true, + bool draw_faces=true, + bool use_default_color=false, + bool inverse_normal=false, + bool draw_rays=true, + bool draw_lines=true, + bool draw_text=true, + bool no_2D_mode=false) : + CGAL::QGLViewer(parent), + m_scene(buf), + m_draw_vertices(draw_vertices), + m_draw_edges(draw_edges), + m_draw_rays(draw_rays), + m_draw_lines(draw_lines), + m_draw_faces(draw_faces), + m_draw_text(draw_text), + m_draw_normals(false), + m_draw_cylinder_edge(false), + m_draw_sphere_vertex(false), + m_draw_mesh_triangles(false), + m_flat_shading(true), + m_use_default_color(use_default_color), + m_use_default_color_normal(false), + m_display_face_normal(false), + m_inverse_normal(inverse_normal), + m_no_2D_mode(no_2D_mode), + m_geometry_feature_enabled(true), + m_prev_scene_empty(true), + m_default_color_normal(220, 60, 20), + m_ambient_color(0.6f, 0.5f, 0.5f, 0.5f), + m_are_buffers_initialized(false) + { // Define 'Control+Q' as the new exit shortcut (default was 'Escape') setShortcut(qglviewer::EXIT_VIEWER, ::Qt::CTRL, ::Qt::Key_Q); @@ -155,7 +154,7 @@ public: setMouseBinding(::Qt::Key_C, ::Qt::ControlModifier, ::Qt::MiddleButton, qglviewer::FRAME, qglviewer::ZOOM); setWheelBinding(::Qt::Key_C, ::Qt::ControlModifier, qglviewer::FRAME, qglviewer::ZOOM); - if(title[0] == 0) + if (title[0]==0) setWindowTitle("CGAL Basic Viewer"); else setWindowTitle(title); @@ -163,12 +162,13 @@ public: resize(CGAL_BASIC_VIEWER_INIT_SIZE_X, CGAL_BASIC_VIEWER_INIT_SIZE_Y); } - ~Basic_viewer() { + ~Basic_viewer() + { makeCurrent(); - for(unsigned int i = 0; i < NB_GL_BUFFERS; ++i) + for (unsigned int i=0; iinverseTransformOf(CGAL::qglviewer::Vec(0.f, 0.f, 1.f)); - const CGAL::qglviewer::Vec& pos = m_frame_plane->position(); - return Local_kernel::Plane_3(n[0], n[1], n[2], -n * pos); + Local_kernel::Plane_3 clipping_plane() const + { + CGAL::qglviewer::Vec n=m_frame_plane->inverseTransformOf + (CGAL::qglviewer::Vec(0.f, 0.f, 1.f)); + const CGAL::qglviewer::Vec& pos=m_frame_plane->position(); + return Local_kernel::Plane_3(n[0], n[1], n[2], -n*pos); } - bool clipping_plane_enabled() const { return (m_use_clipping_plane != CLIPPING_PLANE_OFF); } + bool clipping_plane_enabled() const + { return (m_use_clipping_plane!=CLIPPING_PLANE_OFF); } - const Graphics_scene& graphics_scene() const { return m_scene; } + const Graphics_scene& graphics_scene() const + { return m_scene; } /*****************/ - virtual void redraw() { + virtual void redraw() + { initialize_buffers(); update(); - if(m_prev_scene_empty) { - initialize_vertices_and_edges_size(); - } - m_prev_scene_empty = (m_scene.empty()); + if(m_prev_scene_empty) + { initialize_vertices_and_edges_size(); } + m_prev_scene_empty=(m_scene.empty()); } - void reverse_all_normals() { - m_inverse_normal = !m_inverse_normal; + void reverse_all_normals() + { + m_inverse_normal=!m_inverse_normal; m_scene.reverse_all_normals(); } // Returns true if the data structure lies on a plane - bool is_two_dimensional() const { return !m_no_2D_mode && m_scene.is_two_dimensional(); } + bool is_two_dimensional() const + { return !m_no_2D_mode && m_scene.is_two_dimensional(); } - virtual void draw() { + virtual void draw() + { glEnable(GL_DEPTH_TEST); QMatrix4x4 clipping_mMatrix; clipping_mMatrix.setToIdentity(); - for(int i = 0; i < 16; i++) { - clipping_mMatrix.data()[i] = m_frame_plane->matrix()[i]; - } + for(int i=0; i< 16 ; i++) + { clipping_mMatrix.data()[i] = m_frame_plane->matrix()[i]; } QVector4D clipPlane = clipping_mMatrix * QVector4D(0.0, 0.0, 1.0, 0.0); - QVector4D plane_point = clipping_mMatrix * QVector4D(0, 0, 0, 1); - if(!m_are_buffers_initialized) { - initialize_buffers(); - } + QVector4D plane_point = clipping_mMatrix * QVector4D(0,0,0,1); + if(!m_are_buffers_initialized) + { initialize_buffers(); } QVector3D color; attrib_buffers(this); - if(m_draw_vertices) { - if(m_draw_sphere_vertex && m_geometry_feature_enabled) { + if(m_draw_vertices) + { + if (m_draw_sphere_vertex && m_geometry_feature_enabled) + { auto renderer = [this, &color, &clipPlane, &plane_point](float rendering_mode) { rendering_program_sphere.bind(); - if(m_use_default_color) { + if (m_use_default_color) + { auto vertex_color = m_scene.get_default_color_point(); - color = QVector3D((double)vertex_color.red() / (double)255, (double)vertex_color.green() / (double)255, - (double)vertex_color.blue() / (double)255); + color = QVector3D((double)vertex_color.red()/(double)255, + (double)vertex_color.green()/(double)255, + (double)vertex_color.blue()/(double)255); rendering_program_sphere.setUniformValue("u_DefaultColor", color); rendering_program_sphere.setUniformValue("u_UseDefaultColor", static_cast(1)); - } else { + } + else + { rendering_program_sphere.setUniformValue("u_UseDefaultColor", static_cast(0)); } - rendering_program_sphere.setUniformValue("u_Radius", - static_cast(sceneRadius() * m_size_vertices * 0.002)); - rendering_program_sphere.setUniformValue("u_ClipPlane", clipPlane); + rendering_program_sphere.setUniformValue("u_Radius", static_cast(sceneRadius()*m_size_vertices*0.002)); + rendering_program_sphere.setUniformValue("u_ClipPlane", clipPlane); rendering_program_sphere.setUniformValue("u_PointPlane", plane_point); rendering_program_sphere.setUniformValue("u_RenderingMode", rendering_mode); @@ -305,32 +351,41 @@ public: }; enum { - DRAW_ALL = -1, // draw all + DRAW_ALL = -1, // draw all DRAW_INSIDE_ONLY, // draw only the part inside the clipping plane DRAW_OUTSIDE_ONLY // draw only the part outside the clipping plane }; - if(m_use_clipping_plane == CLIPPING_PLANE_SOLID_HALF_ONLY) { + if (m_use_clipping_plane == CLIPPING_PLANE_SOLID_HALF_ONLY) + { renderer(DRAW_INSIDE_ONLY); - } else { + } + else + { renderer(DRAW_ALL); } rendering_program_sphere.release(); - } else { + } + else + { auto renderer = [this, &color, &clipPlane, &plane_point](float rendering_mode) { rendering_program_p_l.bind(); - if(m_use_default_color) { + if (m_use_default_color) + { auto vertex_color = m_scene.get_default_color_point(); - color = QVector3D((double)vertex_color.red() / (double)255, (double)vertex_color.green() / (double)255, - (double)vertex_color.blue() / (double)255); + color = QVector3D((double)vertex_color.red()/(double)255, + (double)vertex_color.green()/(double)255, + (double)vertex_color.blue()/(double)255); rendering_program_p_l.setUniformValue("u_DefaultColor", color); rendering_program_p_l.setUniformValue("u_UseDefaultColor", static_cast(1)); - } else { + } + else + { rendering_program_p_l.setUniformValue("u_UseDefaultColor", static_cast(0)); } - rendering_program_p_l.setUniformValue("u_PointSize", GLfloat(m_size_vertices)); + rendering_program_p_l.setUniformValue("u_PointSize", GLfloat(m_size_vertices)); rendering_program_p_l.setUniformValue("u_IsOrthographic", GLint(is_two_dimensional())); rendering_program_p_l.setUniformValue("u_ClipPlane", clipPlane); @@ -342,14 +397,17 @@ public: }; enum { - DRAW_ALL = -1, // draw all + DRAW_ALL = -1, // draw all DRAW_INSIDE_ONLY, // draw only the part inside the clipping plane DRAW_OUTSIDE_ONLY // draw only the part outside the clipping plane }; - if(m_use_clipping_plane == CLIPPING_PLANE_SOLID_HALF_ONLY) { + if (m_use_clipping_plane == CLIPPING_PLANE_SOLID_HALF_ONLY) + { renderer(DRAW_INSIDE_ONLY); - } else { + } + else + { renderer(DRAW_ALL); } @@ -357,23 +415,28 @@ public: } } - if(m_draw_edges && !m_draw_mesh_triangles) { - if(m_draw_cylinder_edge && m_geometry_feature_enabled) { + if(m_draw_edges && !m_draw_mesh_triangles) + { + if (m_draw_cylinder_edge && m_geometry_feature_enabled) + { auto renderer = [this, &color, &clipPlane, &plane_point](float rendering_mode) { rendering_program_cylinder.bind(); - if(m_use_default_color) { + if (m_use_default_color) + { auto edge_color = m_scene.get_default_color_segment(); - color = QVector3D((double)edge_color.red() / (double)255, (double)edge_color.green() / (double)255, - (double)edge_color.blue() / (double)255); + color = QVector3D((double)edge_color.red()/(double)255, + (double)edge_color.green()/(double)255, + (double)edge_color.blue()/(double)255); rendering_program_cylinder.setUniformValue("u_DefaultColor", color); rendering_program_cylinder.setUniformValue("u_UseDefaultColor", static_cast(1)); - } else { + } + else + { rendering_program_cylinder.setUniformValue("u_UseDefaultColor", static_cast(0)); } - rendering_program_cylinder.setUniformValue("u_Radius", - static_cast(sceneRadius() * m_size_edges * 0.001)); - rendering_program_cylinder.setUniformValue("u_ClipPlane", clipPlane); + rendering_program_cylinder.setUniformValue("u_Radius", static_cast(sceneRadius()*m_size_edges*0.001)); + rendering_program_cylinder.setUniformValue("u_ClipPlane", clipPlane); rendering_program_cylinder.setUniformValue("u_PointPlane", plane_point); rendering_program_cylinder.setUniformValue("u_RenderingMode", rendering_mode); @@ -382,31 +445,44 @@ public: }; enum { - DRAW_ALL = -1, // draw all + DRAW_ALL = -1, // draw all DRAW_INSIDE_ONLY, // draw only the part inside the clipping plane DRAW_OUTSIDE_ONLY // draw only the part outside the clipping plane }; - if(m_use_clipping_plane == CLIPPING_PLANE_SOLID_HALF_ONLY) { + if (m_use_clipping_plane == CLIPPING_PLANE_SOLID_HALF_ONLY) + { renderer(DRAW_INSIDE_ONLY); - } else { + } + else + { renderer(DRAW_ALL); } rendering_program_cylinder.release(); - } else { + } + else + { auto renderer = [this, &color, &clipPlane, &plane_point](float rendering_mode) { - QVector2D viewport = {CGAL_BASIC_VIEWER_INIT_SIZE_X, CGAL_BASIC_VIEWER_INIT_SIZE_Y}; + + QVector2D viewport = { + CGAL_BASIC_VIEWER_INIT_SIZE_X, + CGAL_BASIC_VIEWER_INIT_SIZE_Y + }; rendering_program_line.bind(); - if(m_use_default_color) { + if (m_use_default_color) + { auto edge_color = m_scene.get_default_color_segment(); - color = QVector3D((double)edge_color.red() / (double)255, (double)edge_color.green() / (double)255, - (double)edge_color.blue() / (double)255); + color = QVector3D((double)edge_color.red()/(double)255, + (double)edge_color.green()/(double)255, + (double)edge_color.blue()/(double)255); rendering_program_line.setUniformValue("u_DefaultColor", color); rendering_program_line.setUniformValue("u_UseDefaultColor", static_cast(1)); - } else { + } + else + { rendering_program_line.setUniformValue("u_UseDefaultColor", static_cast(0)); } rendering_program_line.setUniformValue("u_PointSize", static_cast(m_size_edges)); @@ -422,14 +498,17 @@ public: }; enum { - DRAW_ALL = -1, // draw all + DRAW_ALL = -1, // draw all DRAW_INSIDE_ONLY, // draw only the part inside the clipping plane DRAW_OUTSIDE_ONLY // draw only the part outside the clipping plane }; - if(m_use_clipping_plane == CLIPPING_PLANE_SOLID_HALF_ONLY) { + if (m_use_clipping_plane == CLIPPING_PLANE_SOLID_HALF_ONLY) + { renderer(DRAW_INSIDE_ONLY); - } else { + } + else + { renderer(DRAW_ALL); } @@ -437,20 +516,25 @@ public: } } - if(m_draw_rays) { + if(m_draw_rays) + { auto renderer = [this, &color, &clipPlane, &plane_point](float rendering_mode) { rendering_program_p_l.bind(); - if(m_use_default_color) { + if (m_use_default_color) + { auto ray_color = m_scene.get_default_color_ray(); - color = QVector3D((double)ray_color.red() / (double)255, (double)ray_color.green() / (double)255, - (double)ray_color.blue() / (double)255); + color = QVector3D((double)ray_color.red()/(double)255, + (double)ray_color.green()/(double)255, + (double)ray_color.blue()/(double)255); rendering_program_p_l.setUniformValue("u_DefaultColor", color); rendering_program_p_l.setUniformValue("u_UseDefaultColor", static_cast(1)); - } else { + } + else + { rendering_program_p_l.setUniformValue("u_UseDefaultColor", static_cast(0)); } - rendering_program_p_l.setUniformValue("u_PointSize", GLfloat(m_size_rays)); + rendering_program_p_l.setUniformValue("u_PointSize", GLfloat(m_size_rays)); rendering_program_p_l.setUniformValue("u_IsOrthographic", GLint(is_two_dimensional())); rendering_program_p_l.setUniformValue("u_ClipPlane", clipPlane); @@ -462,34 +546,42 @@ public: }; enum { - DRAW_ALL = -1, // draw all + DRAW_ALL = -1, // draw all DRAW_INSIDE_ONLY, // draw only the part inside the clipping plane DRAW_OUTSIDE_ONLY // draw only the part outside the clipping plane }; - if(m_use_clipping_plane == CLIPPING_PLANE_SOLID_HALF_ONLY) { + if (m_use_clipping_plane == CLIPPING_PLANE_SOLID_HALF_ONLY) + { renderer(DRAW_INSIDE_ONLY); - } else { + } + else + { renderer(DRAW_ALL); } rendering_program_p_l.release(); } - if(m_draw_lines) { + if(m_draw_lines) + { auto renderer = [this, &color, &clipPlane, &plane_point](float rendering_mode) { rendering_program_p_l.bind(); - if(m_use_default_color) { + if (m_use_default_color) + { auto line_color = m_scene.get_default_color_line(); - color = QVector3D((double)line_color.red() / (double)255, (double)line_color.green() / (double)255, - (double)line_color.blue() / (double)255); + color = QVector3D((double)line_color.red()/(double)255, + (double)line_color.green()/(double)255, + (double)line_color.blue()/(double)255); rendering_program_p_l.setUniformValue("u_DefaultColor", color); rendering_program_p_l.setUniformValue("u_UseDefaultColor", static_cast(1)); - } else { + } + else + { rendering_program_p_l.setUniformValue("u_UseDefaultColor", static_cast(0)); } - rendering_program_p_l.setUniformValue("u_PointSize", GLfloat(m_size_lines)); + rendering_program_p_l.setUniformValue("u_PointSize", GLfloat(m_size_lines)); rendering_program_p_l.setUniformValue("u_IsOrthographic", GLint(is_two_dimensional())); rendering_program_p_l.setUniformValue("u_ClipPlane", clipPlane); @@ -501,14 +593,17 @@ public: }; enum { - DRAW_ALL = -1, // draw all + DRAW_ALL = -1, // draw all DRAW_INSIDE_ONLY, // draw only the part inside the clipping plane DRAW_OUTSIDE_ONLY // draw only the part outside the clipping plane }; - if(m_use_clipping_plane == CLIPPING_PLANE_SOLID_HALF_ONLY) { + if (m_use_clipping_plane == CLIPPING_PLANE_SOLID_HALF_ONLY) + { renderer(DRAW_INSIDE_ONLY); - } else { + } + else + { renderer(DRAW_ALL); } @@ -518,31 +613,37 @@ public: // Fix Z-fighting by drawing faces at a depth GLfloat offset_factor; GLfloat offset_units; - if(is_two_dimensional()) { + if (is_two_dimensional()) { glGetFloatv(GL_POLYGON_OFFSET_FACTOR, &offset_factor); glGetFloatv(GL_POLYGON_OFFSET_UNITS, &offset_units); glPolygonOffset(0.1f, 0.9f); } - if(m_draw_faces) { + if (m_draw_faces) + { // reference: https://stackoverflow.com/questions/37780345/opengl-how-to-create-order-independent-transparency // rendering_mode == -1: draw all as solid; // rendering_mode == 0: draw solid only; // rendering_mode == 1: draw transparent only; - auto renderer = [this, &color, &clipPlane, &plane_point](float rendering_mode) { + auto renderer = [this, &color, &clipPlane, &plane_point](float rendering_mode) + { glEnable(GL_POLYGON_OFFSET_FILL); glPolygonOffset(2.0, 2.0); glDepthFunc(GL_LESS); rendering_program_face.bind(); - if(m_use_default_color) { + if (m_use_default_color) + { auto face_color = m_scene.get_default_color_face(); - color = QVector3D((double)face_color.red() / (double)255, (double)face_color.green() / (double)255, - (double)face_color.blue() / (double)255); + color = QVector3D((double)face_color.red()/(double)255, + (double)face_color.green()/(double)255, + (double)face_color.blue()/(double)255); rendering_program_face.setUniformValue("u_DefaultColor", color); rendering_program_face.setUniformValue("u_UseDefaultColor", static_cast(1)); - } else { + } + else + { rendering_program_face.setUniformValue("u_UseDefaultColor", static_cast(0)); } rendering_program_face.setUniformValue("u_RenderingMode", rendering_mode); @@ -556,27 +657,26 @@ public: }; auto renderer_clipping_plane = [this](bool clipping_plane_rendering) { - if(!isOpenGL_4_3()) - return; - if(!clipping_plane_rendering) - return; + if (!isOpenGL_4_3()) return; + if (!clipping_plane_rendering) return; // render clipping plane here rendering_program_clipping_plane.bind(); vao[VAO_CLIPPING_PLANE].bind(); glLineWidth(0.1f); - glDrawArrays(GL_LINES, 0, static_cast((m_array_for_clipping_plane.size() / 3))); + glDrawArrays(GL_LINES, 0, static_cast((m_array_for_clipping_plane.size()/3))); glLineWidth(1.0f); vao[VAO_CLIPPING_PLANE].release(); rendering_program_clipping_plane.release(); }; enum { - DRAW_SOLID_ALL = -1, // draw all mesh in solid mode - DRAW_SOLID_HALF, // draw only the mesh inside the clipping plane as solid + DRAW_SOLID_ALL = -1, // draw all mesh in solid mode + DRAW_SOLID_HALF, // draw only the mesh inside the clipping plane as solid DRAW_TRANSPARENT_HALF // draw only the mesh outside the clipping plane as transparent }; - if(m_use_clipping_plane == CLIPPING_PLANE_SOLID_HALF_TRANSPARENT_HALF) { + if (m_use_clipping_plane == CLIPPING_PLANE_SOLID_HALF_TRANSPARENT_HALF) + { // The z-buffer will prevent transparent objects from being displayed behind other transparent objects. // Before rendering all transparent objects, disable z-testing first. @@ -584,7 +684,7 @@ public: renderer(DRAW_SOLID_HALF); // 2. draw transparent layer second with back face culling to avoid messy triangles - glDepthMask(false); // disable z-testing + glDepthMask(false); //disable z-testing glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_CULL_FACE); @@ -593,53 +693,63 @@ public: renderer(DRAW_TRANSPARENT_HALF); // 3. draw solid again without culling and blend to make sure the solid mesh is visible - glDepthMask(true); // enable z-testing + glDepthMask(true); //enable z-testing glDisable(GL_CULL_FACE); glDisable(GL_BLEND); renderer(DRAW_SOLID_HALF); // 4. render clipping plane here renderer_clipping_plane(clipping_plane_rendering); - } else if(m_use_clipping_plane == CLIPPING_PLANE_SOLID_HALF_WIRE_HALF || - m_use_clipping_plane == CLIPPING_PLANE_SOLID_HALF_ONLY) + } + else if (m_use_clipping_plane == CLIPPING_PLANE_SOLID_HALF_WIRE_HALF || + m_use_clipping_plane == CLIPPING_PLANE_SOLID_HALF_ONLY) { // 1. draw solid HALF renderer(DRAW_SOLID_HALF); // 2. render clipping plane here renderer_clipping_plane(clipping_plane_rendering); - } else { + } + else + { // 1. draw solid FOR ALL renderer(DRAW_SOLID_ALL); } - if(is_two_dimensional()) + if (is_two_dimensional()) glPolygonOffset(offset_factor, offset_units); rendering_program_face.release(); } - if(m_draw_normals) { + if (m_draw_normals) + { auto renderer = [this, &color, &clipPlane, &plane_point](float rendering_mode) { rendering_program_normal.bind(); - if(m_use_default_color_normal) { - color = QVector3D((double)m_default_color_normal.red() / (double)255, - (double)m_default_color_normal.green() / (double)255, - (double)m_default_color_normal.blue() / (double)255); + if (m_use_default_color_normal) + { + color = QVector3D((double)m_default_color_normal.red()/(double)255, + (double)m_default_color_normal.green()/(double)255, + (double)m_default_color_normal.blue()/(double)255); rendering_program_normal.setUniformValue("u_DefaultColor", color); rendering_program_normal.setUniformValue("u_UseDefaultColor", static_cast(1)); - } else { + } + else + { rendering_program_normal.setUniformValue("u_UseDefaultColor", static_cast(0)); } rendering_program_normal.setUniformValue("u_Factor", static_cast(m_height_factor_normals)); rendering_program_normal.setUniformValue("u_SceneRadius", static_cast(sceneRadius())); - if(m_display_face_normal) { + if (m_display_face_normal) + { rendering_program_normal.setUniformValue("u_DisplayFaceNormal", static_cast(1)); - } else { + } + else + { rendering_program_normal.setUniformValue("u_DisplayFaceNormal", static_cast(0)); } - rendering_program_normal.setUniformValue("u_ClipPlane", clipPlane); + rendering_program_normal.setUniformValue("u_ClipPlane", clipPlane); rendering_program_normal.setUniformValue("u_PointPlane", plane_point); rendering_program_normal.setUniformValue("u_RenderingMode", rendering_mode); @@ -649,23 +759,28 @@ public: }; enum { - DRAW_ALL = -1, // draw all + DRAW_ALL = -1, // draw all DRAW_INSIDE_ONLY, // draw only the part inside the clipping plane DRAW_OUTSIDE_ONLY // draw only the part outside the clipping plane }; - if(m_use_clipping_plane == CLIPPING_PLANE_SOLID_HALF_ONLY) { + if (m_use_clipping_plane == CLIPPING_PLANE_SOLID_HALF_ONLY) + { renderer(DRAW_INSIDE_ONLY); - } else { + } + else + { renderer(DRAW_ALL); } rendering_program_normal.release(); } - if(m_draw_mesh_triangles) { + if (m_draw_mesh_triangles) + { - auto renderer = [this, &clipPlane, &plane_point](float rendering_mode) { + auto renderer = [this, &clipPlane, &plane_point](float rendering_mode) + { rendering_program_triangle.bind(); rendering_program_triangle.setUniformValue("u_RenderingMode", rendering_mode); rendering_program_triangle.setUniformValue("u_ClipPlane", clipPlane); @@ -676,28 +791,36 @@ public: }; enum { - DRAW_ALL = -1, // draw all + DRAW_ALL = -1, // draw all DRAW_INSIDE_ONLY, // draw only the part inside the clipping plane DRAW_OUTSIDE_ONLY // draw only the part outside the clipping plane }; - if(m_use_clipping_plane == CLIPPING_PLANE_SOLID_HALF_ONLY) { + if (m_use_clipping_plane == CLIPPING_PLANE_SOLID_HALF_ONLY) + { renderer(DRAW_INSIDE_ONLY); - } else { + } + else + { renderer(DRAW_ALL); } rendering_program_triangle.release(); } - if(m_draw_text) { + if (m_draw_text) + { glDisable(GL_LIGHTING); - for(std::size_t i = 0; i < m_scene.m_texts_size(); ++i) { + for (std::size_t i=0; iprojectedCoordinatesOf(CGAL::qglviewer::Vec( - std::get<0>(m_texts_vec[i]).x(), std::get<0>(m_texts_vec[i]).y(), std::get<0>(m_texts_vec[i]).z())); + CGAL::qglviewer::Vec screenPos=camera()->projectedCoordinatesOf + (CGAL::qglviewer::Vec(std::get<0>(m_texts_vec[i]).x(), + std::get<0>(m_texts_vec[i]).y(), + std::get<0>(m_texts_vec[i]).z())); - drawText((int)screenPos[0], (int)screenPos[1], QString(std::get<1>(m_texts_vec[i]).c_str())); + drawText((int)screenPos[0], (int)screenPos[1], + QString(std::get<1>(m_texts_vec[i]).c_str())); } glEnable(GL_LIGHTING); } @@ -711,7 +834,8 @@ public: } protected: - void compile_shaders() { + void compile_shaders() + { rendering_program_face.removeAllShaders(); rendering_program_p_l.removeAllShaders(); rendering_program_line.removeAllShaders(); @@ -722,16 +846,16 @@ protected: rendering_program_triangle.removeAllShaders(); // Create the buffers - for(unsigned int i = 0; i < NB_GL_BUFFERS; ++i) { - if(!buffers[i].isCreated() && !buffers[i].create()) { - std::cerr << "VBO Creation number " << i << " FAILED" << std::endl; - } + for (unsigned int i=0; icompileSourceCode(source_)) { - std::cerr << "Compiling vertex source FAILED" << std::endl; - } + QOpenGLShader *vertex_shader_p_l = new QOpenGLShader(QOpenGLShader::Vertex); + if(!vertex_shader_p_l->compileSourceCode(source_)) + { std::cerr<<"Compiling vertex source FAILED"<compileSourceCode(source_)) { - std::cerr << "Compiling fragment source FAILED" << std::endl; - } + QOpenGLShader *fragment_shader_p_l= new QOpenGLShader(QOpenGLShader::Fragment); + if(!fragment_shader_p_l->compileSourceCode(source_)) + { std::cerr<<"Compiling fragment source FAILED"<compileSourceCode(source_)) { - std::cerr << "Compiling vertex source FAILED" << std::endl; - } + QOpenGLShader *vertex_shader_face = new QOpenGLShader(QOpenGLShader::Vertex); + if(!vertex_shader_face->compileSourceCode(source_)) + { std::cerr<<"Compiling vertex source FAILED"<compileSourceCode(source_)) { - std::cerr << "Compiling fragment source FAILED" << std::endl; - } + QOpenGLShader *fragment_shader_face= new QOpenGLShader(QOpenGLShader::Fragment); + if(!fragment_shader_face->compileSourceCode(source_)) + { std::cerr<<"Compiling fragment source FAILED"<compileSourceCode(source_)) { - std::cerr << "Compiling vertex source for clipping plane FAILED" << std::endl; - } + QOpenGLShader *vertex_shader_clipping_plane = new QOpenGLShader(QOpenGLShader::Vertex); + if (!vertex_shader_clipping_plane->compileSourceCode(source_)) + { std::cerr << "Compiling vertex source for clipping plane FAILED" << std::endl; } source_ = FRAGMENT_SOURCE_CLIPPING_PLANE; - QOpenGLShader* fragment_shader_clipping_plane = new QOpenGLShader(QOpenGLShader::Fragment); - if(!fragment_shader_clipping_plane->compileSourceCode(source_)) { - std::cerr << "Compiling fragment source for clipping plane FAILED" << std::endl; - } + QOpenGLShader *fragment_shader_clipping_plane = new QOpenGLShader(QOpenGLShader::Fragment); + if (!fragment_shader_clipping_plane->compileSourceCode(source_)) + { std::cerr << "Compiling fragment source for clipping plane FAILED" << std::endl; } + + if (!rendering_program_clipping_plane.addShader(vertex_shader_clipping_plane)) + { std::cerr << "Adding vertex shader for clipping plane FAILED" << std::endl;} + if (!rendering_program_clipping_plane.addShader(fragment_shader_clipping_plane)) + { std::cerr << "Adding fragment shader for clipping plane FAILED" << std::endl; } + if (!rendering_program_clipping_plane.link()) + { std::cerr << "Linking Program for clipping plane FAILED" << std::endl; } - if(!rendering_program_clipping_plane.addShader(vertex_shader_clipping_plane)) { - std::cerr << "Adding vertex shader for clipping plane FAILED" << std::endl; - } - if(!rendering_program_clipping_plane.addShader(fragment_shader_clipping_plane)) { - std::cerr << "Adding fragment shader for clipping plane FAILED" << std::endl; - } - if(!rendering_program_clipping_plane.link()) { - std::cerr << "Linking Program for clipping plane FAILED" << std::endl; - } } // source_ = isOpenGL_4_3() @@ -841,193 +960,169 @@ protected: // { std::cerr << "Linking Program for clipping plane FAILED" << std::endl; } // Sphere shader - if(isOpenGL_4_3()) { + if (isOpenGL_4_3()) + { source_ = VERTEX_SOURCE_SHAPE; - QOpenGLShader* vertex_shader_sphere = new QOpenGLShader(QOpenGLShader::Vertex); - if(!vertex_shader_sphere->compileSourceCode(source_)) { - std::cerr << "Compiling vertex source for sphere FAILED" << std::endl; - } + QOpenGLShader *vertex_shader_sphere = new QOpenGLShader(QOpenGLShader::Vertex); + if (!vertex_shader_sphere->compileSourceCode(source_)) + { std::cerr << "Compiling vertex source for sphere FAILED" << std::endl; } source_ = GEOMETRY_SOURCE_SPHERE; - QOpenGLShader* geometry_shader_sphere = new QOpenGLShader(QOpenGLShader::Geometry); - if(!geometry_shader_sphere->compileSourceCode(source_)) { - std::cerr << "Compiling geometry source for sphere FAILED" << std::endl; - } + QOpenGLShader *geometry_shader_sphere = new QOpenGLShader(QOpenGLShader::Geometry); + if (!geometry_shader_sphere->compileSourceCode(source_)) + { std::cerr << "Compiling geometry source for sphere FAILED" << std::endl; } source_ = FRAGMENT_SOURCE_P_L; - QOpenGLShader* fragment_shader_sphere = new QOpenGLShader(QOpenGLShader::Fragment); - if(!fragment_shader_sphere->compileSourceCode(source_)) { - std::cerr << "Compiling fragment source for sphere FAILED" << std::endl; - } + QOpenGLShader *fragment_shader_sphere = new QOpenGLShader(QOpenGLShader::Fragment); + if (!fragment_shader_sphere->compileSourceCode(source_)) + { std::cerr << "Compiling fragment source for sphere FAILED" << std::endl; } - if(!rendering_program_sphere.addShader(vertex_shader_sphere)) { - std::cerr << "Adding vertex shader for sphere FAILED" << std::endl; - } - if(!rendering_program_sphere.addShader(geometry_shader_sphere)) { - std::cerr << "Adding geometry shader for sphere FAILED" << std::endl; - } - if(!rendering_program_sphere.addShader(fragment_shader_sphere)) { - std::cerr << "Adding fragment shader for clipping plane FAILED" << std::endl; - } - if(!rendering_program_sphere.link()) { - std::cerr << "Linking Program for sphere FAILED" << std::endl; - } + + if (!rendering_program_sphere.addShader(vertex_shader_sphere)) + { std::cerr << "Adding vertex shader for sphere FAILED" << std::endl;} + if (!rendering_program_sphere.addShader(geometry_shader_sphere)) + { std::cerr << "Adding geometry shader for sphere FAILED" << std::endl;} + if (!rendering_program_sphere.addShader(fragment_shader_sphere)) + { std::cerr << "Adding fragment shader for clipping plane FAILED" << std::endl; } + if (!rendering_program_sphere.link()) + { std::cerr << "Linking Program for sphere FAILED" << std::endl; } } // Cylinder shader - if(isOpenGL_4_3()) { + if (isOpenGL_4_3()) + { // clipping plane shader source_ = VERTEX_SOURCE_SHAPE; - QOpenGLShader* vertex_shader_cylinder = new QOpenGLShader(QOpenGLShader::Vertex); - if(!vertex_shader_cylinder->compileSourceCode(source_)) { - std::cerr << "Compiling vertex source for cylinder FAILED" << std::endl; - } + QOpenGLShader *vertex_shader_cylinder = new QOpenGLShader(QOpenGLShader::Vertex); + if (!vertex_shader_cylinder->compileSourceCode(source_)) + { std::cerr << "Compiling vertex source for cylinder FAILED" << std::endl; } source_ = GEOMETRY_SOURCE_CYLINDER; - QOpenGLShader* geometry_shader_cylinder = new QOpenGLShader(QOpenGLShader::Geometry); - if(!geometry_shader_cylinder->compileSourceCode(source_)) { - std::cerr << "Compiling geometry source for cylinder FAILED" << std::endl; - } + QOpenGLShader *geometry_shader_cylinder = new QOpenGLShader(QOpenGLShader::Geometry); + if (!geometry_shader_cylinder->compileSourceCode(source_)) + { std::cerr << "Compiling geometry source for cylinder FAILED" << std::endl; } source_ = FRAGMENT_SOURCE_P_L; - QOpenGLShader* fragment_shader_cylinder = new QOpenGLShader(QOpenGLShader::Fragment); - if(!fragment_shader_cylinder->compileSourceCode(source_)) { - std::cerr << "Compiling fragment source for cylinder FAILED" << std::endl; - } + QOpenGLShader *fragment_shader_cylinder = new QOpenGLShader(QOpenGLShader::Fragment); + if (!fragment_shader_cylinder->compileSourceCode(source_)) + { std::cerr << "Compiling fragment source for cylinder FAILED" << std::endl; } - if(!rendering_program_cylinder.addShader(vertex_shader_cylinder)) { - std::cerr << "Adding vertex shader for cylinder FAILED" << std::endl; - } - if(!rendering_program_cylinder.addShader(geometry_shader_cylinder)) { - std::cerr << "Adding geometry shader for cylinder FAILED" << std::endl; - } - if(!rendering_program_cylinder.addShader(fragment_shader_cylinder)) { - std::cerr << "Adding fragment shader for clipping plane FAILED" << std::endl; - } - if(!rendering_program_cylinder.link()) { - std::cerr << "Linking Program for cylinder FAILED" << std::endl; - } + + if (!rendering_program_cylinder.addShader(vertex_shader_cylinder)) + { std::cerr << "Adding vertex shader for cylinder FAILED" << std::endl;} + if (!rendering_program_cylinder.addShader(geometry_shader_cylinder)) + { std::cerr << "Adding geometry shader for cylinder FAILED" << std::endl;} + if (!rendering_program_cylinder.addShader(fragment_shader_cylinder)) + { std::cerr << "Adding fragment shader for clipping plane FAILED" << std::endl; } + if (!rendering_program_cylinder.link()) + { std::cerr << "Linking Program for cylinder FAILED" << std::endl; } } // Normal shader - if(isOpenGL_4_3()) { + if (isOpenGL_4_3()) + { source_ = VERTEX_SOURCE_NORMAL; - QOpenGLShader* vertex_shader_normal = new QOpenGLShader(QOpenGLShader::Vertex); - if(!vertex_shader_normal->compileSourceCode(source_)) { - std::cerr << "Compiling vertex source for normal FAILED" << std::endl; - } + QOpenGLShader *vertex_shader_normal = new QOpenGLShader(QOpenGLShader::Vertex); + if (!vertex_shader_normal->compileSourceCode(source_)) + { std::cerr << "Compiling vertex source for normal FAILED" << std::endl; } source_ = GEOMETRY_SOURCE_NORMAL; - QOpenGLShader* geometry_shader_normal = new QOpenGLShader(QOpenGLShader::Geometry); - if(!geometry_shader_normal->compileSourceCode(source_)) { - std::cerr << "Compiling geometry source for normal FAILED" << std::endl; - } + QOpenGLShader *geometry_shader_normal = new QOpenGLShader(QOpenGLShader::Geometry); + if (!geometry_shader_normal->compileSourceCode(source_)) + { std::cerr << "Compiling geometry source for normal FAILED" << std::endl; } source_ = FRAGMENT_SOURCE_P_L; - QOpenGLShader* fragment_shader_normal = new QOpenGLShader(QOpenGLShader::Fragment); - if(!fragment_shader_normal->compileSourceCode(source_)) { - std::cerr << "Compiling fragment source for normal FAILED" << std::endl; - } + QOpenGLShader *fragment_shader_normal = new QOpenGLShader(QOpenGLShader::Fragment); + if (!fragment_shader_normal->compileSourceCode(source_)) + { std::cerr << "Compiling fragment source for normal FAILED" << std::endl; } - if(!rendering_program_normal.addShader(vertex_shader_normal)) { - std::cerr << "Adding vertex shader for normal FAILED" << std::endl; - } - if(!rendering_program_normal.addShader(geometry_shader_normal)) { - std::cerr << "Adding geometry shader for normal FAILED" << std::endl; - } - if(!rendering_program_normal.addShader(fragment_shader_normal)) { - std::cerr << "Adding fragment shader for clipping plane FAILED" << std::endl; - } - if(!rendering_program_normal.link()) { - std::cerr << "Linking Program for normal FAILED" << std::endl; - } + + if (!rendering_program_normal.addShader(vertex_shader_normal)) + { std::cerr << "Adding vertex shader for normal FAILED" << std::endl;} + if (!rendering_program_normal.addShader(geometry_shader_normal)) + { std::cerr << "Adding geometry shader for normal FAILED" << std::endl;} + if (!rendering_program_normal.addShader(fragment_shader_normal)) + { std::cerr << "Adding fragment shader for clipping plane FAILED" << std::endl; } + if (!rendering_program_normal.link()) + { std::cerr << "Linking Program for normal FAILED" << std::endl; } } // Normal shader - if(isOpenGL_4_3()) { + if (isOpenGL_4_3()) + { source_ = VERTEX_SOURCE_TRIANGLE; - QOpenGLShader* vertex_shader_triangle = new QOpenGLShader(QOpenGLShader::Vertex); - if(!vertex_shader_triangle->compileSourceCode(source_)) { - std::cerr << "Compiling vertex source for triangle FAILED" << std::endl; - } + QOpenGLShader *vertex_shader_triangle = new QOpenGLShader(QOpenGLShader::Vertex); + if (!vertex_shader_triangle->compileSourceCode(source_)) + { std::cerr << "Compiling vertex source for triangle FAILED" << std::endl; } source_ = GEOMETRY_SOURCE_TRIANGLE; - QOpenGLShader* geometry_shader_triangle = new QOpenGLShader(QOpenGLShader::Geometry); - if(!geometry_shader_triangle->compileSourceCode(source_)) { - std::cerr << "Compiling geometry source for triangle FAILED" << std::endl; - } + QOpenGLShader *geometry_shader_triangle = new QOpenGLShader(QOpenGLShader::Geometry); + if (!geometry_shader_triangle->compileSourceCode(source_)) + { std::cerr << "Compiling geometry source for triangle FAILED" << std::endl; } source_ = FRAGMENT_SOURCE_P_L; - QOpenGLShader* fragment_shader_triangle = new QOpenGLShader(QOpenGLShader::Fragment); - if(!fragment_shader_triangle->compileSourceCode(source_)) { - std::cerr << "Compiling fragment source for triangle FAILED" << std::endl; - } + QOpenGLShader *fragment_shader_triangle = new QOpenGLShader(QOpenGLShader::Fragment); + if (!fragment_shader_triangle->compileSourceCode(source_)) + { std::cerr << "Compiling fragment source for triangle FAILED" << std::endl; } - if(!rendering_program_triangle.addShader(vertex_shader_triangle)) { - std::cerr << "Adding vertex shader for triangle FAILED" << std::endl; - } - if(!rendering_program_triangle.addShader(geometry_shader_triangle)) { - std::cerr << "Adding geometry shader for triangle FAILED" << std::endl; - } - if(!rendering_program_triangle.addShader(fragment_shader_triangle)) { - std::cerr << "Adding fragment shader for clipping plane FAILED" << std::endl; - } - if(!rendering_program_triangle.link()) { - std::cerr << "Linking Program for triangle FAILED" << std::endl; - } + + if (!rendering_program_triangle.addShader(vertex_shader_triangle)) + { std::cerr << "Adding vertex shader for triangle FAILED" << std::endl;} + if (!rendering_program_triangle.addShader(geometry_shader_triangle)) + { std::cerr << "Adding geometry shader for triangle FAILED" << std::endl;} + if (!rendering_program_triangle.addShader(fragment_shader_triangle)) + { std::cerr << "Adding fragment shader for clipping plane FAILED" << std::endl; } + if (!rendering_program_triangle.link()) + { std::cerr << "Linking Program for triangle FAILED" << std::endl; } } // Line shader - if(isOpenGL_4_3()) { + if (isOpenGL_4_3()) + { source_ = VERTEX_SOURCE_LINE_WIDTH; - QOpenGLShader* vertex_shader_line = new QOpenGLShader(QOpenGLShader::Vertex); - if(!vertex_shader_line->compileSourceCode(source_)) { - std::cerr << "Compiling vertex source for line FAILED" << std::endl; - } + QOpenGLShader *vertex_shader_line = new QOpenGLShader(QOpenGLShader::Vertex); + if (!vertex_shader_line->compileSourceCode(source_)) + { std::cerr << "Compiling vertex source for line FAILED" << std::endl; } source_ = GEOMETRY_SOURCE_LINE_WIDTH; - QOpenGLShader* geometry_shader_line = new QOpenGLShader(QOpenGLShader::Geometry); - if(!geometry_shader_line->compileSourceCode(source_)) { - std::cerr << "Compiling geometry source for line FAILED" << std::endl; - } + QOpenGLShader *geometry_shader_line = new QOpenGLShader(QOpenGLShader::Geometry); + if (!geometry_shader_line->compileSourceCode(source_)) + { std::cerr << "Compiling geometry source for line FAILED" << std::endl; } source_ = FRAGMENT_SOURCE_P_L; - QOpenGLShader* fragment_shader_line = new QOpenGLShader(QOpenGLShader::Fragment); - if(!fragment_shader_line->compileSourceCode(source_)) { - std::cerr << "Compiling fragment source for line FAILED" << std::endl; - } + QOpenGLShader *fragment_shader_line = new QOpenGLShader(QOpenGLShader::Fragment); + if (!fragment_shader_line->compileSourceCode(source_)) + { std::cerr << "Compiling fragment source for line FAILED" << std::endl; } - if(!rendering_program_line.addShader(vertex_shader_line)) { - std::cerr << "Adding vertex shader for line FAILED" << std::endl; - } - if(!rendering_program_line.addShader(geometry_shader_line)) { - std::cerr << "Adding geometry shader for line FAILED" << std::endl; - } - if(!rendering_program_line.addShader(fragment_shader_line)) { - std::cerr << "Adding fragment shader for line FAILED" << std::endl; - } - if(!rendering_program_line.link()) { - std::cerr << "Linking Program for line FAILED" << std::endl; - } + + if (!rendering_program_line.addShader(vertex_shader_line)) + { std::cerr << "Adding vertex shader for line FAILED" << std::endl;} + if (!rendering_program_line.addShader(geometry_shader_line)) + { std::cerr << "Adding geometry shader for line FAILED" << std::endl;} + if (!rendering_program_line.addShader(fragment_shader_line)) + { std::cerr << "Adding fragment shader for line FAILED" << std::endl; } + if (!rendering_program_line.link()) + { std::cerr << "Linking Program for line FAILED" << std::endl; } } } - void initialize_buffers() { + void initialize_buffers() + { set_camera_mode(); rendering_program_p_l.bind(); @@ -1039,18 +1134,18 @@ protected: positions = m_scene.get_array_of_index(GS::POS_POINTS); colors = m_scene.get_array_of_index(GS::COLOR_POINTS); - CGAL_assertion(bufn < NB_GL_BUFFERS); + CGAL_assertion(bufn(positions.size() * sizeof(float))); + buffers[bufn].allocate(positions.data(), static_cast(positions.size()*sizeof(float))); rendering_program_p_l.enableAttributeArray("a_Pos"); - rendering_program_p_l.setAttributeBuffer("a_Pos", GL_FLOAT, 0, 3); + rendering_program_p_l.setAttributeBuffer("a_Pos",GL_FLOAT,0,3); ++bufn; - CGAL_assertion(bufn < NB_GL_BUFFERS); + CGAL_assertion(bufn(colors.size() * sizeof(float))); + buffers[bufn].allocate(colors.data(), static_cast(colors.size()*sizeof(float))); rendering_program_p_l.enableAttributeArray("a_Color"); - rendering_program_p_l.setAttributeBuffer("a_Color", GL_FLOAT, 0, 3); + rendering_program_p_l.setAttributeBuffer("a_Color",GL_FLOAT,0,3); // 2) SEGMENT SHADER @@ -1059,18 +1154,18 @@ protected: colors = m_scene.get_array_of_index(GS::COLOR_SEGMENTS); ++bufn; - CGAL_assertion(bufn < NB_GL_BUFFERS); + CGAL_assertion(bufn(positions.size() * sizeof(float))); + buffers[bufn].allocate(positions.data(), static_cast(positions.size()*sizeof(float))); rendering_program_p_l.enableAttributeArray("a_Pos"); - rendering_program_p_l.setAttributeBuffer("a_Pos", GL_FLOAT, 0, 3); + rendering_program_p_l.setAttributeBuffer("a_Pos",GL_FLOAT,0,3); ++bufn; - CGAL_assertion(bufn < NB_GL_BUFFERS); + CGAL_assertion(bufn(colors.size() * sizeof(float))); + buffers[bufn].allocate(colors.data(), static_cast(colors.size()*sizeof(float))); rendering_program_p_l.enableAttributeArray("a_Color"); - rendering_program_p_l.setAttributeBuffer("a_Color", GL_FLOAT, 0, 3); + rendering_program_p_l.setAttributeBuffer("a_Color",GL_FLOAT,0,3); // 3) RAYS SHADER @@ -1079,18 +1174,18 @@ protected: colors = m_scene.get_array_of_index(GS::COLOR_RAYS); ++bufn; - CGAL_assertion(bufn < NB_GL_BUFFERS); + CGAL_assertion(bufn(positions.size() * sizeof(float))); + buffers[bufn].allocate(positions.data(), static_cast(positions.size()*sizeof(float))); rendering_program_p_l.enableAttributeArray("a_Pos"); - rendering_program_p_l.setAttributeBuffer("a_Pos", GL_FLOAT, 0, 3); + rendering_program_p_l.setAttributeBuffer("a_Pos",GL_FLOAT,0,3); ++bufn; - CGAL_assertion(bufn < NB_GL_BUFFERS); + CGAL_assertion(bufn(colors.size() * sizeof(float))); + buffers[bufn].allocate(colors.data(), static_cast(colors.size()*sizeof(float))); rendering_program_p_l.enableAttributeArray("a_Color"); - rendering_program_p_l.setAttributeBuffer("a_Color", GL_FLOAT, 0, 3); + rendering_program_p_l.setAttributeBuffer("a_Color",GL_FLOAT,0,3); // 4) LINES SHADER @@ -1099,49 +1194,52 @@ protected: colors = m_scene.get_array_of_index(GS::COLOR_LINES); ++bufn; - CGAL_assertion(bufn < NB_GL_BUFFERS); + CGAL_assertion(bufn(positions.size() * sizeof(float))); + buffers[bufn].allocate(positions.data(), static_cast(positions.size()*sizeof(float))); rendering_program_p_l.enableAttributeArray("a_Pos"); - rendering_program_p_l.setAttributeBuffer("a_Pos", GL_FLOAT, 0, 3); + rendering_program_p_l.setAttributeBuffer("a_Pos",GL_FLOAT,0,3); ++bufn; - CGAL_assertion(bufn < NB_GL_BUFFERS); + CGAL_assertion(bufn(colors.size() * sizeof(float))); + buffers[bufn].allocate(colors.data(), static_cast(colors.size()*sizeof(float))); rendering_program_p_l.enableAttributeArray("a_Color"); - rendering_program_p_l.setAttributeBuffer("a_Color", GL_FLOAT, 0, 3); + rendering_program_p_l.setAttributeBuffer("a_Color",GL_FLOAT,0,3); // 5) FACE SHADER vao[VAO_FACES].bind(); positions = m_scene.get_array_of_index(GS::POS_FACES); - normals = m_scene.get_array_of_index(m_flat_shading ? GS::FLAT_NORMAL_FACES : GS::SMOOTH_NORMAL_FACES); + normals = m_scene.get_array_of_index( + m_flat_shading ? GS::FLAT_NORMAL_FACES : GS::SMOOTH_NORMAL_FACES + ); colors = m_scene.get_array_of_index(GS::COLOR_FACES); ++bufn; - CGAL_assertion(bufn < NB_GL_BUFFERS); + CGAL_assertion(bufn(positions.size() * sizeof(float))); + buffers[bufn].allocate(positions.data(), static_cast(positions.size()*sizeof(float))); rendering_program_face.enableAttributeArray("a_Pos"); - rendering_program_face.setAttributeBuffer("a_Pos", GL_FLOAT, 0, 3); + rendering_program_face.setAttributeBuffer("a_Pos",GL_FLOAT,0,3); ++bufn; - CGAL_assertion(bufn < NB_GL_BUFFERS); + CGAL_assertion(bufn(normals.size() * sizeof(float))); + buffers[bufn].allocate(normals.data(), static_cast(normals.size()*sizeof(float))); rendering_program_face.enableAttributeArray("a_Normal"); - rendering_program_face.setAttributeBuffer("a_Normal", GL_FLOAT, 0, 3); + rendering_program_face.setAttributeBuffer("a_Normal",GL_FLOAT,0,3); ++bufn; - CGAL_assertion(bufn < NB_GL_BUFFERS); + CGAL_assertion(bufn(colors.size() * sizeof(float))); + buffers[bufn].allocate(colors.data(), static_cast(colors.size()*sizeof(float))); rendering_program_face.enableAttributeArray("a_Color"); - rendering_program_face.setAttributeBuffer("a_Color", GL_FLOAT, 0, 3); + rendering_program_face.setAttributeBuffer("a_Color",GL_FLOAT,0,3); // 6) clipping plane shader - if(isOpenGL_4_3()) { + if (isOpenGL_4_3()) + { generate_clipping_plane(); rendering_program_clipping_plane.bind(); @@ -1151,7 +1249,7 @@ protected: CGAL_assertion(bufn < NB_GL_BUFFERS); buffers[bufn].bind(); buffers[bufn].allocate(m_array_for_clipping_plane.data(), - static_cast(m_array_for_clipping_plane.size() * sizeof(BufferType))); + static_cast(m_array_for_clipping_plane.size()*sizeof(BufferType))); rendering_program_clipping_plane.enableAttributeArray("a_Pos"); rendering_program_clipping_plane.setAttributeBuffer("a_Pos", GL_FLOAT, 0, 3); @@ -1163,34 +1261,45 @@ protected: m_are_buffers_initialized = true; } - void attrib_buffers(CGAL::QGLViewer* viewer) { + void attrib_buffers(CGAL::QGLViewer* viewer) + { QMatrix4x4 mvpMatrix; QMatrix4x4 mvMatrix; double mat[16]; viewer->camera()->getModelViewProjectionMatrix(mat); - for(unsigned int i = 0; i < 16; i++) { + for(unsigned int i=0; i < 16; i++) + { mvpMatrix.data()[i] = (float)mat[i]; } viewer->camera()->getModelViewMatrix(mat); - for(unsigned int i = 0; i < 16; i++) { + for(unsigned int i=0; i < 16; i++) + { mvMatrix.data()[i] = (float)mat[i]; } // define material - QVector4D diffuse(0.9f, 0.9f, 0.9f, 0.9f); + QVector4D diffuse( 0.9f, + 0.9f, + 0.9f, + 0.9f ); - QVector4D specular(0.0f, 0.0f, 0.0f, 1.0f); + QVector4D specular( 0.0f, + 0.0f, + 0.0f, + 1.0f ); CGAL::Bbox_3 bb; - if(bb == m_scene.bounding_box()) // Case of "empty" bounding box + if (bb==m_scene.bounding_box()) // Case of "empty" bounding box { - bb = Local_point(CGAL::ORIGIN).bbox(); - bb = bb + Local_point(1, 1, 1).bbox(); // To avoid a warning from Qglviewer - } else { - bb = m_scene.bounding_box(); + bb=Local_point(CGAL::ORIGIN).bbox(); + bb=bb + Local_point(1,1,1).bbox(); // To avoid a warning from Qglviewer } + else + { bb=m_scene.bounding_box(); } - QVector4D position((bb.xmax() - bb.xmin()) / 2, (bb.ymax() - bb.ymin()) / 2, bb.zmax(), 0.0); - GLfloat shininess = 1.0f; + QVector4D position((bb.xmax()-bb.xmin())/2, + (bb.ymax()-bb.ymin())/2, + bb.zmax(), 0.0); + GLfloat shininess = 1.0f; rendering_program_face.bind(); int mvpLocation = rendering_program_face.uniformLocation("u_Mvp"); @@ -1228,12 +1337,12 @@ protected: rendering_program_sphere.setUniformValue(mvpLocation, mvpMatrix); rendering_program_sphere.release(); - if(isOpenGL_4_3()) { + if (isOpenGL_4_3()) + { QMatrix4x4 clipping_mMatrix; clipping_mMatrix.setToIdentity(); - for(int i = 0; i < 16; i++) { - clipping_mMatrix.data()[i] = m_frame_plane->matrix()[i]; - } + for(int i=0; i< 16 ; i++) + { clipping_mMatrix.data()[i] = m_frame_plane->matrix()[i]; } rendering_program_clipping_plane.bind(); int vpLocation = rendering_program_clipping_plane.uniformLocation("u_Vp"); @@ -1243,13 +1352,15 @@ protected: rendering_program_clipping_plane.release(); } - if(isOpenGL_4_3()) { + if (isOpenGL_4_3()) + { rendering_program_normal.bind(); QMatrix4x4 projection; double mat[16]; viewer->camera()->getProjectionMatrix(mat); - for(unsigned int i = 0; i < 16; i++) { + for(unsigned int i=0; i < 16; i++) + { projection.data()[i] = (float)mat[i]; } @@ -1260,7 +1371,8 @@ protected: rendering_program_normal.release(); } - if(isOpenGL_4_3()) { + if (isOpenGL_4_3()) + { rendering_program_triangle.bind(); int mvpLocation = rendering_program_triangle.uniformLocation("u_Mvp"); @@ -1268,7 +1380,8 @@ protected: rendering_program_triangle.release(); } - if(isOpenGL_4_3()) { + if (isOpenGL_4_3()) + { rendering_program_line.bind(); int mvpLocation = rendering_program_line.uniformLocation("u_Mvp"); @@ -1277,40 +1390,41 @@ protected: } } - void set_camera_mode() { - if(is_two_dimensional()) { + void set_camera_mode() + { + if (is_two_dimensional()) + { camera()->setType(CGAL::qglviewer::Camera::ORTHOGRAPHIC); // Camera Constraint: constraint.setRotationConstraintType(CGAL::qglviewer::AxisPlaneConstraint::AXIS); constraint.setTranslationConstraintType(CGAL::qglviewer::AxisPlaneConstraint::FREE); - double cx = 0., cy = 0., cz = 0.; - if(m_scene.has_zero_x()) { - cx = 1.; - } else if(m_scene.has_zero_y()) { - cy = 1.; - } else { - cz = 1.; - } + double cx=0., cy=0., cz=0.; + if (m_scene.has_zero_x()) { cx=1.; } + else if (m_scene.has_zero_y()) { cy=1.; } + else { cz=1.; } - camera()->setViewDirection(CGAL::qglviewer::Vec(-cx, -cy, -cz)); + camera()->setViewDirection(CGAL::qglviewer::Vec(-cx,-cy,-cz)); constraint.setRotationConstraintDirection(CGAL::qglviewer::Vec(cx, cy, cz)); camera()->frame()->setConstraint(&constraint); - } else { + } + else + { camera()->setType(CGAL::qglviewer::Camera::PERSPECTIVE); camera()->frame()->setConstraint(nullptr); } } - virtual void init() { + virtual void init() + { set_camera_mode(); initializeOpenGLFunctions(); // Light default parameters glLineWidth(m_size_edges); glEnable(GL_POLYGON_OFFSET_FILL); - glPolygonOffset(1.f, 1.f); - glClearColor(1.0f, 1.0f, 1.0f, 0.0f); + glPolygonOffset(1.f,1.f); + glClearColor(1.0f,1.0f,1.0f,0.0f); glDisable(GL_BLEND); glEnable(GL_PROGRAM_POINT_SIZE); glEnable(GL_LINE_SMOOTH); @@ -1321,17 +1435,21 @@ protected: compile_shaders(); CGAL::Bbox_3 bb; - if(bb == m_scene.bounding_box()) // Case of "empty" bounding box + if (bb==m_scene.bounding_box()) // Case of "empty" bounding box { - bb = Local_point(CGAL::ORIGIN).bbox(); - bb = bb + Local_point(1, 1, 1).bbox(); // To avoid a warning from Qglviewer - } else { - bb = m_scene.bounding_box(); + bb=Local_point(CGAL::ORIGIN).bbox(); + bb=bb + Local_point(1,1,1).bbox(); // To avoid a warning from Qglviewer } - this->camera()->setSceneBoundingBox(CGAL::qglviewer::Vec(bb.xmin(), bb.ymin(), bb.zmin()), - CGAL::qglviewer::Vec(bb.xmax(), bb.ymax(), bb.zmax())); + else + { bb=m_scene.bounding_box(); } + this->camera()->setSceneBoundingBox(CGAL::qglviewer::Vec(bb.xmin(), + bb.ymin(), + bb.zmin()), + CGAL::qglviewer::Vec(bb.xmax(), + bb.ymax(), + bb.zmax())); - m_frame_plane = new CGAL::qglviewer::ManipulatedFrame; + m_frame_plane=new CGAL::qglviewer::ManipulatedFrame; // Check for geometry shader availability int max_geometry_output_vertices = 0; @@ -1339,49 +1457,54 @@ protected: int max_geometry_output_components = 0; glGetIntegerv(GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS, &max_geometry_output_components); - if(max_geometry_output_vertices < 128 || max_geometry_output_components < 1024) { + if (max_geometry_output_vertices < 128 || max_geometry_output_components < 1024) + { std::cout << "Cylinder edge and sphere vertex feature disabled! (max_geometry_output_vertices=" - << max_geometry_output_vertices << ", max_geometry_output_components=" << max_geometry_output_components - << ")\n"; + << max_geometry_output_vertices << ", max_geometry_output_components=" + << max_geometry_output_components << ")\n"; m_geometry_feature_enabled = false; } /// This code cannot be done in the constructor, because the Graphics_scene /// is not yet created (cf. for example LCC demo). - if(m_inverse_normal) { - reverse_all_normals(); - } + if (m_inverse_normal) + { reverse_all_normals(); } initialize_vertices_and_edges_size(); this->showEntireScene(); } - void initialize_vertices_and_edges_size() { - if(!m_scene.empty()) { - auto& bbox = m_scene.bounding_box(); - double d = CGAL::sqrt(CGAL::squared_distance(Local_point(bbox.xmin(), bbox.ymin(), bbox.zmin()), - Local_point(bbox.xmax(), bbox.ymax(), bbox.zmax()))); + void initialize_vertices_and_edges_size() + { + if(!m_scene.empty()) + { + auto& bbox=m_scene.bounding_box(); + double d=CGAL::sqrt(CGAL::squared_distance + (Local_point(bbox.xmin(), bbox.ymin(), bbox.zmin()), + Local_point(bbox.xmax(), bbox.ymax(), bbox.zmax()))); // std::cout<<"Length of the diagonal: "<modifiers() == ::Qt::ShiftModifier) && (e->button() == ::Qt::LeftButton)) { - if(manipulatedFrame()) { + virtual void mouseDoubleClickEvent(QMouseEvent *e) + { + if ((e->modifiers()==::Qt::ShiftModifier) && (e->button()==::Qt::LeftButton)) + { + if (manipulatedFrame()) + { camera()->frame()->alignWithFrame(manipulatedFrame(), true); } } else { @@ -1418,287 +1544,307 @@ protected: } } - virtual void keyPressEvent(QKeyEvent* e) { - if(!on_key_pressed || !on_key_pressed(e, this)) { + virtual void keyPressEvent(QKeyEvent *e) + { + if(!on_key_pressed || !on_key_pressed(e, this)) + { const ::Qt::KeyboardModifiers modifiers = e->modifiers(); - if((e->key() == ::Qt::Key_C) && (modifiers == ::Qt::NoButton)) { - if(!isOpenGL_4_3()) - return; - if(!is_two_dimensional()) { + if ((e->key()==::Qt::Key_C) && (modifiers==::Qt::NoButton)) + { + if (!isOpenGL_4_3()) return; + if (!is_two_dimensional()) + { // toggle clipping plane m_use_clipping_plane = (m_use_clipping_plane + 1) % CLIPPING_PLANE_END_INDEX; - if(m_use_clipping_plane == CLIPPING_PLANE_OFF) { - setManipulatedFrame(nullptr); - } else { - setManipulatedFrame(m_frame_plane); - } + if (m_use_clipping_plane==CLIPPING_PLANE_OFF) + { setManipulatedFrame(nullptr); } + else + { setManipulatedFrame(m_frame_plane); } - switch(m_use_clipping_plane) { - case CLIPPING_PLANE_OFF: - displayMessage(QString("Draw clipping = false")); - break; - case CLIPPING_PLANE_SOLID_HALF_TRANSPARENT_HALF: - clipping_plane_rendering = true; - displayMessage(QString("Draw clipping = solid half & transparent half")); - break; - case CLIPPING_PLANE_SOLID_HALF_WIRE_HALF: - displayMessage(QString("Draw clipping = solid half & wireframe half")); - break; - case CLIPPING_PLANE_SOLID_HALF_ONLY: - displayMessage(QString("Draw clipping = solid half only")); - break; - default: - break; + switch(m_use_clipping_plane) + { + case CLIPPING_PLANE_OFF: displayMessage(QString("Draw clipping = false")); break; + case CLIPPING_PLANE_SOLID_HALF_TRANSPARENT_HALF: clipping_plane_rendering=true; displayMessage(QString("Draw clipping = solid half & transparent half")); break; + case CLIPPING_PLANE_SOLID_HALF_WIRE_HALF: displayMessage(QString("Draw clipping = solid half & wireframe half")); break; + case CLIPPING_PLANE_SOLID_HALF_ONLY: displayMessage(QString("Draw clipping = solid half only")); break; + default: break; } update(); } } - else if((e->key() == ::Qt::Key_C) && (modifiers == ::Qt::AltModifier)) + else if ((e->key()==::Qt::Key_C) && (modifiers==::Qt::AltModifier)) { - if(!isOpenGL_4_3()) - return; - if(m_use_clipping_plane != CLIPPING_PLANE_OFF) { + if (!isOpenGL_4_3()) return; + if (m_use_clipping_plane!=CLIPPING_PLANE_OFF) + { clipping_plane_rendering = !clipping_plane_rendering; - displayMessage(QString("Draw clipping plane=%1.").arg(clipping_plane_rendering ? "true" : "false")); + displayMessage(QString("Draw clipping plane=%1.").arg(clipping_plane_rendering?"true":"false")); update(); } - } else if((e->key() == ::Qt::Key_E) && (modifiers == ::Qt::NoButton)) { - m_draw_edges = !m_draw_edges; - displayMessage(QString("Draw edges=%1.").arg(m_draw_edges ? "true" : "false")); + } + else if ((e->key()==::Qt::Key_E) && (modifiers==::Qt::NoButton)) + { + m_draw_edges=!m_draw_edges; + displayMessage(QString("Draw edges=%1.").arg(m_draw_edges?"true":"false")); update(); - } else if((e->key() == ::Qt::Key_M) && (modifiers == ::Qt::NoButton)) { - m_use_default_color = !m_use_default_color; - displayMessage(QString("Mono color=%1.").arg(m_use_default_color ? "true" : "false")); + } + else if ((e->key()==::Qt::Key_M) && (modifiers==::Qt::NoButton)) + { + m_use_default_color=!m_use_default_color; + displayMessage(QString("Mono color=%1.").arg(m_use_default_color?"true":"false")); update(); - } else if((e->key() == ::Qt::Key_N) && (modifiers == ::Qt::NoButton)) { + } + else if ((e->key()==::Qt::Key_N) && (modifiers==::Qt::NoButton)) + { reverse_all_normals(); - displayMessage(QString("Inverse normal=%1.").arg(m_inverse_normal ? "true" : "false")); + displayMessage(QString("Inverse normal=%1.").arg(m_inverse_normal?"true":"false")); redraw(); - } else if((e->key() == ::Qt::Key_S) && (modifiers == ::Qt::NoButton)) { - m_flat_shading = !m_flat_shading; - if(m_flat_shading) + } + else if ((e->key()==::Qt::Key_S) && (modifiers==::Qt::NoButton)) + { + m_flat_shading=!m_flat_shading; + if (m_flat_shading) displayMessage("Flat shading."); else displayMessage("Gouraud shading."); redraw(); - } else if((e->key() == ::Qt::Key_T) && (modifiers == ::Qt::NoButton)) { - m_draw_text = !m_draw_text; - displayMessage(QString("Draw text=%1.").arg(m_draw_text ? "true" : "false")); + } + else if ((e->key()==::Qt::Key_T) && (modifiers==::Qt::NoButton)) + { + m_draw_text=!m_draw_text; + displayMessage(QString("Draw text=%1.").arg(m_draw_text?"true":"false")); update(); - } else if((e->key() == ::Qt::Key_U) && (modifiers == ::Qt::NoButton)) { - if(is_two_dimensional()) { + } + else if ((e->key()==::Qt::Key_U) && (modifiers==::Qt::NoButton)) + { + if (is_two_dimensional()) + { displayMessage(QString("Move camera direction upside down.")); - /* CGAL::qglviewer::Vec cur=camera()->viewDirection(); // TODO ! - double cx=cur.x, cy=cur.y, cz=cur.z; - if (has_zero_x()) { cx=-cx; } - else if (has_zero_y()) { cy=-cy; } - else { cz=-cz; } - double cx=0., cy=0., cz=0.; - if (has_zero_x()) { cx=(cur.x<0?-1.:1); } - else if (has_zero_y()) { cy=(cur.y<0?-1.:1); } - else { cz=(cur.z<0?-1.:1); }*/ + /* CGAL::qglviewer::Vec cur=camera()->viewDirection(); // TODO ! + double cx=cur.x, cy=cur.y, cz=cur.z; + if (has_zero_x()) { cx=-cx; } + else if (has_zero_y()) { cy=-cy; } + else { cz=-cz; } + double cx=0., cy=0., cz=0.; + if (has_zero_x()) { cx=(cur.x<0?-1.:1); } + else if (has_zero_y()) { cy=(cur.y<0?-1.:1); } + else { cz=(cur.z<0?-1.:1); }*/ camera()->setUpVector(-camera()->upVector()); - // camera()->frame()->setConstraint(NULL); - // camera()->setViewDirection(CGAL::qglviewer::Vec(-cx,-cy,-cz)); - // constraint.setRotationConstraintDirection(CGAL::qglviewer::Vec(cx, cy, cz)); - // camera()->frame()->setConstraint(&constraint); - // update(); + //camera()->frame()->setConstraint(NULL); + // camera()->setViewDirection(CGAL::qglviewer::Vec(-cx,-cy,-cz)); + //constraint.setRotationConstraintDirection(CGAL::qglviewer::Vec(cx, cy, cz)); + //camera()->frame()->setConstraint(&constraint); + //update(); redraw(); } - } else if((e->key() == ::Qt::Key_V) && (modifiers == ::Qt::NoButton)) { - m_draw_vertices = !m_draw_vertices; - displayMessage(QString("Draw vertices=%1.").arg(m_draw_vertices ? "true" : "false")); - update(); - } else if((e->key() == ::Qt::Key_W) && (modifiers == ::Qt::NoButton)) { - m_draw_faces = !m_draw_faces; - displayMessage(QString("Draw faces=%1.").arg(m_draw_faces ? "true" : "false")); - update(); - } else if((e->key() == ::Qt::Key_Plus) && (!modifiers.testFlag(::Qt::ControlModifier))) // No ctrl + } + else if ((e->key()==::Qt::Key_V) && (modifiers==::Qt::NoButton)) { - m_size_edges += .5; + m_draw_vertices=!m_draw_vertices; + displayMessage(QString("Draw vertices=%1.").arg(m_draw_vertices?"true":"false")); + update(); + } + else if ((e->key()==::Qt::Key_W) && (modifiers==::Qt::NoButton)) + { + m_draw_faces=!m_draw_faces; + displayMessage(QString("Draw faces=%1.").arg(m_draw_faces?"true":"false")); + update(); + } + else if ((e->key()==::Qt::Key_Plus) && (!modifiers.testFlag(::Qt::ControlModifier))) // No ctrl + { + m_size_edges+=.5; displayMessage(QString("Size of edges=%1.").arg(m_size_edges)); update(); - } else if((e->key() == ::Qt::Key_Minus) && (!modifiers.testFlag(::Qt::ControlModifier))) // No ctrl + } + else if ((e->key()==::Qt::Key_Minus) && (!modifiers.testFlag(::Qt::ControlModifier))) // No ctrl { - if(m_size_edges > .5) - m_size_edges -= .5; + if (m_size_edges>.5) m_size_edges-=.5; displayMessage(QString("Size of edges=%1.").arg(m_size_edges)); update(); - } else if((e->key() == ::Qt::Key_Plus) && (modifiers.testFlag(::Qt::ControlModifier))) { - m_size_vertices += .5; + } + else if ((e->key()==::Qt::Key_Plus) && (modifiers.testFlag(::Qt::ControlModifier))) + { + m_size_vertices+=.5; displayMessage(QString("Size of points=%1.").arg(m_size_vertices)); update(); - } else if((e->key() == ::Qt::Key_Minus) && (modifiers.testFlag(::Qt::ControlModifier))) { - if(m_size_vertices > .5) - m_size_vertices -= .5; + } + else if ((e->key()==::Qt::Key_Minus) && (modifiers.testFlag(::Qt::ControlModifier))) + { + if (m_size_vertices>.5) m_size_vertices-=.5; displayMessage(QString("Size of points=%1.").arg(m_size_vertices)); update(); - } else if((e->key() == ::Qt::Key_PageUp) && (modifiers == ::Qt::NoButton)) { - m_ambient_color.setX(m_ambient_color.x() + .1); - if(m_ambient_color.x() > 1.) - m_ambient_color.setX(1.); - m_ambient_color.setY(m_ambient_color.x() + .1); - if(m_ambient_color.y() > 1.) - m_ambient_color.setY(1.); - m_ambient_color.setZ(m_ambient_color.x() + .1); - if(m_ambient_color.z() > 1.) - m_ambient_color.setZ(1.); - displayMessage(QString("Light color=(%1 %2 %3).") - .arg(m_ambient_color.x()) - .arg(m_ambient_color.y()) - .arg(m_ambient_color.z())); + } + else if ((e->key()==::Qt::Key_PageUp) && (modifiers==::Qt::NoButton)) + { + m_ambient_color.setX(m_ambient_color.x()+.1); + if (m_ambient_color.x()>1.) m_ambient_color.setX(1.); + m_ambient_color.setY(m_ambient_color.x()+.1); + if (m_ambient_color.y()>1.) m_ambient_color.setY(1.); + m_ambient_color.setZ(m_ambient_color.x()+.1); + if (m_ambient_color.z()>1.) m_ambient_color.setZ(1.); + displayMessage(QString("Light color=(%1 %2 %3)."). + arg(m_ambient_color.x()).arg(m_ambient_color.y()).arg(m_ambient_color.z())); update(); - } else if((e->key() == ::Qt::Key_PageDown) && (modifiers == ::Qt::NoButton)) { - m_ambient_color.setX(m_ambient_color.x() - .1); - if(m_ambient_color.x() < 0.) - m_ambient_color.setX(0.); - m_ambient_color.setY(m_ambient_color.y() - .1); - if(m_ambient_color.y() < 0.) - m_ambient_color.setY(0.); - m_ambient_color.setZ(m_ambient_color.z() - .1); - if(m_ambient_color.z() < 0.) - m_ambient_color.setZ(0.); - displayMessage(QString("Light color=(%1 %2 %3).") - .arg(m_ambient_color.x()) - .arg(m_ambient_color.y()) - .arg(m_ambient_color.z())); + } + else if ((e->key()==::Qt::Key_PageDown) && (modifiers==::Qt::NoButton)) + { + m_ambient_color.setX(m_ambient_color.x()-.1); + if (m_ambient_color.x()<0.) m_ambient_color.setX(0.); + m_ambient_color.setY(m_ambient_color.y()-.1); + if (m_ambient_color.y()<0.) m_ambient_color.setY(0.); + m_ambient_color.setZ(m_ambient_color.z()-.1); + if (m_ambient_color.z()<0.) m_ambient_color.setZ(0.); + displayMessage(QString("Light color=(%1 %2 %3)."). + arg(m_ambient_color.x()).arg(m_ambient_color.y()).arg(m_ambient_color.z())); update(); - } else if((e->key() == ::Qt::Key_PageUp) && (modifiers == ::Qt::ShiftModifier)) { - m_ambient_color.setX(m_ambient_color.x() + .1); - if(m_ambient_color.x() > 1.) - m_ambient_color.setX(1.); - displayMessage(QString("Light color=(%1 %2 %3).") - .arg(m_ambient_color.x()) - .arg(m_ambient_color.y()) - .arg(m_ambient_color.z())); + } + else if ((e->key()==::Qt::Key_PageUp) && (modifiers==::Qt::ShiftModifier)) + { + m_ambient_color.setX(m_ambient_color.x()+.1); + if (m_ambient_color.x()>1.) m_ambient_color.setX(1.); + displayMessage(QString("Light color=(%1 %2 %3)."). + arg(m_ambient_color.x()).arg(m_ambient_color.y()).arg(m_ambient_color.z())); update(); - } else if((e->key() == ::Qt::Key_PageUp) && (modifiers == ::Qt::AltModifier)) { - m_ambient_color.setY(m_ambient_color.y() + .1); - if(m_ambient_color.y() > 1.) - m_ambient_color.setY(1.); - displayMessage(QString("Light color=(%1 %2 %3).") - .arg(m_ambient_color.x()) - .arg(m_ambient_color.y()) - .arg(m_ambient_color.z())); + } + else if ((e->key()==::Qt::Key_PageUp) && (modifiers==::Qt::AltModifier)) + { + m_ambient_color.setY(m_ambient_color.y()+.1); + if (m_ambient_color.y()>1.) m_ambient_color.setY(1.); + displayMessage(QString("Light color=(%1 %2 %3)."). + arg(m_ambient_color.x()).arg(m_ambient_color.y()).arg(m_ambient_color.z())); update(); - } else if((e->key() == ::Qt::Key_PageUp) && (modifiers == ::Qt::ControlModifier)) { - m_ambient_color.setZ(m_ambient_color.z() + .1); - if(m_ambient_color.z() > 1.) - m_ambient_color.setZ(1.); - displayMessage(QString("Light color=(%1 %2 %3).") - .arg(m_ambient_color.x()) - .arg(m_ambient_color.y()) - .arg(m_ambient_color.z())); + } + else if ((e->key()==::Qt::Key_PageUp) && (modifiers==::Qt::ControlModifier)) + { + m_ambient_color.setZ(m_ambient_color.z()+.1); + if (m_ambient_color.z()>1.) m_ambient_color.setZ(1.); + displayMessage(QString("Light color=(%1 %2 %3)."). + arg(m_ambient_color.x()).arg(m_ambient_color.y()).arg(m_ambient_color.z())); update(); - } else if((e->key() == ::Qt::Key_PageDown) && (modifiers == ::Qt::ShiftModifier)) { - m_ambient_color.setX(m_ambient_color.x() - .1); - if(m_ambient_color.x() < 0.) - m_ambient_color.setX(0.); - displayMessage(QString("Light color=(%1 %2 %3).") - .arg(m_ambient_color.x()) - .arg(m_ambient_color.y()) - .arg(m_ambient_color.z())); + } + else if ((e->key()==::Qt::Key_PageDown) && (modifiers==::Qt::ShiftModifier)) + { + m_ambient_color.setX(m_ambient_color.x()-.1); + if (m_ambient_color.x()<0.) m_ambient_color.setX(0.); + displayMessage(QString("Light color=(%1 %2 %3)."). + arg(m_ambient_color.x()).arg(m_ambient_color.y()).arg(m_ambient_color.z())); update(); - } else if((e->key() == ::Qt::Key_PageDown) && (modifiers == ::Qt::AltModifier)) { - m_ambient_color.setY(m_ambient_color.y() - .1); - if(m_ambient_color.y() < 0.) - m_ambient_color.setY(0.); - displayMessage(QString("Light color=(%1 %2 %3).") - .arg(m_ambient_color.x()) - .arg(m_ambient_color.y()) - .arg(m_ambient_color.z())); + } + else if ((e->key()==::Qt::Key_PageDown) && (modifiers==::Qt::AltModifier)) + { + m_ambient_color.setY(m_ambient_color.y()-.1); + if (m_ambient_color.y()<0.) m_ambient_color.setY(0.); + displayMessage(QString("Light color=(%1 %2 %3)."). + arg(m_ambient_color.x()).arg(m_ambient_color.y()).arg(m_ambient_color.z())); update(); - } else if((e->key() == ::Qt::Key_PageDown) && (modifiers == ::Qt::ControlModifier)) { - m_ambient_color.setZ(m_ambient_color.z() - .1); - if(m_ambient_color.z() < 0.) - m_ambient_color.setZ(0.); - displayMessage(QString("Light color=(%1 %2 %3).") - .arg(m_ambient_color.x()) - .arg(m_ambient_color.y()) - .arg(m_ambient_color.z())); + } + else if ((e->key()==::Qt::Key_PageDown) && (modifiers==::Qt::ControlModifier)) + { + m_ambient_color.setZ(m_ambient_color.z()-.1); + if (m_ambient_color.z()<0.) m_ambient_color.setZ(0.); + displayMessage(QString("Light color=(%1 %2 %3)."). + arg(m_ambient_color.x()).arg(m_ambient_color.y()).arg(m_ambient_color.z())); update(); - } else if((e->key() == ::Qt::Key_O) && (modifiers == ::Qt::NoButton)) { - bool old_2D = is_two_dimensional(); - m_no_2D_mode = !m_no_2D_mode; - if(old_2D != is_two_dimensional()) { - if(is_two_dimensional()) { - displayMessage(QString("Viewer is in 2D mode.")); - } else { - displayMessage(QString("Viewer is in 3D mode.")); - } + } + else if ((e->key()==::Qt::Key_O) && (modifiers==::Qt::NoButton)) + { + bool old_2D=is_two_dimensional(); + m_no_2D_mode=!m_no_2D_mode; + if (old_2D!=is_two_dimensional()) + { + if (is_two_dimensional()) + { displayMessage(QString("Viewer is in 2D mode.")); } + else { displayMessage(QString("Viewer is in 3D mode.")); } set_camera_mode(); update(); } - } else if((e->key() == ::Qt::Key_V) && (modifiers == ::Qt::ControlModifier)) { + } + else if ((e->key()==::Qt::Key_V) && (modifiers==::Qt::ControlModifier)) + { m_draw_sphere_vertex = !m_draw_sphere_vertex; - displayMessage(QString("Draw sphere vertex=%1.").arg(m_draw_sphere_vertex ? "true" : "false")); + displayMessage(QString("Draw sphere vertex=%1.").arg(m_draw_sphere_vertex?"true":"false")); update(); - } else if((e->key() == ::Qt::Key_E) && (modifiers == ::Qt::ControlModifier)) { + } + else if ((e->key()==::Qt::Key_E) && (modifiers==::Qt::ControlModifier)) + { m_draw_cylinder_edge = !m_draw_cylinder_edge; - displayMessage(QString("Draw cylinder edge=%1.").arg(m_draw_cylinder_edge ? "true" : "false")); + displayMessage(QString("Draw cylinder edge=%1.").arg(m_draw_cylinder_edge?"true":"false")); update(); - } else if((e->key() == ::Qt::Key_N) && (modifiers == ::Qt::ControlModifier)) { + } + else if ((e->key()==::Qt::Key_N) && (modifiers==::Qt::ControlModifier)) + { m_draw_normals = !m_draw_normals; - displayMessage(QString("Draw normals=%1.").arg(m_draw_normals ? "true" : "false")); + displayMessage(QString("Draw normals=%1.").arg(m_draw_normals?"true":"false")); update(); - } else if((e->key() == ::Qt::Key_T) && (modifiers == ::Qt::ControlModifier)) { + } + else if ((e->key()==::Qt::Key_T) && (modifiers==::Qt::ControlModifier)) + { m_draw_mesh_triangles = !m_draw_mesh_triangles; - displayMessage(QString("Draw triangles=%1.").arg(m_draw_mesh_triangles ? "true" : "false")); + displayMessage(QString("Draw triangles=%1.").arg(m_draw_mesh_triangles?"true":"false")); update(); - } else if((e->key() == ::Qt::Key_M) && (modifiers == ::Qt::ControlModifier)) { + } + else if ((e->key()==::Qt::Key_M) && (modifiers==::Qt::ControlModifier)) + { m_use_default_color_normal = !m_use_default_color_normal; - displayMessage(QString("Normal mono color=%1.").arg(m_use_default_color_normal ? "true" : "false")); + displayMessage(QString("Normal mono color=%1.").arg(m_use_default_color_normal?"true":"false")); update(); - } else if((e->key() == ::Qt::Key_N) && (modifiers == ::Qt::ShiftModifier)) { + } + else if ((e->key()==::Qt::Key_N) && (modifiers==::Qt::ShiftModifier)) + { m_display_face_normal = !m_display_face_normal; - displayMessage(QString("Display face normal=%1.").arg(m_display_face_normal ? "true" : "false")); + displayMessage(QString("Display face normal=%1.").arg(m_display_face_normal?"true":"false")); update(); - } else if((e->key() == ::Qt::Key_F2)) { + } + else if ((e->key()==::Qt::Key_F2)) + { capture_screenshot(QString("./screenshot.png")); displayMessage(QString("Screenshot saved in ./screenshot")); - } else { - CGAL::QGLViewer::keyPressEvent(e); - } // By default call QGLViewer key press + } + else + { CGAL::QGLViewer::keyPressEvent(e); } // By default call QGLViewer key press } } - virtual QString helpString() const { return helpString("CGAL Basic Viewer"); } + virtual QString helpString() const + { return helpString("CGAL Basic Viewer"); } - virtual QString helpString(const char* title) const { - QString text(QString("

") + QString(title) + QString("

")); + virtual QString helpString(const char* title) const + { + QString text(QString("

")+QString(title)+QString("

")); text += "Use the mouse to move the camera around the object. "; text += "You can respectively revolve around, zoom and translate with " - "the three mouse buttons. "; + "the three mouse buttons. "; text += "Left and middle buttons pressed together rotate around the " - "camera view direction axis

"; + "camera view direction axis

"; text += "Pressing Alt and one of the function keys " - "(F1..F12) defines a camera keyFrame. "; + "(F1..F12) defines a camera keyFrame. "; text += "Simply press the function key again to restore it. " - "Several keyFrames define a "; + "Several keyFrames define a "; text += "camera path. Paths are saved when you quit the application " - "and restored at next start.

"; + "and restored at next start.

"; text += "Press F to display the frame rate, A for the " - "world axis, "; + "world axis, "; text += "Alt+Return for full screen mode and Control+S " - "to save a snapshot. "; + "to save a snapshot. "; text += "See the Keyboard tab in this window for a complete " - "shortcut list.

"; + "shortcut list.

"; text += "Double clicks automates single click actions: A left button " - "double click aligns the closer axis with the camera (if close enough). "; + "double click aligns the closer axis with the camera (if close enough). "; text += "A middle button double click fits the zoom of the camera and " - "the right button re-centers the scene.

"; + "the right button re-centers the scene.

"; text += "A left button double click while holding right button pressed " - "defines the camera Revolve Around Point. "; + "defines the camera Revolve Around Point. "; text += "See the Mouse tab and the documentation web pages for " - "details.

"; + "details.

"; text += "Press Escape to exit the viewer."; return text; } - void capture_screenshot(const QString& file_path) { - QScreen* screen; + void capture_screenshot(const QString& file_path) + { + QScreen *screen; screen = QApplication::primaryScreen(); // auto geom = screen->geometry(); @@ -1707,7 +1853,7 @@ protected: } public: - std::function on_key_pressed; + std::function on_key_pressed; protected: const Graphics_scene& m_scene; @@ -1739,19 +1885,19 @@ protected: CLIPPING_PLANE_END_INDEX }; - int m_use_clipping_plane = CLIPPING_PLANE_OFF; - CGAL::qglviewer::ManipulatedFrame* m_frame_plane = nullptr; + int m_use_clipping_plane=CLIPPING_PLANE_OFF; + CGAL::qglviewer::ManipulatedFrame* m_frame_plane=nullptr; // Buffer for clipping plane is not stored in the scene because it is not // filled by users but by the basic viewer. std::vector m_array_for_clipping_plane; - double m_size_vertices = 1.; - double m_size_edges = 1.; - double m_size_rays = 1.; - double m_size_lines = 1.; - double m_size_normals = .2; - double m_height_factor_normals = .02; + double m_size_vertices=1.; + double m_size_edges=1.; + double m_size_rays=1.; + double m_size_lines=1.; + double m_size_normals=.2; + double m_height_factor_normals=.02; CGAL::IO::Color m_default_color_normal; QVector4D m_ambient_color; @@ -1761,13 +1907,22 @@ protected: // CGAL::qglviewer::LocalConstraint constraint; CGAL::qglviewer::WorldConstraint constraint; - static const unsigned int NB_GL_BUFFERS = (GS::END_POS - GS::BEGIN_POS) + (GS::END_COLOR - GS::BEGIN_COLOR) + - 3; // +2 for normals (mono and color), +1 for clipping plane + static const unsigned int NB_GL_BUFFERS=(GS::END_POS-GS::BEGIN_POS)+ + (GS::END_COLOR-GS::BEGIN_COLOR)+3; // +2 for normals (mono and color), +1 for clipping plane QOpenGLBuffer buffers[NB_GL_BUFFERS]; // +1 for the buffer of clipping plane // The following enum gives the indices of the different vao. - enum { VAO_POINTS = 0, VAO_SEGMENTS, VAO_RAYS, VAO_LINES, VAO_FACES, VAO_CLIPPING_PLANE, NB_VAO_BUFFERS }; + enum + { + VAO_POINTS=0, + VAO_SEGMENTS, + VAO_RAYS, + VAO_LINES, + VAO_FACES, + VAO_CLIPPING_PLANE, + NB_VAO_BUFFERS + }; QOpenGLVertexArrayObject vao[NB_VAO_BUFFERS]; QOpenGLShaderProgram rendering_program_face; @@ -1780,22 +1935,24 @@ protected: QOpenGLShaderProgram rendering_program_triangle; // variables for clipping plane - bool clipping_plane_rendering = true; // will be toggled when alt+c is pressed, which is used for indicating whether - // or not to render the clipping plane ; + bool clipping_plane_rendering = true; // will be toggled when alt+c is pressed, which is used for indicating whether or not to render the clipping plane ; float clipping_plane_rendering_transparency = 0.5f; // to what extent the transparent part should be rendered; + }; //------------------------------------------------------------------------------ class QApplication_and_basic_viewer { public: - QApplication_and_basic_viewer(const CGAL::Graphics_scene& buffer, const char* title = "CGAL Basic Viewer") - : m_application(nullptr) - , m_basic_viewer(nullptr) - , m_argc(1) { - m_argv[0] = new char[strlen(title) + 1]; - memcpy(m_argv[0], title, strlen(title) + 1); - m_argv[1] = nullptr; + QApplication_and_basic_viewer(const CGAL::Graphics_scene& buffer, + const char* title="CGAL Basic Viewer"): + m_application(nullptr), + m_basic_viewer(nullptr), + m_argc(1) + { + m_argv[0]=new char[strlen(title)+1]; + memcpy(m_argv[0], title, strlen(title)+1); + m_argv[1]=nullptr; #if defined(CGAL_TEST_SUITE) bool cgal_test_suite = true; @@ -1803,39 +1960,44 @@ public: bool cgal_test_suite = qEnvironmentVariableIsSet("CGAL_TEST_SUITE"); #endif - if(cgal_test_suite) { - return; - } + if (cgal_test_suite) + { return; } Qt::init_ogl_context(4, 3); - m_application = new QApplication(m_argc, const_cast(m_argv)); - m_basic_viewer = new Basic_viewer(m_application->activeWindow(), buffer, title); + m_application=new QApplication(m_argc, const_cast(m_argv)); + m_basic_viewer=new Basic_viewer(m_application->activeWindow(), + buffer, title); } - ~QApplication_and_basic_viewer() { + ~QApplication_and_basic_viewer() + { delete[] m_argv[0]; delete m_basic_viewer; delete m_application; } - operator bool() const { return m_application != nullptr; } + operator bool() const + { return m_application!=nullptr; } - void run() { - if(m_application != nullptr) { + void run() + { + if (m_application!=nullptr) + { m_basic_viewer->show(); m_application->exec(); } } - Basic_viewer& basic_viewer() { - CGAL_assertion(m_basic_viewer != nullptr); + Basic_viewer& basic_viewer() + { + CGAL_assertion(m_basic_viewer!=nullptr); return *m_basic_viewer; } protected: QApplication* m_application; Basic_viewer* m_basic_viewer; - char* m_argv[2]; + char *m_argv[2]; int m_argc; }; @@ -1845,19 +2007,23 @@ protected: // Can be changed later if we have several viewers. using Qt::Basic_viewer; -inline void draw_graphics_scene(const Graphics_scene& graphics_scene, const char* title = "CGAL Basic Viewer (Qt)") { +inline +void draw_graphics_scene(const Graphics_scene& graphics_scene, + const char *title="CGAL Basic Viewer (Qt)") +{ #if defined(CGAL_TEST_SUITE) bool cgal_test_suite = true; #else bool cgal_test_suite = qEnvironmentVariableIsSet("CGAL_TEST_SUITE"); #endif - if(!cgal_test_suite) { + if (!cgal_test_suite) + { Qt::init_ogl_context(4, 3); int argc = 1; - const char* argv[2] = {title, nullptr}; - QApplication app(argc, const_cast(argv)); + const char *argv[2] = {title, nullptr}; + QApplication app(argc, const_cast(argv)); Basic_viewer basic_viewer(app.activeWindow(), graphics_scene, title); basic_viewer.show();