From f58073aa014dbde66b04240c9fac03b0ec1b2d56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Fri, 18 Mar 2022 08:39:55 +0100 Subject: [PATCH 001/107] add a double version of alpha computation generated using Herbie --- .../Intersections_2/Segment_2_Segment_2.h | 57 ++++++++++++++++--- 1 file changed, 50 insertions(+), 7 deletions(-) diff --git a/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h b/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h index 19d1b300232..55a9a5fe448 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h @@ -353,6 +353,55 @@ protected: mutable typename K::Point_2 _intersection_point, _other_point; }; + +// code generated using Herbie https://herbie.uwplse.org/ +inline +double s2s2_interpt(double x0, double y0, + double x1, double y1, + double x2, double y2, + double x3, double y3) +{ + double tmp; + if (x1 <= -9.794158788366665e-11) { + tmp = -(x1 / (x0 - x1)); + } else { + double t_0 = (y1 - y3) / (y1 - y0); + double tmp_1; + if (x1 <= -1.7579125018815487e-296) { + tmp_1 = t_0; + } else if (x1 <= 1.7250761038378636e-206) { + tmp_1 = x2 / ((fma(x2, y0, fma(y3, x0, (x1 * y2))) - fma(x2, y1, fma(y3, x1, (x0 * y2)))) / (y3 - y1)); + } else if (x1 <= 3.6888389969707494e-205) { + tmp_1 = t_0; + } else if (x1 <= 1.4339509931401463e-80) { + tmp_1 = (fma(x1, y2, fma(y1, x3, (y3 * x2))) - fma(x2, y1, fma(x1, y3, (y2 * x3)))) / fma((x3 - x2), (y1 - y0), ((x0 - x1) * (y3 - y2))); + } else if (x1 <= 1.72960576050945e+52) { + tmp_1 = (y1 - y2) / (y1 - y0); + } else if (x1 <= 2.145089573601479e+104) { + tmp_1 = (x1 - x3) / (x1 - x0); + } else { + tmp_1 = (x1 - x2) / (x1 - x0); + } + tmp = tmp_1; + } + return tmp; +} + +template +FT s2s2_interpt(const FT& x0, const FT& y0, + const FT& x1, const FT& y1, + const FT& x2, const FT& y2, + const FT& x3, const FT& y3) +{ + FT s1_dx = x0 - x1, + s1_dy = y0 - y1, + s2_dx = x3 - x2, + s2_dy = y3 - y2, + lx = x3 - x1, + ly = y3 - y1; + return (lx*s2_dy-ly*s2_dx)/(s1_dx*s2_dy-s1_dy*s2_dx); +} + template typename Segment_2_Segment_2_pair::Intersection_results Segment_2_Segment_2_pair::intersection_type() const @@ -400,14 +449,8 @@ Segment_2_Segment_2_pair::intersection_type() const : CGAL::make_array( _seg2->point(s2s2_id[c][2]), _seg2->point(s2s2_id[c][3]), _seg1->point(s2s2_id[c][0]), _seg1->point(s2s2_id[c][1]) ); - typename K::FT s1_dx = pts[0].x() - pts[1].x(), - s1_dy = pts[0].y() - pts[1].y(), - s2_dx = pts[3].x() - pts[2].x(), - s2_dy = pts[3].y() - pts[2].y(), - lx = pts[3].x() - pts[1].x(), - ly = pts[3].y() - pts[1].y(); + typename K::FT alpha = s2s2_interpt(pts[0].x(), pts[0].y(), pts[1].x(), pts[1].y(), pts[2].x(), pts[2].y(), pts[3].x(), pts[3].y()); - typename K::FT alpha = (lx*s2_dy-ly*s2_dx)/(s1_dx*s2_dy-s1_dy*s2_dx); _intersection_point = K().construct_barycenter_2_object()(pts[0], alpha, pts[1]); return _result; From b50cbad2245e0f0982841d2e93d90873b6ddf489 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Fri, 18 Mar 2022 08:46:57 +0100 Subject: [PATCH 002/107] better name --- .../CGAL/Intersections_2/Segment_2_Segment_2.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h b/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h index 55a9a5fe448..ba98405cc1e 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h @@ -356,10 +356,10 @@ protected: // code generated using Herbie https://herbie.uwplse.org/ inline -double s2s2_interpt(double x0, double y0, - double x1, double y1, - double x2, double y2, - double x3, double y3) +double s2s2_alpha(double x0, double y0, + double x1, double y1, + double x2, double y2, + double x3, double y3) { double tmp; if (x1 <= -9.794158788366665e-11) { @@ -388,10 +388,10 @@ double s2s2_interpt(double x0, double y0, } template -FT s2s2_interpt(const FT& x0, const FT& y0, - const FT& x1, const FT& y1, - const FT& x2, const FT& y2, - const FT& x3, const FT& y3) +FT s2s2_alpha(const FT& x0, const FT& y0, + const FT& x1, const FT& y1, + const FT& x2, const FT& y2, + const FT& x3, const FT& y3) { FT s1_dx = x0 - x1, s1_dy = y0 - y1, @@ -449,7 +449,7 @@ Segment_2_Segment_2_pair::intersection_type() const : CGAL::make_array( _seg2->point(s2s2_id[c][2]), _seg2->point(s2s2_id[c][3]), _seg1->point(s2s2_id[c][0]), _seg1->point(s2s2_id[c][1]) ); - typename K::FT alpha = s2s2_interpt(pts[0].x(), pts[0].y(), pts[1].x(), pts[1].y(), pts[2].x(), pts[2].y(), pts[3].x(), pts[3].y()); + typename K::FT alpha = s2s2_alpha(pts[0].x(), pts[0].y(), pts[1].x(), pts[1].y(), pts[2].x(), pts[2].y(), pts[3].x(), pts[3].y()); _intersection_point = K().construct_barycenter_2_object()(pts[0], alpha, pts[1]); From 246bc7f4eaca6a4ea27ee73c0615c8e8a80b1079 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Fri, 18 Mar 2022 08:50:11 +0100 Subject: [PATCH 003/107] remove tabs and add std:: --- .../Intersections_2/Segment_2_Segment_2.h | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h b/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h index ba98405cc1e..de34ef3e15e 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h @@ -361,30 +361,30 @@ double s2s2_alpha(double x0, double y0, double x2, double y2, double x3, double y3) { - double tmp; - if (x1 <= -9.794158788366665e-11) { - tmp = -(x1 / (x0 - x1)); - } else { - double t_0 = (y1 - y3) / (y1 - y0); - double tmp_1; - if (x1 <= -1.7579125018815487e-296) { - tmp_1 = t_0; - } else if (x1 <= 1.7250761038378636e-206) { - tmp_1 = x2 / ((fma(x2, y0, fma(y3, x0, (x1 * y2))) - fma(x2, y1, fma(y3, x1, (x0 * y2)))) / (y3 - y1)); - } else if (x1 <= 3.6888389969707494e-205) { - tmp_1 = t_0; - } else if (x1 <= 1.4339509931401463e-80) { - tmp_1 = (fma(x1, y2, fma(y1, x3, (y3 * x2))) - fma(x2, y1, fma(x1, y3, (y2 * x3)))) / fma((x3 - x2), (y1 - y0), ((x0 - x1) * (y3 - y2))); - } else if (x1 <= 1.72960576050945e+52) { - tmp_1 = (y1 - y2) / (y1 - y0); - } else if (x1 <= 2.145089573601479e+104) { - tmp_1 = (x1 - x3) / (x1 - x0); - } else { - tmp_1 = (x1 - x2) / (x1 - x0); - } - tmp = tmp_1; - } - return tmp; + double tmp; + if (x1 <= -9.794158788366665e-11) { + tmp = -(x1 / (x0 - x1)); + } else { + double t_0 = (y1 - y3) / (y1 - y0); + double tmp_1; + if (x1 <= -1.7579125018815487e-296) { + tmp_1 = t_0; + } else if (x1 <= 1.7250761038378636e-206) { + tmp_1 = x2 / ((std::fma(x2, y0, std::fma(y3, x0, (x1 * y2))) - std::fma(x2, y1, std::fma(y3, x1, (x0 * y2)))) / (y3 - y1)); + } else if (x1 <= 3.6888389969707494e-205) { + tmp_1 = t_0; + } else if (x1 <= 1.4339509931401463e-80) { + tmp_1 = (std::fma(x1, y2, std::fma(y1, x3, (y3 * x2))) - std::fma(x2, y1, std::fma(x1, y3, (y2 * x3)))) / std::fma((x3 - x2), (y1 - y0), ((x0 - x1) * (y3 - y2))); + } else if (x1 <= 1.72960576050945e+52) { + tmp_1 = (y1 - y2) / (y1 - y0); + } else if (x1 <= 2.145089573601479e+104) { + tmp_1 = (x1 - x3) / (x1 - x0); + } else { + tmp_1 = (x1 - x2) / (x1 - x0); + } + tmp = tmp_1; + } + return tmp; } template From 5913be0db84d1b0705c3c7d7eae347a88817d379 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Tue, 22 Mar 2022 12:13:42 +0100 Subject: [PATCH 004/107] add documentation group --- Mesh_3/include/CGAL/Mesh_3/generate_label_weights.h | 1 + 1 file changed, 1 insertion(+) diff --git a/Mesh_3/include/CGAL/Mesh_3/generate_label_weights.h b/Mesh_3/include/CGAL/Mesh_3/generate_label_weights.h index 6f3d9d77bab..1f1a8014a13 100644 --- a/Mesh_3/include/CGAL/Mesh_3/generate_label_weights.h +++ b/Mesh_3/include/CGAL/Mesh_3/generate_label_weights.h @@ -227,6 +227,7 @@ CGAL::Image_3 generate_label_weights_with_known_word_type(const CGAL::Image_3& i /// @endcond /*! +* \ingroup PkgMesh3Functions * Free function that generates a `CGAL::Image_3` of weights associated to each * voxel of `image`, to make the output mesh surfaces smoother. * The weights image is generated using the algorithm described by Stalling et al From 0dfa8a494153eb9c808a01ce6c1c8f377872d88e Mon Sep 17 00:00:00 2001 From: Giles Bathgate Date: Sun, 3 Apr 2022 11:41:07 +0100 Subject: [PATCH 005/107] Avoid double hash lookup --- Nef_3/include/CGAL/Nef_3/SNC_external_structure.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Nef_3/include/CGAL/Nef_3/SNC_external_structure.h b/Nef_3/include/CGAL/Nef_3/SNC_external_structure.h index d66bc30ac18..df8c8877d1f 100644 --- a/Nef_3/include/CGAL/Nef_3/SNC_external_structure.h +++ b/Nef_3/include/CGAL/Nef_3/SNC_external_structure.h @@ -897,8 +897,7 @@ public: if ( f->volume() != Volume_handle() ) continue; CGAL_NEF_TRACEN( "Outer shell #" << ShellSf[f] << " volume?"); - Volume_handle c = determine_volume( MinimalSFace[ShellSf[f]], - MinimalSFace, ShellSf ); + Volume_handle c = determine_volume( f, MinimalSFace, ShellSf ); c->mark() = f->mark(); link_as_outer_shell( f, c ); } From 04f7b8d7b90e4732ab656ccbbc3f65dccf9817e0 Mon Sep 17 00:00:00 2001 From: Giles Bathgate Date: Sun, 27 Mar 2022 10:17:01 +0100 Subject: [PATCH 006/107] Avoid filter failure in ray shoot facet --- Nef_3/include/CGAL/Nef_3/SNC_point_locator.h | 64 ++++++++++---------- 1 file changed, 33 insertions(+), 31 deletions(-) diff --git a/Nef_3/include/CGAL/Nef_3/SNC_point_locator.h b/Nef_3/include/CGAL/Nef_3/SNC_point_locator.h index 8bda46183c5..25b9be3c6d6 100644 --- a/Nef_3/include/CGAL/Nef_3/SNC_point_locator.h +++ b/Nef_3/include/CGAL/Nef_3/SNC_point_locator.h @@ -218,6 +218,22 @@ public: delete candidate_provider; } + // We next check if v is a vertex on the face to avoid a geometric test + static inline bool v_vertex_of_f(Vertex_handle v, Halffacet_handle f) { + Halffacet_cycle_iterator fci; + for(fci=f->facet_cycles_begin(); fci!=f->facet_cycles_end(); ++fci) { + if(fci.is_shalfedge()) { + SHalfedge_around_facet_circulator sfc(fci), send(sfc); + CGAL_For_all(sfc,send) { + if(sfc->source()->center_vertex() == v){ + return true; + } + } + } + } + return false; + } + virtual Object_handle shoot(const Ray_3& ray, int mask=255) const { Vertex_handle null_handle; return this->shoot(ray, null_handle, mask); @@ -282,20 +298,22 @@ public: Point_3 q; _CGAL_NEF_TRACEN("trying facet with on plane "<plane()<< " with point on "<plane().point()); - if( SNC_intersection::does_intersect_internally( ray, f, q) ) { - _CGAL_NEF_TRACEN("ray intersects facet on "<is_point_on_cell( q, objects_iterator)); - if( !candidate_provider->is_point_on_cell( q, objects_iterator)) - continue; - eor = q; - result = make_object(f); - hit = true; - _CGAL_NEF_TRACEN("the facet becomes the new hit object"); + if( (ray_source_vertex == Vertex_handle()) || !v_vertex_of_f(ray_source_vertex,f) ) { + if( SNC_intersection::does_intersect_internally( ray, f, q) ) { + _CGAL_NEF_TRACEN("ray intersects facet on "<is_point_on_cell( q, objects_iterator)); + if( !candidate_provider->is_point_on_cell( q, objects_iterator)) + continue; + eor = q; + result = make_object(f); + hit = true; + _CGAL_NEF_TRACEN("the facet becomes the new hit object"); + } } } else if((mask&15) == 15) @@ -443,23 +461,7 @@ public: return make_object(f); } - // We next check if v is a vertex on the face to avoid a geometric test - bool v_vertex_of_f = false; - Halffacet_cycle_iterator fci; - for(fci=f->facet_cycles_begin(); (! v_vertex_of_f) && (fci!=f->facet_cycles_end()); ++fci) { - if(fci.is_shalfedge()) { - SHalfedge_around_facet_circulator sfc(fci), send(sfc); - CGAL_For_all(sfc,send) { - if(sfc->source()->center_vertex() == v){ - v_vertex_of_f = true; - break; - } - } - } - } - - - if( (! v_vertex_of_f) && SNC_intersection::does_intersect_internally(s,f,ip) ) { + if( !v_vertex_of_f(v,f) && SNC_intersection::does_intersect_internally(s,f,ip) ) { s = Segment_3(p, normalized(ip)); result = make_object(f); } From af913fd00feb4444ecf471d1ad0ae2486dea646f Mon Sep 17 00:00:00 2001 From: Giles Bathgate Date: Wed, 6 Apr 2022 20:17:15 +0100 Subject: [PATCH 007/107] Use separate lists K3_tree node to avoid object casts --- Nef_3/include/CGAL/Nef_3/K3_tree.h | 198 +++----- Nef_3/include/CGAL/Nef_3/SNC_point_locator.h | 503 +++++++------------ 2 files changed, 264 insertions(+), 437 deletions(-) diff --git a/Nef_3/include/CGAL/Nef_3/K3_tree.h b/Nef_3/include/CGAL/Nef_3/K3_tree.h index e2bf66a33be..7c2ecbcae6d 100644 --- a/Nef_3/include/CGAL/Nef_3/K3_tree.h +++ b/Nef_3/include/CGAL/Nef_3/K3_tree.h @@ -108,15 +108,8 @@ typedef Smaller_than< public: typedef Node* Node_handle; Node(const Vertex_list& V, const Halfedge_list& E, const Halffacet_list& F) : - left_node(nullptr), right_node(nullptr) + left_node(nullptr), right_node(nullptr), vertex_list(V), edge_list(E), facet_list(F) { - object_list.reserve(V.size()+E.size()+F.size()); - for(Vertex_const_iterator vi=V.begin(); vi!=V.end(); ++vi) - object_list.push_back(make_object(*vi)); - for(Halfedge_const_iterator ei=E.begin(); ei!=E.end(); ++ei) - object_list.push_back(make_object(*ei)); - for(Halffacet_const_iterator fi=F.begin(); fi!=F.end(); ++fi) - object_list.push_back(make_object(*fi)); } Node(Node_handle l, Node_handle r, const Plane_3& pl) : @@ -133,20 +126,27 @@ public: Node_handle left() const { return left_node; } Node_handle right() const { return right_node; } const Plane_3& plane() const { return splitting_plane; } - const Object_list& objects() const { return object_list; } + + bool empty() { return vertex_list.empty() && edge_list.empty() && facet_list.empty(); } + Vertex_const_iterator vertices_begin() { return vertex_list.begin(); } + Vertex_const_iterator vertices_end() { return vertex_list.end(); } + Halfedge_const_iterator edges_begin() { return edge_list.begin(); } + Halfedge_const_iterator edges_end() { return edge_list.end(); } + Halffacet_const_iterator facets_begin() { return facet_list.begin(); } + Halffacet_const_iterator facets_end() { return facet_list.end(); } void transform(const Aff_transformation_3& t) { if(left_node != nullptr) { CGAL_assertion(right_node != nullptr); left_node->transform(t); - right_node->transform(t); - splitting_plane = splitting_plane.transform(t); + right_node->transform(t); + splitting_plane = splitting_plane.transform(t); } } void add_facet(Halffacet_handle f, int depth) { if(left_node == nullptr) { - object_list.push_back(make_object(f)); + facet_list.push_back(f); return; } @@ -160,7 +160,7 @@ public: void add_edge(Halfedge_handle e, int depth) { if(left_node == nullptr) { - object_list.push_back(make_object(e)); + edge_list.push_back(e); return; } @@ -174,7 +174,7 @@ public: void add_vertex(Vertex_handle v, int depth) { if(left_node == nullptr) { - object_list.push_back(make_object(v)); + vertex_list.push_back(v); return; } @@ -187,33 +187,19 @@ public: } -friend std::ostream& operator<< - (std::ostream& os, const Node_handle node) { - CGAL_assertion( node != nullptr); - if( node->is_leaf()) - os << node->objects().size(); - else { - os << " ( "; - if( !node->left()) os << '-'; - else os << node->left(); - os << " , "; - if( !node->right()) os << '-'; - else os << node->right(); - os << " ) "; - } - return os; -} - private: Node_handle left_node; Node_handle right_node; Plane_3 splitting_plane; - Object_list object_list; + Vertex_list vertex_list; + Halffacet_list facet_list; + Halfedge_list edge_list; }; typedef boost::container::deque Node_range; typedef Node* Node_handle; + typedef std::vector Node_list; public: @@ -266,10 +252,6 @@ public: ++(*this); // place the interator in the first intersected cell } Iterator( const Self& i) : S(i.S), node(i.node) {} - const Object_list& operator*() const { - CGAL_assertion( node != nullptr); - return node->objects(); - } Self& operator++() { if( S.empty()) @@ -350,35 +332,6 @@ void divide_segment_by_plane( Segment_3 s, Plane_3 pl, }; }; - class Objects_along_ray : public Objects_around_segment - { - typedef Objects_around_segment Base; - protected: - Traits traits; - public: - Objects_along_ray( const K3_tree& k, const Ray_3& r) { - CGAL_NEF_TRACEN("Objects_along_ray: input ray: "< v_mark(false); - Unique_hash_map< Halfedge_handle, bool> e_mark(false); - Unique_hash_map< Halffacet_handle, bool> f_mark(false); - for( typename Objects_around_segment::Iterator oar = objects.begin(); - oar != objects.end(); ++oar) { - for( typename Object_list::const_iterator o = (*oar).begin(); - o != (*oar).end(); ++o) { // TODO: implement operator->(...) - Vertex_handle v; - Halfedge_handle e; - Halffacet_handle f; - if( CGAL::assign( v, *o)) { - if( !v_mark[v]) { - O.push_back(*o); - v_mark[v] = true; - } - } - else if( CGAL::assign( e, *o)) { - if( !e_mark [e]) { - O.push_back(*o); - e_mark[e] = true; - } - } - else if( CGAL::assign( f, *o)) { - if( !f_mark[f]) { - O.push_back(*o); - f_mark[f] = true; - } - } - else - CGAL_error_msg( "wrong handle"); - } + for(typename Objects_around_segment::Iterator oas = objects.begin(); oas != objects.end(); ++oas) { + nodes.push_back(oas.get_node()); } - return O; + return nodes; } - - bool is_point_on_cell( const Point_3& p, const typename Objects_around_segment::Iterator& target) const { - return is_point_on_cell( p, target.get_node(), root); + bool is_point_in_node( const Point_3& p, const Node_handle target) const { + return is_point_in_node( p, target, root); } void add_facet(Halffacet_handle f) { @@ -510,12 +433,8 @@ public: void pre_visit(const Node_handle) {} void post_visit(const Node_handle n) { - typename Object_list::const_iterator o; - for( o = n->objects().begin(); - o != n->objects().end(); ++o) { - Vertex_handle v; - if( CGAL::assign( v, *o)) - b.extend(v->point()); + for(Vertex_const_iterator vi = n->vertex_list.begin(); vi!=n->vertex_list.end(); ++vi) { + b.extend((*vi)->point()); } } @@ -722,7 +641,7 @@ static Node_handle get_child_by_side( const Node_handle node, Oriented_side side return node->right(); } -Node_handle locate_cell_containing( const Point_3& p, const Node_handle node) const { +Node_handle locate_node_containing( const Point_3& p, const Node_handle node) const { CGAL_precondition( node != nullptr); if( node->is_leaf()) return node; @@ -730,26 +649,57 @@ Node_handle locate_cell_containing( const Point_3& p, const Node_handle node) co Oriented_side side = node->plane().oriented_side(p); if(side == ON_ORIENTED_BOUNDARY) side = ON_NEGATIVE_SIDE; - return locate_cell_containing(p, get_child_by_side(node, side)); + return locate_node_containing(p, get_child_by_side(node, side)); } -const Object_list& locate( const Point_3& p, const Node_handle node) const { - CGAL_precondition( node != nullptr); - return locate_cell_containing( p, node)->objects(); -} -bool is_point_on_cell( const Point_3& p, const Node_handle target, const Node_handle current) const { +bool is_point_in_node( const Point_3& p, const Node_handle target, const Node_handle current) const { CGAL_precondition( target != nullptr && current != nullptr); if( current->is_leaf()) return (current == target); Oriented_side side = current->plane().oriented_side(p); if( side == ON_NEGATIVE_SIDE) - return is_point_on_cell( p, target, current->left()); + return is_point_in_node( p, target, current->left()); else if( side == ON_POSITIVE_SIDE) - return is_point_on_cell( p, target, current->right()); + return is_point_in_node( p, target, current->right()); CGAL_assertion( side == ON_ORIENTED_BOUNDARY); - return (is_point_on_cell( p, target, current->left()) || - is_point_on_cell( p, target, current->right())); + return (is_point_in_node( p, target, current->left()) || + is_point_in_node( p, target, current->right())); +} + +Segment_3 ray_to_segment(const Ray_3& r) const +{ + CGAL_NEF_TRACEN("Objects_along_ray: input ray: "<objects_along_ray(ray); - Objects_along_ray_iterator objects_iterator = objects.begin(); - while( !hit && objects_iterator != objects.end()) { - Object_list candidates = *objects_iterator; - Object_list_iterator o; - CGAL_for_each( o, candidates) { - if( CGAL::assign( v, *o) && ((mask&1) != 0)) { + + Node_list nodes = candidate_provider->nodes_along_ray(ray); + typename Node_list::iterator nodes_iterator = nodes.begin(); + + while( !hit && nodes_iterator != nodes.end()) { + Node_handle n(*nodes_iterator); + if((mask&1)!=0) { + for(typename Vertex_list::const_iterator vi=n->vertices_begin(); vi!=n->vertices_end(); ++vi) { + Vertex_handle v(*vi); _CGAL_NEF_TRACEN("trying vertex on "<point()); if( (ray.source() != v->point()) && ray.has_on(v->point())) { _CGAL_NEF_TRACEN("the ray intersects the vertex"); _CGAL_NEF_TRACEN("prev. intersection? "<point())) continue; eor = v->point(); @@ -254,34 +262,39 @@ public: _CGAL_NEF_TRACEN("the vertex becomes the new hit object"); } } - else if( CGAL::assign( e, *o) && ((mask&2) != 0)) { + } + if((mask&2)!=0) { + for(typename Halfedge_list::const_iterator ei=n->edges_begin(); ei!=n->edges_end(); ++ei) { + Halfedge_handle e(*ei); Point_3 q; _CGAL_NEF_TRACEN("trying edge on "<< Segment_3(e->source()->point(),e->twin()->source()->point())); if ( (ray_source_vertex == Vertex_handle()) || ( (ray_source_vertex != e->source()) && (ray_source_vertex != e->twin()->source())) ) { - - if( SNC_intersection::does_intersect_internally( ray, Segment_3(e->source()->point(), - e->twin()->source()->point()), q)) { - _CGAL_NEF_TRACEN("ray intersects edge on " << q); - _CGAL_NEF_TRACEN("prev. intersection? " << hit); - CGAL_assertion_code - (if (hit) _CGAL_NEF_TRACEN("prev. intersection on " << eor)); - if (hit && !has_smaller_distance_to_point(ray.source(), q, eor)) - continue; - _CGAL_NEF_TRACEN("is the intersection point on the current cell? " << - candidate_provider->is_point_on_cell(q, objects_iterator)); - if (!candidate_provider->is_point_on_cell(q, objects_iterator)) - continue; - eor = q; - result = make_object(e); - hit = true; - _CGAL_NEF_TRACEN("the edge becomes the new hit object"); - } + if( SNC_intersection::does_intersect_internally( ray, Segment_3(e->source()->point(), + e->twin()->source()->point()), q)) { + _CGAL_NEF_TRACEN("ray intersects edge on "<is_point_in_node( q, n)); + if( !candidate_provider->is_point_in_node( q, n)) + continue; + eor = q; + result = make_object(e); + hit = true; + _CGAL_NEF_TRACEN("the edge becomes the new hit object"); + } } } - else if( CGAL::assign( f, *o) && ((mask&4) != 0)) { + } + if((mask&4)!=0) { + for(typename Halffacet_list::const_iterator fi=n->facets_begin(); fi!=n->facets_end(); ++fi) { + Halffacet_handle f(*fi); Point_3 q; _CGAL_NEF_TRACEN("trying facet with on plane "<plane()<< - " with point on "<plane().point()); + " with point on "<plane().point()); if( SNC_intersection::does_intersect_internally( ray, f, q) ) { _CGAL_NEF_TRACEN("ray intersects facet on "<is_point_on_cell( q, objects_iterator)); - if( !candidate_provider->is_point_on_cell( q, objects_iterator)) + candidate_provider->is_point_in_node( q, n)); + if( !candidate_provider->is_point_in_node( q, n)) continue; eor = q; result = make_object(f); @@ -298,145 +311,105 @@ public: _CGAL_NEF_TRACEN("the facet becomes the new hit object"); } } - else if((mask&15) == 15) - CGAL_error_msg( "wrong handle"); } if(!hit) - ++objects_iterator; + ++nodes_iterator; } + CGAL_NEF_TIMER(rs_t.stop()); return result; } virtual Object_handle locate( const Point_3& p) const { if(Infi_box::extended_kernel()) { - CGAL_NEF_TIMER(pl_t.start()); - CGAL_assertion( initialized); - _CGAL_NEF_TRACEN( "locate "<objects_around_point(p); - Object_list_iterator o = candidates.begin(); - bool found = false; - while( !found && o != candidates.end()) { - if( CGAL::assign( v, *o)) { + CGAL_NEF_TIMER(pl_t.start()); + CGAL_assertion( initialized); + _CGAL_NEF_TRACEN( "locate "<locate_node_containing(p); + for(typename Vertex_list::const_iterator vi=n->vertices_begin(); vi!=n->vertices_end(); ++vi) { + Vertex_handle v(*vi); if ( p == v->point()) { _CGAL_NEF_TRACEN("found on vertex "<point()); - result = make_object(v); - found = true; + return make_object(v); } } - else if( CGAL::assign( e, *o)) { - if ( SNC_intersection::does_contain_internally(e->source()->point(), e->twin()->source()->point(), p) ) { + for(typename Halfedge_list::const_iterator ei=n->edges_begin(); ei!=n->edges_end(); ++ei) { + Halfedge_handle e(*ei); + if (SNC_intersection::does_contain_internally(e->source()->point(),e->twin()->source()->point(), p) ) { _CGAL_NEF_TRACEN("found on edge "<source()->point(),e->twin()->source()->point())); - result = make_object(e); - found = true; + return make_object(e); } } - else if( CGAL::assign( f, *o)) { + for(typename Halffacet_list::const_iterator fi=n->facets_begin(); fi!=n->facets_end(); ++fi) { + Halffacet_handle f(*fi); if (SNC_intersection::does_contain_internally( f, p) ) { _CGAL_NEF_TRACEN("found on facet..."); - result = make_object(f); - found = true; + return make_object(f); } } - o++; - } - if( !found) { + _CGAL_NEF_TRACEN("point not found in 2-skeleton"); _CGAL_NEF_TRACEN("shooting ray to determine the volume"); Ray_3 r( p, Vector_3( -1, 0, 0)); - result = make_object(determine_volume(r)); - } CGAL_NEF_TIMER(pl_t.start()); - CGAL_NEF_TIMER(pl_t.stop()); - return result; + return make_object(determine_volume(r)); + + } else { // standard kernel - } else { // standard kernel + CGAL_assertion( initialized); + _CGAL_NEF_TRACEN( "locate "<locate_node_containing(p); + typename Vertex_list::const_iterator vi = n->vertices_begin(); - CGAL_assertion( initialized); - _CGAL_NEF_TRACEN( "locate "<objects_around_point(p); - Object_list_iterator o = candidates.begin(); + if(n->empty()) + return make_object(Base(*this).volumes_begin()); - if(candidates.empty()) - return make_object(Base(*this).volumes_begin()); - - CGAL::assign(v,*o); - CGAL_assertion(CGAL::assign(v,*o)); - if(p==v->point()) - return make_object(v); - - closest = v; - ++o; - while(o!=candidates.end() && CGAL::assign(v,*o)) { - if ( p == v->point()) { - _CGAL_NEF_TRACEN("found on vertex "<point()); + Vertex_handle v(*vi),closest; + if(p==v->point()) return make_object(v); - } - if(CGAL::has_smaller_distance_to_point(p, v->point(), closest->point())){ - closest = v; - } - ++o; - } - - v = closest; - result = make_object(v); - - Segment_3 s(p,v->point()); - // bool first = true; - Point_3 ip; - - /* - // TODO: das geht effizienter - Object_list_iterator of(o); - while(of != candidates.end() && assign(e, *of)) ++of; - - typename SNC_structure::SHalfedge_iterator sei; - for(sei=v->shalfedges_begin(); sei!=v->shalfedges_end(); ++sei){ - if(sei->is_twin()) continue; - Halffacet_handle fout = sei->facet(); - if(fout->is_twin()) fout = fout->twin(); - Object_list_iterator ofc(of); - for(;ofc!=candidates.end();++ofc) { - if(CGAL::assign(f,*ofc)) { - if(f == fout->twin()) - std::cerr << "shit" << std::endl; - if(f == fout) { - Object_list_iterator oe(ofc); - --ofc; - candidates.erase(oe); - } + closest = v; + ++vi; + while(vi!=n->vertices_end()) { + v = *vi; + if ( p == v->point()) { + _CGAL_NEF_TRACEN("found on vertex "<point()); + return make_object(v); } + + if(CGAL::has_smaller_distance_to_point(p, v->point(), closest->point())){ + closest = v; + } + ++vi; } - } - */ - for(;o!=candidates.end();++o) { - if( CGAL::assign( e, *o)) { - // if(first && - // (e->source() == v || e->twin()->source() == v)) continue; + + v = closest; + result = make_object(v); + + Segment_3 s(p,v->point()); + Point_3 ip; + + Halfedge_handle e; + for(typename Halfedge_list::const_iterator ei=n->edges_begin(); ei!=n->edges_end(); ++ei) { + e = *ei; Segment_3 ss(e->source()->point(),e->twin()->source()->point()); CGAL_NEF_TRACEN("test edge " << e->source()->point() << "->" << e->twin()->source()->point()); if (SNC_intersection::does_contain_internally(e->source()->point(), e->twin()->source()->point(), p)) { - _CGAL_NEF_TRACEN("found on edge "<< ss); + _CGAL_NEF_TRACEN("found on edge "<< ss); return make_object(e); } if((e->source() != v) && (e->twin()->source() != v) && SNC_intersection::does_intersect_internally(s, ss, ip)) { - // first = false; s = Segment_3(p, normalized(ip)); result = make_object(e); } + } - } else - if( CGAL::assign( f, *o)) { + Halffacet_handle f; + for(typename Halffacet_list::const_iterator fi=n->facets_begin(); fi!=n->facets_end(); ++fi) { + f = *fi; CGAL_NEF_TRACEN("test facet " << f->plane()); if (SNC_intersection::does_contain_internally(f,p) ) { _CGAL_NEF_TRACEN("found on facet..."); @@ -458,214 +431,118 @@ public: } } - - if( (! v_vertex_of_f) && SNC_intersection::does_intersect_internally(s,f,ip) ) { + if( (! v_vertex_of_f) && SNC_intersection::does_intersect_internally(s,f,ip) ) { s = Segment_3(p, normalized(ip)); result = make_object(f); } } - else CGAL_error_msg( "wrong handle type"); - } - //CGAL_warning("altered code in SNC_point_locator"); - /* - Halffacet_iterator fc; - CGAL_forall_facets(fc, *this->sncp()) { - CGAL_assertion(!SNC_intersection::does_intersect_internally(s,f,ip)); + if( CGAL::assign( v, result)) { + _CGAL_NEF_TRACEN("vertex hit, obtaining volume..." << v->point()); + + //CGAL_warning("altered code in SNC_point_locator"); + SM_point_locator L(&*v); + Object_handle so = L.locate(s.source()-s.target(), true); + SFace_handle sf; + if(CGAL::assign(sf,so)) + return make_object(sf->volume()); + CGAL_error_msg( "wrong handle type"); + return Object_handle(); + + } else if( CGAL::assign( f, result)) { + _CGAL_NEF_TRACEN("facet hit, obtaining volume..."); + if(f->plane().oriented_side(p) == ON_NEGATIVE_SIDE) + f = f->twin(); + return make_object(f->incident_volume()); + } else if( CGAL::assign(e, result)) { + SM_decorator SD(&*e->source()); + if( SD.is_isolated(e)) + return make_object(e->incident_sface()->volume()); + return make_object(get_visible_facet(e,Ray_3(s.source(),s.to_vector()))->incident_volume()); } - - Halfedge_iterator ec; - CGAL_forall_edges(ec, *this->sncp()) { - Segment_3 ss(ec->source()->point(), ec->twin()->source()->point()); - CGAL_assertion(!SNC_intersection::does_intersect_internally(s,ss,ip)); - } - - Vertex_iterator vc; - CGAL_forall_vertices(vc, *this->sncp()) { - std::cerr << "test vertex " << vc->point() << std::endl; - CGAL_assertion(vc->point() == s.target() || !s.has_on(vc->point())); - } - */ - - if( CGAL::assign( v, result)) { - _CGAL_NEF_TRACEN("vertex hit, obtaining volume..." << v->point()); - - //CGAL_warning("altered code in SNC_point_locator"); - SM_point_locator L(&*v); - Object_handle so = L.locate(s.source()-s.target(), true); - SFace_handle sf; - if(CGAL::assign(sf,so)) - return make_object(sf->volume()); CGAL_error_msg( "wrong handle type"); return Object_handle(); -/* - SHalfedge_handle se; - CGAL_assertion(CGAL::assign(se,so)); - CGAL_NEF_TRACEN("intersect segment " << s << " with edges"); - for(;ox!=candidates.end();++ox) { - if(!CGAL::assign(e,*ox)) continue; - CGAL_NEF_TRACEN("test edge " << e->source()->point() << "->" << e->twin()->source()->point()); - if(SNC_intersection::does_intersect_internally(s,Segment_3(e->source()->point(),e->twin()->source()->point()),ip)) { - s = Segment_3(p, normalized(ip)); - result = make_object(e); - } - } - CGAL_assertion(CGAL::assign(e,result)); - CGAL::assign(e,result); - f = get_visible_facet(e, Ray_3(p, s.target())); - if( f != Halffacet_handle()) - return f->incident_volume(); - SM_decorator SD(&*v); // now, the vertex has no incident facets - CGAL_assertion( SD.number_of_sfaces() == 1); - return SD.sfaces_begin()->volume(); -*/ - } else if( CGAL::assign( f, result)) { - _CGAL_NEF_TRACEN("facet hit, obtaining volume..."); - if(f->plane().oriented_side(p) == ON_NEGATIVE_SIDE) - f = f->twin(); - return make_object(f->incident_volume()); - } else if( CGAL::assign(e, result)) { - SM_decorator SD(&*e->source()); - if( SD.is_isolated(e)) - return make_object(e->incident_sface()->volume()); - return make_object(get_visible_facet(e,Ray_3(s.source(),s.to_vector()))->incident_volume()); } - CGAL_error_msg( "wrong handle type"); - return Object_handle(); - } } virtual void intersect_with_edges_and_facets( Halfedge_handle e0, - const typename SNC_point_locator::Intersection_call_back& call_back) const { - - CGAL_NEF_TIMER(it_t.start()); - CGAL_assertion( initialized); + const Intersection_call_back& call_back) const { _CGAL_NEF_TRACEN( "intersecting edge: "<<&*e0<<' '<source()->point(), - e0->twin()->source()->point())); - - - Segment_3 s(Segment_3(e0->source()->point(),e0->twin()->source()->point())); - Vertex_handle v; - Halfedge_handle e; - Halffacet_handle f; - Object_list_iterator o; - Object_list objects = candidate_provider->objects_around_segment(s); - CGAL_for_each( o, objects) { - if( CGAL::assign( v, *o)) { - /* do nothing */ - } - else if( CGAL::assign( e, *o)) { - -#ifdef CGAL_NEF3_DUMP_STATISTICS - ++number_of_intersection_candidates; -#endif - - Point_3 q; - if( SNC_intersection::does_intersect_internally( s, Segment_3(e->source()->point(), - e->twin()->source()->point()), q)) { - q = normalized(q); - call_back( e0, make_object(Halfedge_handle(e)), q); - _CGAL_NEF_TRACEN("edge intersects edge "<<' '<<&*e<< Segment_3(e->source()->point(), - e->twin()->source()->point())<<" on "<plane()<<" on "<twin()->source()->point())); + Segment_3 s(e0->source()->point(),e0->twin()->source()->point()); + Node_list nodes = candidate_provider->nodes_around_segment(s); + intersect_with_edges(e0,call_back,s,nodes); + intersect_with_facets(e0,call_back,s,nodes); } virtual void intersect_with_edges( Halfedge_handle e0, - const typename SNC_point_locator::Intersection_call_back& call_back) const { + const Intersection_call_back& call_back) const { CGAL_NEF_TIMER(it_t.start()); - CGAL_assertion( initialized); _CGAL_NEF_TRACEN( "intersecting edge: "<<&*e0<<' '<source()->point(), - e0->twin()->source()->point())); - Segment_3 s(Segment_3(e0->source()->point(),e0->twin()->source()->point())); - Vertex_handle v; - Halfedge_handle e; - Halffacet_handle f; - Object_list_iterator o; - Object_list objects = candidate_provider->objects_around_segment(s); - CGAL_for_each( o, objects) { - if( CGAL::assign( v, *o)) { - /* do nothing */ - } - else if( CGAL::assign( e, *o)) { - -#ifdef CGAL_NEF3_DUMP_STATISTICS - ++number_of_intersection_candidates; -#endif - - Point_3 q; - if( SNC_intersection::does_intersect_internally( s, Segment_3(e->source()->point(), - e->twin()->source()->point()), q)) { - q = normalized(q); - call_back( e0, make_object(Halfedge_handle(e)), q); - _CGAL_NEF_TRACEN("edge intersects edge "<<' '<<&*e<< Segment_3(e->source()->point(), - e->twin()->source()->point())<<" on "<twin()->source()->point())); + Segment_3 s(e0->source()->point(),e0->twin()->source()->point()); + Node_list nodes = candidate_provider->nodes_around_segment(s); + intersect_with_edges(e0,call_back,s,nodes); } virtual void intersect_with_facets( Halfedge_handle e0, - const typename SNC_point_locator::Intersection_call_back& call_back) const { - CGAL_NEF_TIMER(it_t.start()); + const Intersection_call_back& call_back) const { CGAL_assertion( initialized); _CGAL_NEF_TRACEN( "intersecting edge: "<< Segment_3(e0->source()->point(), - e0->twin()->source()->point())); - Segment_3 s(Segment_3(e0->source()->point(),e0->twin()->source()->point())); - Vertex_handle v; - Halfedge_handle e; - Halffacet_handle f; - Object_list_iterator o; - Object_list objects = candidate_provider->objects_around_segment(s); - CGAL_for_each( o, objects) { - if( CGAL::assign( v, *o)) { - /* do nothing */ - } - else if( CGAL::assign( e, *o)) { - /* do nothing */ - } - else if( CGAL::assign( f, *o)) { - -#ifdef CGAL_NEF3_DUMP_STATISTICS - ++number_of_intersection_candidates; -#endif - - Point_3 q; - if( SNC_intersection::does_intersect_internally( s, f, q) ) { - q = normalized(q); - call_back( e0, make_object(Halffacet_handle(f)), q); - _CGAL_NEF_TRACEN("edge intersects facet on plane "<plane()<<" on "<twin()->source()->point())); + Segment_3 s(e0->source()->point(),e0->twin()->source()->point()); + Node_list nodes = candidate_provider->nodes_around_segment(s); + intersect_with_facets(e0,call_back,s,nodes); } private: + + void intersect_with_edges( Halfedge_handle e0, + const Intersection_call_back& call_back, Segment_3& s, Node_list& nodes) const { + Unique_hash_map visited(false); + for(typename Node_list::iterator ni = nodes.begin(); ni!=nodes.end(); ++ni) { + Node_handle n(*ni); + for(typename Halfedge_list::const_iterator e = n->edges_begin(); e!=n->edges_end(); ++e) { + if(!visited[*e]) { +#ifdef CGAL_NEF3_DUMP_STATISTICS + ++number_of_intersection_candidates; +#endif + Point_3 q; + if(SNC_intersection::does_intersect_internally( s, Segment_3((*e)->source()->point(), + (*e)->twin()->source()->point()), q)) { + q = normalized(q); + call_back( e0, make_object(Halfedge_handle(*e)), q); + _CGAL_NEF_TRACEN("edge intersects edge "<<' '<<&*e<< Segment_3((*e)->source()->point(), + (*e)->twin()->source()->point())<<" on "< visited(false); + for(typename Node_list::iterator ni = nodes.begin(); ni!=nodes.end(); ++ni) { + Node_handle n(*ni); + for(typename Halffacet_list::const_iterator f = n->facets_begin(); f!=n->facets_end(); ++f) { + if(!visited[*f]) { +#ifdef CGAL_NEF3_DUMP_STATISTICS + ++number_of_intersection_candidates; +#endif + Point_3 q; + if(SNC_intersection::does_intersect_internally( s, *f, q) ) { + q = normalized(q); + call_back( e0, make_object(Halffacet_handle(*f)), q); + _CGAL_NEF_TRACEN("edge intersects facet on plane "<plane()<<" on "< Date: Wed, 6 Apr 2022 23:10:06 +0100 Subject: [PATCH 008/107] Remove object casting in Intersection_call_back --- Nef_3/include/CGAL/Nef_3/Binary_operation.h | 46 +++---------------- Nef_3/include/CGAL/Nef_3/K3_tree.h | 2 +- Nef_3/include/CGAL/Nef_3/SNC_point_locator.h | 9 ++-- .../CGAL/Nef_3/binop_intersection_tests.h | 6 +-- 4 files changed, 16 insertions(+), 47 deletions(-) diff --git a/Nef_3/include/CGAL/Nef_3/Binary_operation.h b/Nef_3/include/CGAL/Nef_3/Binary_operation.h index bcfe27e3591..57a1eaa0cf6 100644 --- a/Nef_3/include/CGAL/Nef_3/Binary_operation.h +++ b/Nef_3/include/CGAL/Nef_3/Binary_operation.h @@ -180,37 +180,9 @@ class Binary_operation : public CGAL::SNC_decorator { snc0(s0), snc1(s1), bop(_bop), result(r), inverse_order(invert_order), A(Ain) {} - void operator()(Halfedge_handle e0, Object_handle o1, const Point_3& ip) - const { - -#ifdef CGAL_NEF3_DUMP_STATISTICS - ++number_of_intersections; -#endif - - Halfedge_handle e; - Halffacet_handle f; - - Point_3 p(normalized(ip)); -#ifdef CGAL_USE_TRACE - CGAL_NEF_TRACEN("Intersection_call_back: intersection reported on " << p << " (normalized: " << normalized(p) << " )"); - CGAL_NEF_TRACEN("edge 0 has source " << e0->source()->point() << " and direction " << e0->vector()); - if( CGAL::assign( e, o1)) { - CGAL_NEF_TRACEN("edge 1 has source " << e->source()->point() << " and direction " << e->vector()); - } - else if( CGAL::assign( f, o1)) { - CGAL_NEF_TRACEN("face 1 has plane equation " << f->plane()); - } - else - CGAL_error_msg( "wrong handle"); -#endif - -#if defined (CGAL_NEF3_TIMER_OVERLAY) || (CGAL_NEF3_TIMER_INTERSECTION) - timer_overlay.start(); -#endif - - if( CGAL::assign( e, o1)) { - // std::cerr << "inverse order " << inverse_order << std::endl; - + void operator()(Halfedge_handle e0, Halfedge_handle e, const Point_3& ip) const override + { + Point_3 p(normalized(ip)); #ifdef CGAL_NEF_EXPERIMENTAL_CODE typename CGAL::Edge_edge_overlay eeo(result, e0, e); Sphere_map* M0 = eeo.create_edge_edge_overlay(p, bop, inverse_order, A); @@ -228,7 +200,10 @@ class Binary_operation : public CGAL::SNC_decorator { result.delete_vertex(v1); #endif } - else if( CGAL::assign( f, o1)) { + + void operator()(Halfedge_handle e0, Halffacet_handle f, const Point_3& ip) const override + { + Point_3 p(normalized(ip)); #ifdef CGAL_NEF3_OVERLAY_BY_HAND_OFF Binary_operation D(result); Vertex_handle v0, v1; @@ -246,14 +221,7 @@ class Binary_operation : public CGAL::SNC_decorator { O.simplify(A); #endif // CGAL_NEF3_OVERLAY_BY_HAND_OFF } - else - CGAL_error_msg( "wrong handle"); -#if defined (CGAL_NEF3_TIMER_OVERLAY) || (CGAL_NEF3_TIMER_INTERSECTION) - timer_overlay.stop(); -#endif - - } private: const SNC_structure& snc0; const SNC_structure& snc1; diff --git a/Nef_3/include/CGAL/Nef_3/K3_tree.h b/Nef_3/include/CGAL/Nef_3/K3_tree.h index 7c2ecbcae6d..fc148f9a51d 100644 --- a/Nef_3/include/CGAL/Nef_3/K3_tree.h +++ b/Nef_3/include/CGAL/Nef_3/K3_tree.h @@ -394,7 +394,7 @@ public: non_efective_splits=0; root = build_kdtree(vertices, edges, facets, 0); } - Node_handle locate_node_containing( const Point_3 p) const { + Node_handle locate_node_containing( const Point_3& p) const { return locate_node_containing( p, root); } Node_list nodes_along_ray( const Ray_3& r) const { diff --git a/Nef_3/include/CGAL/Nef_3/SNC_point_locator.h b/Nef_3/include/CGAL/Nef_3/SNC_point_locator.h index a753c84aead..0d66c608742 100644 --- a/Nef_3/include/CGAL/Nef_3/SNC_point_locator.h +++ b/Nef_3/include/CGAL/Nef_3/SNC_point_locator.h @@ -98,9 +98,10 @@ public: class Intersection_call_back { public: - virtual void operator()( Halfedge_handle edge, Object_handle object, + virtual void operator()( Halfedge_handle edge0, Halfedge_handle edge1, + const Point_3& intersection_point) const = 0; + virtual void operator()( Halfedge_handle edge0, Halffacet_handle facet1, const Point_3& intersection_point) const = 0; - virtual ~Intersection_call_back() {} }; @@ -511,7 +512,7 @@ private: if(SNC_intersection::does_intersect_internally( s, Segment_3((*e)->source()->point(), (*e)->twin()->source()->point()), q)) { q = normalized(q); - call_back( e0, make_object(Halfedge_handle(*e)), q); + call_back( e0, *e, q); _CGAL_NEF_TRACEN("edge intersects edge "<<' '<<&*e<< Segment_3((*e)->source()->point(), (*e)->twin()->source()->point())<<" on "<plane()<<" on "< Date: Wed, 6 Apr 2022 23:39:24 +0100 Subject: [PATCH 009/107] Use enum in SNC_point_locator to avoid object casts --- Nef_3/include/CGAL/Nef_3/SNC_point_locator.h | 65 ++++++++++++-------- 1 file changed, 41 insertions(+), 24 deletions(-) diff --git a/Nef_3/include/CGAL/Nef_3/SNC_point_locator.h b/Nef_3/include/CGAL/Nef_3/SNC_point_locator.h index 0d66c608742..9cfe84d52b7 100644 --- a/Nef_3/include/CGAL/Nef_3/SNC_point_locator.h +++ b/Nef_3/include/CGAL/Nef_3/SNC_point_locator.h @@ -230,14 +230,17 @@ public: return this->shoot(ray, null_handle, mask); } + enum SOLUTION { is_vertex_, is_edge_, is_facet_ }; + virtual Object_handle shoot(const Ray_3& ray, Vertex_handle ray_source_vertex, int mask=255) const { CGAL_NEF_TIMER(rs_t.start()); CGAL_assertion( initialized); _CGAL_NEF_TRACEN( "shooting: "<point())) continue; eor = v->point(); - result = make_object(v); + v_res = v; + solution = is_vertex_; hit = true; _CGAL_NEF_TRACEN("the vertex becomes the new hit object"); } @@ -283,7 +287,8 @@ public: if( !candidate_provider->is_point_in_node( q, n)) continue; eor = q; - result = make_object(e); + e_res = e; + solution = is_edge_; hit = true; _CGAL_NEF_TRACEN("the edge becomes the new hit object"); } @@ -307,7 +312,8 @@ public: if( !candidate_provider->is_point_in_node( q, n)) continue; eor = q; - result = make_object(f); + f_res = f; + solution = is_facet_; hit = true; _CGAL_NEF_TRACEN("the facet becomes the new hit object"); } @@ -318,7 +324,12 @@ public: } CGAL_NEF_TIMER(rs_t.stop()); - return result; + switch (solution) { + case is_vertex_: return make_object(v_res); + case is_edge_: return make_object(e_res); + case is_facet_: return make_object(f_res); + } + return Object_handle(); } virtual Object_handle locate( const Point_3& p) const { @@ -360,7 +371,7 @@ public: CGAL_assertion( initialized); _CGAL_NEF_TRACEN( "locate "<locate_node_containing(p); typename Vertex_list::const_iterator vi = n->vertices_begin(); @@ -388,7 +399,11 @@ public: } v = closest; - result = make_object(v); + Vertex_handle v_res; + Halfedge_handle e_res; + Halffacet_handle f_res; + v_res = v; + solution = is_vertex_; Segment_3 s(p,v->point()); Point_3 ip; @@ -404,7 +419,8 @@ public: } if((e->source() != v) && (e->twin()->source() != v) && SNC_intersection::does_intersect_internally(s, ss, ip)) { s = Segment_3(p, normalized(ip)); - result = make_object(e); + e_res = e; + solution = is_edge_; } } @@ -434,15 +450,16 @@ public: if( (! v_vertex_of_f) && SNC_intersection::does_intersect_internally(s,f,ip) ) { s = Segment_3(p, normalized(ip)); - result = make_object(f); + f_res = f; + solution = is_facet_; } } - if( CGAL::assign( v, result)) { - _CGAL_NEF_TRACEN("vertex hit, obtaining volume..." << v->point()); + if( solution == is_vertex_) { + _CGAL_NEF_TRACEN("vertex hit, obtaining volume..." << v_res->point()); //CGAL_warning("altered code in SNC_point_locator"); - SM_point_locator L(&*v); + SM_point_locator L(&*v_res); Object_handle so = L.locate(s.source()-s.target(), true); SFace_handle sf; if(CGAL::assign(sf,so)) @@ -450,16 +467,16 @@ public: CGAL_error_msg( "wrong handle type"); return Object_handle(); - } else if( CGAL::assign( f, result)) { + } else if( solution == is_facet_) { _CGAL_NEF_TRACEN("facet hit, obtaining volume..."); - if(f->plane().oriented_side(p) == ON_NEGATIVE_SIDE) - f = f->twin(); - return make_object(f->incident_volume()); - } else if( CGAL::assign(e, result)) { - SM_decorator SD(&*e->source()); - if( SD.is_isolated(e)) - return make_object(e->incident_sface()->volume()); - return make_object(get_visible_facet(e,Ray_3(s.source(),s.to_vector()))->incident_volume()); + if(f_res->plane().oriented_side(p) == ON_NEGATIVE_SIDE) + f_res = f_res->twin(); + return make_object(f_res->incident_volume()); + } else if( solution == is_edge_) { + SM_decorator SD(&*e_res->source()); + if( SD.is_isolated(e_res)) + return make_object(e_res->incident_sface()->volume()); + return make_object(get_visible_facet(e_res,Ray_3(s.source(),s.to_vector()))->incident_volume()); } CGAL_error_msg( "wrong handle type"); return Object_handle(); From 3aea3f4691f8fbaff1f0c35e9cb01a00bea1615e Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Thu, 7 Apr 2022 13:14:14 +0100 Subject: [PATCH 010/107] initialize solution --- Nef_3/include/CGAL/Nef_3/SNC_point_locator.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Nef_3/include/CGAL/Nef_3/SNC_point_locator.h b/Nef_3/include/CGAL/Nef_3/SNC_point_locator.h index 9cfe84d52b7..b8773744ccb 100644 --- a/Nef_3/include/CGAL/Nef_3/SNC_point_locator.h +++ b/Nef_3/include/CGAL/Nef_3/SNC_point_locator.h @@ -230,14 +230,14 @@ public: return this->shoot(ray, null_handle, mask); } - enum SOLUTION { is_vertex_, is_edge_, is_facet_ }; + enum SOLUTION { is_vertex_, is_edge_, is_facet_ , is_none_}; virtual Object_handle shoot(const Ray_3& ray, Vertex_handle ray_source_vertex, int mask=255) const { CGAL_NEF_TIMER(rs_t.start()); CGAL_assertion( initialized); _CGAL_NEF_TRACEN( "shooting: "< Date: Thu, 7 Apr 2022 17:39:59 +0100 Subject: [PATCH 011/107] Rename local variable to not conflict with member variable name --- Nef_3/include/CGAL/Nef_3/K3_tree.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Nef_3/include/CGAL/Nef_3/K3_tree.h b/Nef_3/include/CGAL/Nef_3/K3_tree.h index fc148f9a51d..ab760dc1e85 100644 --- a/Nef_3/include/CGAL/Nef_3/K3_tree.h +++ b/Nef_3/include/CGAL/Nef_3/K3_tree.h @@ -402,12 +402,12 @@ public: return nodes_around_segment(s); } Node_list nodes_around_segment( const Segment_3& s) const { - Node_list nodes; + Node_list result; Objects_around_segment objects( *this, s); for(typename Objects_around_segment::Iterator oas = objects.begin(); oas != objects.end(); ++oas) { - nodes.push_back(oas.get_node()); + result.push_back(oas.get_node()); } - return nodes; + return result; } bool is_point_in_node( const Point_3& p, const Node_handle target) const { return is_point_in_node( p, target, root); From 0bbb92aac7f71a6427ac90acbeb1bdba31f7827d Mon Sep 17 00:00:00 2001 From: Giles Bathgate Date: Thu, 7 Apr 2022 18:07:32 +0100 Subject: [PATCH 012/107] Inline variable to only construct segment when needed --- Nef_3/include/CGAL/Nef_3/SNC_point_locator.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Nef_3/include/CGAL/Nef_3/SNC_point_locator.h b/Nef_3/include/CGAL/Nef_3/SNC_point_locator.h index b8773744ccb..d63e4065436 100644 --- a/Nef_3/include/CGAL/Nef_3/SNC_point_locator.h +++ b/Nef_3/include/CGAL/Nef_3/SNC_point_locator.h @@ -411,13 +411,13 @@ public: Halfedge_handle e; for(typename Halfedge_list::const_iterator ei=n->edges_begin(); ei!=n->edges_end(); ++ei) { e = *ei; - Segment_3 ss(e->source()->point(),e->twin()->source()->point()); CGAL_NEF_TRACEN("test edge " << e->source()->point() << "->" << e->twin()->source()->point()); if (SNC_intersection::does_contain_internally(e->source()->point(), e->twin()->source()->point(), p)) { _CGAL_NEF_TRACEN("found on edge "<< ss); return make_object(e); } - if((e->source() != v) && (e->twin()->source() != v) && SNC_intersection::does_intersect_internally(s, ss, ip)) { + if((e->source() != v) && (e->twin()->source() != v) && + SNC_intersection::does_intersect_internally(s, Segment_3(e->source()->point(),e->twin()->source()->point()), ip)) { s = Segment_3(p, normalized(ip)); e_res = e; solution = is_edge_; From 68d896b49656359b27a120ac4fd0bab7317bba8c Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Wed, 13 Apr 2022 11:53:02 +0100 Subject: [PATCH 013/107] Fix warnings --- Nef_3/include/CGAL/Nef_3/K3_tree.h | 2 +- Nef_3/include/CGAL/Nef_3/SNC_point_locator.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Nef_3/include/CGAL/Nef_3/K3_tree.h b/Nef_3/include/CGAL/Nef_3/K3_tree.h index ab760dc1e85..77afbf5e629 100644 --- a/Nef_3/include/CGAL/Nef_3/K3_tree.h +++ b/Nef_3/include/CGAL/Nef_3/K3_tree.h @@ -193,8 +193,8 @@ private: Node_handle right_node; Plane_3 splitting_plane; Vertex_list vertex_list; - Halffacet_list facet_list; Halfedge_list edge_list; + Halffacet_list facet_list; }; typedef boost::container::deque Node_range; diff --git a/Nef_3/include/CGAL/Nef_3/SNC_point_locator.h b/Nef_3/include/CGAL/Nef_3/SNC_point_locator.h index d63e4065436..cd645313149 100644 --- a/Nef_3/include/CGAL/Nef_3/SNC_point_locator.h +++ b/Nef_3/include/CGAL/Nef_3/SNC_point_locator.h @@ -328,8 +328,8 @@ public: case is_vertex_: return make_object(v_res); case is_edge_: return make_object(e_res); case is_facet_: return make_object(f_res); + case is_none_ : return Object_handle();; } - return Object_handle(); } virtual Object_handle locate( const Point_3& p) const { From 168ae33f73f750c0265a1803ba79f8ffad0e036a Mon Sep 17 00:00:00 2001 From: Giles Bathgate Date: Wed, 13 Apr 2022 17:36:12 +0100 Subject: [PATCH 014/107] Remove extraneous semicolon, initialize solution enum. --- Nef_3/include/CGAL/Nef_3/SNC_point_locator.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Nef_3/include/CGAL/Nef_3/SNC_point_locator.h b/Nef_3/include/CGAL/Nef_3/SNC_point_locator.h index cd645313149..5db4ce863da 100644 --- a/Nef_3/include/CGAL/Nef_3/SNC_point_locator.h +++ b/Nef_3/include/CGAL/Nef_3/SNC_point_locator.h @@ -328,7 +328,7 @@ public: case is_vertex_: return make_object(v_res); case is_edge_: return make_object(e_res); case is_facet_: return make_object(f_res); - case is_none_ : return Object_handle();; + case is_none_ : return Object_handle(); } } @@ -371,7 +371,7 @@ public: CGAL_assertion( initialized); _CGAL_NEF_TRACEN( "locate "<locate_node_containing(p); typename Vertex_list::const_iterator vi = n->vertices_begin(); From 36f22609480ac4eb4c15e4f605aa11127b1e9f55 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Thu, 14 Apr 2022 08:36:36 +0100 Subject: [PATCH 015/107] Move return() out of the switch to avoid warning --- Nef_3/include/CGAL/Nef_3/SNC_point_locator.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Nef_3/include/CGAL/Nef_3/SNC_point_locator.h b/Nef_3/include/CGAL/Nef_3/SNC_point_locator.h index 5db4ce863da..62005d1123a 100644 --- a/Nef_3/include/CGAL/Nef_3/SNC_point_locator.h +++ b/Nef_3/include/CGAL/Nef_3/SNC_point_locator.h @@ -328,8 +328,9 @@ public: case is_vertex_: return make_object(v_res); case is_edge_: return make_object(e_res); case is_facet_: return make_object(f_res); - case is_none_ : return Object_handle(); + case is_none_ : break; } + return Object_handle(); } virtual Object_handle locate( const Point_3& p) const { From b692e59abdd19c0acfa2711801d3086b6a70e797 Mon Sep 17 00:00:00 2001 From: Sven Oesau Date: Fri, 6 May 2022 12:20:11 +0200 Subject: [PATCH 016/107] Moved parameters from compute method to class template. --- .../optimal_rotation/optimal_rotation_polar_eigen.cpp | 4 ++-- .../optimal_rotation/optimal_rotation_svd_eigen.cpp | 4 ++-- .../CGAL/Deformation_Eigen_closest_rotation_traits_3.h | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Surface_mesh_deformation/benchmark/Surface_mesh_deformation/optimal_rotation/optimal_rotation_polar_eigen.cpp b/Surface_mesh_deformation/benchmark/Surface_mesh_deformation/optimal_rotation/optimal_rotation_polar_eigen.cpp index 6000307464a..eacaf0fb4b0 100644 --- a/Surface_mesh_deformation/benchmark/Surface_mesh_deformation/optimal_rotation/optimal_rotation_polar_eigen.cpp +++ b/Surface_mesh_deformation/benchmark/Surface_mesh_deformation/optimal_rotation/optimal_rotation_polar_eigen.cpp @@ -56,8 +56,8 @@ void polar_eigen(const Mat& A, Mat& R, bool& SVD) { // The computation of the eigenvalues might have diverged. // Fallback to an accurate SVD based decomposiiton method. - Eigen::JacobiSVD svd; - svd.compute(A, Eigen::ComputeFullU | Eigen::ComputeFullV ); + Eigen::JacobiSVD svd; + svd.compute(A); const Mat& u = svd.matrixU(); const Mat& v = svd.matrixV(); const Vec& w = svd.singularValues(); R = u*v.transpose(); SVD = true; diff --git a/Surface_mesh_deformation/benchmark/Surface_mesh_deformation/optimal_rotation/optimal_rotation_svd_eigen.cpp b/Surface_mesh_deformation/benchmark/Surface_mesh_deformation/optimal_rotation/optimal_rotation_svd_eigen.cpp index ba6e332f2bf..8d72811fcf7 100644 --- a/Surface_mesh_deformation/benchmark/Surface_mesh_deformation/optimal_rotation/optimal_rotation_svd_eigen.cpp +++ b/Surface_mesh_deformation/benchmark/Surface_mesh_deformation/optimal_rotation/optimal_rotation_svd_eigen.cpp @@ -20,7 +20,7 @@ int main() { } int ite = 200000; - Eigen::JacobiSVD svd; + Eigen::JacobiSVD svd; Eigen::Matrix3d u, v, cov, r; Eigen::Vector3d w; @@ -44,7 +44,7 @@ int main() { for (int i = 0; i < ite; i++) { - svd.compute( cov, Eigen::ComputeFullU | Eigen::ComputeFullV ); + svd.compute( cov ); u = svd.matrixU(); v = svd.matrixV(); w = svd.singularValues(); r = v*u.transpose(); } diff --git a/Surface_mesh_deformation/include/CGAL/Deformation_Eigen_closest_rotation_traits_3.h b/Surface_mesh_deformation/include/CGAL/Deformation_Eigen_closest_rotation_traits_3.h index 59b2fc45b98..c5a3b8a4948 100644 --- a/Surface_mesh_deformation/include/CGAL/Deformation_Eigen_closest_rotation_traits_3.h +++ b/Surface_mesh_deformation/include/CGAL/Deformation_Eigen_closest_rotation_traits_3.h @@ -80,8 +80,8 @@ public: /// Computes the closest rotation to `m` and places it into `R` void compute_close_rotation(const Matrix& m, Matrix& R) { - Eigen::JacobiSVD solver; - solver.compute( m, Eigen::ComputeFullU | Eigen::ComputeFullV ); + Eigen::JacobiSVD solver; + solver.compute( m ); const Matrix& u = solver.matrixU(); const Matrix& v = solver.matrixV(); R = v * u.transpose(); From 9ade574b1adc30c762a8988537f0d680d6f9e869 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Thu, 12 May 2022 12:13:08 +0200 Subject: [PATCH 017/107] Add devicePixelRatio() to Camera --- GraphicsView/include/CGAL/Qt/camera.h | 4 +++- GraphicsView/include/CGAL/Qt/camera_impl.h | 3 ++- GraphicsView/include/CGAL/Qt/qglviewer_impl.h | 4 ++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/GraphicsView/include/CGAL/Qt/camera.h b/GraphicsView/include/CGAL/Qt/camera.h index bda76bafb05..70f7c8edd8e 100644 --- a/GraphicsView/include/CGAL/Qt/camera.h +++ b/GraphicsView/include/CGAL/Qt/camera.h @@ -199,6 +199,7 @@ public: CGAL::QGLViewer's window dimensions when the Camera is attached to a CGAL::QGLViewer. See also QOpenGLWidget::height() */ int screenHeight() const { return screenHeight_; } + qreal devicePixelRatio() const { return devicePixelRatio_; } void getViewport(GLint viewport[4]) const; qreal pixelGLRatio(const Vec &position) const; @@ -279,7 +280,7 @@ public Q_SLOTS: setScreenWidthAndHeight(int(100.0 * aspect), 100); } - void setScreenWidthAndHeight(int width, int height); + void setScreenWidthAndHeight(int width, int height, qreal devicePixelRatio = 1.0); /*! Sets the zNearCoefficient() value. */ void setZNearCoefficient(qreal coef) { zNearCoef_ = coef; @@ -444,6 +445,7 @@ private: // C a m e r a p a r a m e t e r s int screenWidth_, screenHeight_; // size of the window, in pixels + qreal devicePixelRatio_; qreal fieldOfView_; // in radians Vec sceneCenter_; qreal sceneRadius_; // OpenGL units diff --git a/GraphicsView/include/CGAL/Qt/camera_impl.h b/GraphicsView/include/CGAL/Qt/camera_impl.h index 672e5d91c23..a963e13574d 100644 --- a/GraphicsView/include/CGAL/Qt/camera_impl.h +++ b/GraphicsView/include/CGAL/Qt/camera_impl.h @@ -160,10 +160,11 @@ frustrum coherence. If your Camera is used without a CGAL::QGLViewer (offscreen rendering, shadow maps), use setAspectRatio() instead to define the projection matrix. */ CGAL_INLINE_FUNCTION -void Camera::setScreenWidthAndHeight(int width, int height) { +void Camera::setScreenWidthAndHeight(int width, int height, qreal devicePixelRatio) { // Prevent negative and zero dimensions that would cause divisions by zero. screenWidth_ = width > 0 ? width : 1; screenHeight_ = height > 0 ? height : 1; + devicePixelRatio_ = devicePixelRatio; projectionMatrixIsUpToDate_ = false; } diff --git a/GraphicsView/include/CGAL/Qt/qglviewer_impl.h b/GraphicsView/include/CGAL/Qt/qglviewer_impl.h index 70fdfdd9a15..87c3b4e3a61 100644 --- a/GraphicsView/include/CGAL/Qt/qglviewer_impl.h +++ b/GraphicsView/include/CGAL/Qt/qglviewer_impl.h @@ -807,7 +807,7 @@ void CGAL::QGLViewer::setCamera(qglviewer::Camera *const camera) { camera->setSceneRadius(sceneRadius()); camera->setSceneCenter(sceneCenter()); - camera->setScreenWidthAndHeight(width(), height()); + camera->setScreenWidthAndHeight(width(), height(), devicePixelRatio()); // Disconnect current camera from this viewer. disconnect(this->camera()->frame(), SIGNAL(manipulated()), this, @@ -2369,7 +2369,7 @@ CGAL_INLINE_FUNCTION void CGAL::QGLViewer::resizeGL(int width, int height) { QOpenGLWidget::resizeGL(width, height); glViewport(0, 0, GLint(width), GLint(height)); - camera()->setScreenWidthAndHeight(this->width(), this->height()); + camera()->setScreenWidthAndHeight(this->width(), this->height(), this->devicePixelRatio()); } ////////////////////////////////////////////////////////////////////////// From 225e3c221735c65d56b43738f3260218c9f0721b Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Thu, 12 May 2022 12:39:21 +0200 Subject: [PATCH 018/107] Add a function read_depth_under_pixel The function takes care of HiDPI screen, using `devicePixelRatio()`. --- GraphicsView/include/CGAL/Qt/camera.h | 11 +++++++++++ GraphicsView/include/CGAL/Qt/camera_impl.h | 3 +-- Polyhedron/demo/Polyhedron/Scene.cpp | 6 +++--- Polyhedron/demo/Polyhedron/Scene_group_item.cpp | 2 +- Triangulation_3/demo/Triangulation_3/Viewer.cpp | 12 ++++++------ 5 files changed, 22 insertions(+), 12 deletions(-) diff --git a/GraphicsView/include/CGAL/Qt/camera.h b/GraphicsView/include/CGAL/Qt/camera.h index 70f7c8edd8e..cb16a02fb94 100644 --- a/GraphicsView/include/CGAL/Qt/camera.h +++ b/GraphicsView/include/CGAL/Qt/camera.h @@ -18,6 +18,7 @@ #include #include #include +#include namespace CGAL{ class QGLViewer; @@ -469,6 +470,16 @@ private: KeyFrameInterpolator *interpolationKfi_; }; +inline float read_depth_under_pixel(const QPoint &pixel, QOpenGLFunctions *p, + const Camera *camera) { + float depth = 2.0f; + const auto pixel_ratio = camera->devicePixelRatio(); + p->glReadPixels(pixel.x() * pixel_ratio, + (camera->screenHeight() - 1 - pixel.y()) * pixel_ratio, 1, 1, + GL_DEPTH_COMPONENT, GL_FLOAT, &depth); + return depth; +} + } // namespace qglviewer } //CGAL #endif // QGLVIEWER_CAMERA_H diff --git a/GraphicsView/include/CGAL/Qt/camera_impl.h b/GraphicsView/include/CGAL/Qt/camera_impl.h index a963e13574d..6005f48e5e4 100644 --- a/GraphicsView/include/CGAL/Qt/camera_impl.h +++ b/GraphicsView/include/CGAL/Qt/camera_impl.h @@ -885,8 +885,7 @@ Vec Camera::pointUnderPixel(const QPoint &pixel, bool &found) const { // Qt uses upper corner for its origin while GL uses the lower corner. if(auto p = dynamic_cast(parent())) { - p->glReadPixels(pixel.x(), screenHeight() - 1 - pixel.y(), 1, 1, - GL_DEPTH_COMPONENT, GL_FLOAT, &depth); + depth = read_depth_under_pixel(pixel, p, this); } found = depth < 1.0; Vec point(pixel.x(), pixel.y(), depth); diff --git a/Polyhedron/demo/Polyhedron/Scene.cpp b/Polyhedron/demo/Polyhedron/Scene.cpp index 484369f361b..065d3f9e8d8 100644 --- a/Polyhedron/demo/Polyhedron/Scene.cpp +++ b/Polyhedron/demo/Polyhedron/Scene.cpp @@ -564,7 +564,7 @@ void Scene::renderScene(const QList &items, // read depth buffer at pick location; float depth = 1.0; - viewer->glReadPixels(picked_pixel.x(),viewer->camera()->screenHeight()-1-picked_pixel.y(),1,1,GL_DEPTH_COMPONENT, GL_FLOAT, &depth); + depth = read_depth_under_pixel(picked_pixel, viewer, viewer->camera()); if (depth != 1.0) { //add object to list of picked objects; @@ -634,7 +634,7 @@ void Scene::renderWireScene(const QList &items, // read depth buffer at pick location; float depth = 1.0; - viewer->glReadPixels(picked_pixel.x(),viewer->camera()->screenHeight()-1-picked_pixel.y(),1,1,GL_DEPTH_COMPONENT, GL_FLOAT, &depth); + depth = read_depth_under_pixel(picked_pixel, viewer, viewer->camera()); if (depth != 1.0) { //add object to list of picked objects; @@ -676,7 +676,7 @@ void Scene::renderPointScene(const QList &items, if(item.renderingMode() == Points && with_names) { // read depth buffer at pick location; float depth = 1.0; - viewer->glReadPixels(picked_pixel.x(),viewer->camera()->screenHeight()-1-picked_pixel.y(),1,1,GL_DEPTH_COMPONENT, GL_FLOAT, &depth); + depth = read_depth_under_pixel(picked_pixel, viewer, viewer->camera()); if (depth != 1.0) { //add object to list of picked objects; diff --git a/Polyhedron/demo/Polyhedron/Scene_group_item.cpp b/Polyhedron/demo/Polyhedron/Scene_group_item.cpp index 29e0685ec51..b064cf4573f 100644 --- a/Polyhedron/demo/Polyhedron/Scene_group_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_group_item.cpp @@ -211,7 +211,7 @@ void Scene_group_item::renderChildren(Viewer_interface *viewer, if(with_names) { // read depth buffer at pick location; float depth = 1.0; - viewer->glReadPixels(picked_pixel.x(),viewer->camera()->screenHeight()-1-picked_pixel.y(),1,1,GL_DEPTH_COMPONENT, GL_FLOAT, &depth); + depth = read_depth_under_pixel(picked_pixel, viewer, viewer->camera()); if (depth != 1.0) { //add object to list of picked objects; diff --git a/Triangulation_3/demo/Triangulation_3/Viewer.cpp b/Triangulation_3/demo/Triangulation_3/Viewer.cpp index 62937f5a5bc..8aa6f1baddb 100644 --- a/Triangulation_3/demo/Triangulation_3/Viewer.cpp +++ b/Triangulation_3/demo/Triangulation_3/Viewer.cpp @@ -1696,9 +1696,9 @@ void Viewer::drawWithNames() rendering_program.release(); //read depth and store in map - GLfloat depth = 1.0f; - glReadPixels(picking_pos.x(),camera()->screenHeight()-1-picking_pos.y(),1,1,GL_DEPTH_COMPONENT, GL_FLOAT, &depth); - if (depth != 1.0) + GLfloat depth = 2.0f; + depth = read_depth_under_pixel(picking_pos, this, this->camera()); + if (depth < 2.0f) { picked_IDs[depth] = i; } @@ -1740,9 +1740,9 @@ void Viewer::drawWithNames() rendering_program.release(); //read depth and store in map - GLfloat depth = 1.0f; - glReadPixels(picking_pos.x(),camera()->screenHeight()-1-picking_pos.y(),1,1,GL_DEPTH_COMPONENT, GL_FLOAT, &depth); - if (depth != 1.0) + GLfloat depth = 2.0f; + depth = read_depth_under_pixel(picking_pos, this, this->camera()); + if (depth < 2.0f) { picked_IDs[depth] = -1; } From 9211f1768f38a39ef6b1ad1dd020c6dafc8a33f2 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Thu, 12 May 2022 14:15:01 +0200 Subject: [PATCH 019/107] Add a generic read_pixel for other pixel readings --- GraphicsView/include/CGAL/Qt/camera.h | 28 ++++++++++++++++--- .../Plugins/Mesh_3/Io_image_plugin.cpp | 6 +--- .../Plugins/PCA/Scene_edit_box_item.cpp | 7 +---- .../demo/Polyhedron/Scene_spheres_item.cpp | 8 +----- 4 files changed, 27 insertions(+), 22 deletions(-) diff --git a/GraphicsView/include/CGAL/Qt/camera.h b/GraphicsView/include/CGAL/Qt/camera.h index cb16a02fb94..8b4ed1d2e00 100644 --- a/GraphicsView/include/CGAL/Qt/camera.h +++ b/GraphicsView/include/CGAL/Qt/camera.h @@ -470,13 +470,33 @@ private: KeyFrameInterpolator *interpolationKfi_; }; -inline float read_depth_under_pixel(const QPoint &pixel, QOpenGLFunctions *p, - const Camera *camera) { - float depth = 2.0f; +inline void read_pixel(const QPoint &pixel, QOpenGLFunctions *p, + const Camera *camera, GLenum format, GLenum type, + GLvoid *pixel_data) { const auto pixel_ratio = camera->devicePixelRatio(); p->glReadPixels(pixel.x() * pixel_ratio, (camera->screenHeight() - 1 - pixel.y()) * pixel_ratio, 1, 1, - GL_DEPTH_COMPONENT, GL_FLOAT, &depth); + format, type, pixel_data); +} + +inline auto read_pixel_as_float_rgb(const QPoint &pixel, QOpenGLFunctions *p, + const Camera *camera) { + std::array res; + read_pixel(pixel, p, camera, GL_RGB, GL_FLOAT, res.data()); + return res; +} + +inline auto read_pixel_as_ubyte_rgba(const QPoint &pixel, QOpenGLFunctions *p, + const Camera *camera) { + std::array res; + read_pixel(pixel, p, camera, GL_RGBA, GL_UNSIGNED_BYTE, res.data()); + return res; +} + +inline float read_depth_under_pixel(const QPoint &pixel, QOpenGLFunctions *p, + const Camera *camera) { + float depth = 2.0f; + read_pixel(pixel, p, camera, GL_DEPTH_COMPONENT, GL_FLOAT, &depth); return depth; } diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Io_image_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Io_image_plugin.cpp index 428a0b2611e..72ef02c7c4c 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Io_image_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Io_image_plugin.cpp @@ -116,11 +116,7 @@ private: boost::optional fc; Viewer_interface* viewer; void getPixel(const QPoint& e) { - float data[3]; - int vp[4]; - viewer->glGetIntegerv(GL_VIEWPORT, vp); - viewer->glReadPixels(e.x(), vp[3] - e.y(), 1, 1, GL_RGB, GL_FLOAT, data); - + const auto data = read_pixel_as_float_rgb(e, viewer, viewer->camera()); if(fc) { Q_EMIT x(QString::number((*fc)(data[0]), 'f', 6 )); } else if(ic) { diff --git a/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp index f4ceff2c056..0013271d9d6 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp @@ -1049,11 +1049,7 @@ void Scene_edit_box_item_priv::picking(int& type, int& id, Viewer_interface *vie viewer->setBackgroundColor(::Qt::white); draw_picking(viewer); - int rowLength = deviceWidth * 4; // data asked in RGBA,so 4 bytes. - const static int dataLength = rowLength * deviceHeight; - GLubyte* buffer = new GLubyte[dataLength]; - // Qt uses upper corner for its origin while GL uses the lower corner. - viewer->glReadPixels(picked_pixel.x(), deviceHeight-1-picked_pixel.y(), 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffer); + const auto buffer = read_pixel_as_ubyte_rgba(picked_pixel, viewer, viewer->camera()); //decode ID and pick (don't forget the case nothing is picked if(!(buffer[0]==buffer[1] && buffer[1]==buffer[2])) { @@ -1080,7 +1076,6 @@ void Scene_edit_box_item_priv::picking(int& type, int& id, Viewer_interface *vie } } } - delete[] buffer; viewer->setBackgroundColor(bgColor); fbo->release(); delete fbo; diff --git a/Polyhedron/demo/Polyhedron/Scene_spheres_item.cpp b/Polyhedron/demo/Polyhedron/Scene_spheres_item.cpp index 836b4641636..fac56fbda9b 100644 --- a/Polyhedron/demo/Polyhedron/Scene_spheres_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_spheres_item.cpp @@ -187,8 +187,6 @@ void Scene_spheres_item::draw(Viewer_interface *viewer) const setBuffersFilled(true); setBuffersInit(viewer, true); } - int deviceWidth = viewer->camera()->screenWidth(); - int deviceHeight = viewer->camera()->screenHeight(); if(d->has_plane) { QVector4D cp = cgal_plane_to_vector4d(d->plane); @@ -207,12 +205,8 @@ void Scene_spheres_item::draw(Viewer_interface *viewer) const } if(d->pickable && (d->spheres.size() > 1 && viewer->inDrawWithNames())) { - int rowLength = deviceWidth * 4; // data asked in RGBA,so 4 bytes. - const static int dataLength = rowLength * deviceHeight; - GLubyte* buffer = new GLubyte[dataLength]; - // Qt uses upper corner for its origin while GL uses the lower corner. QPoint picking_target = viewer->mapFromGlobal(QCursor::pos()); - viewer->glReadPixels(picking_target.x(), deviceHeight-1-picking_target.y(), 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffer); + const auto buffer = read_pixel_as_ubyte_rgba(picking_target, viewer, viewer->camera()); int ID = (buffer[0] + buffer[1] * 256 +buffer[2] * 256*256) ; if(buffer[0]*buffer[1]*buffer[2] < 255*255*255) { From a98b548ba85b8efa0e4cbb697f1d1e6a6d344687 Mon Sep 17 00:00:00 2001 From: Sven Oesau Date: Thu, 12 May 2022 16:03:53 +0200 Subject: [PATCH 020/107] Using EIGEN_VERSION_AT_LEAST(3,4,90) to use new Eigen::JacobiSVD interface from eigen3 version 3.4.90 and newer --- Solver_interface/include/CGAL/Eigen_svd.h | 6 +++++- .../optimal_rotation_polar_eigen.cpp | 9 +++++++-- .../optimal_rotation_svd_eigen.cpp | 14 +++++++++++++- .../Deformation_Eigen_closest_rotation_traits_3.h | 7 ++++++- 4 files changed, 31 insertions(+), 5 deletions(-) diff --git a/Solver_interface/include/CGAL/Eigen_svd.h b/Solver_interface/include/CGAL/Eigen_svd.h index 0841976072a..276812001b8 100644 --- a/Solver_interface/include/CGAL/Eigen_svd.h +++ b/Solver_interface/include/CGAL/Eigen_svd.h @@ -51,7 +51,11 @@ public: /// \return the condition number of \f$ M\f$ static FT solve(const Matrix& M, Vector& B) { - Eigen::JacobiSVD jacobiSvd(M.eigen_object(),::Eigen::ComputeThinU | ::Eigen::ComputeThinV); +#if EIGEN_VERSION_AT_LEAST(3,4,90) + Eigen::JacobiSVD jacobiSvd(M.eigen_object()); +#else + Eigen::JacobiSVD jacobiSvd(M.eigen_object(), ::Eigen::ComputeThinU | ::Eigen::ComputeThinV); +#endif B.eigen_object()=jacobiSvd.solve(Vector::EigenType(B.eigen_object())); return jacobiSvd.singularValues().array().abs().maxCoeff() / jacobiSvd.singularValues().array().abs().minCoeff(); diff --git a/Surface_mesh_deformation/benchmark/Surface_mesh_deformation/optimal_rotation/optimal_rotation_polar_eigen.cpp b/Surface_mesh_deformation/benchmark/Surface_mesh_deformation/optimal_rotation/optimal_rotation_polar_eigen.cpp index eacaf0fb4b0..562bcb90e3c 100644 --- a/Surface_mesh_deformation/benchmark/Surface_mesh_deformation/optimal_rotation/optimal_rotation_polar_eigen.cpp +++ b/Surface_mesh_deformation/benchmark/Surface_mesh_deformation/optimal_rotation/optimal_rotation_polar_eigen.cpp @@ -55,9 +55,14 @@ void polar_eigen(const Mat& A, Mat& R, bool& SVD) if(fetestexcept(FE_UNDERFLOW) || eig.eigenvalues()(0)/eig.eigenvalues()(2)/100.0 svd; + // Fallback to an accurate SVD based decomposition method. +#if EIGEN_VERSION_AT_LEAST(3,4,90) + Eigen::JacobiSVD svd; svd.compute(A); +#else + Eigen::JacobiSVD svd; + svd.compute(A, Eigen::ComputeFullU | Eigen::ComputeFullV); +#endif const Mat& u = svd.matrixU(); const Mat& v = svd.matrixV(); const Vec& w = svd.singularValues(); R = u*v.transpose(); SVD = true; diff --git a/Surface_mesh_deformation/benchmark/Surface_mesh_deformation/optimal_rotation/optimal_rotation_svd_eigen.cpp b/Surface_mesh_deformation/benchmark/Surface_mesh_deformation/optimal_rotation/optimal_rotation_svd_eigen.cpp index 8d72811fcf7..573e5e7bea5 100644 --- a/Surface_mesh_deformation/benchmark/Surface_mesh_deformation/optimal_rotation/optimal_rotation_svd_eigen.cpp +++ b/Surface_mesh_deformation/benchmark/Surface_mesh_deformation/optimal_rotation/optimal_rotation_svd_eigen.cpp @@ -20,6 +20,13 @@ int main() { } int ite = 200000; + +#if EIGEN_VERSION_AT_LEAST(3,4,90) + Eigen::JacobiSVD svd; +#else + Eigen::JacobiSVD svd; +#endif + Eigen::JacobiSVD svd; Eigen::Matrix3d u, v, cov, r; Eigen::Vector3d w; @@ -44,7 +51,12 @@ int main() { for (int i = 0; i < ite; i++) { - svd.compute( cov ); +#if EIGEN_VERSION_AT_LEAST(3,4,90) + svd.compute(cov); +#else + svd.compute(cov, Eigen::ComputeFullU | Eigen::ComputeFullV); +#endif + u = svd.matrixU(); v = svd.matrixV(); w = svd.singularValues(); r = v*u.transpose(); } diff --git a/Surface_mesh_deformation/include/CGAL/Deformation_Eigen_closest_rotation_traits_3.h b/Surface_mesh_deformation/include/CGAL/Deformation_Eigen_closest_rotation_traits_3.h index c5a3b8a4948..98c938b5fbc 100644 --- a/Surface_mesh_deformation/include/CGAL/Deformation_Eigen_closest_rotation_traits_3.h +++ b/Surface_mesh_deformation/include/CGAL/Deformation_Eigen_closest_rotation_traits_3.h @@ -80,8 +80,13 @@ public: /// Computes the closest rotation to `m` and places it into `R` void compute_close_rotation(const Matrix& m, Matrix& R) { +#if EIGEN_VERSION_AT_LEAST(3,4,90) Eigen::JacobiSVD solver; - solver.compute( m ); + solver.compute(m); +#else + Eigen::JacobiSVD solver; + solver.compute(m, Eigen::ComputeFullU | Eigen::ComputeFullV); +#endif const Matrix& u = solver.matrixU(); const Matrix& v = solver.matrixV(); R = v * u.transpose(); From 2795a6374c60d0381253bc6d07f7c83d376bb03a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 12 May 2022 16:19:28 +0200 Subject: [PATCH 021/107] add an example to simplify a mesh in parallel --- .../CMakeLists.txt | 13 ++ .../collapse_small_edges_in_parallel.cpp | 157 ++++++++++++++++++ 2 files changed, 170 insertions(+) create mode 100644 Surface_mesh_simplification/examples/Surface_mesh_simplification/collapse_small_edges_in_parallel.cpp diff --git a/Surface_mesh_simplification/examples/Surface_mesh_simplification/CMakeLists.txt b/Surface_mesh_simplification/examples/Surface_mesh_simplification/CMakeLists.txt index 2f0a61cc06e..e26d9e72d0a 100644 --- a/Surface_mesh_simplification/examples/Surface_mesh_simplification/CMakeLists.txt +++ b/Surface_mesh_simplification/examples/Surface_mesh_simplification/CMakeLists.txt @@ -51,3 +51,16 @@ if(OpenMesh_FOUND) create_single_source_cgal_program("edge_collapse_OpenMesh.cpp") target_link_libraries(edge_collapse_OpenMesh PRIVATE ${OPENMESH_LIBRARIES}) endif() + +find_package(METIS) +include(CGAL_METIS_support) + +find_package(TBB) +include(CGAL_TBB_support) + +if(TARGET CGAL::TBB_support AND TARGET CGAL::METIS_support) + create_single_source_cgal_program("collapse_small_edges_in_parallel.cpp") + target_link_libraries(collapse_small_edges_in_parallel PUBLIC CGAL::TBB_support CGAL::METIS_support) +else() + message(STATUS "collapse_small_edges_in_parallel, which use the METIS and TBB libraries will not be compiled.") +endif() diff --git a/Surface_mesh_simplification/examples/Surface_mesh_simplification/collapse_small_edges_in_parallel.cpp b/Surface_mesh_simplification/examples/Surface_mesh_simplification/collapse_small_edges_in_parallel.cpp new file mode 100644 index 00000000000..17eebbe0314 --- /dev/null +++ b/Surface_mesh_simplification/examples/Surface_mesh_simplification/collapse_small_edges_in_parallel.cpp @@ -0,0 +1,157 @@ +#include +#include + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include + +#include +#include + + +typedef CGAL::Simple_cartesian Kernel; + +typedef Kernel::Point_3 Point_3; +typedef CGAL::Surface_mesh Triangle_mesh; + + +namespace SMS = CGAL::Surface_mesh_simplification; +namespace PMP = CGAL::Polygon_mesh_processing; + +struct Border_is_constrained_edge_map{ + const Triangle_mesh& sm; + typedef Triangle_mesh::Edge_index key_type; + typedef bool value_type; + typedef value_type reference; + typedef boost::readable_property_map_tag category; + Border_is_constrained_edge_map(const Triangle_mesh& sm) + : sm(sm) + {} + friend bool get(Border_is_constrained_edge_map m, const key_type& edge) { + return CGAL::is_border(edge, m.sm); + } +}; + +struct Simplify +{ + Triangle_mesh* tm_ptr; + double edge_length; + + Simplify() + :tm_ptr(NULL), edge_length(0) + {} + + Simplify(Triangle_mesh& tm, double edge_length) + : tm_ptr(&tm), edge_length(edge_length) + {} + + void operator()() const + { + + SMS::Edge_length_cost cost; + SMS::Edge_length_stop_predicate stop(edge_length); + Border_is_constrained_edge_map eicm(*tm_ptr); + SMS::Constrained_placement, + Border_is_constrained_edge_map > placement(eicm); + + SMS::edge_collapse(*tm_ptr, stop, + CGAL::parameters::edge_is_constrained_map(eicm) + .get_placement(placement) + .get_cost(cost)); + } +}; + +int main(int argc, char** argv) +{ + typedef boost::graph_traits::face_descriptor face_descriptor; + + std::ifstream in((argc>1) ? std::string(argv[1]) : CGAL::data_file_path("meshes/elephant.off")); + double edge_length = (argc>2) ? std::atof(argv[2]) : 0.02; + int number_of_parts = (argc>3) ? std::atoi(argv[3]) : 8; + + Triangle_mesh tm; + in >> tm; + + std::cerr << "Input: #V = "<< num_vertices(tm) << " #E = "<< num_edges(tm) + << " #F = " << num_faces(tm) << std::endl; + + CGAL::Real_timer t; + t.start(); + + // Partition ID map + Triangle_mesh::Property_map fpmap + = tm.add_property_map("f:partition").first; + + // Set some custom options for METIS + idx_t options[METIS_NOPTIONS]; + METIS_SetDefaultOptions(options); + options[METIS_OPTION_CONTIG] = 1; // need to have contiguous subdomains + options[METIS_OPTION_UFACTOR] = 1; + + CGAL::METIS::partition_dual_graph(tm, number_of_parts, CGAL::parameters::METIS_options(&options) + // .vertex_index_map(get(boost::vertex_index,tm)) + .face_partition_id_map(fpmap)); + + SMS::LindstromTurk_placement placement; + SMS::Edge_length_cost cost; + SMS::Edge_length_stop_predicate stop(edge_length); + + CGAL::Face_filtered_graph fg(tm); + std::vector meshes(number_of_parts); + for (int i=0; i< number_of_parts; ++i) + { + fg.set_selected_faces(i, fpmap); + CGAL::copy_face_graph(fg, meshes[i]); + } + + tbb::task_group tasks; + for(int id=0; id Date: Fri, 13 May 2022 18:09:08 +0200 Subject: [PATCH 022/107] Redirect and readability - correcting permanent redirect - improve readability --- .../Developer_manual/Chapter_namespaces.txt | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/Documentation/doc/Documentation/Developer_manual/Chapter_namespaces.txt b/Documentation/doc/Documentation/Developer_manual/Chapter_namespaces.txt index 17f8a076b34..819075ba39c 100644 --- a/Documentation/doc/Documentation/Developer_manual/Chapter_namespaces.txt +++ b/Documentation/doc/Documentation/Developer_manual/Chapter_namespaces.txt @@ -63,14 +63,13 @@ class Some_further_class_local_to_Package; According to the resolutions of the following issues in the forthcoming \cpp-standard ( - 225, - 226 - 229. + 225, + 226 and + 229 ): -Unless otherwise specified, no global or non-member function in the standard library +\"Unless otherwise specified, no global or non-member function in the standard library shall use a function from another namespace which is found through argument-dependent -name lookup -, the namespace `CGAL::NTS` does not need to be used anymore +name lookup\", the namespace `CGAL::NTS` does not need to be used anymore (currently `CGAL_NTS` macro boils down to `CGAL::`). \section Developer_manualRequirementsandrecommendations_1 Requirements and recommendations From d3b2201e7aa8e0a7f6bd51a5f310957a0144f9b6 Mon Sep 17 00:00:00 2001 From: albert-github Date: Sun, 15 May 2022 13:34:18 +0200 Subject: [PATCH 023/107] Arrangement_on_surface_2: unknown attribute compact specified The `
    ` tag has no attribute `compact`. - only the HTML tag `` has the `compact` attribute according to https://www.w3schools.com/tags/att_menu_compact.asp but it is not supported in any major browser. - according to https://www.geeksforgeeks.org/html-ol-compact-attribute/ the `
      ` tag can have a `compact` attribute but it is not supported by any any major browser. --- .../doc/Arrangement_on_surface_2/Arrangement_on_surface_2.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/Arrangement_on_surface_2.txt b/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/Arrangement_on_surface_2.txt index 903dcb16903..029b95fa637 100644 --- a/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/Arrangement_on_surface_2.txt +++ b/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/Arrangement_on_surface_2.txt @@ -6241,7 +6241,7 @@ face, respectively, \f$v_b\f$, \f$e_b\f$, and \f$f_b\f$ denote input blue features, and \f$v\f$, \f$e\f$, and \f$f\f$ denote output features. -
        +
        1. A new vertex \f$v\f$ is induced by coinciding vertices \f$v_r\f$ and \f$v_b\f$.
        2. From 5bc8c089a0d6aca41eab21aecada83958d408b7f Mon Sep 17 00:00:00 2001 From: albert-github Date: Mon, 16 May 2022 12:11:40 +0200 Subject: [PATCH 024/107] Redirect and readability From review: - replace `` by `
          - remove `,` --- .../Documentation/Developer_manual/Chapter_namespaces.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Documentation/doc/Documentation/Developer_manual/Chapter_namespaces.txt b/Documentation/doc/Documentation/Developer_manual/Chapter_namespaces.txt index 819075ba39c..f2241888167 100644 --- a/Documentation/doc/Documentation/Developer_manual/Chapter_namespaces.txt +++ b/Documentation/doc/Documentation/Developer_manual/Chapter_namespaces.txt @@ -67,9 +67,10 @@ According to the resolutions of the following issues in the forthcoming 226 and 229 ): -\"Unless otherwise specified, no global or non-member function in the standard library +
          Unless otherwise specified, no global or non-member function in the standard library shall use a function from another namespace which is found through argument-dependent -name lookup\", the namespace `CGAL::NTS` does not need to be used anymore +name lookup
          +the namespace `CGAL::NTS` does not need to be used anymore (currently `CGAL_NTS` macro boils down to `CGAL::`). \section Developer_manualRequirementsandrecommendations_1 Requirements and recommendations From 213da3115fed35b7a88e22ff4321df1fbe5d22ab Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Mon, 16 May 2022 16:20:13 +0200 Subject: [PATCH 025/107] Fix the display of the pivot point --- GraphicsView/include/CGAL/Qt/qglviewer_impl.h | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/GraphicsView/include/CGAL/Qt/qglviewer_impl.h b/GraphicsView/include/CGAL/Qt/qglviewer_impl.h index 87c3b4e3a61..07eb161909e 100644 --- a/GraphicsView/include/CGAL/Qt/qglviewer_impl.h +++ b/GraphicsView/include/CGAL/Qt/qglviewer_impl.h @@ -1147,7 +1147,9 @@ void CGAL::QGLViewer::beginSelection(const QPoint &point) { makeCurrent(); glEnable(GL_SCISSOR_TEST); - glScissor(point.x(), camera()->screenHeight()-1-point.y(), 1, 1); + glScissor(point.x() * devicePixelRatio(), + (camera()->screenHeight() - point.y()) * devicePixelRatio() - 1, 1, + 1); } /*! This method is called by select() after scene elements were drawn by @@ -3187,10 +3189,11 @@ void CGAL::QGLViewer::drawVisualHints() { mvpMatrix.ortho(-1,1,-1,1,-1,1); size=30*devicePixelRatio(); rendering_program.setUniformValue("mvp_matrix", mvpMatrix); - glViewport(GLint((camera()->projectedCoordinatesOf(camera()->pivotPoint()).x-size/2)*devicePixelRatio()), - GLint((height() - camera()->projectedCoordinatesOf(camera()->pivotPoint()).y-size/2)*devicePixelRatio()), size, size); - glScissor (GLint((camera()->projectedCoordinatesOf(camera()->pivotPoint()).x-size/2)*devicePixelRatio()), - GLint((height() - camera()->projectedCoordinatesOf(camera()->pivotPoint()).y-size/2)*devicePixelRatio()), size, size); + const auto point_2d = camera()->projectedCoordinatesOf(camera()->pivotPoint()); + glViewport(GLint(point_2d.x*devicePixelRatio()-size/2), + GLint((height() - point_2d.y)*devicePixelRatio()-size/2), size, size); + glScissor (GLint(point_2d.x*devicePixelRatio()-size/2), + GLint((height() - point_2d.y)*devicePixelRatio()-size/2), size, size); rendering_program.setUniformValue("color", QColor(::Qt::black)); glDisable(GL_DEPTH_TEST); glDrawArrays(GL_LINES, 0, static_cast(4)); From b32619fedd9b2ef43c60ff05e305f1cdb389ccd6 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Mon, 16 May 2022 17:12:00 +0200 Subject: [PATCH 026/107] Fix the picking --- GraphicsView/include/CGAL/Qt/camera.h | 2 +- Polyhedron/demo/Polyhedron/Scene.cpp | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/GraphicsView/include/CGAL/Qt/camera.h b/GraphicsView/include/CGAL/Qt/camera.h index 8b4ed1d2e00..08f76d4eb0b 100644 --- a/GraphicsView/include/CGAL/Qt/camera.h +++ b/GraphicsView/include/CGAL/Qt/camera.h @@ -475,7 +475,7 @@ inline void read_pixel(const QPoint &pixel, QOpenGLFunctions *p, GLvoid *pixel_data) { const auto pixel_ratio = camera->devicePixelRatio(); p->glReadPixels(pixel.x() * pixel_ratio, - (camera->screenHeight() - 1 - pixel.y()) * pixel_ratio, 1, 1, + (camera->screenHeight() - pixel.y()) * pixel_ratio - 1, 1, 1, format, type, pixel_data); } diff --git a/Polyhedron/demo/Polyhedron/Scene.cpp b/Polyhedron/demo/Polyhedron/Scene.cpp index 065d3f9e8d8..f7b5846dc51 100644 --- a/Polyhedron/demo/Polyhedron/Scene.cpp +++ b/Polyhedron/demo/Polyhedron/Scene.cpp @@ -563,9 +563,8 @@ void Scene::renderScene(const QList &items, if(with_names) { // read depth buffer at pick location; - float depth = 1.0; - depth = read_depth_under_pixel(picked_pixel, viewer, viewer->camera()); - if (depth != 1.0) + float depth = read_depth_under_pixel(picked_pixel, viewer, viewer->camera()); + if (depth < 2.0) { //add object to list of picked objects; picked_item_IDs[depth] = index; From 4968d218b55793cb8f1f3093c14de8fe636daa94 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Tue, 17 May 2022 10:31:07 +0100 Subject: [PATCH 027/107] Fix doxygen warnings --- .../include/CGAL/Poisson_reconstruction_function.h | 6 ++---- .../include/CGAL/Reconstruction_triangulation_3.h | 10 +++++----- .../include/CGAL/poisson_refine_triangulation.h | 14 +++++++------- Polyhedron/include/CGAL/Polyhedron_3.h | 4 ++-- .../CGAL/IO/output_surface_facets_to_polyhedron.h | 12 ++++++------ 5 files changed, 22 insertions(+), 24 deletions(-) diff --git a/Poisson_surface_reconstruction_3/include/CGAL/Poisson_reconstruction_function.h b/Poisson_surface_reconstruction_3/include/CGAL/Poisson_reconstruction_function.h index f6852710264..cb190bbe135 100644 --- a/Poisson_surface_reconstruction_3/include/CGAL/Poisson_reconstruction_function.h +++ b/Poisson_surface_reconstruction_3/include/CGAL/Poisson_reconstruction_function.h @@ -763,8 +763,7 @@ private: /// Poisson reconstruction. /// Returns false on error. /// - /// @commentheading Template parameters: - /// @param SparseLinearAlgebraTraits_d Symmetric definite positive sparse linear solver. + /// @tparam SparseLinearAlgebraTraits_d Symmetric definite positive sparse linear solver. template bool solve_poisson( SparseLinearAlgebraTraits_d solver, ///< sparse linear solver @@ -1203,8 +1202,7 @@ private: /// Assemble vi's row of the linear system A*X=B /// - /// @commentheading Template parameters: - /// @param SparseLinearAlgebraTraits_d Symmetric definite positive sparse linear solver. + /// @tparam SparseLinearAlgebraTraits_d Symmetric definite positive sparse linear solver. template void assemble_poisson_row(typename SparseLinearAlgebraTraits_d::Matrix& A, Vertex_handle vi, diff --git a/Poisson_surface_reconstruction_3/include/CGAL/Reconstruction_triangulation_3.h b/Poisson_surface_reconstruction_3/include/CGAL/Reconstruction_triangulation_3.h index 9ab7e018b68..7dd6a245aa3 100644 --- a/Poisson_surface_reconstruction_3/include/CGAL/Reconstruction_triangulation_3.h +++ b/Poisson_surface_reconstruction_3/include/CGAL/Reconstruction_triangulation_3.h @@ -348,12 +348,12 @@ public: /// Insert the [first, beyond) range of points in the triangulation using a spatial sort. /// Default type is INPUT. /// - /// @commentheading Template Parameters: - /// @param InputIterator iterator over input points. - /// @param PointPMap is a model of `ReadablePropertyMap` with a value_type = Point_3. + /// *Template Parameters:* + /// @tparam InputIterator iterator over input points. + /// @tparam PointPMap is a model of `ReadablePropertyMap` with a value_type = Point_3. /// It can be omitted if InputIterator value_type is convertible to Point_3. - /// @param NormalPMap is a model of `ReadablePropertyMap` with a value_type = Vector_3. - /// + /// @tparam NormalPMap is a model of `ReadablePropertyMap` with a value_type = Vector_3. + /// @tparam Visitor the visitor type /// @return the number of inserted points. // This variant requires all parameters. diff --git a/Poisson_surface_reconstruction_3/include/CGAL/poisson_refine_triangulation.h b/Poisson_surface_reconstruction_3/include/CGAL/poisson_refine_triangulation.h index 9d5d3a8c031..379c69c8413 100644 --- a/Poisson_surface_reconstruction_3/include/CGAL/poisson_refine_triangulation.h +++ b/Poisson_surface_reconstruction_3/include/CGAL/poisson_refine_triangulation.h @@ -180,17 +180,17 @@ public: /// bad means badly shaped or too big). /// @return the number of vertices inserted. /// -/// @commentheading Preconditions: +/// *Preconditions:* /// - Tr must use a geometric traits with robust circumcenter computation. /// - convergence is guaranteed if radius_edge_ratio_bound >= 1.0. /// -/// @commentheading Template Parameters: -/// @param Tr 3D Delaunay triangulation. -/// @param Surface Sphere_3 or Iso_cuboid_3. -/// @param Sizing_field A sizing field functor type -/// @param Second_sizing_field A sizing field functor type +/// *Template Parameters* +/// @tparam Tr 3D Delaunay triangulation. +/// @tparam Surface Sphere_3 or Iso_cuboid_3. +/// @tparam Sizing_field A sizing field functor type +/// @tparam Second_sizing_field A sizing field functor type /// -/// @commentheading Sizing fields +/// *Sizing fields* /// - The first sizing field is the real sizing field that is targeted by /// the refinement process. It may be costly to use. /// - The second sizing field is supposed to be a sizing field that is less diff --git a/Polyhedron/include/CGAL/Polyhedron_3.h b/Polyhedron/include/CGAL/Polyhedron_3.h index b948f2e6dcb..5ee6901bc7c 100644 --- a/Polyhedron/include/CGAL/Polyhedron_3.h +++ b/Polyhedron/include/CGAL/Polyhedron_3.h @@ -1448,10 +1448,10 @@ public: /// Erases the small connected components and the isolated vertices. /// - /// @commentheading Preconditions: + /// *Preconditions:* /// supports vertices, halfedges, and removal operation. /// - /// @commentheading Template Parameters: + /// *Parameters* /// @param nb_components_to_keep the number of large connected components to keep. /// /// @return the number of connected components erased (ignoring isolated vertices). diff --git a/Surface_mesher/include/CGAL/IO/output_surface_facets_to_polyhedron.h b/Surface_mesher/include/CGAL/IO/output_surface_facets_to_polyhedron.h index a1b9fade7d7..08935e04503 100644 --- a/Surface_mesher/include/CGAL/IO/output_surface_facets_to_polyhedron.h +++ b/Surface_mesher/include/CGAL/IO/output_surface_facets_to_polyhedron.h @@ -23,17 +23,17 @@ namespace CGAL { -/// \deprecated Gets reconstructed surface out of a SurfaceMeshComplex_2InTriangulation_3 object. +/// \deprecated Gets reconstructed surface out of a `SurfaceMeshComplex_2InTriangulation_3` object. /// /// This variant exports the surface as a polyhedron. /// It requires the surface to be manifold. For this purpose, -/// you may call make_surface_mesh() with Manifold_tag or Manifold_with_boundary_tag parameter. +/// you may call `make_surface_mesh()` with `Manifold_tag` or `Manifold_with_boundary_tag` parameter. /// -/// @commentheading Template Parameters: -/// @param SurfaceMeshComplex_2InTriangulation_3 model of the SurfaceMeshComplex_2InTriangulation_3 concept. -/// @param Polyhedron an instance of CGAL::Polyhedron_3. +/// *Template Parameters:* +/// @tparam SurfaceMeshComplex_2InTriangulation_3 model of the `SurfaceMeshComplex_2InTriangulation_3` concept. +/// @tparam Polyhedron an instance of `CGAL::Polyhedron_3`. /// -/// @return true if the surface is manifold and orientable. +/// @return `true` if the surface is manifold and orientable. template CGAL_DEPRECATED_MSG( From 191e99adc8c55941cc8c034fb49e5ebad3e35053 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Tue, 17 May 2022 10:41:26 +0100 Subject: [PATCH 028/107] Fix Orthtree --- Orthtree/include/CGAL/Orthtree.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Orthtree/include/CGAL/Orthtree.h b/Orthtree/include/CGAL/Orthtree.h index 5c8cc3ca021..b2931f84429 100644 --- a/Orthtree/include/CGAL/Orthtree.h +++ b/Orthtree/include/CGAL/Orthtree.h @@ -855,19 +855,19 @@ private: // functions : } /*! - \brief finds the `k` points within a specific radius that are nearest to `query`. + \brief finds the `k` points within a specific radius that are + nearest to the center of `query_sphere`. This function guarantees that there are no closer points than the ones returned, but it does not guarantee that it will return at least `k` points. For a query where the search radius encloses `k` or fewer points, all enclosed points will be returned. - If the search radius passed is too small, no points may be returned. + If the search radius is too small, no points may be returned. This function is useful when the user already knows how sparse the points are, or if they do not care about points that are too far away. Setting a small radius may have performance benefits. \tparam OutputIterator must be a model of `OutputIterator` that accepts points - \param search_point the location to find points near - \param search_radius_squared the size of the region to search within + \param query_sphere the region to search within \param k the number of points to find \param output the output iterator to add the found points to (in order of increasing distance) */ From 389ef8ea32bcfae70747251170e1e33a4e223986 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Tue, 17 May 2022 10:51:32 +0100 Subject: [PATCH 029/107] Fix Shape Approximantion (and almost AABB) --- AABB_tree/include/CGAL/AABB_tree.h | 4 ++-- .../include/CGAL/Variational_shape_approximation.h | 14 ++++++++------ 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/AABB_tree/include/CGAL/AABB_tree.h b/AABB_tree/include/CGAL/AABB_tree.h index 3985cf099db..6b78257447c 100644 --- a/AABB_tree/include/CGAL/AABB_tree.h +++ b/AABB_tree/include/CGAL/AABB_tree.h @@ -563,10 +563,10 @@ public: /** * @brief Builds the tree by recursive expansion. * @param first the first primitive to insert - * @param last the last primitive to insert + * @param beyond the last primitive to insert * @param range the number of primitive of the range * - * [first,last[ is the range of primitives to be added to the tree. + * [first,beyond[ is the range of primitives to be added to the tree. */ template void expand(Node& node, diff --git a/Surface_mesh_approximation/include/CGAL/Variational_shape_approximation.h b/Surface_mesh_approximation/include/CGAL/Variational_shape_approximation.h index 1a495cf99ce..566aec602d7 100644 --- a/Surface_mesh_approximation/include/CGAL/Variational_shape_approximation.h +++ b/Surface_mesh_approximation/include/CGAL/Variational_shape_approximation.h @@ -1209,7 +1209,8 @@ private: * @param t concurrency tag */ template - void fit(const ProxyWrapperIterator beg, const ProxyWrapperIterator end, const CGAL::Sequential_tag &) { + void fit(const ProxyWrapperIterator beg, const ProxyWrapperIterator end, const CGAL::Sequential_tag & t) { + CGAL_USE(t); std::vector > px_faces(m_proxies.size()); for(face_descriptor f : faces(*m_ptm)) px_faces[get(m_fproxy_map, f)].push_back(f); @@ -1230,7 +1231,8 @@ private: * @param t concurrency tag */ template - void fit(const ProxyWrapperIterator beg, const ProxyWrapperIterator end, const CGAL::Parallel_tag &) { + void fit(const ProxyWrapperIterator beg, const ProxyWrapperIterator end, const CGAL::Parallel_tag & t) { + CGAL_USE(t); std::vector > px_faces(m_proxies.size()); for(face_descriptor f : faces(*m_ptm)) px_faces[get(m_fproxy_map, f)].push_back(f); @@ -1334,7 +1336,7 @@ private: * 3. Update the proxy error. * 4. Update proxy map. * @pre current face proxy map is valid - * @param face_descriptor face + * @param f face * @param px_idx proxy index * @return fitted wrapped proxy */ @@ -1790,7 +1792,7 @@ private: /*! * @brief walks along the region boundary cycle to the first halfedge * pointing to a vertex associated with an anchor. - * @param[in/out] he_start region boundary halfedge + * @param[in,out] he_start region boundary halfedge */ void walk_to_first_anchor(halfedge_descriptor &he_start) { const halfedge_descriptor start_mark = he_start; @@ -1805,7 +1807,7 @@ private: /*! * @brief walks along the region boundary cycle to the next anchor * and records the path as a `Boundary_chord`. - * @param[in/out] he_start starting region boundary halfedge + * @param[in,out] he_start starting region boundary halfedge * pointing to a vertex associated with an anchor * @param[out] chord recorded path chord */ @@ -1818,7 +1820,7 @@ private: /*! * @brief walks to the next boundary cycle halfedge. - * @param[in/out] he_start region boundary halfedge + * @param[in,out] he_start region boundary halfedge */ void walk_to_next_border_halfedge(halfedge_descriptor &he_start) const { const std::size_t px_idx = get(m_fproxy_map, face(he_start, *m_ptm)); From 3ad94a739372a35624b2195b1aeb96ec0214c8cf Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Tue, 17 May 2022 12:04:52 +0100 Subject: [PATCH 030/107] Use \pre --- .../include/CGAL/poisson_refine_triangulation.h | 2 +- Polyhedron/include/CGAL/Polyhedron_3.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Poisson_surface_reconstruction_3/include/CGAL/poisson_refine_triangulation.h b/Poisson_surface_reconstruction_3/include/CGAL/poisson_refine_triangulation.h index 379c69c8413..14d91140b5e 100644 --- a/Poisson_surface_reconstruction_3/include/CGAL/poisson_refine_triangulation.h +++ b/Poisson_surface_reconstruction_3/include/CGAL/poisson_refine_triangulation.h @@ -180,7 +180,7 @@ public: /// bad means badly shaped or too big). /// @return the number of vertices inserted. /// -/// *Preconditions:* +/// \pre /// - Tr must use a geometric traits with robust circumcenter computation. /// - convergence is guaranteed if radius_edge_ratio_bound >= 1.0. /// diff --git a/Polyhedron/include/CGAL/Polyhedron_3.h b/Polyhedron/include/CGAL/Polyhedron_3.h index 5ee6901bc7c..6505e960139 100644 --- a/Polyhedron/include/CGAL/Polyhedron_3.h +++ b/Polyhedron/include/CGAL/Polyhedron_3.h @@ -1448,8 +1448,8 @@ public: /// Erases the small connected components and the isolated vertices. /// - /// *Preconditions:* - /// supports vertices, halfedges, and removal operation. + /// + /// \pre supports vertices, halfedges, and removal operation. /// /// *Parameters* /// @param nb_components_to_keep the number of large connected components to keep. From 93c19eeccf2aa196b080f327e7342d9727a4e8da Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Thu, 19 May 2022 14:27:17 +0200 Subject: [PATCH 031/107] Add testcase of issue #5055 --- .../test/Triangulation_2/issue_5055.cpp | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 Triangulation_2/test/Triangulation_2/issue_5055.cpp diff --git a/Triangulation_2/test/Triangulation_2/issue_5055.cpp b/Triangulation_2/test/Triangulation_2/issue_5055.cpp new file mode 100644 index 00000000000..0fc7ef56e9a --- /dev/null +++ b/Triangulation_2/test/Triangulation_2/issue_5055.cpp @@ -0,0 +1,80 @@ +#include +#include +#include +#include +#include + +typedef CGAL::Epick Kernel; +typedef Kernel::Point_3 Point3; + +typedef CGAL::Projection_traits_xy_3 TriangulationTraits; +typedef CGAL::Triangulation_vertex_base_2 VertexBase; +typedef CGAL::Constrained_triangulation_face_base_2 + FaceBase; +typedef CGAL::Triangulation_data_structure_2 + TriangulationData; +typedef CGAL::Constrained_Delaunay_triangulation_2< + TriangulationTraits, TriangulationData, CGAL::Exact_predicates_tag> + ConstrainedTriangulation; +typedef CGAL::Constrained_triangulation_plus_2 CDT; + +int main() { + CDT cdt; + cdt.insert_constraint( + Point3(7.22060172459952354984e+02, 5.46431441157868448499e+02, + 1.09259033203125000000e+02), + Point3(7.21605164369421572701e+02, 5.47286947218267187054e+02, + 1.09231933593750000000e+02)); + cdt.insert_constraint( + Point3(4.89054338074482529919e+02, 7.34795619763430352123e+01, + 1.19170654296875000000e+02), + Point3(4.88992971641138979066e+02, 7.06742393092105203323e+01, + 1.19197509765625000000e+02)); + cdt.insert_constraint( + Point3(6.58294921875000000000e+02, 4.94029296875000000000e+02, + 1.08803459167480468750e+02), + Point3(6.55601638506381050320e+02, 4.92704923416975930195e+02, + 1.08774169921875000000e+02)); + cdt.insert_constraint( + Point3(7.48077080682167661507e+02, 5.16511846264136920581e+02, + 1.09748291015625000000e+02), + Point3(7.46966796875000000000e+02, 5.16371093750000000000e+02, + 1.09758056640625000000e+02)); + cdt.insert_constraint( + Point3(5.59349064841414701732e+02, 4.42600717751872252848e+02, + 1.08587158203125000000e+02), + Point3(5.56660156250000000000e+02, 4.41277343750000000000e+02, + 1.08660644531250000000e+02)); + cdt.insert_constraint( + Point3(6.36340512288503987293e+02, 4.83223199100345823354e+02, + 1.08523681640625000000e+02), + Point3(6.36339843750000000000e+02, 4.83224609375000000000e+02, + 1.08523681640625000000e+02)); + cdt.insert_constraint( + Point3(5.72431981051620141443e+02, 4.62372208487347847949e+02, + 1.08266105651855468750e+02), + Point3(5.71998046875000000000e+02, 4.61550781250000000000e+02, + 1.08266105651855468750e+02)); + cdt.insert_constraint( + Point3(5.54615246238433428516e+02, 3.99093747119970316817e+02, + 1.08986572265625000000e+02), + Point3(5.53910156250000000000e+02, 3.96179687500000000000e+02, + 1.09051513671875000000e+02)); + cdt.insert_constraint( + Point3(6.29072265625000000000e+02, 4.77775390625000000000e+02, + 1.08448486328125000000e+02), + Point3(6.29071750798135099103e+02, 4.77776482510548703431e+02, + 1.08448486328125000000e+02)); + cdt.insert_constraint( + Point3(4.89089689771187522638e+02, 7.46450533344111875067e+01, + 1.19143554687500000000e+02), + Point3(4.89006004028320262478e+02, 7.14945312499999943157e+01, + 1.19197509765625000000e+02)); + cdt.insert_constraint( + Point3(4.89054338074482529919e+02, 7.34795619763430352123e+01, + 1.19170654296875000000e+02), + Point3(4.88992951403166102864e+02, 7.06733141447368495847e+01, + 1.19197509765625000000e+02)); + + return 0; +} From 35ec6c83ac09a852955d9a33959b0f0719222fe3 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Thu, 19 May 2022 14:38:35 +0200 Subject: [PATCH 032/107] Add CGAL include paths first --- .../cmake/modules/CGAL_SetupCGALDependencies.cmake | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Installation/cmake/modules/CGAL_SetupCGALDependencies.cmake b/Installation/cmake/modules/CGAL_SetupCGALDependencies.cmake index 59e846b89d2..ffddd0917c0 100644 --- a/Installation/cmake/modules/CGAL_SetupCGALDependencies.cmake +++ b/Installation/cmake/modules/CGAL_SetupCGALDependencies.cmake @@ -75,6 +75,13 @@ endif() # keyword. # function(CGAL_setup_CGAL_dependencies target) + foreach(dir ${CGAL_INCLUDE_DIRS}) + target_include_directories(${target} INTERFACE + $) + endforeach() + target_include_directories(${target} INTERFACE + $) + if(CGAL_DISABLE_GMP) target_compile_definitions(${target} INTERFACE CGAL_DISABLE_GMP=1) else() @@ -96,13 +103,6 @@ function(CGAL_setup_CGAL_dependencies target) use_CGAL_Boost_support(${target} INTERFACE) - foreach(dir ${CGAL_INCLUDE_DIRS}) - target_include_directories(${target} INTERFACE - $) - endforeach() - target_include_directories(${target} INTERFACE - $) - # Make CGAL depend on threads-support (for Epeck and Epeck_d) if(CGAL_HAS_NO_THREADS) target_compile_definitions(${target} INTERFACE CGAL_HAS_NO_THREADS) From b6b56e1ee1d9ac3a55903edb79b17f43070ee8ee Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Thu, 19 May 2022 15:18:03 +0200 Subject: [PATCH 033/107] updated crontab (automated commit) --- Maintenance/infrastructure/cgal.geometryfactory.com/crontab | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Maintenance/infrastructure/cgal.geometryfactory.com/crontab b/Maintenance/infrastructure/cgal.geometryfactory.com/crontab index 27a916856a1..139138c7c6d 100644 --- a/Maintenance/infrastructure/cgal.geometryfactory.com/crontab +++ b/Maintenance/infrastructure/cgal.geometryfactory.com/crontab @@ -19,7 +19,7 @@ LC_CTYPE=en_US.UTF-8 # The script also updates the manual tools. # "master" alone -0 21 * * Sun cd $HOME/CGAL/create_internal_release && /usr/bin/time scl enable rh-git29 -- $HOME/bin/create_release $HOME/CGAL/branches/master.git --do-it || echo ERROR +0 21 * * Sun cd $HOME/CGAL/create_internal_release && /usr/bin/time scl enable rh-git29 -- $HOME/bin/create_release $HOME/CGAL/branches/master.git --do-it --beta 1 || echo ERROR # "integration" 0 21 * * Mon,Tue,Wed,Thu cd $HOME/CGAL/create_internal_release && /usr/bin/time scl enable rh-git29 -- $HOME/bin/create_release $HOME/CGAL/branches/integration.git $HOME/CGAL/branches/empty-dir --do-it || echo ERROR # from branch 5.4 From 00ed010317f7b1dd743d576c53760ecdaa2df516 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Thu, 19 May 2022 16:48:29 +0200 Subject: [PATCH 034/107] Prepare CHANGES.html for 5.5-beta1 --- Installation/CHANGES.md | 56 +++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/Installation/CHANGES.md b/Installation/CHANGES.md index 07d95edbe5d..74c86d2e2bc 100644 --- a/Installation/CHANGES.md +++ b/Installation/CHANGES.md @@ -7,7 +7,7 @@ Release History Release date: June 2022 -### 3D Alpha Wrapping (new package) +### [3D Alpha Wrapping (new package)](https://doc.cgal.org/5.5/Manual/packages.html#PkgAlphaWrap3) - This component takes a 3D triangle mesh, soup, or point set as input, and generates a valid (watertight, intersection-free, and combinatorially 2-manifold) surface triangle mesh @@ -19,29 +19,26 @@ Release date: June 2022 to the input, respectively. Once combined, these parameters provide a means to trade fidelity to the input for complexity of the output. -### [Point Set Processing](https://doc.cgal.org/5.5/Manual/packages.html#PkgPointSetProcessing3) - -- A new optional named parameter, `min_points_per_cell` has been added to [`grid_simplify_point_set()`](https://doc.cgal.org/5.5/Point_set_processing_3/group__PkgPointSetProcessing3Algorithms.html#ga7757ef9b3900e42fde26f5a0ac56e20f). By adding a minimal number of points in a cell such that a point is retained, one can also filter out low density areas and outliers: in the case of densely sampled point clouds, this yields better results than using grid simplification and then outlier removal, while being very vast. The default value is `1` to keep the previous behavior as default. - -### [dD Spatial Searching](https://doc.cgal.org/5.5/Manual/packages.html#PkgSpatialSearchingD) - -- Added the member function `write_graphviz()` to the class `Kd_tree` that writes the tree in a stream in the [Graphviz](https://graphviz.org/) format. + See also the [announcement page](https://www.cgal.org/2022/05/18/alpha_wrap/). ### [3D Convex Hulls](https://doc.cgal.org/5.5/Manual/packages.html#PkgConvexHull3) -- Added an overload of the function `CGAL::convex_hull_3()`, which writes the result in an indexed triangle set. +- Added an [overload of the function `CGAL::convex_hull_3()`](https://doc.cgal.org/5.5/Convex_hull_3/group__PkgConvexHull3Functions.html#ga52fca4745c2ef0351063fbe66b035fd1), which writes the result in an indexed triangle set. -### Surface Mesh Simplification -- Introduced four variations of the Garland-Heckbert simplification algorithm based on the probabilistic approach of Trettner and Kobbelt (Fast and Robust QEF Minimization using Probabilistic Quadrics): `GarlandHeckbert_plane_policies`, `GarlandHeckbert_probabilistic_plane_policies`, `GarlandHeckbert_triangle_policies`, and `GarlandHeckbert_probabilistic_triangle_policies` -- The class `GarlandHeckbert_policies` has been deprecated, `GarlandHeckbert_plane_policies` replaces it. +### [2D Polygons](https://doc.cgal.org/5.5/Manual/packages.html#PkgPolygon2) -### [CGAL and the Boost Graph Library (BGL)](https://doc.cgal.org/5.5/Manual/packages.html#PkgBGL) +- Add vertex, edge, and hole ranges. +- The concept [`GeneralPolygonWithHoles_2`](https://doc.cgal.org/5.5/Polygon/classGeneralPolygonWithHoles__2.html) now requires the nested type `Polygon_2` instead of `General_polygon_2`. -- Added the function [`invert_selection()`](https://doc.cgal.org/5.5/BGL/structCGAL_1_1Face__filtered__graph.html#aa428541ebbdd35f9a6e9a3ffd60178df) in the class [`Face_filtered_graph`](https://doc.cgal.org/5.5/BGL/structCGAL_1_1Face__filtered__graph.html), which toggles the selected status of a graph: selected faces are deselected, and unselected faces are selected. +### [2D Regularized Boolean Set-Operations](https://doc.cgal.org/5.5/Manual/packages.html#PkgBooleanSetOperations2) +- The concept [`GeneralPolygonSetTraits_2`](https://doc.cgal.org/5.5/Boolean_set_operations_2/classGeneralPolygonSetTraits__2.html) now requires the nested type `Construct_polygon_with_holes_2` instead of `Construct_general_polygon_with_holes_2`. -### Combinatorial Maps +### [Combinatorial Maps](https://doc.cgal.org/5.5/Manual/packages.html#PkgCombinatorialMaps) -- Removed old code deprecated in CGAL 4.9 and 4.10 (global fonctions, and information associated with darts). +- Removed old code deprecated in CGAL 4.9 and 4.10 (global functions, and information associated with darts). + +### [2D Arrangements](https://doc.cgal.org/5.5/Manual/packages.html#PkgArrangementOnSurface2) +- Fixed the `intersect_2`, `compare_y_at_x_right`, and `compare_y_at_x_left` function objects of the traits class template [`Arr_geodesic_arc_on_sphere_traits_2`](https://doc.cgal.org/5.5/Arrangement_on_surface_2/classCGAL_1_1Arr__geodesic__arc__on__sphere__traits__2.html) that handles geodesic arcs on sphere and applied a small syntactical fix to the tracing traits. ### [Tetrahedral Mesh Generation](https://doc.cgal.org/5.5/Manual/packages.html#PkgMesh3) @@ -50,22 +47,27 @@ Release date: June 2022 as a post-processing step for the tetrahedral mesh generation. ### [Polygon Mesh Processing](https://doc.cgal.org/5.5/Manual/packages.html#PkgPolygonMeshProcessing) -- Added the function `CGAL::Polygon_mesh_processing::orient_triangle_soup_with_reference_triangle_soup()`, which enables re-orienting the faces of a triangle soup based on the orientation of the nearest face in a reference triangle soup. -- Added the function `CGAL::Polygon_mesh_processing::compatible_orientations()`, which enables to retrieve the (in)compatibility of orientations of faces from different connected components. -- Added the function `CGAL::Polygon_mesh_processing::tangential_relaxation()`, which applies an area-based tangential mesh smoothing to the vertices of a surface triangle mesh. -- Added the named parameter `visitor`to the function `triangulate_hole()`, which enables to track progress with callbacks. +- Added the function [`CGAL::Polygon_mesh_processing::orient_triangle_soup_with_reference_triangle_soup()`](https://doc.cgal.org/5.5/Polygon_mesh_processing/group__PMP__orientation__grp.html#ga855b1c55c201b91ab04eebd2811a87fd), which enables re-orienting the faces of a triangle soup based on the orientation of the nearest face in a reference triangle soup. +- Added the function [`CGAL::Polygon_mesh_processing::compatible_orientations()`](https://doc.cgal.org/5.5/Polygon_mesh_processing/group__PMP__orientation__grp.html#ga9ac9b9434084b64f3304df636c3178a3), which enables to retrieve the (in)compatibility of orientations of faces from different connected components. +- Added the function [`CGAL::Polygon_mesh_processing::tangential_relaxation()`](https://doc.cgal.org/5.5/Polygon_mesh_processing/group__PMP__meshing__grp.html#ga136c659162e5360354db5879db7431b4), which applies an area-based tangential mesh smoothing to the vertices of a surface triangle mesh. +- Added the named parameter `visitor` to the function [`triangulate_hole()`](https://doc.cgal.org/5.5/Polygon_mesh_processing/group__PMP__hole__filling__grp.html#gad2d3c43bce0ef90a16530478196d7f42), which enables to track progress with callbacks. - Added more functions in the [visitor of the corefinement based methods](https://doc.cgal.org/5.5/Polygon_mesh_processing/classPMPCorefinementVisitor.html) to track progress. -### [2D Polygons](https://doc.cgal.org/5.5/Manual/packages.html#PkgPolygon2) +### [Surface Mesh Simplification](https://doc.cgal.org/5.5/Manual/packages.html#PkgSurfaceMeshSimplification) +- Introduced four variations of the Garland-Heckbert simplification algorithm based on the probabilistic approach of Trettner and Kobbelt (Fast and Robust QEF Minimization using Probabilistic Quadrics): [`GarlandHeckbert_plane_policies`](https://doc.cgal.org/5.5/Surface_mesh_simplification/classCGAL_1_1Surface__mesh__simplification_1_1GarlandHeckbert__plane__policies.html), [`GarlandHeckbert_probabilistic_plane_policies`](https://doc.cgal.org/5.5/Surface_mesh_simplification/classCGAL_1_1Surface__mesh__simplification_1_1GarlandHeckbert__probabilistic__plane__policies.html), [`GarlandHeckbert_triangle_policies`](https://doc.cgal.org/5.5/Surface_mesh_simplification/classCGAL_1_1Surface__mesh__simplification_1_1GarlandHeckbert__triangle__policies.html), and [`GarlandHeckbert_probabilistic_triangle_policies`](https://doc.cgal.org/5.5/Surface_mesh_simplification/classCGAL_1_1Surface__mesh__simplification_1_1GarlandHeckbert__probabilistic__triangle__policies.html). +- The class `GarlandHeckbert_policies` has been deprecated, `GarlandHeckbert_plane_policies` replaces it. -- Add vertex, edge, and hole ranges. -- The concept `GeneralPolygonWithHoles_2` now requires the nested type `Polygon_2` instead of `General_polygon_2`. +### [Point Set Processing](https://doc.cgal.org/5.5/Manual/packages.html#PkgPointSetProcessing3) -### [2D Regularized Boolean Set-Operations](https://doc.cgal.org/5.5/Manual/packages.html#PkgBooleanSetOperations2) -- The concept `GeneralPolygonSetTraits_2` now requires the nested type `Construct_polygon_with_holes_2` instead of `Construct_general_polygon_with_holes_2`. +- A new optional named parameter, `min_points_per_cell` has been added to [`grid_simplify_point_set()`](https://doc.cgal.org/5.5/Point_set_processing_3/group__PkgPointSetProcessing3Algorithms.html#ga7757ef9b3900e42fde26f5a0ac56e20f). By adding a minimal number of points in a cell such that a point is retained, one can also filter out low density areas and outliers: in the case of densely sampled point clouds, this yields better results than using grid simplification and then outlier removal, while being very vast. The default value is `1` to keep the previous behavior as default. -### [2D Arrangements](https://doc.cgal.org/5.5/Manual/packages.html#PkgArrangementOnSurface2) -- Fixed the intersect_2, compare_y_at_x_right, and compare_y_at_x_left function objects of the traits class template that handles geodesic arcs on sphere and applied a small syntactical fix to the tracing traits. +### [dD Spatial Searching](https://doc.cgal.org/5.5/Manual/packages.html#PkgSpatialSearchingD) + +- Added the member function [`write_graphviz()`](https://doc.cgal.org/5.5/Spatial_searching/classCGAL_1_1Kd__tree.html#ac2851b5cafb8d5cce0dc5fb107c8f13f) to the class `Kd_tree` that writes the tree in a stream in the [Graphviz](https://graphviz.org/) format. + +### [CGAL and the Boost Graph Library (BGL)](https://doc.cgal.org/5.5/Manual/packages.html#PkgBGL) + +- Added the function [`invert_selection()`](https://doc.cgal.org/5.5/BGL/structCGAL_1_1Face__filtered__graph.html#aa428541ebbdd35f9a6e9a3ffd60178df) in the class [`Face_filtered_graph`](https://doc.cgal.org/5.5/BGL/structCGAL_1_1Face__filtered__graph.html), which toggles the selected status of a graph: selected faces are deselected, and unselected faces are selected. [Release 5.4](https://github.com/CGAL/cgal/releases/tag/v5.4) From 1cdf1ee26a1b2457282fc87150b0a8c6bf0be657 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Thu, 19 May 2022 16:50:57 +0200 Subject: [PATCH 035/107] Update menu_version.js --- Documentation/doc/resources/1.8.13/menu_version.js | 5 +++-- Documentation/doc/resources/1.8.14/menu_version.js | 5 +++-- Documentation/doc/resources/1.8.20/menu_version.js | 5 +++-- Documentation/doc/resources/1.8.4/menu_version.js | 5 +++-- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/Documentation/doc/resources/1.8.13/menu_version.js b/Documentation/doc/resources/1.8.13/menu_version.js index e8a424f40cd..903056a6cac 100644 --- a/Documentation/doc/resources/1.8.13/menu_version.js +++ b/Documentation/doc/resources/1.8.13/menu_version.js @@ -6,9 +6,10 @@ var current_version_local = 'master' var all_versions = [ 'master', + '5.5-beta1', 'latest', - '5.4', - '5.3.1', + '5.4.1', + '5.3.2', '5.2.4', '5.1.5', '5.0.4', diff --git a/Documentation/doc/resources/1.8.14/menu_version.js b/Documentation/doc/resources/1.8.14/menu_version.js index e8a424f40cd..903056a6cac 100644 --- a/Documentation/doc/resources/1.8.14/menu_version.js +++ b/Documentation/doc/resources/1.8.14/menu_version.js @@ -6,9 +6,10 @@ var current_version_local = 'master' var all_versions = [ 'master', + '5.5-beta1', 'latest', - '5.4', - '5.3.1', + '5.4.1', + '5.3.2', '5.2.4', '5.1.5', '5.0.4', diff --git a/Documentation/doc/resources/1.8.20/menu_version.js b/Documentation/doc/resources/1.8.20/menu_version.js index e8a424f40cd..903056a6cac 100644 --- a/Documentation/doc/resources/1.8.20/menu_version.js +++ b/Documentation/doc/resources/1.8.20/menu_version.js @@ -6,9 +6,10 @@ var current_version_local = 'master' var all_versions = [ 'master', + '5.5-beta1', 'latest', - '5.4', - '5.3.1', + '5.4.1', + '5.3.2', '5.2.4', '5.1.5', '5.0.4', diff --git a/Documentation/doc/resources/1.8.4/menu_version.js b/Documentation/doc/resources/1.8.4/menu_version.js index e8a424f40cd..903056a6cac 100644 --- a/Documentation/doc/resources/1.8.4/menu_version.js +++ b/Documentation/doc/resources/1.8.4/menu_version.js @@ -6,9 +6,10 @@ var current_version_local = 'master' var all_versions = [ 'master', + '5.5-beta1', 'latest', - '5.4', - '5.3.1', + '5.4.1', + '5.3.2', '5.2.4', '5.1.5', '5.0.4', From a47790f1d5bbfed8cf1e2fd5ab75ac32c61a2a19 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Thu, 19 May 2022 16:54:36 +0200 Subject: [PATCH 036/107] Version files for 5.5-beta1 --- Installation/include/CGAL/version.h | 4 ++-- Installation/lib/cmake/CGAL/CGALConfigVersion.cmake | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Installation/include/CGAL/version.h b/Installation/include/CGAL/version.h index 5283590d252..622e6e36cd2 100644 --- a/Installation/include/CGAL/version.h +++ b/Installation/include/CGAL/version.h @@ -17,10 +17,10 @@ #define CGAL_VERSION_H #ifndef SWIG -#define CGAL_VERSION 5.5-dev +#define CGAL_VERSION 5.5-beta1 #define CGAL_GIT_HASH abcdef #endif -#define CGAL_VERSION_NR 1050500900 +#define CGAL_VERSION_NR 1050500910 #define CGAL_SVN_REVISION 99999 #define CGAL_RELEASE_DATE 20220531 diff --git a/Installation/lib/cmake/CGAL/CGALConfigVersion.cmake b/Installation/lib/cmake/CGAL/CGALConfigVersion.cmake index 315ff61ca1a..4ca238e403e 100644 --- a/Installation/lib/cmake/CGAL/CGALConfigVersion.cmake +++ b/Installation/lib/cmake/CGAL/CGALConfigVersion.cmake @@ -2,7 +2,7 @@ set(CGAL_MAJOR_VERSION 5) set(CGAL_MINOR_VERSION 5) set(CGAL_BUGFIX_VERSION 0) include(${CMAKE_CURRENT_LIST_DIR}/CGALConfigBuildVersion.cmake) -set(CGAL_VERSION_PUBLIC_RELEASE_VERSION "5.5-dev") +set(CGAL_VERSION_PUBLIC_RELEASE_VERSION "5.5-beta1") set(CGAL_VERSION_PUBLIC_RELEASE_NAME "CGAL-${CGAL_VERSION_PUBLIC_RELEASE_VERSION}") if (CGAL_BUGFIX_VERSION AND CGAL_BUGFIX_VERSION GREATER 0) From e73e030dcaadd78aaee151f37b76feef17347d91 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Thu, 19 May 2022 17:20:18 +0200 Subject: [PATCH 037/107] Update minimal version of Eigen to 3.3.4 --- Documentation/doc/Documentation/Third_party.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/doc/Documentation/Third_party.txt b/Documentation/doc/Documentation/Third_party.txt index 6e25f350ae0..3131ae3caaa 100644 --- a/Documentation/doc/Documentation/Third_party.txt +++ b/Documentation/doc/Documentation/Third_party.txt @@ -12,7 +12,7 @@ supporting C++14 or later. | Operating System | Compiler | | :---------- | :--------------- | | Linux | \gnu `g++` 10.2.1 or later\cgalFootnote{\cgalFootnoteCode{http://gcc.gnu.org/}} | -| | `Clang` \cgalFootnote{\cgalFootnoteCode{http://clang.llvm.org/}} compiler version 13.0.0 | +| | `Clang` \cgalFootnote{\cgalFootnoteCode{http://clang.llvm.org/}} compiler version 13.0.1 | | \ms Windows | \gnu `g++` 10.2.1 or later\cgalFootnote{\cgalFootnoteCode{http://gcc.gnu.org/}} | | | \ms Visual `C++` 14.0, 15.9, 16.10, 17.0 (\visualstudio 2015, 2017, 2019, and 2022)\cgalFootnote{\cgalFootnoteCode{https://visualstudio.microsoft.com/}} | | MacOS X | \gnu `g++` 10.2.1 or later\cgalFootnote{\cgalFootnoteCode{http://gcc.gnu.org/}} | @@ -117,7 +117,7 @@ The exhaustive list of \qt5 components used in demos is: `qcollectiongenerator` (with `sqlite` driver plugin), and `Xml`. \subsection thirdpartyEigen Eigen -Version 3.1 or later +Version 3.3.4 or later \eigen is a `C++` template library for linear algebra. \eigen supports all matrix sizes, various matrix decomposition methods and sparse linear solvers. From 46d43e592b4167f2ff4772670475c1b947c9b090 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Fri, 20 May 2022 14:46:24 +0100 Subject: [PATCH 038/107] Use const& in demo instead of copying a polygon --- .../Polyline_simplification_2/Polyline_simplification_2.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Polyline_simplification_2/demo/Polyline_simplification_2/Polyline_simplification_2.cpp b/Polyline_simplification_2/demo/Polyline_simplification_2/Polyline_simplification_2.cpp index 987b924dcee..52bc9061b0c 100644 --- a/Polyline_simplification_2/demo/Polyline_simplification_2/Polyline_simplification_2.cpp +++ b/Polyline_simplification_2/demo/Polyline_simplification_2/Polyline_simplification_2.cpp @@ -397,7 +397,7 @@ void MainWindow::loadWKT(QString fileName) m_pct.insert_constraint(poly.begin(), poly.end()); } } - for(Polygon_with_holes_2 poly : polygons){ + for(const Polygon_with_holes_2& poly : polygons){ m_pct.insert_constraint(poly.outer_boundary().vertices_begin(), poly.outer_boundary().vertices_end()); for(Polygon_with_holes_2::Hole_const_iterator it = poly.holes_begin(); it != poly.holes_end(); ++it){ const Polygon_2& hole = *it; From ef0899445f0578bee0a13470bf75f20b13a95493 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Mon, 23 May 2022 11:16:11 +0100 Subject: [PATCH 039/107] Polyhedron_3: Fix saving a polyline as part of a scene --- Polyhedron/demo/Polyhedron/Plugins/IO/Polylines_io_plugin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/Polylines_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/Polylines_io_plugin.cpp index a405be72fe9..4063d2107ed 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/Polylines_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/Polylines_io_plugin.cpp @@ -62,7 +62,7 @@ public: } QString name() const override{ return "polylines_io_plugin"; } - QString nameFilters() const override{ return "Polylines files (*.polylines.txt *.cgal)"; } + QString nameFilters() const override{ return "Polylines files (*.polylines.txt);; CGAL Polylines files (*.cgal)"; } bool canLoad(QFileInfo fileinfo) const override; QList load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true) override; From ff16bec07166bd2c3cae65d21c39d98d689e2738 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Mon, 23 May 2022 16:52:17 +0200 Subject: [PATCH 040/107] clean up EXAMPLE_PATH --- Alpha_shapes_3/doc/Alpha_shapes_3/Doxyfile.in | 3 +-- BGL/doc/BGL/Doxyfile.in | 13 ++++++------- .../doc/Hyperbolic_triangulation_2/Doxyfile.in | 2 -- Mesh_3/doc/Mesh_3/Doxyfile.in | 2 +- Orthtree/doc/Orthtree/Doxyfile.in | 2 -- Periodic_3_mesh_3/doc/Periodic_3_mesh_3/Doxyfile.in | 1 - .../Doxyfile.in | 2 -- Polygon/doc/Polygon/Doxyfile.in | 3 +-- Stream_support/doc/Stream_support/Doxyfile.in | 1 - .../doc/Tetrahedral_remeshing/Doxyfile.in | 2 -- 10 files changed, 9 insertions(+), 22 deletions(-) diff --git a/Alpha_shapes_3/doc/Alpha_shapes_3/Doxyfile.in b/Alpha_shapes_3/doc/Alpha_shapes_3/Doxyfile.in index 6fe61e68211..76909d608fa 100644 --- a/Alpha_shapes_3/doc/Alpha_shapes_3/Doxyfile.in +++ b/Alpha_shapes_3/doc/Alpha_shapes_3/Doxyfile.in @@ -2,5 +2,4 @@ PROJECT_NAME = "CGAL ${CGAL_DOC_VERSION} - 3D Alpha Shapes" -EXAMPLE_PATH = ${CGAL_Alpha_shapes_2_EXAMPLE_DIR} \ - ${CGAL_Alpha_shapes_3_EXAMPLE_DIR} +EXAMPLE_PATH += ${CGAL_Alpha_shapes_2_EXAMPLE_DIR} diff --git a/BGL/doc/BGL/Doxyfile.in b/BGL/doc/BGL/Doxyfile.in index 970bf3ffa8b..4e5d35a91d2 100644 --- a/BGL/doc/BGL/Doxyfile.in +++ b/BGL/doc/BGL/Doxyfile.in @@ -21,13 +21,12 @@ INPUT += ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/Euler_operations.h \ ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/graph_traits_inheritance_macros.h -EXAMPLE_PATH = ${CGAL_Surface_mesh_skeletonization_EXAMPLE_DIR} \ - ${CGAL_Surface_mesh_segmentation_EXAMPLE_DIR} \ - ${CGAL_Polygon_mesh_processing_EXAMPLE_DIR} \ - ${CGAL_Surface_mesh_EXAMPLE_DIR} \ - ${CGAL_Property_map_EXAMPLE_DIR} \ - ${CGAL_Polyhedron_EXAMPLE_DIR} \ - ${CGAL_BGL_EXAMPLE_DIR} +EXAMPLE_PATH += ${CGAL_Surface_mesh_skeletonization_EXAMPLE_DIR} \ + ${CGAL_Surface_mesh_segmentation_EXAMPLE_DIR} \ + ${CGAL_Polygon_mesh_processing_EXAMPLE_DIR} \ + ${CGAL_Surface_mesh_EXAMPLE_DIR} \ + ${CGAL_Property_map_EXAMPLE_DIR} \ + ${CGAL_Polyhedron_EXAMPLE_DIR} ALIASES += "bgllink{1}=\1" diff --git a/Hyperbolic_triangulation_2/doc/Hyperbolic_triangulation_2/Doxyfile.in b/Hyperbolic_triangulation_2/doc/Hyperbolic_triangulation_2/Doxyfile.in index 8d17ef5c0b8..c97e9fc5008 100644 --- a/Hyperbolic_triangulation_2/doc/Hyperbolic_triangulation_2/Doxyfile.in +++ b/Hyperbolic_triangulation_2/doc/Hyperbolic_triangulation_2/Doxyfile.in @@ -2,8 +2,6 @@ EXTRACT_PRIVATE = NO -EXAMPLE_PATH = ${CGAL_PACKAGE_DIR}/examples - PROJECT_NAME = "CGAL ${CGAL_DOC_VERSION} - 2D Hyperbolic Delaunay Triangulations" HTML_EXTRA_STYLESHEET = ${CGAL_PACKAGE_DOC_DIR}/css/customstyle.css diff --git a/Mesh_3/doc/Mesh_3/Doxyfile.in b/Mesh_3/doc/Mesh_3/Doxyfile.in index 62ea73403e6..c5f22c38811 100644 --- a/Mesh_3/doc/Mesh_3/Doxyfile.in +++ b/Mesh_3/doc/Mesh_3/Doxyfile.in @@ -23,4 +23,4 @@ HTML_EXTRA_FILES = ${CGAL_PACKAGE_DOC_DIR}/fig/implicit_domain_3.jpg ${CGAL_PACKAGE_DOC_DIR}/fig/protection-complex.png \ ${CGAL_PACKAGE_DOC_DIR}/fig/no-protection-complex.png -EXAMPLE_PATH += ${CGAL_PACKAGE_INCLUDE_DIR} +EXAMPLE_PATH += ${CGAL_PACKAGE_INCLUDE_DIR} # non-documented headers are advertised diff --git a/Orthtree/doc/Orthtree/Doxyfile.in b/Orthtree/doc/Orthtree/Doxyfile.in index 49945a16c84..980e12e8f6e 100644 --- a/Orthtree/doc/Orthtree/Doxyfile.in +++ b/Orthtree/doc/Orthtree/Doxyfile.in @@ -5,5 +5,3 @@ PROJECT_NAME = "CGAL ${CGAL_DOC_VERSION} - Quadtrees, Octrees, and Orthtrees" EXTRACT_ALL = false HIDE_UNDOC_MEMBERS = true HIDE_UNDOC_CLASSES = true - -EXAMPLE_PATH = ${CGAL_PACKAGE_DIR}/examples diff --git a/Periodic_3_mesh_3/doc/Periodic_3_mesh_3/Doxyfile.in b/Periodic_3_mesh_3/doc/Periodic_3_mesh_3/Doxyfile.in index b4db01df482..d49050978bf 100644 --- a/Periodic_3_mesh_3/doc/Periodic_3_mesh_3/Doxyfile.in +++ b/Periodic_3_mesh_3/doc/Periodic_3_mesh_3/Doxyfile.in @@ -1,7 +1,6 @@ @INCLUDE = ${CGAL_DOC_PACKAGE_DEFAULTS} PROJECT_NAME = "CGAL ${CGAL_DOC_VERSION} - 3D Periodic Mesh Generation" -EXAMPLE_PATH += ${CGAL_PACKAGE_INCLUDE_DIR} EXTRACT_ALL = false HIDE_UNDOC_CLASSES = true WARN_IF_UNDOCUMENTED = false diff --git a/Periodic_4_hyperbolic_triangulation_2/doc/Periodic_4_hyperbolic_triangulation_2/Doxyfile.in b/Periodic_4_hyperbolic_triangulation_2/doc/Periodic_4_hyperbolic_triangulation_2/Doxyfile.in index b7edd8e9ac9..6de78d75066 100644 --- a/Periodic_4_hyperbolic_triangulation_2/doc/Periodic_4_hyperbolic_triangulation_2/Doxyfile.in +++ b/Periodic_4_hyperbolic_triangulation_2/doc/Periodic_4_hyperbolic_triangulation_2/Doxyfile.in @@ -1,7 +1,5 @@ @INCLUDE = ${CGAL_DOC_PACKAGE_DEFAULTS} -EXAMPLE_PATH = ${CGAL_PACKAGE_DIR}/examples - EXTRACT_ALL = YES EXTRACT_LOCAL_CLASSES = YES INHERIT_DOCS = YES diff --git a/Polygon/doc/Polygon/Doxyfile.in b/Polygon/doc/Polygon/Doxyfile.in index 8cfb32b528f..5b7caa6808a 100644 --- a/Polygon/doc/Polygon/Doxyfile.in +++ b/Polygon/doc/Polygon/Doxyfile.in @@ -1,8 +1,7 @@ @INCLUDE = ${CGAL_DOC_PACKAGE_DEFAULTS} PROJECT_NAME = "CGAL ${CGAL_DOC_VERSION} - 2D Polygons" -EXAMPLE_PATH = ${CGAL_PACKAGE_DIR}/examples \ - ${CGAL_Stream_support_EXAMPLE_DIR} +EXAMPLE_PATH += ${CGAL_Stream_support_EXAMPLE_DIR} EXTRACT_ALL = false HIDE_UNDOC_MEMBERS = true diff --git a/Stream_support/doc/Stream_support/Doxyfile.in b/Stream_support/doc/Stream_support/Doxyfile.in index f0c48c2e204..31fdc18aeef 100644 --- a/Stream_support/doc/Stream_support/Doxyfile.in +++ b/Stream_support/doc/Stream_support/Doxyfile.in @@ -1,7 +1,6 @@ @INCLUDE = ${CGAL_DOC_PACKAGE_DEFAULTS} PROJECT_NAME = "CGAL ${CGAL_DOC_VERSION} - IO Streams" -EXAMPLE_PATH = ${CGAL_PACKAGE_DIR}/examples EXTRACT_ALL = false HIDE_UNDOC_MEMBERS = true diff --git a/Tetrahedral_remeshing/doc/Tetrahedral_remeshing/Doxyfile.in b/Tetrahedral_remeshing/doc/Tetrahedral_remeshing/Doxyfile.in index 59dccb4ff04..a3841240c16 100644 --- a/Tetrahedral_remeshing/doc/Tetrahedral_remeshing/Doxyfile.in +++ b/Tetrahedral_remeshing/doc/Tetrahedral_remeshing/Doxyfile.in @@ -6,6 +6,4 @@ EXTRACT_ALL = false HIDE_UNDOC_CLASSES = true WARN_IF_UNDOCUMENTED = false -EXAMPLE_PATH += ${CGAL_Tetrahedral_remeshing_EXAMPLE_DIR} - EXCLUDE = ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/Tetrahedral_remeshing/internal From 7c0eb5bff34bf435960a861a671d91ddfcbfdf17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Mon, 23 May 2022 17:37:38 +0200 Subject: [PATCH 041/107] remove geometric test on default constructed objects --- HalfedgeDS/test/HalfedgeDS/test_hds_range_based_loops.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/HalfedgeDS/test/HalfedgeDS/test_hds_range_based_loops.cpp b/HalfedgeDS/test/HalfedgeDS/test_hds_range_based_loops.cpp index 893d5e40b0e..a58aac2c880 100644 --- a/HalfedgeDS/test/HalfedgeDS/test_hds_range_based_loops.cpp +++ b/HalfedgeDS/test/HalfedgeDS/test_hds_range_based_loops.cpp @@ -24,7 +24,6 @@ void test_vertex_handles( assert(hds_list.vertex_handles().size() == 1); for (auto vh : hds_list.vertex_handles()) { assert(vh == lit); - assert(vh->point() == lit->point()); assert(vh->halfedge() == lit->halfedge()); ++lit; } @@ -34,7 +33,6 @@ void test_vertex_handles( assert(hds_vector.vertex_handles().size() == 1); for (auto vh : hds_vector.vertex_handles()) { assert(vh == vit); - assert(vh->point() == vit->point()); assert(vh->halfedge() == vit->halfedge()); ++vit; } @@ -49,7 +47,6 @@ void test_const_vertex_handles( assert(hds_list.vertex_handles().size() == 1); for (const auto& vh : hds_list.vertex_handles()) { assert(vh == lit); - assert(vh->point() == lit->point()); assert(vh->halfedge() == lit->halfedge()); ++lit; } @@ -59,7 +56,6 @@ void test_const_vertex_handles( assert(hds_vector.vertex_handles().size() == 1); for (const auto& vh : hds_vector.vertex_handles()) { assert(vh == vit); - assert(vh->point() == vit->point()); assert(vh->halfedge() == vit->halfedge()); ++vit; } @@ -74,7 +70,6 @@ void test_face_handles( assert(hds_list.face_handles().size() == 2); for (auto fh : hds_list.face_handles()) { assert(fh == lit); - assert(fh->plane() == lit->plane()); assert(fh->halfedge() == lit->halfedge()); ++lit; } @@ -84,7 +79,6 @@ void test_face_handles( assert(hds_vector.face_handles().size() == 2); for (auto fh : hds_vector.face_handles()) { assert(fh == vit); - assert(fh->plane() == vit->plane()); assert(fh->halfedge() == vit->halfedge()); ++vit; } @@ -99,7 +93,6 @@ void test_const_face_handles( assert(hds_list.face_handles().size() == 2); for (const auto& fh : hds_list.face_handles()) { assert(fh == lit); - assert(fh->plane() == lit->plane()); assert(fh->halfedge() == lit->halfedge()); ++lit; } @@ -109,7 +102,6 @@ void test_const_face_handles( assert(hds_vector.face_handles().size() == 2); for (const auto& fh : hds_vector.face_handles()) { assert(fh == vit); - assert(fh->plane() == vit->plane()); assert(fh->halfedge() == vit->halfedge()); ++vit; } From 7a6b8755613ff918d05dc646c7de146510532797 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 9 Mar 2022 19:41:52 +0100 Subject: [PATCH 042/107] add snap_borders --- .../Plugins/PMP/Repair_polyhedron_plugin.cpp | 30 +++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Repair_polyhedron_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Repair_polyhedron_plugin.cpp index 0c7e1eba63e..e591584ecd9 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/Repair_polyhedron_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Repair_polyhedron_plugin.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include "ui_RemoveNeedlesDialog.h" #include @@ -53,6 +54,7 @@ public: actionAutorefine = new QAction(tr("Autorefine Mesh"), mw); actionAutorefineAndRMSelfIntersections = new QAction(tr("Autorefine and Remove Self-Intersections"), mw); actionRemoveNeedlesAndCaps = new QAction(tr("Remove Needles And Caps")); + actionSnapBorders = new QAction(tr("Snap Boundaries")); actionRemoveIsolatedVertices->setObjectName("actionRemoveIsolatedVertices"); actionRemoveDegenerateFaces->setObjectName("actionRemoveDegenerateFaces"); @@ -64,6 +66,7 @@ public: actionAutorefine->setObjectName("actionAutorefine"); actionAutorefineAndRMSelfIntersections->setObjectName("actionAutorefineAndRMSelfIntersections"); actionRemoveNeedlesAndCaps->setObjectName("actionRemoveNeedlesAndCaps"); + actionSnapBorders->setObjectName("actionSnapBorders"); actionRemoveDegenerateFaces->setProperty("subMenuName", "Polygon Mesh Processing/Repair/Experimental"); actionStitchCloseBorderHalfedges->setProperty("subMenuName", "Polygon Mesh Processing/Repair/Experimental"); @@ -74,7 +77,7 @@ public: actionMergeDuplicatedVerticesOnBoundaryCycles->setProperty("subMenuName", "Polygon Mesh Processing/Repair"); actionAutorefine->setProperty("subMenuName", "Polygon Mesh Processing/Repair/Experimental"); actionAutorefineAndRMSelfIntersections->setProperty("subMenuName", "Polygon Mesh Processing/Repair/Experimental"); - actionRemoveNeedlesAndCaps->setProperty("subMenuName", "Polygon Mesh Processing/Repair/Experimental"); + actionSnapBorders->setProperty("subMenuName", "Polygon Mesh Processing/Repair/Experimental"); autoConnectActions(); } @@ -90,7 +93,8 @@ public: << actionMergeDuplicatedVerticesOnBoundaryCycles << actionAutorefine << actionAutorefineAndRMSelfIntersections - << actionRemoveNeedlesAndCaps; + << actionRemoveNeedlesAndCaps + << actionSnapBorders; } bool applicable(QAction*) const @@ -128,6 +132,7 @@ public Q_SLOTS: void on_actionAutorefine_triggered(); void on_actionAutorefineAndRMSelfIntersections_triggered(); void on_actionRemoveNeedlesAndCaps_triggered(); + void on_actionSnapBorders_triggered(); private: QAction* actionRemoveIsolatedVertices; @@ -140,6 +145,7 @@ private: QAction* actionAutorefine; QAction* actionAutorefineAndRMSelfIntersections; QAction* actionRemoveNeedlesAndCaps; + QAction* actionSnapBorders; Messages_interface* messages; }; // end Polyhedron_demo_repair_polyhedron_plugin @@ -196,6 +202,26 @@ void Polyhedron_demo_repair_polyhedron_plugin::on_actionRemoveNeedlesAndCaps_tri sm_item->itemChanged(); } +void Polyhedron_demo_repair_polyhedron_plugin::on_actionSnapBorders_triggered() +{ + QCursor tmp_cursor(Qt::WaitCursor); + CGAL::Three::Three::CursorScopeGuard guard(tmp_cursor); + + const Scene_interface::Item_id index = scene->mainSelectionIndex(); + Scene_surface_mesh_item* sm_item = qobject_cast(scene->item(index)); + if(!sm_item) + { + return; + } + + // try to snap remaining boundaries + CGAL::Polygon_mesh_processing::experimental::snap_borders(*sm_item->face_graph()); + CGAL::Polygon_mesh_processing::stitch_borders(*sm_item->face_graph(), CGAL::parameters::do_simplify_border(true)); + + sm_item->invalidateOpenGLBuffers(); + sm_item->itemChanged(); +} + template void Polyhedron_demo_repair_polyhedron_plugin::on_actionRemoveDegenerateFaces_triggered(Scene_interface::Item_id index) { From 789f37e82cb3b18e2bab2a5fe289368636ecdd54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 10 Mar 2022 11:21:08 +0100 Subject: [PATCH 043/107] add merge_reversible_connected_components --- .../PMP/Polyhedron_stitching_plugin.cpp | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Polyhedron_stitching_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Polyhedron_stitching_plugin.cpp index 40fed3f5a24..a8aaeeef03f 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/Polyhedron_stitching_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Polyhedron_stitching_plugin.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -26,8 +27,9 @@ class Polyhedron_demo_polyhedron_stitching_plugin : QAction* actionDetectBorders; QAction* actionStitchBorders; QAction* actionStitchByCC; + QAction* actionMergeReversibleCCs; public: - QList actions() const { return QList() << actionDetectBorders << actionStitchBorders << actionStitchByCC; } + QList actions() const { return QList() << actionDetectBorders << actionStitchBorders << actionStitchByCC << actionMergeReversibleCCs; } void init(QMainWindow* mainWindow, CGAL::Three::Scene_interface* scene_interface, Messages_interface* /* m */) { scene = scene_interface; @@ -42,6 +44,10 @@ public: actionStitchByCC->setObjectName("actionStitchByCC"); actionStitchByCC->setProperty("subMenuName", "Polygon Mesh Processing/Repair"); + actionMergeReversibleCCs = new QAction(tr("Merge Reversible Connected Components"), mainWindow); + actionMergeReversibleCCs->setObjectName("actionMergeReversibleCCs"); + actionMergeReversibleCCs->setProperty("subMenuName", "Polygon Mesh Processing/Repair"); + autoConnectActions(); } @@ -63,10 +69,14 @@ public: template void on_actionStitchByCC_triggered(Scene_interface::Item_id index); + template + void on_actionMergeReversibleCCs_triggered(Scene_interface::Item_id index); + public Q_SLOTS: void on_actionDetectBorders_triggered(); void on_actionStitchBorders_triggered(); void on_actionStitchByCC_triggered(); + void on_actionMergeReversibleCCs_triggered(); }; // end Polyhedron_demo_polyhedron_stitching_plugin @@ -151,6 +161,18 @@ void Polyhedron_demo_polyhedron_stitching_plugin::on_actionStitchByCC_triggered( scene->itemChanged(item); } +template +void Polyhedron_demo_polyhedron_stitching_plugin::on_actionMergeReversibleCCs_triggered(Scene_interface::Item_id index) +{ + Item* item = + qobject_cast(scene->item(index)); + + if(!item) + return; + CGAL::Polygon_mesh_processing::merge_reversible_connected_components(*item->polyhedron()); + item->invalidateOpenGLBuffers(); + scene->itemChanged(item); +} void Polyhedron_demo_polyhedron_stitching_plugin::on_actionStitchByCC_triggered() { @@ -158,4 +180,11 @@ void Polyhedron_demo_polyhedron_stitching_plugin::on_actionStitchByCC_triggered( on_actionStitchByCC_triggered(index); } } + +void Polyhedron_demo_polyhedron_stitching_plugin::on_actionMergeReversibleCCs_triggered() +{ + Q_FOREACH(int index, scene->selectionIndices()){ + on_actionMergeReversibleCCs_triggered(index); + } +} #include "Polyhedron_stitching_plugin.moc" From 7c4b08e7aa4f2077550bae8e19473df8c74a1e93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Fri, 11 Mar 2022 10:08:38 +0100 Subject: [PATCH 044/107] orient if closed --- .../demo/Polyhedron/Plugins/PMP/Polyhedron_stitching_plugin.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Polyhedron_stitching_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Polyhedron_stitching_plugin.cpp index a8aaeeef03f..6716404c425 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/Polyhedron_stitching_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Polyhedron_stitching_plugin.cpp @@ -170,6 +170,8 @@ void Polyhedron_demo_polyhedron_stitching_plugin::on_actionMergeReversibleCCs_tr if(!item) return; CGAL::Polygon_mesh_processing::merge_reversible_connected_components(*item->polyhedron()); + if (CGAL::is_closed(*item->polyhedron())) + CGAL::Polygon_mesh_processing::orient(*item->polyhedron()); item->invalidateOpenGLBuffers(); scene->itemChanged(item); } From 38135b884f0b42910d04509e5493c3b9d7354c88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Fri, 11 Mar 2022 10:54:24 +0100 Subject: [PATCH 045/107] be more permissive with orient --- .../Polygon_mesh_processing/orientation.h | 19 ++++++++++++++----- .../PMP/Polyhedron_stitching_plugin.cpp | 3 +-- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h index 135d80edbcc..1a6d82f80fc 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h @@ -364,8 +364,9 @@ void reverse_face_orientations(const FaceRange& face_range, PolygonMesh& pmesh) /** * \ingroup PMP_orientation_grp -* -* makes each connected component of a closed triangulated surface mesh inward or outward oriented. +* makes each closed connected component of a triangulated surface mesh +* inward or outward oriented. If a connected component is not closed, +* the fact that its orientation is changed or not is not guaranteed. * * @tparam TriangleMesh a model of `FaceListGraph` and `MutableFaceGraph` * @tparam NamedParameters a sequence of \ref bgl_namedparameters @@ -418,7 +419,6 @@ void orient(TriangleMesh& tm, CGAL_precondition(is_triangle_mesh(tm)); CGAL_precondition(is_valid_polygon_mesh(tm)); - CGAL_precondition(is_closed(tm)); using parameters::choose_parameter; using parameters::get_parameter; @@ -464,8 +464,17 @@ void orient(TriangleMesh& tm, //orient ccs outward for(std::size_t id=0; idpolyhedron()); - if (CGAL::is_closed(*item->polyhedron())) - CGAL::Polygon_mesh_processing::orient(*item->polyhedron()); + CGAL::Polygon_mesh_processing::orient(*item->polyhedron()); item->invalidateOpenGLBuffers(); scene->itemChanged(item); } From ca2362629c37bb473ca6292df5e1437d00d9154c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Fri, 11 Mar 2022 14:28:18 +0100 Subject: [PATCH 046/107] get rid of the removed halfedges --- .../CGAL/Polygon_mesh_processing/internal/Snapping/snap.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Snapping/snap.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Snapping/snap.h index e127b84e8e5..4520e825de5 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Snapping/snap.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Snapping/snap.h @@ -151,13 +151,19 @@ void simplify_range(HalfedgeRange& halfedge_range, new_tolerance += CGAL::approximate_sqrt(CGAL::squared_distance(new_p, pt)); } + if (!CGAL::Euler::does_satisfy_link_condition(edge(h, tm), tm)) + continue; + const halfedge_descriptor opoh = opposite(prev(opposite(h, tm), tm), tm); + if (is_border(opoh, tm)) + edges_to_test.erase( opoh ); vertex_descriptor v = Euler::collapse_edge(edge(h, tm), tm); + put(vpm, v, new_p); put(tolerance_map, v, new_tolerance); if(get(range_halfedges, prev_h)) edges_to_test.insert(prev_h); - if(get(range_halfedges, next_h)) + if(next_h!=opoh && get(range_halfedges, next_h)) edges_to_test.insert(next_h); ++collapsed_n; From febeb2debc371a23850fe6c8a83273a2c4a66d05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Mon, 14 Mar 2022 18:04:21 +0100 Subject: [PATCH 047/107] add ui for self snapping --- .../Polyhedron/Plugins/PMP/CMakeLists.txt | 2 +- .../Plugins/PMP/Repair_polyhedron_plugin.cpp | 137 +++++++++++++++++- .../Polyhedron/Plugins/PMP/SelfSnapDialog.ui | 91 ++++++++++++ 3 files changed, 222 insertions(+), 8 deletions(-) create mode 100644 Polyhedron/demo/Polyhedron/Plugins/PMP/SelfSnapDialog.ui diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/CMakeLists.txt b/Polyhedron/demo/Polyhedron/Plugins/PMP/CMakeLists.txt index 76b60fbd535..53cfdc9b825 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/CMakeLists.txt @@ -123,7 +123,7 @@ target_link_libraries( PUBLIC scene_surface_mesh_item scene_polylines_item scene_points_with_normal_item) -qt5_wrap_ui( repairUI_FILES RemoveNeedlesDialog.ui) +qt5_wrap_ui( repairUI_FILES RemoveNeedlesDialog.ui SelfSnapDialog.ui) polyhedron_demo_plugin(repair_polyhedron_plugin Repair_polyhedron_plugin ${repairUI_FILES} KEYWORDS PMP) target_link_libraries(repair_polyhedron_plugin PUBLIC scene_points_with_normal_item scene_surface_mesh_item) diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Repair_polyhedron_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Repair_polyhedron_plugin.cpp index e591584ecd9..52510d174e9 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/Repair_polyhedron_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Repair_polyhedron_plugin.cpp @@ -21,6 +21,7 @@ #include #include "ui_RemoveNeedlesDialog.h" +#include "ui_SelfSnapDialog.h" #include #include #include @@ -204,9 +205,6 @@ void Polyhedron_demo_repair_polyhedron_plugin::on_actionRemoveNeedlesAndCaps_tri void Polyhedron_demo_repair_polyhedron_plugin::on_actionSnapBorders_triggered() { - QCursor tmp_cursor(Qt::WaitCursor); - CGAL::Three::Three::CursorScopeGuard guard(tmp_cursor); - const Scene_interface::Item_id index = scene->mainSelectionIndex(); Scene_surface_mesh_item* sm_item = qobject_cast(scene->item(index)); if(!sm_item) @@ -214,9 +212,134 @@ void Polyhedron_demo_repair_polyhedron_plugin::on_actionSnapBorders_triggered() return; } - // try to snap remaining boundaries - CGAL::Polygon_mesh_processing::experimental::snap_borders(*sm_item->face_graph()); - CGAL::Polygon_mesh_processing::stitch_borders(*sm_item->face_graph(), CGAL::parameters::do_simplify_border(true)); + + QDialog dialog; + Ui::SelfSnapDialog ui; + ui.setupUi(&dialog); + connect(ui.use_local_tolerance, SIGNAL(toggled(bool)), + ui.tolerances, SLOT(setDisabled(bool))); + + if(dialog.exec() != QDialog::Accepted) + return; + + QCursor tmp_cursor(Qt::WaitCursor); + CGAL::Three::Three::CursorScopeGuard guard(tmp_cursor); + + typedef Scene_surface_mesh_item::Face_graph Face_graph; + Face_graph& tm = *sm_item->face_graph(); + typedef boost::graph_traits::halfedge_descriptor halfedge_descriptor; + typedef boost::graph_traits::vertex_descriptor vertex_descriptor; + + CGAL::Polygon_mesh_processing::stitch_borders(tm); +#if 1 +/// detection of non-manifold parts + std::map< std::pair, std::vector > edges; + for(halfedge_descriptor h : halfedges(tm)) + { + if (is_border(h,tm)) + edges[CGAL::make_sorted_pair(tm.point(target(h,tm)), tm.point(source(h,tm)))].push_back(h); + } + + std::vector fccs(num_faces(tm),-1); + int nbcc = CGAL::Polygon_mesh_processing::connected_components(tm, CGAL::make_property_map(fccs)); + //this has to be done per cycle so as to keep 2 patches + // remove the smallest CCs + std::vector cc_sizes(nbcc, 0); + for(int i : fccs) + cc_sizes[i]+=1; + std::set ccs_to_rm; + for (auto p : edges) + if (p.second.size() >= 2) + for(halfedge_descriptor h : p.second) + { + int ccid = fccs[face(opposite(h, tm),tm)]; + if ( cc_sizes[ccid]<=4 ) + ccs_to_rm.insert(ccid); + } + std::cout << "removing " << ccs_to_rm.size() << " ccs\n"; + CGAL::Polygon_mesh_processing::remove_connected_components(tm, ccs_to_rm, CGAL::make_property_map(fccs)); + std::cout << "input is valid after cc removal:"<< CGAL::is_valid_polygon_mesh(tm) << "\n"; +/// +#endif + + if (ui.use_local_tolerance->isChecked()) + { + CGAL::Polygon_mesh_processing::experimental::snap_borders(tm, CGAL::parameters::do_simplify_border(ui.do_simplify_border->isChecked())); + CGAL::Polygon_mesh_processing::stitch_borders(tm); + CGAL::Polygon_mesh_processing::duplicate_non_manifold_vertices(tm); + } + else + { + std::vector tolerances/* = 0.005, 0.0125, 0.025, 0.05, 0.07 */; + bool ok; + Q_FOREACH(QString tol_text, ui.tolerances->text().split(",")) + { + double d = tol_text.toDouble(&ok); + if (ok) + tolerances.push_back(d); + else + QMessageBox(QMessageBox::Warning, + QString("Invalid value"), + QString("\""+tol_text+"\" is not a valid double, ignored."), + QMessageBox::Ok, + this->mw).exec(); + } + + for (double tol : tolerances ) + { + std::cout << "using tol = " << tol << "\n"; + CGAL::Constant_property_map tolerance_map(tol); + CGAL::Polygon_mesh_processing::experimental::snap_borders(tm, tolerance_map, CGAL::parameters::do_simplify_border(ui.do_simplify_border->isChecked())); + + CGAL::Polygon_mesh_processing::stitch_borders(tm); + CGAL::Polygon_mesh_processing::duplicate_non_manifold_vertices(tm); + + // post processing + std::vector remaining_cycles; + CGAL::Polygon_mesh_processing::extract_boundary_cycles(tm, std::back_inserter(remaining_cycles)); + + int tested=0, done=0; + for (halfedge_descriptor hc : remaining_cycles) + { + if (next(next(hc,tm),tm)==prev(hc,tm)) + { + ++tested; + //get smallest halfedge + halfedge_descriptor hm = hc; + double min_l = CGAL::Polygon_mesh_processing::edge_length(hc, tm); + + double el = CGAL::Polygon_mesh_processing::edge_length(next(hc, tm), tm); + if (eltol) + continue; + if (!CGAL::Euler::does_satisfy_link_condition(edge(hm, tm), tm)) + { + // simply fill the face + std::array vr = { source(hm, tm), target(hm, tm), target(next(hm, tm), tm) }; + CGAL::Euler::add_face(vr, tm); + continue; + } + + std::array vr = { source(hm, tm), target(hm, tm), target(next(hm, tm), tm) }; + CGAL::Euler::add_face(vr, tm); + CGAL::Euler::collapse_edge(edge(hm, tm), tm); + ++done; + } + } + } + } + CGAL::Polygon_mesh_processing::duplicate_non_manifold_vertices(tm); sm_item->invalidateOpenGLBuffers(); sm_item->itemChanged(); @@ -257,7 +380,7 @@ void Polyhedron_demo_repair_polyhedron_plugin::on_actionRemoveSelfIntersections_ { bool solved = CGAL::Polygon_mesh_processing::experimental::remove_self_intersections( - *poly_item->polyhedron()); + *poly_item->polyhedron(), CGAL::parameters::preserve_genus(false)); if (!solved) CGAL::Three::Three::information(tr("Some self-intersection could not be fixed")); poly_item->invalidateOpenGLBuffers(); diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/SelfSnapDialog.ui b/Polyhedron/demo/Polyhedron/Plugins/PMP/SelfSnapDialog.ui new file mode 100644 index 00000000000..6df35f1a021 --- /dev/null +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/SelfSnapDialog.ui @@ -0,0 +1,91 @@ + + + SelfSnapDialog + + + + 0 + 0 + 413 + 179 + + + + Dialog + + + + + + Use Local Tolerance + + + + + + + Fixed Snapping (comma separate values for several runs): + + + + + + + + + + Collapse Edges Before Snap + + + true + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + SelfSnapDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + SelfSnapDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + From 3a64aef0831c6c8b6f1a1bf7c946710264a47126 Mon Sep 17 00:00:00 2001 From: Sebastien Loriot Date: Wed, 11 May 2022 16:24:31 +0200 Subject: [PATCH 048/107] Fix working --- .../include/CGAL/Polygon_mesh_processing/orientation.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h index 1a6d82f80fc..2246b28b045 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h @@ -366,7 +366,7 @@ void reverse_face_orientations(const FaceRange& face_range, PolygonMesh& pmesh) * \ingroup PMP_orientation_grp * makes each closed connected component of a triangulated surface mesh * inward or outward oriented. If a connected component is not closed, -* the fact that its orientation is changed or not is not guaranteed. +* the orientation may or may not be changed or not is not guaranteed. * * @tparam TriangleMesh a model of `FaceListGraph` and `MutableFaceGraph` * @tparam NamedParameters a sequence of \ref bgl_namedparameters From 7067cec5066c0e356a52abbcc78d502ae72668ff Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Tue, 24 May 2022 07:55:01 +0100 Subject: [PATCH 049/107] Polygon: Add move semantics --- .../include/CGAL/General_polygon_with_holes_2.h | 16 +++++++++++++++- Polygon/include/CGAL/Polygon_2.h | 7 +++++++ Polygon/include/CGAL/Polygon_with_holes_2.h | 13 ++++++++++++- 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/Polygon/include/CGAL/General_polygon_with_holes_2.h b/Polygon/include/CGAL/General_polygon_with_holes_2.h index d7d0be256bb..99ebb453956 100644 --- a/Polygon/include/CGAL/General_polygon_with_holes_2.h +++ b/Polygon/include/CGAL/General_polygon_with_holes_2.h @@ -63,6 +63,10 @@ public: m_pgn(pgn_boundary) {} + explicit General_polygon_with_holes_2(Polygon_2&& pgn_boundary) : + m_pgn(std::move(pgn_boundary)) + {} + template General_polygon_with_holes_2(const Polygon_2& pgn_boundary, HolesInputIterator h_begin, @@ -71,6 +75,14 @@ public: m_holes(h_begin, h_end) {} + template + General_polygon_with_holes_2(Polygon_2&& pgn_boundary, + HolesInputIterator h_begin, + HolesInputIterator h_end) : + m_pgn(std::move(pgn_boundary)), + m_holes(h_begin, h_end) + {} + Holes_container& holes() { return m_holes; } const Holes_container& holes() const { return m_holes; } @@ -91,6 +103,8 @@ public: void add_hole(const Polygon_2& pgn_hole) { m_holes.push_back(pgn_hole); } + void add_hole(Polygon_2&& pgn_hole) { m_holes.emplace_back(std::move(pgn_hole)); } + void erase_hole(Hole_iterator hit) { m_holes.erase(hit); } bool has_holes() const { return (!m_holes.empty()); } @@ -187,7 +201,7 @@ operator>>(std::istream& is, General_polygon_with_holes_2& p) { Polygon_ pgn_hole; for (unsigned int i=0; i> pgn_hole; - p.add_hole(pgn_hole); + p.add_hole(std::move(pgn_hole)); } } diff --git a/Polygon/include/CGAL/Polygon_2.h b/Polygon/include/CGAL/Polygon_2.h index 987215691ac..f305cad314f 100644 --- a/Polygon/include/CGAL/Polygon_2.h +++ b/Polygon/include/CGAL/Polygon_2.h @@ -163,6 +163,9 @@ class Polygon_2 { Polygon_2(const Polygon_2& polygon) : d_container(polygon.d_container), traits(polygon.traits) {} + Polygon_2(Polygon_2&& polygon) + : d_container(std::move(polygon.d_container)), traits(polygon.traits) {} + /// Creates a polygon with vertices from the sequence /// defined by the range \c [first,last). /// The value type of \c InputIterator must be \c Point_2. @@ -174,6 +177,10 @@ class Polygon_2 { #ifndef DOXYGEN_RUNNING Polygon_2& operator=(const Polygon_2&)=default; + Polygon_2& operator=(Polygon_2&& p) + { + d_container = std::move(p.d_container); + } #endif /// @} diff --git a/Polygon/include/CGAL/Polygon_with_holes_2.h b/Polygon/include/CGAL/Polygon_with_holes_2.h index 91d35a36560..879ea6050a7 100644 --- a/Polygon/include/CGAL/Polygon_with_holes_2.h +++ b/Polygon/include/CGAL/Polygon_with_holes_2.h @@ -63,6 +63,10 @@ public: Base (pgn_boundary) {} + explicit Polygon_with_holes_2 (Polygon_2&& pgn_boundary) : + Base (std::move(pgn_boundary)) + {} + /*! Constructor from a polygon (outer boundary) and hole polygons. */ template Polygon_with_holes_2 (const Polygon_2& pgn_boundary, @@ -71,6 +75,13 @@ public: Base (pgn_boundary, h_begin, h_end) {} + template + Polygon_with_holes_2 (Polygon_2&& pgn_boundary, + HolesInputIterator h_begin, + HolesInputIterator h_end) : + Base (std::move(pgn_boundary), h_begin, h_end) + {} + /*! Obtain the bounding box of the polygon with holes */ Bbox_2 bbox() const { return this->outer_boundary().bbox(); } }; @@ -170,7 +181,7 @@ std::istream &operator>>(std::istream &is, { Polygon_2 hole; is >> hole; - p.add_hole(hole); + p.add_hole(std::move(hole)); } } From 3b52e466a815c0745d803374580193a0ae381fad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Tue, 24 May 2022 10:02:15 +0200 Subject: [PATCH 050/107] AABB_tree doc improvements --- AABB_tree/include/CGAL/AABB_primitive.h | 6 ++---- Documentation/doc/Documentation/General.txt | 13 ++++++++----- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/AABB_tree/include/CGAL/AABB_primitive.h b/AABB_tree/include/CGAL/AABB_primitive.h index faae18e0bf2..b0e9abdaf38 100644 --- a/AABB_tree/include/CGAL/AABB_primitive.h +++ b/AABB_tree/include/CGAL/AABB_primitive.h @@ -53,9 +53,8 @@ public: * The two property maps which are template parameters of the class enable to get the datum and the reference point of * the primitive from the identifier. The last template parameter controls whether the primitive class holds a copy of the datum. * - * \cgalModels `AABBPrimitive` if `ExternalPropertyMaps` is `CGAL::Tag_false`, - * and `AABBPrimitiveWithSharedData` if `ExternalPropertyMaps` is `CGAL::Tag_true`. - * + * \cgalModels `AABBPrimitive` if `ExternalPropertyMaps` is `CGAL::Tag_false`. + * \cgalModels `AABBPrimitiveWithSharedData` if `ExternalPropertyMaps` is `CGAL::Tag_true`. * * \tparam ObjectPropertyMap is a model of `ReadablePropertyMap` with `Id` as * `key_type`. It must be a model of `CopyConstructible`, `DefaultConstructible`, and `CopyAssignable`. @@ -70,7 +69,6 @@ public: * it is constructed on the fly to reduce the memory footprint. * The default is `CGAL::Tag_false` (datum is not stored). * - * \sa `AABBPrimitive` * \sa `AABB_segment_primitive` * \sa `AABB_triangle_primitive` * \sa `AABB_halfedge_graph_segment_primitive` diff --git a/Documentation/doc/Documentation/General.txt b/Documentation/doc/Documentation/General.txt index a14d99dd4fe..f1de55dcdc2 100644 --- a/Documentation/doc/Documentation/General.txt +++ b/Documentation/doc/Documentation/General.txt @@ -1,8 +1,3 @@ -///This concept refines both -/// CopyAssignable -///and CopyConstructible. -class Assignable {}; - /// \cgalConcept /// Concept from the \cpp standard. /// See https://en.cppreference.com/w/cpp/named_req/DefaultConstructible @@ -13,6 +8,14 @@ class DefaultConstructible {}; /// See https://en.cppreference.com/w/cpp/named_req/CopyConstructible class CopyConstructible {}; +/// \cgalConcept +/// Concept from the \cpp standard. +/// See https://en.cppreference.com/w/cpp/named_req/CopyAssignable +class CopyAssignable {}; + +///This concept refines both `CopyAssignable` and `CopyConstructible`. +class Assignable {}; + /// \cgalConcept /// Concept from the \cpp standard. /// See https://en.cppreference.com/w/cpp/named_req/Callable From 06053d2186bcffbf89947311b159fa936309683d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Tue, 24 May 2022 10:02:57 +0200 Subject: [PATCH 051/107] Allow empty oracle levels --- .../CGAL/Alpha_wrap_3/internal/Oracle_base.h | 122 ++++++++++++++---- 1 file changed, 95 insertions(+), 27 deletions(-) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Oracle_base.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Oracle_base.h index 5eba09bce0d..c38157a59bf 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Oracle_base.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Oracle_base.h @@ -142,41 +142,85 @@ public: BaseOracle& base() { return static_cast(*this); } const BaseOracle& base() const { return static_cast(*this); } + bool empty() const { return m_tree_ptr->empty(); } + bool do_call() const { return (!empty() || base().do_call()); } + public: typename AABB_tree::Bounding_box bbox() const { - CGAL_precondition(!tree().empty()); + CGAL_precondition(do_call()); - return base().bbox() + tree().bbox(); + typename AABB_tree::Bounding_box bb; + + if(base().do_call()) + bb += base().bbox(); + + if(!empty()) + bb += tree().bbox(); + + return bb; } template bool do_intersect(const T& t) const { - if(base().do_intersect(t)) + CGAL_precondition(do_call()); + + if(base().do_call() && base().do_intersect(t)) return true; - return AABB_helper::do_intersect(t, tree()); + if(!empty()) + return AABB_helper::do_intersect(t, tree()); + + return false; } FT squared_distance(const Point_3& p) const { - const FT base_sqd = base().squared_distance(p); + CGAL_precondition(do_call()); - // @speed could do a smarter traversal, no need to search deeper than the current best - const FT this_sqd = AABB_helper::squared_distance(p, tree()); - - return (std::min)(base_sqd, this_sqd); + if(base().do_call()) + { + if(!empty()) // both non empty + { + const FT base_sqd = base().squared_distance(p); + // @speed could do a smarter traversal, no need to search deeper than the current best + const FT this_sqd = AABB_helper::squared_distance(p, tree()); + return (std::min)(base_sqd, this_sqd); + } + else // this level is empty + { + return base().squared_distance(p); + } + } + else // empty base + { + return AABB_helper::squared_distance(p, tree()); + } } Point_3 closest_point(const Point_3& p) const { - const Point_3 base_c = base().closest_point(p); + CGAL_precondition(do_call()); - // @speed could do a smarter traversal, no need to search deeper than the current best - const Point_3 this_c = AABB_helper::closest_point(p, tree()); - - return (compare_distance_to_point(p, base_c, this_c) == CGAL::SMALLER) ? base_c : this_c; + if(base().do_call()) + { + if(!empty()) // both non empty + { + const Point_3 base_c = base().closest_point(p); + // @speed could do a smarter traversal, no need to search deeper than the current best + const Point_3 this_c = AABB_helper::closest_point(p, tree()); + return (compare_distance_to_point(p, base_c, this_c) == CGAL::SMALLER) ? base_c : this_c; + } + else // this level is empty + { + return base().closest_point(p); + } + } + else // empty base + { + return AABB_helper::closest_point(p, tree()); + } } bool first_intersection(const Point_3& p, const Point_3& q, @@ -184,22 +228,38 @@ public: const FT offset_size, const FT intersection_precision) const { - Point_3 base_o; - bool base_b = base().first_intersection(p, q, base_o, offset_size, intersection_precision); + CGAL_precondition(do_call()); - if(base_b) + if(base().do_call()) { - // @speed could do a smarter traversal, no need to search deeper than the current best - Point_3 this_o; - bool this_b = AABB_helper::first_intersection(p, q, this_o, offset_size, intersection_precision, tree()); - if(this_b) - o = (compare_distance_to_point(p, base_o, this_o) == SMALLER) ? base_o : this_o; - else - o = base_o; + if(!empty()) // both non empty + { + Point_3 base_o; + bool base_b = base().first_intersection(p, q, base_o, offset_size, intersection_precision); - return true; + if(base_b) // intersection found in base + { + // @speed could do a smarter traversal, no need to search deeper than the current best + Point_3 this_o; + bool this_b = AABB_helper::first_intersection(p, q, this_o, offset_size, intersection_precision, tree()); + if(this_b) + o = (compare_distance_to_point(p, base_o, this_o) == SMALLER) ? base_o : this_o; + else + o = base_o; + + return true; + } + else // no intersection found in non-empty base + { + return AABB_helper::first_intersection(p, q, o, offset_size, intersection_precision, tree()); + } + } + else // this level is empty + { + return base().first_intersection(p, q, o, offset_size, intersection_precision); + } } - else + else // empty base { return AABB_helper::first_intersection(p, q, o, offset_size, intersection_precision, tree()); } @@ -250,10 +310,13 @@ public: AABB_tree& tree() { return *m_tree_ptr; } const AABB_tree& tree() const { return *m_tree_ptr; } + bool empty() const { return m_tree_ptr->empty(); } + bool do_call() const { return !empty(); } + public: typename AABB_tree::Bounding_box bbox() const { - CGAL_precondition(!tree().empty()); + CGAL_precondition(!empty()); return tree().bbox(); } @@ -261,27 +324,32 @@ public: template bool do_intersect(const T& t) const { + CGAL_precondition(!empty()); return AABB_helper::do_intersect(t, tree()); } FT squared_distance(const Point_3& p) const { + CGAL_precondition(!empty()); return AABB_helper::squared_distance(p, tree()); } Point_3 closest_point(const Point_3& p) const { + CGAL_precondition(!empty()); return AABB_helper::closest_point(p, tree()); } bool first_intersection(const Point_3& p, const Point_3& q, Point_3& o, const FT offset_size, const FT intersection_precision) const { + CGAL_precondition(!empty()); return AABB_helper::first_intersection(p, q, o, offset_size, intersection_precision, tree()); } bool first_intersection(const Point_3& p, const Point_3& q, Point_3& o, const FT offset_size) const { + CGAL_precondition(!empty()); return AABB_helper::first_intersection(p, q, o, offset_size, 1e-2 * offset_size, tree()); } From 9fbfd9ac39fd7342277d827dbbdd38ff1df8c494 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Tue, 24 May 2022 10:08:56 +0200 Subject: [PATCH 052/107] AW3 oracle improvements (mostly no longer templated by the data) --- .../Alpha_wrap_3/internal/Point_set_oracle.h | 61 ++++++++----------- .../internal/Segment_soup_oracle.h | 42 +++++++------ .../internal/Triangle_mesh_oracle.h | 34 +++++------ .../internal/Triangle_soup_oracle.h | 55 ++++++++++------- Alpha_wrap_3/include/CGAL/alpha_wrap_3.h | 6 +- .../test_AW3_cavity_initializations.cpp | 3 +- .../Alpha_wrap_3/test_AW3_multiple_calls.cpp | 2 +- 7 files changed, 104 insertions(+), 99 deletions(-) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Point_set_oracle.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Point_set_oracle.h index 761de1bdb88..b27ffa0525a 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Point_set_oracle.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Point_set_oracle.h @@ -24,45 +24,25 @@ #include #include -#include - #include #include +#include #include +#include namespace CGAL { namespace Alpha_wraps_3 { namespace internal { -// No longer used, but might find some purpose again in the future -template -struct Point_from_iterator_map -{ - using key_type = InputIterator; - using value_type = typename boost::property_traits::value_type; - using reference = typename boost::property_traits::reference; - using category = boost::readable_property_map_tag; - - Point_from_iterator_map(const PM& pm = PM()) : pm(pm) { } - - inline friend reference get(const Point_from_iterator_map& map, const key_type it) - { - return get(map.pm, *it); - } - - PM pm; -}; - // Just some typedefs for readability -template +template struct PS_oracle_traits { - using Point = typename boost::range_value::type; - using Default_GT = typename Kernel_traits::Kernel; - using Base_GT = typename Default::Get::type; // = Kernel, usually - using Geom_traits = Alpha_wrap_AABB_traits; // Wrap the kernel to add Ball_3 + custom Do_intersect_3 + using Geom_traits = Alpha_wrap_AABB_traits; // Wrap the kernel to add Ball_3 + custom Do_intersect_3 + + using Points = std::vector; + using PR_iterator = typename Points::const_iterator; - using PR_iterator = typename PointRange::const_iterator; using Primitive = AABB_primitive /*DPM*/, Input_iterator_property_map /*RPM*/, @@ -73,25 +53,28 @@ struct PS_oracle_traits using AABB_tree = CGAL::AABB_tree; }; -template class Point_set_oracle - : public AABB_tree_oracle::Geom_traits, - typename PS_oracle_traits::AABB_tree, + : public AABB_tree_oracle::Geom_traits, + typename PS_oracle_traits::AABB_tree, CGAL::Default, // Default_traversal_traits BaseOracle> { - using PSOT = PS_oracle_traits; - using Base_GT = typename PSOT::Base_GT; + using PSOT = PS_oracle_traits; + using Base_GT = GT_; public: using Geom_traits = typename PSOT::Geom_traits; private: + using Points = typename PSOT::Points; using AABB_tree = typename PSOT::AABB_tree; using Oracle_base = AABB_tree_oracle; +private: + Points m_points; + public: // Constructors Point_set_oracle() @@ -110,9 +93,10 @@ public: public: // adds a range of points to the oracle - template + template void add_point_set(const PointRange& points, - const NamedParameters& /*np*/ = CGAL::parameters::default_values()) + const CGAL_NP_CLASS& /*np*/ = CGAL::parameters::default_values()) { if(points.empty()) { @@ -122,11 +106,16 @@ public: return; } + const std::size_t old_size = m_points.size(); + m_points.insert(std::cend(m_points), std::cbegin(points), std::cend(points)); + #ifdef CGAL_AW3_DEBUG std::cout << "Insert into AABB tree (points)..." << std::endl; #endif - this->tree().insert(points.begin(), points.end()); + this->tree().insert(std::next(std::cbegin(m_points), old_size), std::cend(m_points)); + + CGAL_postcondition(this->tree().size() == m_points.size()); } }; diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Segment_soup_oracle.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Segment_soup_oracle.h index b8759e67b51..a6a87f000ab 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Segment_soup_oracle.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Segment_soup_oracle.h @@ -24,26 +24,25 @@ #include #include -#include - #include #include +#include #include +#include namespace CGAL { namespace Alpha_wraps_3 { namespace internal { // Just some typedefs for readability -template +template struct SS_oracle_traits { - using Segment = typename boost::range_value::type; - using Default_GT = typename Kernel_traits::Kernel; - using Base_GT = typename Default::Get::type; // = Kernel, usually - using Geom_traits = Alpha_wrap_AABB_traits; // Wrap the kernel to add Ball_3 + custom Do_intersect_3 + using Geom_traits = Alpha_wrap_AABB_traits; // Wrap the kernel to add Ball_3 + custom Do_intersect_3 + + using Segments = std::vector; + using SR_iterator = typename Segments::const_iterator; - using SR_iterator = typename SegmentRange::const_iterator; using Primitive = AABB_primitive, // DPM CGAL::internal::Source_of_segment_3_iterator_property_map, // RPM @@ -54,25 +53,28 @@ struct SS_oracle_traits using AABB_tree = CGAL::AABB_tree; }; -template class Segment_soup_oracle - : public AABB_tree_oracle::Geom_traits, - typename SS_oracle_traits::AABB_tree, + : public AABB_tree_oracle::Geom_traits, + typename SS_oracle_traits::AABB_tree, CGAL::Default, // Default_traversal_traits BaseOracle> { - using SSOT = SS_oracle_traits; - using Base_GT = typename SSOT::Base_GT; + using SSOT = SS_oracle_traits; + using Base_GT = GT_; public: using Geom_traits = typename SSOT::Geom_traits; private: + using Segments = typename SSOT::Segments; using AABB_tree = typename SSOT::AABB_tree; using Oracle_base = AABB_tree_oracle; +private: + Segments m_segments; + public: // Constructors Segment_soup_oracle() @@ -90,9 +92,10 @@ public: { } public: - template + template void add_segment_soup(const SegmentRange& segments, - const NamedParameters& /*np*/ = CGAL::parameters::default_values()) + const CGAL_NP_CLASS& /*np*/ = CGAL::parameters::default_values()) { if(segments.empty()) { @@ -102,12 +105,15 @@ public: return; } + const std::size_t old_size = m_segments.size(); + m_segments.insert(std::cend(m_segments), std::cbegin(segments), std::cend(segments)); + #ifdef CGAL_AW3_DEBUG std::cout << "Insert into AABB tree (segments)..." << std::endl; #endif - this->tree().insert(segments.begin(), segments.end()); + this->tree().insert(std::next(std::cbegin(m_segments), old_size), std::cend(m_segments)); - CGAL_postcondition(this->tree().size() == segments.size()); + CGAL_postcondition(this->tree().size() == m_segments.size()); } }; diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Triangle_mesh_oracle.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Triangle_mesh_oracle.h index 3d90fd869a3..f4e74da51e9 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Triangle_mesh_oracle.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Triangle_mesh_oracle.h @@ -34,41 +34,36 @@ namespace Alpha_wraps_3 { namespace internal { // Just some typedefs for readability in the main oracle class -template +template struct TM_oracle_traits { - using Default_GT = typename GetGeomTraits::type; + using Geom_traits = Alpha_wrap_AABB_traits; // Wrap the kernel to add Ball_3 + custom Do_intersect_3 - using Base_GT = typename Default::Get::type; // = Kernel, usually - using Geom_traits = Alpha_wrap_AABB_traits; // Wrap the kernel to add Ball_3 + custom Do_intersect_3 using Point_3 = typename Geom_traits::Point_3; using AABB_traits = typename AABB_tree_splitter_traits::AABB_traits; using AABB_tree = typename AABB_tree_splitter_traits::AABB_tree; }; // @speed could do a partial specialization 'subdivide = false' with simpler code for speed? -template class Triangle_mesh_oracle : // this is the base that handles calls to the AABB tree - public AABB_tree_oracle::Geom_traits, - typename TM_oracle_traits::AABB_tree, + public AABB_tree_oracle::Geom_traits, + typename TM_oracle_traits::AABB_tree, typename std::conditional< /*condition*/subdivide, - /*true*/Splitter_traversal_traits::AABB_traits>, - /*false*/Default_traversal_traits::AABB_traits> >::type, + /*true*/Splitter_traversal_traits::AABB_traits>, + /*false*/Default_traversal_traits::AABB_traits> >::type, BaseOracle>, // this is the base that handles splitting input faces and inserting them into the AABB tree public AABB_tree_oracle_splitter::Point_3, - typename TM_oracle_traits::Geom_traits> + typename TM_oracle_traits::Point_3, + typename TM_oracle_traits::Geom_traits> { - using face_descriptor = typename boost::graph_traits::face_descriptor; - - using TMOT = TM_oracle_traits; - using Base_GT = typename TMOT::Base_GT; + using TMOT = TM_oracle_traits; + using Base_GT = GT_; public: using Geom_traits = typename TMOT::Geom_traits; @@ -122,13 +117,16 @@ public: { } public: - template + template void add_triangle_mesh(const TriangleMesh& tmesh, - const NamedParameters& np = CGAL::parameters::default_values()) + const CGAL_NP_CLASS& np = CGAL::parameters::default_values()) { using parameters::get_parameter; using parameters::choose_parameter; + using face_descriptor = typename boost::graph_traits::face_descriptor; + using VPM = typename GetVertexPointMap::const_type; using Point_ref = typename boost::property_traits::reference; diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Triangle_soup_oracle.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Triangle_soup_oracle.h index f2cb2b1772f..39beccaf311 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Triangle_soup_oracle.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Triangle_soup_oracle.h @@ -35,42 +35,34 @@ namespace Alpha_wraps_3 { namespace internal { // Just some typedefs for readability -template +template struct TS_oracle_traits { - using Default_NP = parameters::Default_named_parameters; - using Default_NP_helper = Point_set_processing_3_np_helper; - using Default_GT = typename Default_NP_helper::Geom_traits; - - using Base_GT = typename Default::Get::type; // = Kernel, usually - using Geom_traits = Alpha_wrap_AABB_traits; // Wrap the kernel to add Ball_3 + custom Do_intersect_3 + using Geom_traits = Alpha_wrap_AABB_traits; // Wrap the kernel to add Ball_3 + custom Do_intersect_3 using Point_3 = typename Geom_traits::Point_3; using AABB_traits = typename AABB_tree_splitter_traits::AABB_traits; using AABB_tree = typename AABB_tree_splitter_traits::AABB_tree; }; -template class Triangle_soup_oracle : // this is the base that handles calls to the AABB tree - public AABB_tree_oracle::Geom_traits, - typename TS_oracle_traits::AABB_tree, + public AABB_tree_oracle::Geom_traits, + typename TS_oracle_traits::AABB_tree, typename std::conditional< /*condition*/subdivide, - /*true*/Splitter_traversal_traits::AABB_traits>, - /*false*/Default_traversal_traits::AABB_traits> >::type, + /*true*/Splitter_traversal_traits::AABB_traits>, + /*false*/Default_traversal_traits::AABB_traits> >::type, BaseOracle>, // this is the base that handles splitting input faces and inserting them into the AABB tree public AABB_tree_oracle_splitter::Point_3, - typename TS_oracle_traits::Geom_traits> + typename TS_oracle_traits::Point_3, + typename TS_oracle_traits::Geom_traits> { - using Face = typename boost::range_value::type; - - using TSOT = TS_oracle_traits; - using Base_GT = typename TSOT::Base_GT; + using TSOT = TS_oracle_traits; + using Base_GT = GT_; public: using Geom_traits = typename TSOT::Geom_traits; @@ -124,17 +116,20 @@ public: { } public: - template + template void add_triangle_soup(const PointRange& points, const FaceRange& faces, - const NamedParameters& np = CGAL::parameters::default_values()) + const CGAL_NP_CLASS& np = CGAL::parameters::default_values()) { using parameters::choose_parameter; using parameters::get_parameter; - using PPM = typename GetPointMap::const_type; + using PPM = typename GetPointMap::const_type; using Point_ref = typename boost::property_traits::reference; + using Face = typename boost::range_value::type; + if(points.empty() || faces.empty()) { #ifdef CGAL_AW3_DEBUG @@ -178,6 +173,22 @@ public: std::cout << "Tree: " << this->tree().size() << " primitives (" << faces.size() << " faces in input)" << std::endl; #endif } + + template + void add_triangle_soup(const TriangleRange& triangles, + const CGAL_NP_CLASS& np = CGAL::parameters::default_values()) + { + typename Geom_traits::Is_degenerate_3 is_degenerate = this->geom_traits().is_degenerate_3_object(); + + for(const Triangle_3& tr : triangles) + { + if(is_degenerate(tr)) + continue; + + Splitter_base::split_and_insert_datum(tr, this->tree(), this->geom_traits()); + } + } }; } // namespace internal diff --git a/Alpha_wrap_3/include/CGAL/alpha_wrap_3.h b/Alpha_wrap_3/include/CGAL/alpha_wrap_3.h index ddeb40119ed..b22bf878458 100644 --- a/Alpha_wrap_3/include/CGAL/alpha_wrap_3.h +++ b/Alpha_wrap_3/include/CGAL/alpha_wrap_3.h @@ -104,7 +104,7 @@ void alpha_wrap_3(const PointRange& points, using NP_helper = Point_set_processing_3_np_helper; using Geom_traits = typename NP_helper::Geom_traits; - using Oracle = Alpha_wraps_3::internal::Triangle_soup_oracle; + using Oracle = Alpha_wraps_3::internal::Triangle_soup_oracle; using AW3 = Alpha_wraps_3::internal::Alpha_wrap_3; Geom_traits gt = choose_parameter(get_parameter(in_np, internal_np::geom_traits)); @@ -253,7 +253,7 @@ void alpha_wrap_3(const TriangleMesh& tmesh, using parameters::choose_parameter; using Geom_traits = typename GetGeomTraits::type; - using Oracle = Alpha_wraps_3::internal::Triangle_mesh_oracle; + using Oracle = Alpha_wraps_3::internal::Triangle_mesh_oracle; using AW3 = Alpha_wraps_3::internal::Alpha_wrap_3; Geom_traits gt = choose_parameter(get_parameter(in_np, internal_np::geom_traits)); @@ -349,7 +349,7 @@ void alpha_wrap_3(const PointRange& points, using NP_helper = Point_set_processing_3_np_helper; using Geom_traits = typename NP_helper::Geom_traits; - using Oracle = Alpha_wraps_3::internal::Point_set_oracle; + using Oracle = Alpha_wraps_3::internal::Point_set_oracle; using AW3 = Alpha_wraps_3::internal::Alpha_wrap_3; Geom_traits gt = choose_parameter(get_parameter(in_np, internal_np::geom_traits)); diff --git a/Alpha_wrap_3/test/Alpha_wrap_3/test_AW3_cavity_initializations.cpp b/Alpha_wrap_3/test/Alpha_wrap_3/test_AW3_cavity_initializations.cpp index 5d34bebcbe2..d7567bab205 100644 --- a/Alpha_wrap_3/test/Alpha_wrap_3/test_AW3_cavity_initializations.cpp +++ b/Alpha_wrap_3/test/Alpha_wrap_3/test_AW3_cavity_initializations.cpp @@ -55,7 +55,8 @@ void alpha_wrap_triangle_mesh(Mesh& input_mesh, namespace AW3 = CGAL::Alpha_wraps_3; namespace PMP = CGAL::Polygon_mesh_processing; - using Oracle = AW3::internal::Triangle_mesh_oracle; + using Geom_traits = typename CGAL::GetGeomTraits::type; + using Oracle = AW3::internal::Triangle_mesh_oracle; std::cout << "Input: " << num_vertices(input_mesh) << " vertices, " << num_faces(input_mesh) << " faces" << std::endl; diff --git a/Alpha_wrap_3/test/Alpha_wrap_3/test_AW3_multiple_calls.cpp b/Alpha_wrap_3/test/Alpha_wrap_3/test_AW3_multiple_calls.cpp index a6ee7cef5f8..e2abc6f1f12 100644 --- a/Alpha_wrap_3/test/Alpha_wrap_3/test_AW3_multiple_calls.cpp +++ b/Alpha_wrap_3/test/Alpha_wrap_3/test_AW3_multiple_calls.cpp @@ -36,7 +36,7 @@ void alpha_wrap_triangle_soup(Points& pr, namespace AW3 = CGAL::Alpha_wraps_3; namespace PMP = CGAL::Polygon_mesh_processing; - using Oracle = AW3::internal::Triangle_soup_oracle; + using Oracle = AW3::internal::Triangle_soup_oracle; std::cout << "Input: " << pr.size() << " points, " << fr.size() << " faces" << std::endl; From fd471ebb5ce99ca72eab38fae78ae9c100d356d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Tue, 24 May 2022 10:10:08 +0200 Subject: [PATCH 053/107] Update AW3 examples --- Alpha_wrap_3/examples/Alpha_wrap_3/mixed_inputs_wrap.cpp | 9 +++++---- Alpha_wrap_3/examples/Alpha_wrap_3/point_set_wrap.cpp | 1 + .../examples/Alpha_wrap_3/triangle_mesh_wrap.cpp | 1 + Alpha_wrap_3/examples/Alpha_wrap_3/wrap_from_cavity.cpp | 3 ++- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/Alpha_wrap_3/examples/Alpha_wrap_3/mixed_inputs_wrap.cpp b/Alpha_wrap_3/examples/Alpha_wrap_3/mixed_inputs_wrap.cpp index 1ff887f02e4..eca3fa1654e 100644 --- a/Alpha_wrap_3/examples/Alpha_wrap_3/mixed_inputs_wrap.cpp +++ b/Alpha_wrap_3/examples/Alpha_wrap_3/mixed_inputs_wrap.cpp @@ -75,7 +75,7 @@ int main(int argc, char** argv) std::cerr << "Invalid point set input: " << ps_filename << std::endl; return EXIT_FAILURE; } - std::cout << ps_points.size() << " points (Point Set)" << std::endl; + std::cout << ps_points.size() << " points (point set)" << std::endl; const double relative_alpha = (argc > 4) ? std::stod(argv[4]) : 15.; const double relative_offset = (argc > 5) ? std::stod(argv[5]) : 450.; @@ -93,9 +93,9 @@ int main(int argc, char** argv) CGAL::Real_timer t; t.start(); - using TS_Oracle = CGAL::Alpha_wraps_3::internal::Triangle_soup_oracle; - using SS_Oracle = CGAL::Alpha_wraps_3::internal::Segment_soup_oracle; - using Oracle = CGAL::Alpha_wraps_3::internal::Point_set_oracle; + using TS_Oracle = CGAL::Alpha_wraps_3::internal::Triangle_soup_oracle; + using SS_Oracle = CGAL::Alpha_wraps_3::internal::Segment_soup_oracle; + using Oracle = CGAL::Alpha_wraps_3::internal::Point_set_oracle; TS_Oracle ts_oracle(K{}); SS_Oracle ss_oracle(ts_oracle); @@ -124,6 +124,7 @@ int main(int argc, char** argv) ps_name = ps_name.substr(0, ps_name.find_last_of(".")); std::string output_name = ts_name + "_" + ss_name + "_" + ps_name + "_" + std::to_string(static_cast(relative_alpha)) + "_" + std::to_string(static_cast(relative_offset)) + ".off"; + std::cout << "Writing to " << output_name << std::endl; CGAL::IO::write_polygon_mesh(output_name, output_mesh, CGAL::parameters::stream_precision(17)); return EXIT_SUCCESS; diff --git a/Alpha_wrap_3/examples/Alpha_wrap_3/point_set_wrap.cpp b/Alpha_wrap_3/examples/Alpha_wrap_3/point_set_wrap.cpp index 8520713f0d2..662e3089288 100644 --- a/Alpha_wrap_3/examples/Alpha_wrap_3/point_set_wrap.cpp +++ b/Alpha_wrap_3/examples/Alpha_wrap_3/point_set_wrap.cpp @@ -59,6 +59,7 @@ int main(int argc, char** argv) input_name = input_name.substr(0, input_name.find_last_of(".")); std::string output_name = input_name + "_" + std::to_string(static_cast(relative_alpha)) + "_" + std::to_string(static_cast(relative_offset)) + ".off"; + std::cout << "Writing to " << output_name << std::endl; CGAL::IO::write_polygon_mesh(output_name, wrap, CGAL::parameters::stream_precision(17)); return EXIT_SUCCESS; diff --git a/Alpha_wrap_3/examples/Alpha_wrap_3/triangle_mesh_wrap.cpp b/Alpha_wrap_3/examples/Alpha_wrap_3/triangle_mesh_wrap.cpp index 2f3655eb660..b4b1ec067ff 100644 --- a/Alpha_wrap_3/examples/Alpha_wrap_3/triangle_mesh_wrap.cpp +++ b/Alpha_wrap_3/examples/Alpha_wrap_3/triangle_mesh_wrap.cpp @@ -64,6 +64,7 @@ int main(int argc, char** argv) std::string output_name = input_name + "_" + std::to_string(static_cast(relative_alpha)) + "_" + std::to_string(static_cast(relative_offset)) + ".off"; + std::cout << "Writing to " << output_name << std::endl; CGAL::IO::write_polygon_mesh(output_name, wrap, CGAL::parameters::stream_precision(17)); return EXIT_SUCCESS; diff --git a/Alpha_wrap_3/examples/Alpha_wrap_3/wrap_from_cavity.cpp b/Alpha_wrap_3/examples/Alpha_wrap_3/wrap_from_cavity.cpp index 0cc59a21d81..91b95584f8c 100644 --- a/Alpha_wrap_3/examples/Alpha_wrap_3/wrap_from_cavity.cpp +++ b/Alpha_wrap_3/examples/Alpha_wrap_3/wrap_from_cavity.cpp @@ -47,7 +47,7 @@ int main(int argc, char** argv) const double offset = diag_length / relative_offset; // Construct the wrap - using Oracle = CGAL::Alpha_wraps_3::internal::Triangle_mesh_oracle; + using Oracle = CGAL::Alpha_wraps_3::internal::Triangle_mesh_oracle; Oracle oracle; oracle.add_triangle_mesh(input); @@ -78,6 +78,7 @@ int main(int argc, char** argv) input_name = input_name.substr(0, input_name.find_last_of(".")); std::string output_name = input_name + "_cavity_" + std::to_string(static_cast(relative_alpha)) + "_" + std::to_string(static_cast(relative_offset)) + ".off"; + std::cout << "Writing to " << output_name << std::endl; CGAL::IO::write_polygon_mesh(output_name, wrap, CGAL::parameters::stream_precision(17)); return EXIT_SUCCESS; From 9c57413bb9fd9db66956ec470df576476c625753 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Tue, 24 May 2022 10:10:50 +0200 Subject: [PATCH 054/107] AW3 demo enhancements (enable segments/points, better dialog, etc.) --- .../Alpha_wrap_3/Alpha_wrap_3_plugin.cpp | 215 +++++++++++++++--- .../Plugins/Alpha_wrap_3/CMakeLists.txt | 2 +- .../Alpha_wrap_3/alpha_wrap_3_dialog.ui | 184 +++++++++------ 3 files changed, 302 insertions(+), 99 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp index 82003468880..b849286dcd3 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp @@ -5,6 +5,9 @@ #include "Scene_surface_mesh_item.h" #include "Scene_polygon_soup_item.h" +#include "Scene_polyhedron_selection_item.h" +#include "Scene_polylines_item.h" +#include "Scene_points_with_normal_item.h" #include #include @@ -34,6 +37,9 @@ class Polyhedron_demo_alpha_wrap_3_plugin Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface) Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0") +private: + Ui::alpha_wrap_3_dialog ui; + public: void init(QMainWindow* mainWindow, CGAL::Three::Scene_interface* scene_interface, @@ -49,12 +55,17 @@ public: bool applicable(QAction*) const { - // Ok if there's at least one mesh Q_FOREACH(int index, scene->selectionIndices()) { + if(qobject_cast(scene->item(index))) + return true; if(qobject_cast(scene->item(index))) return true; - if(qobject_cast(scene->item(index))) + if(qobject_cast(scene->item(index))) + return true; + if(qobject_cast(scene->item(index))) + return true; + if(qobject_cast(scene->item(index))) return true; } @@ -67,10 +78,18 @@ public: } private: + void print_message(QString message) const + { + CGAL::Three::Three::information(message); + } + Ui::alpha_wrap_3_dialog create_dialog(QDialog* dialog) { - Ui::alpha_wrap_3_dialog ui; ui.setupUi(dialog); + + connect(ui.wrapEdges, SIGNAL(clicked(bool)), this, SLOT(toggle_wrap_faces())); + connect(ui.wrapFaces, SIGNAL(clicked(bool)), this, SLOT(toggle_wrap_edges())); + connect(ui.buttonBox, SIGNAL(accepted()), dialog, SLOT(accept())); connect(ui.buttonBox, SIGNAL(rejected()), dialog, SLOT(reject())); @@ -78,14 +97,30 @@ private: } public Q_SLOTS: + void toggle_wrap_faces() + { + if(!ui.wrapEdges->isChecked()) // if edges are disabled, so are faces + ui.wrapFaces->setChecked(false); + } + + void toggle_wrap_edges() + { + if(ui.wrapFaces->isChecked()) // if faces are enabled, so are edges + ui.wrapEdges->setChecked(true); + } + void on_actionAlpha_wrap_3_triggered() { - using Points = typename Scene_polygon_soup_item::Points; - using Polygons = typename Scene_polygon_soup_item::Polygons; - using Oracle = CGAL::Alpha_wraps_3::internal::Triangle_soup_oracle; + using Triangles = std::vector; + using Segments = std::vector; + using Points = std::vector; + + using TS_Oracle = CGAL::Alpha_wraps_3::internal::Triangle_soup_oracle; + using SS_Oracle = CGAL::Alpha_wraps_3::internal::Segment_soup_oracle; + using Oracle = CGAL::Alpha_wraps_3::internal::Point_set_oracle; QDialog dialog(mw); - Ui::alpha_wrap_3_dialog ui = create_dialog(&dialog); + ui = create_dialog(&dialog); dialog.setWindowFlags(Qt::Dialog|Qt::CustomizeWindowHint|Qt::WindowCloseButtonHint); int i = dialog.exec(); @@ -103,43 +138,163 @@ public Q_SLOTS: QApplication::setOverrideCursor(Qt::WaitCursor); - Oracle oracle; + TS_Oracle ts_oracle; + SS_Oracle ss_oracle(ts_oracle); + Oracle oracle(ss_oracle); + + Triangles triangles; + Segments segments; + Points points; + Q_FOREACH(int index, scene->selectionIndices()) { + // --- Scene_surface_mesh_item* sm_item = qobject_cast(scene->item(index)); if(sm_item != nullptr) { - if(!is_triangle_mesh(*(sm_item->polyhedron()))) - continue; + SMesh* pMesh = sm_item->polyhedron(); + auto vpm = get(CGAL::vertex_point, *pMesh); - Points points; - Polygons polygons; - CGAL::Polygon_mesh_processing::polygon_mesh_to_polygon_soup(*(sm_item->polyhedron()), - points, polygons); - - oracle.add_triangle_soup(points, polygons); - } - else - { - Scene_polygon_soup_item* soup_item = qobject_cast(scene->item(index)); - if(soup_item != nullptr) + triangles.reserve(triangles.size() + num_faces(*pMesh)); + for(boost::graph_traits::face_descriptor f : faces(*pMesh)) { - bool is_triangle_soup = true; - for(auto p : soup_item->polygons()) + boost::graph_traits::halfedge_descriptor h = halfedge(f, *pMesh); + if(!is_triangle(h, *pMesh)) { - if(p.size() != 3) - { - is_triangle_soup = false; - break; - } + print_message("Warning: non-triangular face in input"); + continue; } - if(is_triangle_soup) - oracle.add_triangle_soup(soup_item->points(), soup_item->polygons()); + triangles.emplace_back(get(vpm, target(h, *pMesh)), + get(vpm, target(next(h, *pMesh), *pMesh)), + get(vpm, source(h, *pMesh))); } + + continue; + } + + // --- + Scene_polygon_soup_item* soup_item = qobject_cast(scene->item(index)); + if(soup_item != nullptr) + { + triangles.reserve(triangles.size() + soup_item->polygons().size()); + + for(const auto& p : soup_item->polygons()) + { + if(p.size() != 3) + { + print_message("Warning: non-triangular face in input"); + continue; + } + + triangles.emplace_back(soup_item->points()[p[0]], + soup_item->points()[p[1]], + soup_item->points()[p[2]]); + } + + continue; + } + + // --- + Scene_polyhedron_selection_item* selection_item = + qobject_cast(scene->item(index)); + if(selection_item != nullptr) + { + SMesh* pMesh = selection_item->polyhedron(); + auto vpm = get(CGAL::vertex_point, *pMesh); + + triangles.reserve(triangles.size() + selection_item->selected_facets.size()); + for(const auto& f : selection_item->selected_facets) + { + boost::graph_traits::halfedge_descriptor h = halfedge(f, *pMesh); + if(!is_triangle(h, *pMesh)) + { + print_message("Warning: non-triangular face in input"); + continue; + } + + triangles.emplace_back(get(vpm, target(h, *pMesh)), + get(vpm, target(next(h, *pMesh), *pMesh)), + get(vpm, source(h, *pMesh))); + } + + segments.reserve(segments.size() + selection_item->selected_edges.size()); + for(const auto& e : selection_item->selected_edges) + { + segments.emplace_back(get(vpm, target(halfedge(e, *pMesh), *pMesh)), + get(vpm, target(opposite(halfedge(e, *pMesh), *pMesh), *pMesh))); + } + + points.reserve(points.size() + selection_item->selected_vertices.size()); + for(const auto& v : selection_item->selected_vertices) + { + points.push_back(get(vpm, v)); + } + + continue; + } + + // --- + Scene_polylines_item* lines_item = qobject_cast(scene->item(index)); + if(lines_item != nullptr) + { + for(auto& polyline : lines_item->polylines) + { + for(auto it=std::begin(polyline), end=std::end(polyline); it!=end; ++it) + { + auto nit = std::next(it); + if(nit != end) + segments.emplace_back(*it, *nit); + } + } + + continue; + } + + // --- + Scene_points_with_normal_item* pts_item = qobject_cast(scene->item(index)); + if(pts_item != nullptr) + { + points.insert(std::cend(points), + std::cbegin(pts_item->point_set()->points()), + std::cend(pts_item->point_set()->points())); + + continue; } } + const bool wrap_triangles = ui.wrapFaces->isChecked(); + const bool wrap_segments = ui.wrapEdges->isChecked(); + + if(!wrap_triangles) + { + segments.reserve(segments.size() + 3 * triangles.size()); + for(const auto& tr : triangles) + { + segments.emplace_back(tr[0], tr[1]); + segments.emplace_back(tr[1], tr[2]); + segments.emplace_back(tr[2], tr[0]); + } + } + + if(!wrap_segments) + { + points.reserve(points.size() + 2 * segments.size()); + for(const auto& s : segments) + { + points.push_back(s[0]); + points.push_back(s[1]); + } + } + + if(wrap_triangles) + oracle.add_triangle_soup(triangles); + if(wrap_segments) + oracle.add_segment_soup(segments); + oracle.add_point_set(points); + + // Oracles set up, time to wrap + CGAL::Bbox_3 bbox = oracle.bbox(); const double diag_length = std::sqrt(CGAL::square(bbox.xmax() - bbox.xmin()) + CGAL::square(bbox.ymax() - bbox.ymin()) + diff --git a/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/CMakeLists.txt b/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/CMakeLists.txt index b38cc7a5dae..89b5b8ea92a 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/CMakeLists.txt @@ -5,4 +5,4 @@ qt5_wrap_ui(alpha_wrap_3UI_FILES alpha_wrap_3_dialog.ui) polyhedron_demo_plugin(alpha_wrap_3_plugin Alpha_wrap_3_plugin ${alpha_wrap_3UI_FILES}) #if the plugin uses external libraries like scene_items -target_link_libraries(alpha_wrap_3_plugin PUBLIC scene_surface_mesh_item scene_polygon_soup_item) +target_link_libraries(alpha_wrap_3_plugin PUBLIC scene_surface_mesh_item scene_polygon_soup_item scene_points_with_normal_item scene_selection_item scene_polylines_item) diff --git a/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/alpha_wrap_3_dialog.ui b/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/alpha_wrap_3_dialog.ui index eda61ccaf00..9b2cb24222c 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/alpha_wrap_3_dialog.ui +++ b/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/alpha_wrap_3_dialog.ui @@ -9,21 +9,31 @@ 0 0 - 532 - 280 + 646 + 432 2D Mesh Criteria - + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + 3D Alpha Wrapping - + @@ -33,42 +43,6 @@ - - - - true - - - Enforce 2-manifoldness - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - true - - - @@ -88,15 +62,21 @@ - - + + + + true + - Use relative-to-bbox offset + Enforce 2-manifoldness + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - + + Qt::Vertical @@ -108,10 +88,23 @@ - - + + - Use relative-to-bbox alpha + + + + true + + + + + + + + + + true @@ -125,6 +118,57 @@ + + + + Offset value: + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Alpha value: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + Qt::Horizontal + + + + + + + <html><head/><body><p>Wrap edges<br/><span style=" font-size:9pt;">If deactivated, only extremities of the edges are taken into account</span></p></body></html> + + + + + + + <html><head/><body><p>Use relative-to-bbox offset<br/><span style=" font-size:9pt;">As ratio of the length of the bbox's diagonal<br/>(value </span><span style=" font-size:9pt; font-style:italic;">x </span><span style=" font-size:9pt;">means </span><span style=" font-size:9pt; font-style:italic;">offset := bbox_diag_l / x)</span></p></body></html> + + + @@ -144,25 +188,32 @@ - - + + - Alpha value: + - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + true - - + + - Offset value: + <html><head/><body><p>Wrap faces<br/><span style=" font-size:9pt;">If deactivated, only edges of the faces are taken into account</span></p></body></html> - - + + + + <html><head/><body><p>Use relative-to-bbox alpha<br/><span style=" font-size:9pt;">As ratio of the length of the bbox's diagonal<br/>(value </span><span style=" font-size:9pt; font-style:italic;">x </span><span style=" font-size:9pt;">means alpha</span><span style=" font-size:9pt; font-style:italic;"> := bbox_diag_l / x)</span></p></body></html> + + + + + Qt::Vertical @@ -174,19 +225,16 @@ + + + + Qt::Horizontal + + + - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - From 01485044b63d6d277b466f68d18babaee2ae726c Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Tue, 24 May 2022 10:11:20 +0100 Subject: [PATCH 055/107] Fix typos in the documentation --- Polygon/include/CGAL/General_polygon_with_holes_2.h | 8 ++++---- Polygon/include/CGAL/Polygon_2.h | 6 +++--- Polygon/include/CGAL/Polygon_with_holes_2.h | 8 ++++---- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Polygon/include/CGAL/General_polygon_with_holes_2.h b/Polygon/include/CGAL/General_polygon_with_holes_2.h index 99ebb453956..cf3d666421b 100644 --- a/Polygon/include/CGAL/General_polygon_with_holes_2.h +++ b/Polygon/include/CGAL/General_polygon_with_holes_2.h @@ -127,10 +127,10 @@ protected: // operator<< //-----------------------------------------------------------------------// /*! -This operator exports a General_polygon_with_holes_2 to the output stream `out`. +This operator exports a `General_polygon_with_holes_2` to the output stream `os`. An \ascii and a binary format exist. The format can be selected with -the \cgal modifiers for streams, `set_ascii_mode(0` and `set_binary_mode()` +the \cgal modifiers for streams, `set_ascii_mode()` and `set_binary_mode()`, respectively. The modifier `set_pretty_mode()` can be used to allow for (a few) structuring comments in the output. Otherwise, the output would be free of comments. The default for writing is \ascii without comments. @@ -178,9 +178,9 @@ operator<<(std::ostream& os, const General_polygon_with_holes_2& p) { //-----------------------------------------------------------------------// /*! -This operator imports a General_polygon_with_holes_2 from the input stream `in`. +This operator imports a `General_polygon_with_holes_2` from the input stream `is`. -Both ASCII and binary formats are supported, and the format is automatically detected. +Both \ascii and binary formats are supported, and the format is automatically detected. The format consists of the number of curves of the outer boundary followed by the curves themselves, followed diff --git a/Polygon/include/CGAL/Polygon_2.h b/Polygon/include/CGAL/Polygon_2.h index f305cad314f..0b37a0131b3 100644 --- a/Polygon/include/CGAL/Polygon_2.h +++ b/Polygon/include/CGAL/Polygon_2.h @@ -577,7 +577,7 @@ operator!=(const Polygon_2 &p1, const Polygon_2 &p2); /// Returns the image of the polygon \c p under the transformation \c t. -/// \memberof Polygon_2 +/// \relates Polygon_2 template Polygon_2 transform(const Transformation& t, const Polygon_2& p); @@ -591,13 +591,13 @@ transform(const Transformation& t, const Polygon_2& p); /// Reads a polygon from stream `is` and assigns it to `p`. /// \pre The extract operator must be defined for `Point_2`. -/// \memberof Polygon_2 +/// \relates Polygon_2 template std::istream &operator>>(std::istream &is, Polygon_2& p); /// Inserts the polygon `p` into the stream `os`. /// \pre The insert operator must be defined for `Point_2`. -/// \memberof Polygon_2 +/// \relates Polygon_2 template std::ostream &operator<<(std::ostream &os, const Polygon_2& p); diff --git a/Polygon/include/CGAL/Polygon_with_holes_2.h b/Polygon/include/CGAL/Polygon_with_holes_2.h index 879ea6050a7..7ec7296a0d8 100644 --- a/Polygon/include/CGAL/Polygon_with_holes_2.h +++ b/Polygon/include/CGAL/Polygon_with_holes_2.h @@ -91,10 +91,10 @@ public: //-----------------------------------------------------------------------// /*! -This operator exports a polygon with holes to the output stream `out`. +This operator exports a polygon with holes to the output stream `os`. An \ascii and a binary format exist. The format can be selected with -the \cgal modifiers for streams, `set_ascii_mode()` and `set_binary_mode()` +the \cgal modifiers for streams, `set_ascii_mode()` and `set_binary_mode()`, respectively. The modifier `set_pretty_mode()` can be used to allow for (a few) structuring comments in the output. Otherwise, the output would be free of comments. The default for writing is \ascii without comments. @@ -154,9 +154,9 @@ std::ostream& operator<<(std::ostream &os, //-----------------------------------------------------------------------// /*! -This operator imports a polygon with holes from the input stream `in`. +This operator imports a polygon with holes from the input stream `is`. -Both ASCII and binary formats are supported, and the format is automatically detected. +Both \ascii and binary formats are supported, and the format is automatically detected. The format consists of the number of points of the outer boundary followed by the points themselves in counterclockwise order, followed by the number of holes, From d476a017fab764e3b7374c2cfbde8cae28cc84da Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Tue, 24 May 2022 12:38:28 +0100 Subject: [PATCH 056/107] Polyline_simplification: Clean up examples --- .../Polyline_simplification_2/points_and_vertices.cpp | 4 ---- .../examples/Polyline_simplification_2/simplify.cpp | 4 ---- .../examples/Polyline_simplification_2/simplify_polygon.cpp | 2 -- .../examples/Polyline_simplification_2/simplify_polyline.cpp | 3 --- 4 files changed, 13 deletions(-) diff --git a/Polyline_simplification_2/examples/Polyline_simplification_2/points_and_vertices.cpp b/Polyline_simplification_2/examples/Polyline_simplification_2/points_and_vertices.cpp index 0faecfc1c97..6c9c76bd45a 100644 --- a/Polyline_simplification_2/examples/Polyline_simplification_2/points_and_vertices.cpp +++ b/Polyline_simplification_2/examples/Polyline_simplification_2/points_and_vertices.cpp @@ -1,7 +1,5 @@ #include #include -#include -#include #include #include @@ -74,5 +72,3 @@ int main(int argc, char* argv[]) print(ct, cid); return 0; } - - diff --git a/Polyline_simplification_2/examples/Polyline_simplification_2/simplify.cpp b/Polyline_simplification_2/examples/Polyline_simplification_2/simplify.cpp index 1e5e4e5afa1..3c95bb05025 100644 --- a/Polyline_simplification_2/examples/Polyline_simplification_2/simplify.cpp +++ b/Polyline_simplification_2/examples/Polyline_simplification_2/simplify.cpp @@ -1,6 +1,3 @@ -#include -#include - #include #include #include @@ -56,4 +53,3 @@ int main(int argc, char* argv[]) } return 0; } - diff --git a/Polyline_simplification_2/examples/Polyline_simplification_2/simplify_polygon.cpp b/Polyline_simplification_2/examples/Polyline_simplification_2/simplify_polygon.cpp index e023c999a8e..2e4e69c7a50 100644 --- a/Polyline_simplification_2/examples/Polyline_simplification_2/simplify_polygon.cpp +++ b/Polyline_simplification_2/examples/Polyline_simplification_2/simplify_polygon.cpp @@ -1,5 +1,3 @@ -#include -#include #include #include #include diff --git a/Polyline_simplification_2/examples/Polyline_simplification_2/simplify_polyline.cpp b/Polyline_simplification_2/examples/Polyline_simplification_2/simplify_polyline.cpp index 7bca0e97a74..38bd2f4bae7 100644 --- a/Polyline_simplification_2/examples/Polyline_simplification_2/simplify_polyline.cpp +++ b/Polyline_simplification_2/examples/Polyline_simplification_2/simplify_polyline.cpp @@ -1,11 +1,8 @@ -#include -#include #include #include #include #include #include -#include #include namespace PS = CGAL::Polyline_simplification_2; From d56584bf284ab67d712ab49baae39330b1a99758 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Tue, 24 May 2022 14:30:42 +0200 Subject: [PATCH 057/107] Misc minor fixes / improvements --- .../examples/Alpha_wrap_3/point_set_wrap.cpp | 3 +++ .../CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h | 13 +++++++++---- .../Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp | 7 +++++++ .../Plugins/Alpha_wrap_3/alpha_wrap_3_dialog.ui | 2 +- 4 files changed, 20 insertions(+), 5 deletions(-) diff --git a/Alpha_wrap_3/examples/Alpha_wrap_3/point_set_wrap.cpp b/Alpha_wrap_3/examples/Alpha_wrap_3/point_set_wrap.cpp index 662e3089288..feaa9c804af 100644 --- a/Alpha_wrap_3/examples/Alpha_wrap_3/point_set_wrap.cpp +++ b/Alpha_wrap_3/examples/Alpha_wrap_3/point_set_wrap.cpp @@ -31,6 +31,8 @@ int main(int argc, char** argv) return EXIT_FAILURE; } + std::cout << points.size() << " points" << std::endl; + // Compute the alpha and offset values const double relative_alpha = (argc > 2) ? std::stod(argv[2]) : 10.; const double relative_offset = (argc > 3) ? std::stod(argv[3]) : 300.; @@ -41,6 +43,7 @@ int main(int argc, char** argv) CGAL::square(bbox.zmax() - bbox.zmin())); const double alpha = diag_length / relative_alpha; const double offset = diag_length / relative_offset; + std::cout << "absolute alpha = " << alpha << " absolute offset = " << offset << std::endl; // Construct the wrap CGAL::Real_timer t; diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h index 51e54a8a4e7..ba170ba02a9 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h @@ -19,6 +19,11 @@ #ifdef CGAL_AW3_DEBUG_PP #ifndef CGAL_AW3_DEBUG #define CGAL_AW3_DEBUG + #define CGAL_AW3_DEBUG_INITIALIZATION + #define CGAL_AW3_DEBUG_STEINER_COMPUTATION + #define CGAL_AW3_DEBUG_QUEUE + #define CGAL_AW3_DEBUG_FACET_STATUS + #define CGAL_AW3_DEBUG_MANIFOLDNESS #endif #endif @@ -306,7 +311,7 @@ public: std::cout << "Alpha wrap faces: " << faces(output_mesh).size() << std::endl; #ifdef CGAL_AW3_DEBUG_DUMP_EVERY_STEP - IO::write_polygon_mesh("final.off", alpha_wrap, CGAL::parameters::stream_precision(17)); + IO::write_polygon_mesh("final.off", output_mesh, CGAL::parameters::stream_precision(17)); dump_triangulation_faces("final_dt3.off", false /*only_boundary_faces*/); #endif #endif @@ -788,9 +793,9 @@ private: const bool is_neighbor_cc_in_offset = m_oracle.do_intersect(neighbor_cc_offset_ball); #ifdef CGAL_AW3_DEBUG_STEINER_COMPUTATION - const Point_3& chc = circumcenter(ch); + std::cout << "Compute_steiner_point(" << &*ch << ", " << &*neighbor << ")" << std::endl; - std::cout << "Compute_steiner_point()" << std::endl; + const Point_3& chc = circumcenter(ch); std::cout << "CH" << std::endl; std::cout << "\t" << ch->vertex(0)->point() << std::endl; std::cout << "\t" << ch->vertex(1)->point() << std::endl; @@ -1012,7 +1017,7 @@ private: std::cout << m_dt.number_of_vertices() << " DT vertices" << std::endl; std::cout << m_queue.size() << " facets in the queue" << std::endl; std::cout << "Face " << fid++ << "\n" - << "c = " << &*ch << " (" << m_dt.is_infinite(ch) << "), n =" << &*neighbor << " (" << m_dt.is_infinite(neighbor) << ")" << "\n" + << "c = " << &*ch << " (" << m_dt.is_infinite(ch) << "), n = " << &*neighbor << " (" << m_dt.is_infinite(neighbor) << ")" << "\n" << m_dt.point(ch, (id+1)&3) << "\n" << m_dt.point(ch, (id+2)&3) << "\n" << m_dt.point(ch, (id+3)&3) << std::endl; std::cout << "Priority: " << gate.priority() << std::endl; #endif diff --git a/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp index b849286dcd3..49f943f5437 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp @@ -293,6 +293,13 @@ public Q_SLOTS: oracle.add_segment_soup(segments); oracle.add_point_set(points); + if(!oracle.do_call()) + { + print_message("Warning: empty input - nothing to wrap"); + QApplication::restoreOverrideCursor(); + return; + } + // Oracles set up, time to wrap CGAL::Bbox_3 bbox = oracle.bbox(); diff --git a/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/alpha_wrap_3_dialog.ui b/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/alpha_wrap_3_dialog.ui index 9b2cb24222c..6877e6a99e5 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/alpha_wrap_3_dialog.ui +++ b/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/alpha_wrap_3_dialog.ui @@ -14,7 +14,7 @@ - 2D Mesh Criteria + 3D Alpha Wrapping From 3a64952314f73cbe45d6e6432654007010b86cb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Tue, 24 May 2022 14:31:00 +0200 Subject: [PATCH 058/107] Fix using outside information to erroneously filter bboxes during traversal --- .../CGAL/Alpha_wrap_3/internal/Alpha_wrap_AABB_traits.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_AABB_traits.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_AABB_traits.h index 8b55605d887..1a3fa7d8183 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_AABB_traits.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_AABB_traits.h @@ -267,7 +267,11 @@ public: for(int i=0; i<4; ++i) { - if(!q.m_b.test(i) && do_overlap(q.m_tbox[i], bb) && Base::operator()(q.m_triangles[i], bb)) + // this overload of do_intersect() must not filter based on q.m_b because + // it is called from the AABB_tree's traversal with a node's bounding box, + // and the fact that a facet is incident to an outside cell is irrelevant + // for the hierarchy of bounding boxes of the primitives. + if(do_overlap(q.m_tbox[i], bb) && Base::operator()(q.m_triangles[i], bb)) return true; } From 06e5884b9c916b11e9820afad463f3858e750657 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Tue, 24 May 2022 15:00:02 +0100 Subject: [PATCH 059/107] Add documentation --- Polygon/include/CGAL/Polygon_2.h | 1 + Polygon/include/CGAL/Polygon_with_holes_2.h | 5 +++++ Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h | 3 ++- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Polygon/include/CGAL/Polygon_2.h b/Polygon/include/CGAL/Polygon_2.h index 0b37a0131b3..e8ee290e2ed 100644 --- a/Polygon/include/CGAL/Polygon_2.h +++ b/Polygon/include/CGAL/Polygon_2.h @@ -163,6 +163,7 @@ class Polygon_2 { Polygon_2(const Polygon_2& polygon) : d_container(polygon.d_container), traits(polygon.traits) {} + /// Move constructor Polygon_2(Polygon_2&& polygon) : d_container(std::move(polygon.d_container)), traits(polygon.traits) {} diff --git a/Polygon/include/CGAL/Polygon_with_holes_2.h b/Polygon/include/CGAL/Polygon_with_holes_2.h index 7ec7296a0d8..1e15ba2e7db 100644 --- a/Polygon/include/CGAL/Polygon_with_holes_2.h +++ b/Polygon/include/CGAL/Polygon_with_holes_2.h @@ -63,6 +63,7 @@ public: Base (pgn_boundary) {} + /*! Move constructor */ explicit Polygon_with_holes_2 (Polygon_2&& pgn_boundary) : Base (std::move(pgn_boundary)) {} @@ -75,6 +76,10 @@ public: Base (pgn_boundary, h_begin, h_end) {} + /*! Move constructor. + * \note In order to move the hole polygons a + * `std::move_iterator` can be used. + */ template Polygon_with_holes_2 (Polygon_2&& pgn_boundary, HolesInputIterator h_begin, diff --git a/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h b/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h index 580d8b6819c..dc30f94af43 100644 --- a/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h +++ b/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h @@ -914,6 +914,7 @@ public: /// Copy constructor: copies `rhs` to `*this`. Performs a deep copy of all properties. Surface_mesh(const Surface_mesh& rhs) { *this = rhs; } + /// Move constructor. Surface_mesh(Surface_mesh&& sm) : vprops_(std::move(sm.vprops_)) , hprops_(std::move(sm.hprops_)) @@ -940,7 +941,7 @@ public: /// assigns `rhs` to `*this`. Performs a deep copy of all properties. Surface_mesh& operator=(const Surface_mesh& rhs); - + /// move assignment Surface_mesh& operator=(Surface_mesh&& sm) { vprops_ = std::move(sm.vprops_); From f29015ef1ca388419aef1e5b72d780ad78720d45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 25 May 2022 00:22:24 +0200 Subject: [PATCH 060/107] please intel 2019 compiler --- Kernel_23/include/CGAL/Kernel/function_objects.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Kernel_23/include/CGAL/Kernel/function_objects.h b/Kernel_23/include/CGAL/Kernel/function_objects.h index b5a4d033a3c..f8a8b6d57c7 100644 --- a/Kernel_23/include/CGAL/Kernel/function_objects.h +++ b/Kernel_23/include/CGAL/Kernel/function_objects.h @@ -3543,7 +3543,7 @@ namespace CommonKernelFunctors { // 25 possibilities, so I keep the template. template - decltype(auto) + typename CGAL::Intersection_traits::result_type operator()(const T1& t1, const T2& t2) const { return Intersections::internal::intersection(t1, t2, K()); } }; @@ -3556,11 +3556,11 @@ namespace CommonKernelFunctors { // n possibilities, so I keep the template. template - decltype(auto) + typename CGAL::Intersection_traits::result_type operator()(const T1& t1, const T2& t2) const { return Intersections::internal::intersection(t1, t2, K() ); } - decltype(auto) + boost::optional > operator()(const Plane_3& pl1, const Plane_3& pl2, const Plane_3& pl3)const { return Intersections::internal::intersection(pl1, pl2, pl3, K() ); } }; From 3598e6ecbd9fb2679459cd9d5c3dbac3649e2df4 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Wed, 25 May 2022 07:26:48 +0100 Subject: [PATCH 061/107] Fix Polygon_2::operator=() --- Polygon/include/CGAL/Polygon_2.h | 1 + 1 file changed, 1 insertion(+) diff --git a/Polygon/include/CGAL/Polygon_2.h b/Polygon/include/CGAL/Polygon_2.h index e8ee290e2ed..5b82553609a 100644 --- a/Polygon/include/CGAL/Polygon_2.h +++ b/Polygon/include/CGAL/Polygon_2.h @@ -181,6 +181,7 @@ class Polygon_2 { Polygon_2& operator=(Polygon_2&& p) { d_container = std::move(p.d_container); + return *this; } #endif From 964bcd83ecf7b33366a89db9eadb5fbab4564718 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Wed, 25 May 2022 09:37:37 +0200 Subject: [PATCH 062/107] Fix unused parameter warning --- .../include/CGAL/Alpha_wrap_3/internal/Triangle_soup_oracle.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Triangle_soup_oracle.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Triangle_soup_oracle.h index 39beccaf311..81fed3d58df 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Triangle_soup_oracle.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Triangle_soup_oracle.h @@ -177,7 +177,7 @@ public: template void add_triangle_soup(const TriangleRange& triangles, - const CGAL_NP_CLASS& np = CGAL::parameters::default_values()) + const CGAL_NP_CLASS& /*np*/ = CGAL::parameters::default_values()) { typename Geom_traits::Is_degenerate_3 is_degenerate = this->geom_traits().is_degenerate_3_object(); From e887e3b0b0b98de1fdde7d94064ea7761c353ed0 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Wed, 25 May 2022 13:31:56 +0100 Subject: [PATCH 063/107] Add test for Polygon_with_holes_2 --- .../test/Polygon/Polygon_with_holes_test.cpp | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 Polygon/test/Polygon/Polygon_with_holes_test.cpp diff --git a/Polygon/test/Polygon/Polygon_with_holes_test.cpp b/Polygon/test/Polygon/Polygon_with_holes_test.cpp new file mode 100644 index 00000000000..60ebab3c89e --- /dev/null +++ b/Polygon/test/Polygon/Polygon_with_holes_test.cpp @@ -0,0 +1,38 @@ +#include +#include +#include + +#include +#include +#include +#include + + +typedef CGAL::Simple_cartesian K; +typedef K::Point_2 Point; + + +typedef CGAL::Polygon_2 Polygon_2; +typedef CGAL::General_polygon_with_holes_2 Polygon_with_holes_2; + +int main() +{ + std::array outer = { Point(0, 0), Point(10, 0), Point(10, 10), Point(0, 10) }; + std::array hole1 = { Point(1, 1), Point(1, 2), Point(2, 2), Point(2, 1) }; + std::array hole2 = { Point(3, 3), Point(3, 4), Point(4, 4), Point(4, 3) }; + + std::vector holes; + holes.reserve(2); + holes.emplace_back(hole1.begin(), hole1.end()); + holes.emplace_back(hole2.begin(), hole2.end()); + + Polygon_2 pouter(outer.begin(), outer.end()); + + Polygon_with_holes_2 pwh(std::move(pouter), std::move_iterator::iterator>(holes.begin()), std::move_iterator::iterator>(holes.end())); + + std::cout << pwh << std::endl; + assert(pouter.is_empty()); + assert(holes[0].is_empty()); + assert(holes[1].is_empty()); + return 0; +} From e8f5d6b04262a61580a6225485b3e3caaa26eca3 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Wed, 25 May 2022 13:57:25 +0100 Subject: [PATCH 064/107] Add test for Polygon_2 --- Polygon/include/CGAL/Polygon_2.h | 11 +++++++---- Polygon/include/CGAL/Polygon_with_holes_2.h | 2 +- Polygon/test/Polygon/PolygonTest.cpp | 13 ++++++++++++- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/Polygon/include/CGAL/Polygon_2.h b/Polygon/include/CGAL/Polygon_2.h index 5b82553609a..02cdadac65b 100644 --- a/Polygon/include/CGAL/Polygon_2.h +++ b/Polygon/include/CGAL/Polygon_2.h @@ -42,11 +42,11 @@ namespace CGAL { /// \ingroup PkgPolygon2Ref -/// The class Polygon_2 implements polygons. The Polygon_2 is +/// The class `Polygon_2` implements polygons. The `Polygon_2` is /// parameterized by a traits class and a container class. The latter /// can be any class that fulfills the requirements for an STL -/// container, and has a function `resize()` that takes an std::size_t as argument -/// . It defaults to the std::vector class. +/// container, and has a function `resize()` that takes an `std::size_t` as argument. +/// It defaults to the `std::vector` class. /// /// \cgalHeading{Implementation} /// @@ -165,7 +165,10 @@ class Polygon_2 { /// Move constructor Polygon_2(Polygon_2&& polygon) - : d_container(std::move(polygon.d_container)), traits(polygon.traits) {} + : d_container(std::move(polygon.d_container)), traits(polygon.traits) + { + CGAL_assertion(polygon.is_empty()); + } /// Creates a polygon with vertices from the sequence /// defined by the range \c [first,last). diff --git a/Polygon/include/CGAL/Polygon_with_holes_2.h b/Polygon/include/CGAL/Polygon_with_holes_2.h index 1e15ba2e7db..2c0c87960e5 100644 --- a/Polygon/include/CGAL/Polygon_with_holes_2.h +++ b/Polygon/include/CGAL/Polygon_with_holes_2.h @@ -78,7 +78,7 @@ public: /*! Move constructor. * \note In order to move the hole polygons a - * `std::move_iterator` can be used. + * `std::move_iterator` may be used. */ template Polygon_with_holes_2 (Polygon_2&& pgn_boundary, diff --git a/Polygon/test/Polygon/PolygonTest.cpp b/Polygon/test/Polygon/PolygonTest.cpp index 8b1cebe50ab..a36aeb86c26 100644 --- a/Polygon/test/Polygon/PolygonTest.cpp +++ b/Polygon/test/Polygon/PolygonTest.cpp @@ -51,6 +51,18 @@ void test_default_methods( vector& pvec0, x=p0; assert(x == p0); + + // move assignement and constructor + x.clear(); + assert(x.is_empty()); + x = std::move(p0); + assert(p0.is_empty()); + assert(x == p0_copy); + + CGAL::Polygon_2 > xm(std::move(x)); + assert(x.is_empty()); + assert(xm == p0_copy); + } { @@ -336,4 +348,3 @@ int main() return 0; } - From 74323a484fb7898d5ee26e7760e0ab18b1bf406f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 25 May 2022 18:52:04 +0200 Subject: [PATCH 065/107] workaround issue with pyquery --- Documentation/doc/scripts/html_output_post_processing.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Documentation/doc/scripts/html_output_post_processing.py b/Documentation/doc/scripts/html_output_post_processing.py index f963ac29744..3b3152dc77b 100755 --- a/Documentation/doc/scripts/html_output_post_processing.py +++ b/Documentation/doc/scripts/html_output_post_processing.py @@ -248,6 +248,11 @@ removes some unneeded files, and performs minor repair on some glitches.''') resources_absdir=args.resources os.chdir(args.output) + #workaround issue with operator<< in pyquery + all_pages=glob.glob('*/*.html') + for f in all_pages: + re_replace_in_file("operator<<\(\)", "operator<<()", f) + # number figure automagically_number_figures() From 47f0eb43d12a54cf76bb7abe5c920fc7f9571df0 Mon Sep 17 00:00:00 2001 From: albert-github Date: Thu, 26 May 2022 19:06:01 +0200 Subject: [PATCH 066/107] Poisson_surface_reconstruction_3: unknown command `@commentheading` Found the warning: ``` output_surface_facets_to_triangle_soup.h:29: warning: Found unknown command '@commentheading' ``` Command is superflouous as the `tparam` command will provide the relevant header.. --- .../include/CGAL/IO/output_surface_facets_to_triangle_soup.h | 1 - 1 file changed, 1 deletion(-) diff --git a/Poisson_surface_reconstruction_3/include/CGAL/IO/output_surface_facets_to_triangle_soup.h b/Poisson_surface_reconstruction_3/include/CGAL/IO/output_surface_facets_to_triangle_soup.h index 7e1a27c5ee5..9c2981bd1cb 100644 --- a/Poisson_surface_reconstruction_3/include/CGAL/IO/output_surface_facets_to_triangle_soup.h +++ b/Poisson_surface_reconstruction_3/include/CGAL/IO/output_surface_facets_to_triangle_soup.h @@ -26,7 +26,6 @@ namespace CGAL { /// /// This variant exports the surface as a triangle soup. /// -/// @commentheading Template Parameters: /// @tparam OutputIteratorValueType value_type of OutputIterator. /// It is default to value_type_traits::type, and can be omitted when the default is fine. /// @tparam SurfaceMeshComplex_2InTriangulation_3 model of the SurfaceMeshComplex_2InTriangulation_3 concept. From ff749f7fd6d7815adfd1b7e1aab359d20866aa77 Mon Sep 17 00:00:00 2001 From: Kevin Athey Date: Fri, 27 May 2022 11:46:34 -0700 Subject: [PATCH 067/107] initialize some stack variables --- Triangulation_3/include/CGAL/Delaunay_triangulation_3.h | 2 +- Triangulation_3/include/CGAL/Triangulation_3.h | 2 +- Triangulation_3/include/CGAL/Triangulation_hierarchy_3.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Triangulation_3/include/CGAL/Delaunay_triangulation_3.h b/Triangulation_3/include/CGAL/Delaunay_triangulation_3.h index 642a0910276..e723a744729 100644 --- a/Triangulation_3/include/CGAL/Delaunay_triangulation_3.h +++ b/Triangulation_3/include/CGAL/Delaunay_triangulation_3.h @@ -1076,7 +1076,7 @@ Delaunay_triangulation_3:: insert(const Point& p, Cell_handle start, bool *could_lock_zone) { Locate_type lt; - int li, lj; + int li = 0, lj = 0; // Parallel if(could_lock_zone) diff --git a/Triangulation_3/include/CGAL/Triangulation_3.h b/Triangulation_3/include/CGAL/Triangulation_3.h index 6368bf90d30..df6b6190243 100644 --- a/Triangulation_3/include/CGAL/Triangulation_3.h +++ b/Triangulation_3/include/CGAL/Triangulation_3.h @@ -3862,7 +3862,7 @@ Triangulation_3:: insert(const Point& p, Cell_handle start) { Locate_type lt; - int li, lj; + int li = 0, lj = 0; Cell_handle c = locate(p, lt, li, lj, start); return insert(p, lt, c, li, lj); } diff --git a/Triangulation_3/include/CGAL/Triangulation_hierarchy_3.h b/Triangulation_3/include/CGAL/Triangulation_hierarchy_3.h index bed4d16cd01..abbd99d0d03 100644 --- a/Triangulation_3/include/CGAL/Triangulation_hierarchy_3.h +++ b/Triangulation_3/include/CGAL/Triangulation_hierarchy_3.h @@ -538,7 +538,7 @@ insert(const Point &p, Cell_handle start) { int vertex_level = random_level(); Locate_type lt; - int i, j; + int i = 0, j = 0; // locate using hierarchy locs positions[maxlevel]; locate(p, lt, i, j, positions, start); @@ -578,7 +578,7 @@ insert_and_give_new_cells(const Point &p, OutputItCells fit, Cell_handle start) Locate_type lt; int i, j; // locate using hierarchy - locs positions[maxlevel]; + locs positions[maxlevel] = {0}; locate(p, lt, i, j, positions, start); // insert at level 0 Vertex_handle vertex = hierarchy[0]->insert_and_give_new_cells(p, From 3909bfed10526d596846dceed814605f579f867e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Mon, 30 May 2022 15:53:15 +0200 Subject: [PATCH 068/107] use a simpler version with value clamp and nan handling Herbie expression was failing to give a result a good result on a simple case so I wrote a simpler version --- .../Intersections_2/Segment_2_Segment_2.h | 37 ++++++------------- 1 file changed, 12 insertions(+), 25 deletions(-) diff --git a/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h b/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h index de34ef3e15e..5fd1545cc38 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h @@ -354,37 +354,23 @@ protected: }; -// code generated using Herbie https://herbie.uwplse.org/ inline double s2s2_alpha(double x0, double y0, double x1, double y1, double x2, double y2, double x3, double y3) { - double tmp; - if (x1 <= -9.794158788366665e-11) { - tmp = -(x1 / (x0 - x1)); - } else { - double t_0 = (y1 - y3) / (y1 - y0); - double tmp_1; - if (x1 <= -1.7579125018815487e-296) { - tmp_1 = t_0; - } else if (x1 <= 1.7250761038378636e-206) { - tmp_1 = x2 / ((std::fma(x2, y0, std::fma(y3, x0, (x1 * y2))) - std::fma(x2, y1, std::fma(y3, x1, (x0 * y2)))) / (y3 - y1)); - } else if (x1 <= 3.6888389969707494e-205) { - tmp_1 = t_0; - } else if (x1 <= 1.4339509931401463e-80) { - tmp_1 = (std::fma(x1, y2, std::fma(y1, x3, (y3 * x2))) - std::fma(x2, y1, std::fma(x1, y3, (y2 * x3)))) / std::fma((x3 - x2), (y1 - y0), ((x0 - x1) * (y3 - y2))); - } else if (x1 <= 1.72960576050945e+52) { - tmp_1 = (y1 - y2) / (y1 - y0); - } else if (x1 <= 2.145089573601479e+104) { - tmp_1 = (x1 - x3) / (x1 - x0); - } else { - tmp_1 = (x1 - x2) / (x1 - x0); - } - tmp = tmp_1; - } - return tmp; + const double s1_dx = x0 - x1, + s1_dy = y0 - y1, + s2_dx = x3 - x2, + s2_dy = y3 - y2, + lx = x3 - x1, + ly = y3 - y1; + double val = std::fma(lx,s2_dy,-ly*s2_dx)/std::fma(s1_dx,s2_dy,-s1_dy*s2_dx); + if (val!=val) return 0.5; + if (val<0) return 0; + if (val>1) return 1; + return val; } template @@ -402,6 +388,7 @@ FT s2s2_alpha(const FT& x0, const FT& y0, return (lx*s2_dy-ly*s2_dx)/(s1_dx*s2_dy-s1_dy*s2_dx); } + template typename Segment_2_Segment_2_pair::Intersection_results Segment_2_Segment_2_pair::intersection_type() const From 84730205a96e02243baf6d4c4de2bb6e6ddd450b Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Tue, 31 May 2022 09:30:35 +0100 Subject: [PATCH 069/107] Use the right template parameter of Polygon_with_holes_2 which is different from General_polygon_with_holes_2 --- Polygon/test/Polygon/Polygon_with_holes_test.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Polygon/test/Polygon/Polygon_with_holes_test.cpp b/Polygon/test/Polygon/Polygon_with_holes_test.cpp index 60ebab3c89e..148088e09fb 100644 --- a/Polygon/test/Polygon/Polygon_with_holes_test.cpp +++ b/Polygon/test/Polygon/Polygon_with_holes_test.cpp @@ -13,7 +13,7 @@ typedef K::Point_2 Point; typedef CGAL::Polygon_2 Polygon_2; -typedef CGAL::General_polygon_with_holes_2 Polygon_with_holes_2; +typedef CGAL::Polygon_with_holes_2 Polygon_with_holes_2; int main() { @@ -30,7 +30,6 @@ int main() Polygon_with_holes_2 pwh(std::move(pouter), std::move_iterator::iterator>(holes.begin()), std::move_iterator::iterator>(holes.end())); - std::cout << pwh << std::endl; assert(pouter.is_empty()); assert(holes[0].is_empty()); assert(holes[1].is_empty()); From 07e5bc9ec2d30aebdf118e5914f10a6947eebe07 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Tue, 31 May 2022 15:34:56 +0100 Subject: [PATCH 070/107] Document parameters --- AABB_tree/include/CGAL/AABB_tree.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/AABB_tree/include/CGAL/AABB_tree.h b/AABB_tree/include/CGAL/AABB_tree.h index 6b78257447c..3e4b684b9b8 100644 --- a/AABB_tree/include/CGAL/AABB_tree.h +++ b/AABB_tree/include/CGAL/AABB_tree.h @@ -565,6 +565,8 @@ public: * @param first the first primitive to insert * @param beyond the last primitive to insert * @param range the number of primitive of the range + * @param compute_bbox a functor + * @param split_primitives a functor * * [first,beyond[ is the range of primitives to be added to the tree. */ From cb3393788fc9090d833013f1db43928ace63cf37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 1 Jun 2022 11:38:55 +0200 Subject: [PATCH 071/107] add face_patch_map to split_long_edges --- .../CGAL/Polygon_mesh_processing/remesh.h | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/remesh.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/remesh.h index 5a9de5fbdb3..9b6b8c173c9 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/remesh.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/remesh.h @@ -377,6 +377,17 @@ void isotropic_remeshing(const FaceRange& faces * \cgalParamDefault{an automatically indexed internal map} * \cgalParamNEnd * +* \cgalParamNBegin{face_patch_map} +* \cgalParamDescription{a property map with the patch id's associated to the faces of `faces`} +* \cgalParamType{a class model of `ReadWritePropertyMap` with `boost::graph_traits::%face_descriptor` +* as key type and the desired property, model of `CopyConstructible` and `LessThanComparable` as value type.} +* \cgalParamDefault{a default property map where each face is associated with the ID of +* the connected component it belongs to. Connected components are +* computed with respect to the constrained edges listed in the property map +* `edge_is_constrained_map`} +* \cgalParamExtra{The map is updated during the remeshing process while new faces are created.} +* \cgalParamNEnd +* * \cgalParamNBegin{edge_is_constrained_map} * \cgalParamDescription{a property map containing the constrained-or-not status of each edge of `pmesh`} * \cgalParamType{a class model of `ReadWritePropertyMap` with `boost::graph_traits::%edge_descriptor` @@ -421,14 +432,22 @@ void split_long_edges(const EdgeRange& edges ECMap ecmap = choose_parameter(get_parameter(np, internal_np::edge_is_constrained), Static_boolean_property_map()); + typedef typename internal_np::Lookup_named_param_def < + internal_np::face_patch_t, + NamedParameters, + internal::Connected_components_pmap//default + > ::type FPMap; + FPMap fpmap = choose_parameter( + get_parameter(np, internal_np::face_patch), + internal::Connected_components_pmap(faces(pmesh), pmesh, ecmap, fimap, false)); + typename internal::Incremental_remesher, // no constraint pmap - internal::Connected_components_pmap, - FIMap + FPMap,FIMap > remesher(pmesh, vpmap, gt, false/*protect constraints*/, ecmap, Static_boolean_property_map(), - internal::Connected_components_pmap(faces(pmesh), pmesh, ecmap, fimap, false), + fpmap, fimap, false/*need aabb_tree*/); From 89ef292122de96fa9894fd549beb728f0e408f42 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Wed, 1 Jun 2022 11:20:23 +0100 Subject: [PATCH 072/107] Document node --- AABB_tree/include/CGAL/AABB_tree.h | 1 + 1 file changed, 1 insertion(+) diff --git a/AABB_tree/include/CGAL/AABB_tree.h b/AABB_tree/include/CGAL/AABB_tree.h index 3e4b684b9b8..81a334d5696 100644 --- a/AABB_tree/include/CGAL/AABB_tree.h +++ b/AABB_tree/include/CGAL/AABB_tree.h @@ -562,6 +562,7 @@ public: /** * @brief Builds the tree by recursive expansion. + * @param node the root node of the subtree to generate * @param first the first primitive to insert * @param beyond the last primitive to insert * @param range the number of primitive of the range From f23deb3b1da2bcc8062dde6c0d69f079770250c3 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Wed, 1 Jun 2022 12:48:17 +0100 Subject: [PATCH 073/107] Remove parameter as it is not used internally --- AABB_tree/include/CGAL/AABB_tree.h | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/AABB_tree/include/CGAL/AABB_tree.h b/AABB_tree/include/CGAL/AABB_tree.h index 81a334d5696..0016d4ecc09 100644 --- a/AABB_tree/include/CGAL/AABB_tree.h +++ b/AABB_tree/include/CGAL/AABB_tree.h @@ -577,8 +577,7 @@ public: ConstPrimitiveIterator beyond, const std::size_t range, const ComputeBbox& compute_bbox, - const SplitPrimitives& split_primitives, - const AABBTraits&); + const SplitPrimitives& split_primitives); public: // returns a point which must be on one primitive @@ -794,8 +793,7 @@ public: ConstPrimitiveIterator beyond, const std::size_t range, const ComputeBbox& compute_bbox, - const SplitPrimitives& split_primitives, - const Tr& traits) + const SplitPrimitives& split_primitives) { node.set_bbox(compute_bbox(first, beyond)); @@ -809,13 +807,13 @@ public: break; case 3: node.set_children(*first, new_node()); - expand(node.right_child(), first+1, beyond, 2, compute_bbox, split_primitives, traits); + expand(node.right_child(), first+1, beyond, 2, compute_bbox, split_primitives); break; default: const std::size_t new_range = range/2; node.set_children(new_node(), new_node()); - expand(node.left_child(), first, first + new_range, new_range, compute_bbox, split_primitives, traits); - expand(node.right_child(), first + new_range, beyond, range - new_range, compute_bbox, split_primitives, traits); + expand(node.left_child(), first, first + new_range, new_range, compute_bbox, split_primitives); + expand(node.right_child(), first + new_range, beyond, range - new_range, compute_bbox, split_primitives); } } @@ -847,8 +845,7 @@ public: m_primitives.begin(), m_primitives.end(), m_primitives.size(), compute_bbox, - split_primitives, - m_traits); + split_primitives); } #ifdef CGAL_HAS_THREADS m_atomic_need_build.store(false, std::memory_order_release); // in case build() is triggered by a call to root_node() From 7b77db9d8d30114626af0dea1e4c33f72307e4d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 1 Jun 2022 15:15:39 +0200 Subject: [PATCH 074/107] set up patch id --- .../internal/Isotropic_remeshing/remesh_impl.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Isotropic_remeshing/remesh_impl.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Isotropic_remeshing/remesh_impl.h index 12d0a273651..c312e67228f 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Isotropic_remeshing/remesh_impl.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Isotropic_remeshing/remesh_impl.h @@ -441,18 +441,24 @@ namespace internal { //insert new edges to keep triangular faces, and update long_edges if (!is_border(hnew, mesh_)) { + Patch_id patch_id = get_patch_id(face(hnew, mesh_)); halfedge_descriptor hnew2 = CGAL::Euler::split_face(hnew, next(next(hnew, mesh_), mesh_), mesh_); put(ecmap_, edge(hnew2, mesh_), false); + set_patch_id(face(hnew2, mesh_), patch_id); + set_patch_id(face(opposite(hnew2, mesh_), mesh_), patch_id); } //do it again on the other side if we're not on boundary halfedge_descriptor hnew_opp = opposite(hnew, mesh_); if (!is_border(hnew_opp, mesh_)) { + Patch_id patch_id = get_patch_id(face(hnew_opp, mesh_)); halfedge_descriptor hnew2 = CGAL::Euler::split_face(prev(hnew_opp, mesh_), next(hnew_opp, mesh_), mesh_); put(ecmap_, edge(hnew2, mesh_), false); + set_patch_id(face(hnew2, mesh_), patch_id); + set_patch_id(face(opposite(hnew2, mesh_), mesh_), patch_id); } } #ifdef CGAL_PMP_REMESHING_VERBOSE From ae581c865a5c82238cb6ce0aea6bbbe9bddd8e75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Thu, 2 Jun 2022 02:21:26 +0200 Subject: [PATCH 075/107] Iterative visualization --- .../CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h | 45 ++++++- .../Alpha_wrap_3/Alpha_wrap_3_plugin.cpp | 110 +++++++++++++++++- 2 files changed, 143 insertions(+), 12 deletions(-) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h index ba170ba02a9..696262f15bc 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h @@ -99,6 +99,17 @@ public: }; }; +struct Wrapping_default_visitor +{ + Wrapping_default_visitor() { } + + template + void before_Steiner_point_insertion(const Wrapper&, const Point&) { } + + template + void after_Steiner_point_insertion(const Wrapper&, VertexHandle) { } +}; + template class Alpha_wrap_3 { @@ -172,6 +183,8 @@ public: public: const Geom_traits& geom_traits() const { return m_dt.geom_traits(); } + Dt& triangulation() { return m_dt; } + const Dt& triangulation() const { return m_dt; } double default_alpha() const { @@ -216,6 +229,15 @@ public: OVPM ovpm = choose_parameter(get_parameter(np, internal_np::vertex_point), get_property_map(vertex_point, output_mesh)); + typedef typename internal_np::Lookup_named_param_def < + internal_np::visitor_t, + NamedParameters, + Wrapping_default_visitor // default + >::reference Visitor; + + Wrapping_default_visitor default_visitor; + Visitor visitor = choose_parameter(get_parameter_reference(np, internal_np::visitor), default_visitor); + std::vector no_seeds; using Seeds = typename internal_np::Lookup_named_param_def< internal_np::seed_points_t, NamedParameters, std::vector >::reference; @@ -237,7 +259,7 @@ public: CGAL::parameters::vertex_point_map(ovpm).stream_precision(17)); #endif - alpha_flood_fill(); + alpha_flood_fill(visitor); #ifdef CGAL_AW3_TIMER t.stop(); @@ -607,11 +629,12 @@ private: return true; } +public: // Manifoldness is tolerated while debugging and extracting at intermediate states // Not the preferred way because it uses 3*nv storage template void extract_possibly_non_manifold_surface(OutputMesh& output_mesh, - OVPM ovpm) + OVPM ovpm) const { namespace PMP = Polygon_mesh_processing; @@ -696,7 +719,7 @@ private: template void extract_manifold_surface(OutputMesh& output_mesh, - OVPM ovpm) + OVPM ovpm) const { namespace PMP = Polygon_mesh_processing; @@ -748,7 +771,12 @@ private: if(faces.empty()) return; - CGAL_assertion(PMP::is_polygon_soup_a_polygon_mesh(faces)); + if(!PMP::is_polygon_soup_a_polygon_mesh(faces)) + { + CGAL_warning_msg(false, "Could NOT extract mesh..."); + return; + } + PMP::polygon_soup_to_polygon_mesh(points, faces, output_mesh, CGAL::parameters::default_values(), CGAL::parameters::vertex_point_map(ovpm)); @@ -763,7 +791,7 @@ private: template void extract_surface(OutputMesh& output_mesh, OVPM ovpm, - const bool tolerate_non_manifoldness = false) + const bool tolerate_non_manifoldness = false) const { if(tolerate_non_manifoldness) extract_possibly_non_manifold_surface(output_mesh, ovpm); @@ -990,7 +1018,8 @@ private: return initialize_with_cavities(seeds); } - void alpha_flood_fill() + template + void alpha_flood_fill(Visitor& visitor) { #ifdef CGAL_AW3_DEBUG std::cout << "> Flood fill..." << std::endl; @@ -1082,10 +1111,14 @@ private: m_queue.erase(Gate(mf)); } + visitor.before_Steiner_point_insertion(*this, steiner_point); + // Actual insertion of the Steiner point Vertex_handle vh = m_dt.insert(steiner_point, lt, conflict_cell, li, lj); vh->info() = DEFAULT; + visitor.after_Steiner_point_insertion(*this, vh); + std::vector new_cells; new_cells.reserve(32); m_dt.incident_cells(vh, std::back_inserter(new_cells)); diff --git a/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp index 49f943f5437..81ee7dc974a 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp @@ -29,6 +29,94 @@ #include "ui_alpha_wrap_3_dialog.h" +template +struct AW3_visu_visitor +{ + AW3_visu_visitor(MainWindow* mw, + Scene* scene, + Scene_surface_mesh_item* wrap_item) + : m_mw(mw), + m_scene(scene), + m_wrap_item(wrap_item) + { } + + void set_fcolors(MainWindow mw, + SMesh* smesh, + std::vector colors) + { + typedef SMesh SMesh; + typedef boost::graph_traits::face_descriptor face_descriptor; + + SMesh::Property_map fcolors = + smesh->property_map("f:color").first; + + bool created; + std::tie(fcolors, created) = smesh->add_property_map("f:color", + CGAL::IO::Color(0,0,0)); + assert(colors.size() == smesh->number_of_faces()); + + int color_id = 0; + for(face_descriptor fd : faces(*smesh)) + fcolors[fd] = colors[color_id++]; + } + +public: + template + void before_Steiner_point_insertion(const Wrapper& wrapper, + const Point& p) + { + if(wrapper.triangulation().number_of_vertices() % 10 != 0) + return; + + if(!m_wrap_item) + return; + + std::cout << "on_Steiner_point_insert (" << wrapper.triangulation().number_of_vertices() << ")" << std::endl; + + SMesh* wrap_ptr = m_wrap_item->polyhedron(); + auto vpm = get(CGAL::vertex_point, *wrap_ptr); + wrapper.extract_surface(*wrap_ptr, vpm, true /*tolerate non manifoldness*/); + + m_wrap_item->invalidateOpenGLBuffers(); + m_wrap_item->redraw(); + m_wrap_item->itemChanged(); + +// SMesh wrap; +// auto vpm = get(CGAL::vertex_point, wrap); +// wrapper.extract_surface(wrap, vpm, true /*tolerate non manifoldness*/); + +// Scene_surface_mesh_item* new_wrap_item = new Scene_surface_mesh_item(wrap); +// new_wrap_item->setName(QString("Wrap")); +// new_wrap_item->setColor(Qt::gray); + +// new_wrap_item->setName(m_wrap_item->name()); +// new_wrap_item->setColor(m_wrap_item->color()); +// new_wrap_item->setRenderingMode(m_wrap_item->renderingMode()); +// new_wrap_item->setVisible(m_wrap_item->visible()); +// Scene_item_with_properties *property_item = dynamic_cast(new_wrap_item); +// m_scene->replaceItem(m_scene->item_id(m_wrap_item), new_wrap_item, true); +// if(property_item) +// property_item->copyProperties(m_wrap_item); +// new_wrap_item->invalidateOpenGLBuffers(); +// m_wrap_item->deleteLater(); + + QApplication::processEvents(); + } + + template + void after_Steiner_point_insertion(const Wrapper& wrapper, + const VertexHandle vh) + { + + } + + +private: + MainWindow* m_mw; + Scene* m_scene; + Scene_surface_mesh_item* m_wrap_item; +}; + class Polyhedron_demo_alpha_wrap_3_plugin : public QObject, public CGAL::Three::Polyhedron_demo_plugin_helper @@ -136,7 +224,7 @@ public Q_SLOTS: if(alpha <= 0. || offset <= 0.) return; - QApplication::setOverrideCursor(Qt::WaitCursor); +// QApplication::setOverrideCursor(Qt::WaitCursor); TS_Oracle ts_oracle; SS_Oracle ss_oracle(ts_oracle); @@ -287,6 +375,11 @@ public Q_SLOTS: } } + std::cout << triangles.size() << " triangles" << std::endl; + std::cout << segments.size() << " edges" << std::endl; + std::cout << points.size() << " points" << std::endl; + std::cout << "wrap s/tr: " << wrap_segments << " " << wrap_triangles << std::endl; + if(wrap_triangles) oracle.add_triangle_soup(triangles); if(wrap_segments) @@ -296,7 +389,7 @@ public Q_SLOTS: if(!oracle.do_call()) { print_message("Warning: empty input - nothing to wrap"); - QApplication::restoreOverrideCursor(); +// QApplication::restoreOverrideCursor(); return; } @@ -315,15 +408,20 @@ public Q_SLOTS: CGAL::Alpha_wraps_3::internal::Alpha_wrap_3 aw3(oracle); SMesh wrap; - aw3(alpha, offset, wrap, - CGAL::parameters::do_enforce_manifoldness(enforce_manifoldness)); Scene_surface_mesh_item* wrap_item = new Scene_surface_mesh_item(wrap); wrap_item->setName(tr("Wrap alpha %2 offset %3").arg(alpha).arg(offset)); - wrap_item->setColor(Qt::cyan); + wrap_item->setColor(Qt::gray); scene->addItem(wrap_item); - QApplication::restoreOverrideCursor(); + AW3_visu_visitormw))>::type, + std::remove_referencescene))>::type> visitor(mw, scene, wrap_item); + + aw3(alpha, offset, wrap, + CGAL::parameters::do_enforce_manifoldness(enforce_manifoldness) + .visitor(visitor)); + +// QApplication::restoreOverrideCursor(); } private: From 965964e8b8d6a66439bf847be089d8f4ac27b9d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Thu, 2 Jun 2022 14:25:43 +0200 Subject: [PATCH 076/107] Visualization with a soup, some colors, alpha shading etc. --- .../CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h | 4 + .../Alpha_wrap_3/Alpha_wrap_3_plugin.cpp | 170 +++++++++++++----- 2 files changed, 128 insertions(+), 46 deletions(-) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h index 696262f15bc..3d09b2a8dff 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h @@ -108,6 +108,8 @@ struct Wrapping_default_visitor template void after_Steiner_point_insertion(const Wrapper&, VertexHandle) { } + + void after_alpha_wrapping() { } }; template @@ -337,6 +339,8 @@ public: dump_triangulation_faces("final_dt3.off", false /*only_boundary_faces*/); #endif #endif + + visitor.after_alpha_wrapping(); } // Convenience overloads diff --git a/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp index 81ee7dc974a..eeda371c185 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp @@ -29,53 +29,117 @@ #include "ui_alpha_wrap_3_dialog.h" -template +template struct AW3_visu_visitor { - AW3_visu_visitor(MainWindow* mw, - Scene* scene, - Scene_surface_mesh_item* wrap_item) - : m_mw(mw), - m_scene(scene), + AW3_visu_visitor(Scene* scene, + WrapItem* wrap_item) + : m_scene(scene), m_wrap_item(wrap_item) { } - void set_fcolors(MainWindow mw, - SMesh* smesh, - std::vector colors) - { - typedef SMesh SMesh; - typedef boost::graph_traits::face_descriptor face_descriptor; - - SMesh::Property_map fcolors = - smesh->property_map("f:color").first; - - bool created; - std::tie(fcolors, created) = smesh->add_property_map("f:color", - CGAL::IO::Color(0,0,0)); - assert(colors.size() == smesh->number_of_faces()); - - int color_id = 0; - for(face_descriptor fd : faces(*smesh)) - fcolors[fd] = colors[color_id++]; - } - public: - template - void before_Steiner_point_insertion(const Wrapper& wrapper, + template + void before_Steiner_point_insertion(const AlphaWrapper& wrapper, const Point& p) { - if(wrapper.triangulation().number_of_vertices() % 10 != 0) - return; + // @todo something nicer & smarter + if(wrapper.triangulation().number_of_vertices() < 500) + { + // Do all iterations + } + else if(wrapper.triangulation().number_of_vertices() < 5000) + { + if(wrapper.triangulation().number_of_vertices() % 10 != 0) + return; + } + else if(wrapper.triangulation().number_of_vertices() < 10000) + { + if(wrapper.triangulation().number_of_vertices() % 100 != 0) + return; + } + else if(wrapper.triangulation().number_of_vertices() < 1000000) + { + if(wrapper.triangulation().number_of_vertices() % 1000 != 0) + return; + } if(!m_wrap_item) return; +// for(auto cit=wrapper.triangulation().finite_cells_begin(), cend=wrapper.triangulation().finite_cells_end(); cit!=cend; ++cit) +// std::cout << cit->time_stamp() << std::endl; + std::cout << "on_Steiner_point_insert (" << wrapper.triangulation().number_of_vertices() << ")" << std::endl; - SMesh* wrap_ptr = m_wrap_item->polyhedron(); - auto vpm = get(CGAL::vertex_point, *wrap_ptr); - wrapper.extract_surface(*wrap_ptr, vpm, true /*tolerate non manifoldness*/); + // EXTRACT --- + + using Dt = typename std::decay::type; + using Vertex_handle = typename Dt::Vertex_handle; + using Facet = typename Dt::Facet; + using Cell_handle = typename Dt::Cell_handle; + + std::vector points; + std::vector > faces; + + std::unordered_map vertex_to_id; + std::size_t nv = 0; + + std::size_t min_time_stamp = -1, max_time_stamp = 0; + for(auto cit=wrapper.triangulation().finite_cells_begin(), cend=wrapper.triangulation().finite_cells_end(); cit!=cend; ++cit) + { + if(cit->time_stamp() > max_time_stamp) + max_time_stamp = cit->time_stamp(); + if(cit->time_stamp() < min_time_stamp) + min_time_stamp = cit->time_stamp(); + } + + std::vector vcolors; + std::vector fcolors; + + std::size_t vi = 0, fi = 0; + for(auto fit=wrapper.triangulation().finite_facets_begin(), fend=wrapper.triangulation().finite_facets_end(); fit!=fend; ++fit) + { + Facet f = *fit; + if(!f.first->info().is_outside) + f = wrapper.triangulation().mirror_facet(f); + + const Cell_handle c = f.first; + const int s = f.second; + const Cell_handle nh = c->neighbor(s); + if(c->info().is_outside == nh->info().is_outside) + continue; + + std::array ids; + for(int pos=0; pos<3; ++pos) + { + Vertex_handle vh = c->vertex(Dt::vertex_triple_index(s, pos)); + auto insertion_res = vertex_to_id.emplace(vh, nv); + if(insertion_res.second) // successful insertion, never-seen-before vertex + { + points.push_back(wrapper.triangulation().point(vh)); + vcolors.push_back(CGAL::IO::Color(0, 0, 0)); + ++nv; + } + + ids[pos] = insertion_res.first->second; + } + + faces.emplace_back(std::vector{ids[0], ids[1], ids[2]}); + double color_val = double(c->time_stamp() - min_time_stamp) / double(max_time_stamp - min_time_stamp); + color_val = int(256. * color_val); + // fcolors.push_back(CGAL::IO::Color(color_val, 10, 150)); // young is red, old is blue + // fcolors.push_back(CGAL::IO::Color(256 - color_val, 256 - color_val, 256 - color_val)); // young is light, old is dark + fcolors.push_back(CGAL::IO::Color(100, 100, 100)); // darkish gray + } + +// std::cout << "DT NV " << wrapper.triangulation().number_of_vertices() << " vs " << nv << " vs " << points.size() << std::endl; +// std::cout << "DT NF " << wrapper.triangulation().number_of_finite_facets() << " vs " << fi << " vs " << faces.size() << std::endl; + + // --- EXTRACT + + m_wrap_item->load(points, faces, fcolors, vcolors); + m_wrap_item->setAlpha(255 / 2); m_wrap_item->invalidateOpenGLBuffers(); m_wrap_item->redraw(); @@ -103,18 +167,25 @@ public: QApplication::processEvents(); } - template - void after_Steiner_point_insertion(const Wrapper& wrapper, + template + void after_Steiner_point_insertion(const AlphaWrapper& wrapper, const VertexHandle vh) { } + void after_alpha_wrapping() + { + m_wrap_item->setAlpha(255); + m_wrap_item->invalidateOpenGLBuffers(); + m_wrap_item->redraw(); + m_wrap_item->itemChanged(); + QApplication::processEvents(); + } private: - MainWindow* m_mw; Scene* m_scene; - Scene_surface_mesh_item* m_wrap_item; + WrapItem* m_wrap_item; }; class Polyhedron_demo_alpha_wrap_3_plugin @@ -258,6 +329,8 @@ public Q_SLOTS: get(vpm, source(h, *pMesh))); } + sm_item->setRenderingMode(Flat); + continue; } @@ -280,6 +353,8 @@ public Q_SLOTS: soup_item->points()[p[2]]); } + soup_item->setRenderingMode(Flat); + continue; } @@ -407,20 +482,23 @@ public Q_SLOTS: CGAL::Alpha_wraps_3::internal::Alpha_wrap_3 aw3(oracle); + Scene_polygon_soup_item* iterative_wrap_item = new Scene_polygon_soup_item(); + iterative_wrap_item->setName(tr("Iterative wrap").arg(alpha).arg(offset)); + scene->addItem(iterative_wrap_item); + + AW3_visu_visitorscene))>::type, + Scene_polygon_soup_item> visitor(scene, iterative_wrap_item); + SMesh wrap; - - Scene_surface_mesh_item* wrap_item = new Scene_surface_mesh_item(wrap); - wrap_item->setName(tr("Wrap alpha %2 offset %3").arg(alpha).arg(offset)); - wrap_item->setColor(Qt::gray); - scene->addItem(wrap_item); - - AW3_visu_visitormw))>::type, - std::remove_referencescene))>::type> visitor(mw, scene, wrap_item); - aw3(alpha, offset, wrap, CGAL::parameters::do_enforce_manifoldness(enforce_manifoldness) .visitor(visitor)); +// Scene_surface_mesh_item* wrap_item = new Scene_surface_mesh_item(wrap); +// wrap_item->setName(tr("Wrap alpha %2 offset %3").arg(alpha).arg(offset)); +// wrap_item->setColor(Qt::gray); +// scene->addItem(wrap_item); + // QApplication::restoreOverrideCursor(); } From 3d4ca1ae4e70a88fb35f071657efdfef12ca9d9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 2 Jun 2022 18:42:12 +0200 Subject: [PATCH 077/107] completely disable boost pool allocator some regressions are observed in multithreaded env --- Arrangement_on_surface_2/include/CGAL/Arr_dcel_base.h | 4 +--- .../include/CGAL/Arrangement_on_surface_2.h | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/Arrangement_on_surface_2/include/CGAL/Arr_dcel_base.h b/Arrangement_on_surface_2/include/CGAL/Arr_dcel_base.h index 790600b274e..0d91b8c5044 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arr_dcel_base.h +++ b/Arrangement_on_surface_2/include/CGAL/Arr_dcel_base.h @@ -34,8 +34,6 @@ #include #include -#include - namespace CGAL { inline void* _clean_pointer(const void* p) @@ -964,7 +962,7 @@ public: * The arrangement DCEL class. */ template > + class Allocator = CGAL_ALLOCATOR(int) > class Arr_dcel_base { public: // Define the vertex, halfedge and face types. diff --git a/Arrangement_on_surface_2/include/CGAL/Arrangement_on_surface_2.h b/Arrangement_on_surface_2/include/CGAL/Arrangement_on_surface_2.h index 4b868f09b2d..7067558ff59 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arrangement_on_surface_2.h +++ b/Arrangement_on_surface_2/include/CGAL/Arrangement_on_surface_2.h @@ -46,8 +46,6 @@ #include #include -#include - namespace CGAL { /*! \class Arrangement_on_surface_2 @@ -66,7 +64,7 @@ class Arrangement_on_surface_2 { public: typedef GeomTraits_ Geometry_traits_2; typedef TopTraits_ Topology_traits; - typedef boost::fast_pool_allocator Allocator; + typedef CGAL_ALLOCATOR(int) Allocator; // first define adaptor ... typedef Arr_traits_basic_adaptor_2 Traits_adaptor_2; From 45c5ef753453dc8e3e3103325584b92b344509d5 Mon Sep 17 00:00:00 2001 From: Brian Spilsbury Date: Sat, 4 Jun 2022 13:17:02 +0900 Subject: [PATCH 078/107] Qualify do_intersect to avoid ambiguous dispatch --- .../Intersections_3/internal/Segment_3_Segment_3_do_intersect.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Segment_3_Segment_3_do_intersect.h b/Intersections_3/include/CGAL/Intersections_3/internal/Segment_3_Segment_3_do_intersect.h index 317e531eda0..5943325975b 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Segment_3_Segment_3_do_intersect.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Segment_3_Segment_3_do_intersect.h @@ -30,7 +30,7 @@ do_intersect(const typename K::Segment_3& s1, { CGAL_precondition(!s1.is_degenerate() && !s2.is_degenerate()); - bool b = do_intersect(s1.supporting_line(), s2.supporting_line(), k); + bool b = internal::do_intersect(s1.supporting_line(), s2.supporting_line(), k); if(b) { // supporting_line intersects: points are coplanar From 92a7312c1d978e468e0ab271947a17ca64aa092a Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Mon, 6 Jun 2022 15:18:05 +0200 Subject: [PATCH 079/107] updated crontab (automated commit) --- Maintenance/infrastructure/cgal.geometryfactory.com/crontab | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Maintenance/infrastructure/cgal.geometryfactory.com/crontab b/Maintenance/infrastructure/cgal.geometryfactory.com/crontab index 139138c7c6d..943e698e79f 100644 --- a/Maintenance/infrastructure/cgal.geometryfactory.com/crontab +++ b/Maintenance/infrastructure/cgal.geometryfactory.com/crontab @@ -19,7 +19,7 @@ LC_CTYPE=en_US.UTF-8 # The script also updates the manual tools. # "master" alone -0 21 * * Sun cd $HOME/CGAL/create_internal_release && /usr/bin/time scl enable rh-git29 -- $HOME/bin/create_release $HOME/CGAL/branches/master.git --do-it --beta 1 || echo ERROR +0 21 * * Sun cd $HOME/CGAL/create_internal_release && /usr/bin/time scl enable rh-git29 -- $HOME/bin/create_release $HOME/CGAL/branches/master.git --do-it --beta 1 --public || echo ERROR # "integration" 0 21 * * Mon,Tue,Wed,Thu cd $HOME/CGAL/create_internal_release && /usr/bin/time scl enable rh-git29 -- $HOME/bin/create_release $HOME/CGAL/branches/integration.git $HOME/CGAL/branches/empty-dir --do-it || echo ERROR # from branch 5.4 From fcb97022af58ff6aa85fc216c4d8cb403666f8ef Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Mon, 6 Jun 2022 16:24:23 +0200 Subject: [PATCH 080/107] This branch targets 5.5-beta2 --- Installation/include/CGAL/version.h | 4 ++-- Installation/lib/cmake/CGAL/CGALConfigVersion.cmake | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Installation/include/CGAL/version.h b/Installation/include/CGAL/version.h index 622e6e36cd2..c5154699cef 100644 --- a/Installation/include/CGAL/version.h +++ b/Installation/include/CGAL/version.h @@ -17,10 +17,10 @@ #define CGAL_VERSION_H #ifndef SWIG -#define CGAL_VERSION 5.5-beta1 +#define CGAL_VERSION 5.5-beta2 #define CGAL_GIT_HASH abcdef #endif -#define CGAL_VERSION_NR 1050500910 +#define CGAL_VERSION_NR 1050500920 #define CGAL_SVN_REVISION 99999 #define CGAL_RELEASE_DATE 20220531 diff --git a/Installation/lib/cmake/CGAL/CGALConfigVersion.cmake b/Installation/lib/cmake/CGAL/CGALConfigVersion.cmake index 4ca238e403e..677e2cc198b 100644 --- a/Installation/lib/cmake/CGAL/CGALConfigVersion.cmake +++ b/Installation/lib/cmake/CGAL/CGALConfigVersion.cmake @@ -2,7 +2,7 @@ set(CGAL_MAJOR_VERSION 5) set(CGAL_MINOR_VERSION 5) set(CGAL_BUGFIX_VERSION 0) include(${CMAKE_CURRENT_LIST_DIR}/CGALConfigBuildVersion.cmake) -set(CGAL_VERSION_PUBLIC_RELEASE_VERSION "5.5-beta1") +set(CGAL_VERSION_PUBLIC_RELEASE_VERSION "5.5-beta2") set(CGAL_VERSION_PUBLIC_RELEASE_NAME "CGAL-${CGAL_VERSION_PUBLIC_RELEASE_VERSION}") if (CGAL_BUGFIX_VERSION AND CGAL_BUGFIX_VERSION GREATER 0) From 87cdfe669434f6f90f185bf5de0c0f5bd422b19e Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Mon, 6 Jun 2022 16:29:00 +0200 Subject: [PATCH 081/107] master will now target 5.6 --- Installation/include/CGAL/version.h | 6 +++--- Installation/lib/cmake/CGAL/CGALConfigVersion.cmake | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Installation/include/CGAL/version.h b/Installation/include/CGAL/version.h index 622e6e36cd2..f655dc58ff5 100644 --- a/Installation/include/CGAL/version.h +++ b/Installation/include/CGAL/version.h @@ -17,12 +17,12 @@ #define CGAL_VERSION_H #ifndef SWIG -#define CGAL_VERSION 5.5-beta1 +#define CGAL_VERSION 5.6-dev #define CGAL_GIT_HASH abcdef #endif -#define CGAL_VERSION_NR 1050500910 +#define CGAL_VERSION_NR 1050600900 #define CGAL_SVN_REVISION 99999 -#define CGAL_RELEASE_DATE 20220531 +#define CGAL_RELEASE_DATE 20221131 #include diff --git a/Installation/lib/cmake/CGAL/CGALConfigVersion.cmake b/Installation/lib/cmake/CGAL/CGALConfigVersion.cmake index 4ca238e403e..87fa9944e4d 100644 --- a/Installation/lib/cmake/CGAL/CGALConfigVersion.cmake +++ b/Installation/lib/cmake/CGAL/CGALConfigVersion.cmake @@ -1,8 +1,8 @@ set(CGAL_MAJOR_VERSION 5) -set(CGAL_MINOR_VERSION 5) +set(CGAL_MINOR_VERSION 6) set(CGAL_BUGFIX_VERSION 0) include(${CMAKE_CURRENT_LIST_DIR}/CGALConfigBuildVersion.cmake) -set(CGAL_VERSION_PUBLIC_RELEASE_VERSION "5.5-beta1") +set(CGAL_VERSION_PUBLIC_RELEASE_VERSION "5.5-dev") set(CGAL_VERSION_PUBLIC_RELEASE_NAME "CGAL-${CGAL_VERSION_PUBLIC_RELEASE_VERSION}") if (CGAL_BUGFIX_VERSION AND CGAL_BUGFIX_VERSION GREATER 0) From 8215242e38609982b9c2c90d6279feacc817d3c7 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Mon, 6 Jun 2022 17:18:03 +0200 Subject: [PATCH 082/107] updated crontab (automated commit) --- Maintenance/infrastructure/cgal.geometryfactory.com/crontab | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Maintenance/infrastructure/cgal.geometryfactory.com/crontab b/Maintenance/infrastructure/cgal.geometryfactory.com/crontab index 943e698e79f..9928567e87a 100644 --- a/Maintenance/infrastructure/cgal.geometryfactory.com/crontab +++ b/Maintenance/infrastructure/cgal.geometryfactory.com/crontab @@ -19,7 +19,7 @@ LC_CTYPE=en_US.UTF-8 # The script also updates the manual tools. # "master" alone -0 21 * * Sun cd $HOME/CGAL/create_internal_release && /usr/bin/time scl enable rh-git29 -- $HOME/bin/create_release $HOME/CGAL/branches/master.git --do-it --beta 1 --public || echo ERROR +0 21 * * Sun cd $HOME/CGAL/create_internal_release && /usr/bin/time scl enable rh-git29 -- $HOME/bin/create_release $HOME/CGAL/branches/master.git --do-it --beta 2 --public || echo ERROR # "integration" 0 21 * * Mon,Tue,Wed,Thu cd $HOME/CGAL/create_internal_release && /usr/bin/time scl enable rh-git29 -- $HOME/bin/create_release $HOME/CGAL/branches/integration.git $HOME/CGAL/branches/empty-dir --do-it || echo ERROR # from branch 5.4 From 54a992ff9f089ff983f9ab14c57a11d298f98807 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Tue, 7 Jun 2022 13:00:45 +0200 Subject: [PATCH 083/107] Thie branch targets 5.4.2 --- Installation/include/CGAL/version.h | 4 ++-- Installation/lib/cmake/CGAL/CGALConfigVersion.cmake | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Installation/include/CGAL/version.h b/Installation/include/CGAL/version.h index 3e564f23ef2..2e3fccccc5b 100644 --- a/Installation/include/CGAL/version.h +++ b/Installation/include/CGAL/version.h @@ -17,10 +17,10 @@ #define CGAL_VERSION_H #ifndef SWIG -#define CGAL_VERSION 5.4.1 +#define CGAL_VERSION 5.4.2 #define CGAL_GIT_HASH abcdef #endif -#define CGAL_VERSION_NR 1050410000 +#define CGAL_VERSION_NR 1050420000 #define CGAL_SVN_REVISION 99999 #define CGAL_RELEASE_DATE 20220128 diff --git a/Installation/lib/cmake/CGAL/CGALConfigVersion.cmake b/Installation/lib/cmake/CGAL/CGALConfigVersion.cmake index e8055e48f93..752eada3321 100644 --- a/Installation/lib/cmake/CGAL/CGALConfigVersion.cmake +++ b/Installation/lib/cmake/CGAL/CGALConfigVersion.cmake @@ -1,8 +1,8 @@ set(CGAL_MAJOR_VERSION 5) set(CGAL_MINOR_VERSION 4) -set(CGAL_BUGFIX_VERSION 1) +set(CGAL_BUGFIX_VERSION 2) include(${CMAKE_CURRENT_LIST_DIR}/CGALConfigBuildVersion.cmake) -set(CGAL_VERSION_PUBLIC_RELEASE_VERSION "5.4.1") +set(CGAL_VERSION_PUBLIC_RELEASE_VERSION "5.4.2") set(CGAL_VERSION_PUBLIC_RELEASE_NAME "CGAL-${CGAL_VERSION_PUBLIC_RELEASE_VERSION}") if (CGAL_BUGFIX_VERSION AND CGAL_BUGFIX_VERSION GREATER 0) From cf4446e27232de82f6408cafb0f7a362e7de5310 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Tue, 7 Jun 2022 13:18:04 +0200 Subject: [PATCH 084/107] updated crontab (automated commit) --- .../infrastructure/cgal.geometryfactory.com/crontab | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Maintenance/infrastructure/cgal.geometryfactory.com/crontab b/Maintenance/infrastructure/cgal.geometryfactory.com/crontab index 9928567e87a..a55ba1a43b5 100644 --- a/Maintenance/infrastructure/cgal.geometryfactory.com/crontab +++ b/Maintenance/infrastructure/cgal.geometryfactory.com/crontab @@ -22,13 +22,15 @@ LC_CTYPE=en_US.UTF-8 0 21 * * Sun cd $HOME/CGAL/create_internal_release && /usr/bin/time scl enable rh-git29 -- $HOME/bin/create_release $HOME/CGAL/branches/master.git --do-it --beta 2 --public || echo ERROR # "integration" 0 21 * * Mon,Tue,Wed,Thu cd $HOME/CGAL/create_internal_release && /usr/bin/time scl enable rh-git29 -- $HOME/bin/create_release $HOME/CGAL/branches/integration.git $HOME/CGAL/branches/empty-dir --do-it || echo ERROR +# from branch 5.5 +0 21 * * Fri cd $HOME/CGAL/create_internal_release-5.5-branch && /usr/bin/time scl enable rh-git29 -- $HOME/bin/create_release $HOME/CGAL/branches/CGAL-5.4-branch.git --public --do-it || echo ERROR # from branch 5.4 -0 21 * * Fri cd $HOME/CGAL/create_internal_release-5.4-branch && /usr/bin/time scl enable rh-git29 -- $HOME/bin/create_release $HOME/CGAL/branches/CGAL-5.4-branch.git --public --do-it || echo ERROR -# from branch 5.3 -0 21 * * Sat cd $HOME/CGAL/create_internal_release-5.3-branch && /usr/bin/time scl enable rh-git29 -- $HOME/bin/create_release $HOME/CGAL/branches/CGAL-5.3-branch.git --public --do-it || echo ERROR +0 21 * * Sat cd $HOME/CGAL/create_internal_release-5.4-branch && /usr/bin/time scl enable rh-git29 -- $HOME/bin/create_release $HOME/CGAL/branches/CGAL-5.4-branch.git --public --do-it || echo ERROR ## Older stuff +# from branch 5.3 +0 21 * * Sat cd $HOME/CGAL/create_internal_release-5.3-branch && /usr/bin/time scl enable rh-git29 -- $HOME/bin/create_release $HOME/CGAL/branches/CGAL-5.3-branch.git --public --do-it || echo ERROR # from branch 5.2 #0 21 * * Fri cd $HOME/CGAL/create_internal_release-5.2-branch && /usr/bin/time scl enable rh-git29 -- $HOME/bin/create_release $HOME/CGAL/branches/CGAL-5.2-branch.git --public --do-it || echo ERROR # from branch 5.1 From 6869bddeaa7fdc4e7f65a309c73282f3d5ca753f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 7 Jun 2022 16:15:53 +0200 Subject: [PATCH 085/107] add a named parameter to avoid flipping high triangles --- .../Isotropic_remeshing/remesh_impl.h | 5 +-- .../repair_degeneracies.h | 31 ++++++++++++++----- .../shape_predicates.h | 2 +- .../internal/parameters_interface.h | 1 + 4 files changed, 28 insertions(+), 11 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Isotropic_remeshing/remesh_impl.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Isotropic_remeshing/remesh_impl.h index 12d0a273651..f1eeec4c6a4 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Isotropic_remeshing/remesh_impl.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Isotropic_remeshing/remesh_impl.h @@ -853,11 +853,12 @@ namespace internal { mesh_, vpmap_, vcmap_, ecmap_, gt_, cap_threshold, // bound on the angle: above 160 deg => cap 4, // bound on shortest/longest edge above 4 => needle - 0);// collapse length threshold : not needed here + 0,// collapse length threshold : not needed here + 0); // flip triangle height threshold std::array r2 = internal::is_badly_shaped( face(opposite(he, mesh_), mesh_), - mesh_, vpmap_, vcmap_, ecmap_, gt_, cap_threshold, 4, 0); + mesh_, vpmap_, vcmap_, ecmap_, gt_, cap_threshold, 4, 0, 0); const bool badly_shaped = (r1[0] != boost::graph_traits::null_halfedge()//needle || r1[1] != boost::graph_traits::null_halfedge()//cap diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair_degeneracies.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair_degeneracies.h index 31d8d003124..7edb6fca279 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair_degeneracies.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair_degeneracies.h @@ -61,7 +61,8 @@ is_badly_shaped(const typename boost::graph_traits::face_descripto const Traits& gt, const double cap_threshold, // angle over 160° ==> cap const double needle_threshold, // longest edge / shortest edge over this ratio ==> needle - const double collapse_length_threshold) // max length of edges allowed to be collapsed + const double collapse_length_threshold, // max length of edges allowed to be collapsed + const double flip_triangle_height_threshold_squared) // max height of triangles allowed to be flipped { namespace PMP = CGAL::Polygon_mesh_processing; @@ -83,8 +84,14 @@ is_badly_shaped(const typename boost::graph_traits::face_descripto } res = PMP::is_cap_triangle_face(f, tmesh, cap_threshold, parameters::vertex_point_map(vpm).geom_traits(gt)); - if(res != null_h && !get(ecm, edge(res, tmesh))) + if( res != null_h && !get(ecm, edge(res, tmesh) ) && + (flip_triangle_height_threshold_squared == 0 || + typename Traits::Compare_squared_distance_3()( get(vpm, target(next(res,tmesh), tmesh)), + typename Traits::Line_3(get(vpm, source(res,tmesh)), get(vpm, target(res,tmesh))), + flip_triangle_height_threshold_squared) != LARGER )) + { return make_array(null_h, res); + } return make_array(null_h, null_h); } @@ -100,13 +107,15 @@ void collect_badly_shaped_triangles(const typename boost::graph_traits cap const double needle_threshold, // longest edge / shortest edge over this ratio ==> needle const double collapse_length_threshold, // max length of edges allowed to be collapsed + const double flip_triangle_height_threshold_squared, // max height squared of triangles that can be flipped HalfedgeContainer& edges_to_collapse, HalfedgeContainer& edges_to_flip) { typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; std::array res = is_badly_shaped(f, tmesh, vpm, vcm, ecm, gt, cap_threshold, - needle_threshold, collapse_length_threshold); + needle_threshold, + collapse_length_threshold, flip_triangle_height_threshold_squared); if(res[0] != boost::graph_traits::null_halfedge()) { @@ -580,6 +589,9 @@ bool remove_almost_degenerate_faces(const FaceRange& face_range, typedef typename boost::property_map::type DVCM; DVCM vcm = get(Vertex_property_tag(), tmesh); + const double flip_triangle_height_threshold_squared = + CGAL::square(choose_parameter(get_parameter(np, internal_np::flip_triangle_height_threshold), 0)); + CGAL_precondition(is_valid_polygon_mesh(tmesh)); CGAL_precondition(is_triangle_mesh(tmesh)); @@ -611,7 +623,8 @@ bool remove_almost_degenerate_faces(const FaceRange& face_range, for(face_descriptor f : face_range) { internal::collect_badly_shaped_triangles(f, tmesh, vpm, vcm, ecm, gt, - cap_threshold, needle_threshold, collapse_length_threshold, + cap_threshold, needle_threshold, + collapse_length_threshold, flip_triangle_height_threshold_squared, edges_to_collapse, edges_to_flip); } @@ -671,7 +684,7 @@ bool remove_almost_degenerate_faces(const FaceRange& face_range, // Verify that the element is still badly shaped const std::array nc = internal::is_badly_shaped(face(h, tmesh), tmesh, vpm, vcm, ecm, gt, - cap_threshold, needle_threshold, collapse_length_threshold); + cap_threshold, needle_threshold, collapse_length_threshold, flip_triangle_height_threshold_squared); if(nc[0] != h) { @@ -757,7 +770,8 @@ bool remove_almost_degenerate_faces(const FaceRange& face_range, if(!is_border(hv, tmesh)) { internal::collect_badly_shaped_triangles(face(hv, tmesh), tmesh, vpm, vcm, ecm, gt, - cap_threshold, needle_threshold, collapse_length_threshold, + cap_threshold, needle_threshold, + collapse_length_threshold, flip_triangle_height_threshold_squared, edges_to_collapse, edges_to_flip); } } @@ -806,7 +820,7 @@ bool remove_almost_degenerate_faces(const FaceRange& face_range, std::array nc = internal::is_badly_shaped(face(h, tmesh), tmesh, vpm, vcm, ecm, gt, cap_threshold, needle_threshold, - collapse_length_threshold); + collapse_length_threshold, flip_triangle_height_threshold_squared); // Check the triangle is still a cap if(nc[1] != h) { @@ -868,7 +882,8 @@ bool remove_almost_degenerate_faces(const FaceRange& face_range, CGAL_assertion(!is_border(h, tmesh)); std::array nc = internal::is_badly_shaped(face(h, tmesh), tmesh, vpm, vcm, ecm, gt, - cap_threshold, needle_threshold, collapse_length_threshold); + cap_threshold, needle_threshold, + collapse_length_threshold, flip_triangle_height_threshold_squared); if(nc[1] != boost::graph_traits::null_halfedge() && nc[1] != h) next_edges_to_flip.insert(nc[1]); diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/shape_predicates.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/shape_predicates.h index e0f87a849ee..3eb3fa892e6 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/shape_predicates.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/shape_predicates.h @@ -503,7 +503,7 @@ struct Is_cap_angle_over_threshold /// \ingroup PMP_predicates_grp /// /// checks whether a triangle face is a cap. -/// A triangle is said to be a cap if one of the its angles is close to `180` degrees. +/// A triangle is said to be a cap if one of its angles is close to `180` degrees. /// /// @tparam TriangleMesh a model of `FaceGraph` /// @tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters" diff --git a/STL_Extension/include/CGAL/STL_Extension/internal/parameters_interface.h b/STL_Extension/include/CGAL/STL_Extension/internal/parameters_interface.h index 0162e1db87a..cfc54c6631c 100644 --- a/STL_Extension/include/CGAL/STL_Extension/internal/parameters_interface.h +++ b/STL_Extension/include/CGAL/STL_Extension/internal/parameters_interface.h @@ -130,6 +130,7 @@ CGAL_add_named_parameter(match_faces_t, match_faces, match_faces) CGAL_add_named_parameter(face_epsilon_map_t, face_epsilon_map, face_epsilon_map) CGAL_add_named_parameter(maximum_number_t, maximum_number, maximum_number) CGAL_add_named_parameter(use_one_sided_hausdorff_t, use_one_sided_hausdorff, use_one_sided_hausdorff) +CGAL_add_named_parameter(flip_triangle_height_threshold_t, flip_triangle_height_threshold, flip_triangle_height_threshold) // List of named parameters that we use in the package 'Surface Mesh Simplification' CGAL_add_named_parameter(get_cost_policy_t, get_cost_policy, get_cost) From be0f80223664114ea57364951ab28a664fe6cd9c Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Tue, 7 Jun 2022 16:34:02 +0200 Subject: [PATCH 086/107] Warn only if CGAL_TEST_SUITE is set and CGAL_DATA_DIR is not --- Installation/lib/cmake/CGAL/CGALConfig.cmake | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Installation/lib/cmake/CGAL/CGALConfig.cmake b/Installation/lib/cmake/CGAL/CGALConfig.cmake index 4f3a16b5026..6edefb1810f 100644 --- a/Installation/lib/cmake/CGAL/CGALConfig.cmake +++ b/Installation/lib/cmake/CGAL/CGALConfig.cmake @@ -89,7 +89,9 @@ if (NOT CGAL_DATA_DIR) if (EXISTS "${CMAKE_SOURCE_DIR}/../../data") set(CGAL_DATA_DIR "${CMAKE_SOURCE_DIR}/../../data") else() - message(WARNING "CGAL_DATA_DIR cannot be deduced, set the variable CGAL_DATA_DIR to set the default value of CGAL::data_file_path()") + if(CGAL_TEST_SUITE) + message(WARNING "CGAL_DATA_DIR cannot be deduced, set the variable CGAL_DATA_DIR to set the default value of CGAL::data_file_path()") + endif() endif() endif() endif() From ef5bca8d105691bfa5661b51181e8517e662d609 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Tue, 7 Jun 2022 17:08:46 +0100 Subject: [PATCH 087/107] Regularized Boolean Set Operations: Help compiler to disambiguate --- .../CGAL/Boolean_set_operations_2/do_intersect.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/do_intersect.h b/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/do_intersect.h index 86a3caa571b..b3eba3b7e2d 100644 --- a/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/do_intersect.h +++ b/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/do_intersect.h @@ -237,7 +237,9 @@ inline bool do_intersect(const General_polygon_with_holes_2& pgn1, // With Traits template inline bool do_intersect(InputIterator begin, InputIterator end, Traits& traits, - unsigned int k=5) + unsigned int k=5, + typename boost::enable_if + >::type* = 0) { return r_do_intersect(begin, end, traits, k); } // Without Traits @@ -245,6 +247,8 @@ inline bool do_intersect(InputIterator begin, InputIterator end, Traits& traits, template inline bool do_intersect(InputIterator begin, InputIterator end, Tag_true = Tag_true(), unsigned int k=5, + typename boost::enable_if + >::type* = 0, Enable_if_Polygon_2_iterator* = 0) { return r_do_intersect(begin, end, k); } @@ -252,6 +256,8 @@ inline bool do_intersect(InputIterator begin, InputIterator end, template inline bool do_intersect(InputIterator begin, InputIterator end, Tag_false, unsigned int k=5, + typename boost::enable_if + >::type* = 0, Enable_if_Polygon_2_iterator* = 0) { typename Iterator_to_gps_traits::Traits traits; @@ -262,6 +268,8 @@ inline bool do_intersect(InputIterator begin, InputIterator end, template inline bool do_intersect(InputIterator begin, InputIterator end, unsigned int k=5, + typename boost::enable_if + >::type* = 0, Disable_if_Polygon_2_iterator* = 0) { typename Iterator_to_gps_traits::Traits traits; From 8c13bdaea39bd6291644c875439444239190bf76 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Tue, 7 Jun 2022 19:47:30 +0100 Subject: [PATCH 088/107] Add issue 6600 test case --- .../test/Intersections_2/issue6600.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 Intersections_2/test/Intersections_2/issue6600.cpp diff --git a/Intersections_2/test/Intersections_2/issue6600.cpp b/Intersections_2/test/Intersections_2/issue6600.cpp new file mode 100644 index 00000000000..4c94455fd31 --- /dev/null +++ b/Intersections_2/test/Intersections_2/issue6600.cpp @@ -0,0 +1,15 @@ +#include +#include +#include +#include + +int main() +{ + typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel; + typedef Kernel::Point_3 Point; + typedef CGAL::Surface_mesh Surface_mesh; + Surface_mesh mesh; + CGAL::Polygon_mesh_processing::experimental::autorefine_and_remove_self_intersections(mesh); + + return 0; +} From 7ba4fbcaabb7a6eaf85baf66a8f99a4152ceeb0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 7 Jun 2022 20:57:57 +0200 Subject: [PATCH 089/107] std++14 style enable_if --- .../CGAL/Boolean_set_operations_2/do_intersect.h | 12 ++++-------- .../CGAL/Boolean_set_operations_2/intersection.h | 3 +-- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/do_intersect.h b/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/do_intersect.h index b3eba3b7e2d..820596d5fb7 100644 --- a/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/do_intersect.h +++ b/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/do_intersect.h @@ -238,8 +238,7 @@ inline bool do_intersect(const General_polygon_with_holes_2& pgn1, template inline bool do_intersect(InputIterator begin, InputIterator end, Traits& traits, unsigned int k=5, - typename boost::enable_if - >::type* = 0) + std::enable_if_t::value>* = 0) { return r_do_intersect(begin, end, traits, k); } // Without Traits @@ -247,8 +246,7 @@ inline bool do_intersect(InputIterator begin, InputIterator end, Traits& traits, template inline bool do_intersect(InputIterator begin, InputIterator end, Tag_true = Tag_true(), unsigned int k=5, - typename boost::enable_if - >::type* = 0, + std::enable_if_t::value>* = 0, Enable_if_Polygon_2_iterator* = 0) { return r_do_intersect(begin, end, k); } @@ -256,8 +254,7 @@ inline bool do_intersect(InputIterator begin, InputIterator end, template inline bool do_intersect(InputIterator begin, InputIterator end, Tag_false, unsigned int k=5, - typename boost::enable_if - >::type* = 0, + std::enable_if_t::value>* = 0, Enable_if_Polygon_2_iterator* = 0) { typename Iterator_to_gps_traits::Traits traits; @@ -268,8 +265,7 @@ inline bool do_intersect(InputIterator begin, InputIterator end, template inline bool do_intersect(InputIterator begin, InputIterator end, unsigned int k=5, - typename boost::enable_if - >::type* = 0, + std::enable_if_t::value>* = 0, Disable_if_Polygon_2_iterator* = 0) { typename Iterator_to_gps_traits::Traits traits; diff --git a/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/intersection.h b/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/intersection.h index 7599c835c5c..f961e507a0e 100644 --- a/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/intersection.h +++ b/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/intersection.h @@ -288,8 +288,7 @@ inline OutputIterator intersection(InputIterator begin, InputIterator end, OutputIterator oi, unsigned int k=5, // workaround to avoid ambiguous calls with kernel functions - typename boost::enable_if - >::type* = 0, + std::enable_if_t::value>* = 0, Disable_if_Polygon_2_iterator* = 0) { typename Iterator_to_gps_traits::Traits traits; From 5b0219128633842c342e6dfb7ec039dc403f8140 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Wed, 8 Jun 2022 09:53:27 +0200 Subject: [PATCH 090/107] Announcement for 5.5.-beta1 --- .../announcement/announcement-beta.md | 144 +++++-------- .../announcement/mailing-beta.eml | 202 +++++++++++------- 2 files changed, 178 insertions(+), 168 deletions(-) diff --git a/Maintenance/public_release/announcement/announcement-beta.md b/Maintenance/public_release/announcement/announcement-beta.md index ad13992963f..744bd37df84 100644 --- a/Maintenance/public_release/announcement/announcement-beta.md +++ b/Maintenance/public_release/announcement/announcement-beta.md @@ -1,88 +1,62 @@ -%The CGAL Open Source Project is pleased to announce the release 5.3 Beta 1 of CGAL, the Computational Geometry Algorithms Library. +The CGAL Open Source Project is pleased to announce the release 5.5 Beta 1 of CGAL, the Computational Geometry Algorithms Library. -CGAL version 5.3 Beta 1 is a public testing release. It should provide a solid ground to report bugs that need to be tackled before the release of the final version of CGAL 5.3 in July 2021. +CGAL version 5.5 Beta 1 is a public testing release. It should provide a solid ground to report bugs that need to be tackled before the release of the final version of CGAL 5.5 in July 2022. + +Besides fixes and general enhancement to existing packages, the following has changed since CGAL 5.4: + +### [3D Alpha Wrapping (new package)](https://doc.cgal.org/5.5/Manual/packages.html#PkgAlphaWrap3) + +- This component takes a 3D triangle mesh, soup, or point set as input, and generates a valid (watertight, intersection-free, and combinatorially 2-manifold) surface triangle mesh that contains the input. + The algorithm proceeds by shrink-wrapping and refining a 3D Delaunay triangulation, starting from a loose bounding box of the input. + Two user-defined parameters, alpha and offset, offer control over the maximum size of cavities where the shrink-wrapping process can enter, and the tightness of the final surface mesh to the input, respectively. Once combined, these parameters provide a means to trade fidelity + to the input for complexity of the output. + + See also the [announcement page](https://www.cgal.org/2022/05/18/alpha_wrap/). + +### [3D Convex Hulls](https://doc.cgal.org/5.5/Manual/packages.html#PkgConvexHull3) + +- Added an [overload of the function `CGAL::convex_hull_3()`](https://doc.cgal.org/5.5/Convex_hull_3/group__PkgConvexHull3Functions.html#ga52fca4745c2ef0351063fbe66b035fd1), which writes the result in an indexed triangle set. + +### [2D Polygons](https://doc.cgal.org/5.5/Manual/packages.html#PkgPolygon2) + +- Add vertex, edge, and hole ranges. +- The concept [`GeneralPolygonWithHoles_2`](https://doc.cgal.org/5.5/Polygon/classGeneralPolygonWithHoles__2.html) now requires the nested type `Polygon_2` instead of `General_polygon_2`. + +### [2D Regularized Boolean Set-Operations](https://doc.cgal.org/5.5/Manual/packages.html#PkgBooleanSetOperations2) +- The concept [`GeneralPolygonSetTraits_2`](https://doc.cgal.org/5.5/Boolean_set_operations_2/classGeneralPolygonSetTraits__2.html) now requires the nested type `Construct_polygon_with_holes_2` instead of `Construct_general_polygon_with_holes_2`. + +### [Combinatorial Maps](https://doc.cgal.org/5.5/Manual/packages.html#PkgCombinatorialMaps) + +- Removed old code deprecated in CGAL 4.9 and 4.10 (global functions, and information associated with darts). + +### [2D Arrangements](https://doc.cgal.org/5.5/Manual/packages.html#PkgArrangementOnSurface2) +- Fixed the `intersect_2`, `compare_y_at_x_right`, and `compare_y_at_x_left` function objects of the traits class template [`Arr_geodesic_arc_on_sphere_traits_2`](https://doc.cgal.org/5.5/Arrangement_on_surface_2/classCGAL_1_1Arr__geodesic__arc__on__sphere__traits__2.html) that handles geodesic arcs on sphere and applied a small syntactical fix to the tracing traits. + +### [Tetrahedral Mesh Generation](https://doc.cgal.org/5.5/Manual/packages.html#PkgMesh3) + +- Added the function [`remove_isolated_vertices()`](https://doc.cgal.org/5.5/Mesh_3/classCGAL_1_1Mesh__complex__3__in__triangulation__3.html#ace57c4e777da457c6e33b4f6e89949ce) as a post-processing step for the tetrahedral mesh generation. + +### [Polygon Mesh Processing](https://doc.cgal.org/5.5/Manual/packages.html#PkgPolygonMeshProcessing) +- Added the function [`CGAL::Polygon_mesh_processing::orient_triangle_soup_with_reference_triangle_soup()`](https://doc.cgal.org/5.5/Polygon_mesh_processing/group__PMP__orientation__grp.html#ga855b1c55c201b91ab04eebd2811a87fd), which enables re-orienting the faces of a triangle soup based on the orientation of the nearest face in a reference triangle soup. +- Added the function [`CGAL::Polygon_mesh_processing::compatible_orientations()`](https://doc.cgal.org/5.5/Polygon_mesh_processing/group__PMP__orientation__grp.html#ga9ac9b9434084b64f3304df636c3178a3), which enables to retrieve the (in)compatibility of orientations of faces from different connected components. +- Added the function [`CGAL::Polygon_mesh_processing::tangential_relaxation()`](https://doc.cgal.org/5.5/Polygon_mesh_processing/group__PMP__meshing__grp.html#ga136c659162e5360354db5879db7431b4), which applies an area-based tangential mesh smoothing to the vertices of a surface triangle mesh. +- Added the named parameter `visitor` to the function [`triangulate_hole()`](https://doc.cgal.org/5.5/Polygon_mesh_processing/group__PMP__hole__filling__grp.html#gad2d3c43bce0ef90a16530478196d7f42), which enables to track progress with callbacks. +- Added more functions in the [visitor of the corefinement based methods](https://doc.cgal.org/5.5/Polygon_mesh_processing/classPMPCorefinementVisitor.html) to track progress. + +### [Surface Mesh Simplification](https://doc.cgal.org/5.5/Manual/packages.html#PkgSurfaceMeshSimplification) +- Introduced four variations of the Garland-Heckbert simplification algorithm based on the probabilistic approach of Trettner and Kobbelt (Fast and Robust QEF Minimization using Probabilistic Quadrics): [`GarlandHeckbert_plane_policies`](https://doc.cgal.org/5.5/Surface_mesh_simplification/classCGAL_1_1Surface__mesh__simplification_1_1GarlandHeckbert__plane__policies.html), [`GarlandHeckbert_probabilistic_plane_policies`](https://doc.cgal.org/5.5/Surface_mesh_simplification/classCGAL_1_1Surface__mesh__simplification_1_1GarlandHeckbert__probabilistic__plane__policies.html), [`GarlandHeckbert_triangle_policies`](https://doc.cgal.org/5.5/Surface_mesh_simplification/classCGAL_1_1Surface__mesh__simplification_1_1GarlandHeckbert__triangle__policies.html), and [`GarlandHeckbert_probabilistic_triangle_policies`](https://doc.cgal.org/5.5/Surface_mesh_simplification/classCGAL_1_1Surface__mesh__simplification_1_1GarlandHeckbert__probabilistic__triangle__policies.html). +- The class `GarlandHeckbert_policies` has been deprecated, `GarlandHeckbert_plane_policies` replaces it. + +### [Point Set Processing](https://doc.cgal.org/5.5/Manual/packages.html#PkgPointSetProcessing3) + +- A new optional named parameter, `min_points_per_cell` has been added to [`grid_simplify_point_set()`](https://doc.cgal.org/5.5/Point_set_processing_3/group__PkgPointSetProcessing3Algorithms.html#ga7757ef9b3900e42fde26f5a0ac56e20f). By adding a minimal number of points in a cell such that a point is retained, one can also filter out low density areas and outliers: in the case of densely sampled point clouds, this yields better results than using grid simplification and then outlier removal, while being very vast. The default value is `1` to keep the previous behavior as default. + +### [dD Spatial Searching](https://doc.cgal.org/5.5/Manual/packages.html#PkgSpatialSearchingD) + +- Added the member function [`write_graphviz()`](https://doc.cgal.org/5.5/Spatial_searching/classCGAL_1_1Kd__tree.html#ac2851b5cafb8d5cce0dc5fb107c8f13f) to the class `Kd_tree` that writes the tree in a stream in the [Graphviz](https://graphviz.org/) format. + +### [CGAL and the Boost Graph Library (BGL)](https://doc.cgal.org/5.5/Manual/packages.html#PkgBGL) + +- Added the function [`invert_selection()`](https://doc.cgal.org/5.5/BGL/structCGAL_1_1Face__filtered__graph.html#aa428541ebbdd35f9a6e9a3ffd60178df) in the class [`Face_filtered_graph`](https://doc.cgal.org/5.5/BGL/structCGAL_1_1Face__filtered__graph.html), which toggles the selected status of a graph: selected faces are deselected, and unselected faces are selected. -Besides fixes and general enhancement to existing packages, the following has changed since CGAL 5.2: - -### [Quadtrees, Octrees, and Orthtrees](https://doc.cgal.org/5.3/Manual/packages.html#PkgOrthtree) (new package) - -- This package implements a tree data structure in which each node encloses a hypercubic section - of space and each non-leave node has hypercubic children whose edge lengths are half its edge length. - Such a data structure is known as a quadtree in 2D, an octree in 3D, and is generalized - as an "orthtree" in higher dimensions. - -### [Triangulations on the Sphere](https://doc.cgal.org/5.3/Manual/packages.html#PkgTriangulationOnSphere2) (new package) - -- This package enables the construction and manipulation of Delaunay triangulations on the 2-sphere. - Triangulations are built incrementally and can be modified by insertion or removal of vertices. - Point location querying and primitives to build the dual Voronoi diagram are provided. - -### File Input / Output - -- Point set, polygon soup, and polygon mesh file I/O functions have been harmonized and documented: - - Point set I/O functions can be found in the packages [Point_set_processing_3](https://doc.cgal.org/5.3/Manual/packages.html#PkgPolygonMeshProcessing), and [Point_set_3](https://doc.cgal.org/5.3/Manual/packages.html#PkgPointSet3). - - Polygon mesh I/O functions can be found in the package [BGL](https://doc.cgal.org/5.3/Manual/packages.html#PkgBGL). - - Polygon soup I/O can be found in the package [Stream_support](https://doc.cgal.org/5.3/Manual/packages.html#PkgStreamSupport). - -A comprehensive list of the supported file formats is available in the Stream_support package -[here](https://doc.cgal.org/5.3/Stream_support/index.html#IOstreamSupportedFormats); -inversely, the following [page](https://doc.cgal.org/5.3/Stream_support/IOStreamSupportedFileFormats.html) -can be used to find out which CGAL data structures can be used given a specific file format. - -### [Requirements](https://doc.cgal.org/5.3/Manual/thirdparty.html) - -- The CMake minimal version is now `3.14`. -- The GNU compiler g++ versions 6 and 7 are no longer tested. Only version 8.3 or later are supported - -### [2D and 3D Linear Geometry Kernel](https://doc.cgal.org/5.3/Manual/packages.html#PkgKernel23) - -- Added `is_translation()`, `is_scaling()`, `is_reflection()`, and `is_rotation()` to the classes - [`Aff_transformation_2`](https://doc.cgal.org/5.3/Kernel_23/classCGAL_1_1Aff__transformation__2.html) - and [`Aff_transformation_3`](https://doc.cgal.org/5.3/Kernel_23/classCGAL_1_1Aff__transformation__3.html), - which enable determining if the transformations use a specialized representation internally. - -### [2D Regularized Boolean Set-Operations](https://doc.cgal.org/5.3/Manual/packages.html#PkgBooleanSetOperations2) -- Added documentation for the free functions [`oriented_side(const Point_2& p, ....)`](https://doc.cgal.org/5.3/Boolean_set_operations_2/group__boolean__oriented__side.html) - that accept a point and a polygon. -- Documentation has been improved across the whole package. - -### [Polygon Mesh Processing](https://doc.cgal.org/5.3/Manual/packages.html#PkgPolygonMeshProcessing) - -- Added the class [`CGAL::Polyhedral_envelope`](https://doc.cgal.org/5.3/Polygon_mesh_processing/structCGAL_1_1Polyhedral__envelope.html), - providing a way to quickly check if a primitive (point, segment, or triangle) - is within a polyhedral envelope around a set of triangles. It is based on the work of - Bolun Wang, Teseo Schneider, Yixin Hu, Marco Attene, and Daniele Panozzo. - "Exact and efficient polyhedral envelope containment check." (ACM Trans. Graph., 39-4, July 2020). -- Added more functions in the [visitor of the corefinement based methods](https://doc.cgal.org/5.3/Polygon_mesh_processing/classPMPCorefinementVisitor.html) - to track all edge creations. - -### [Surface Mesh Topology](https://doc.cgal.org/5.3/Manual/packages.html#PkgSurfaceMeshTopologySummary) -- Added the function [`CGAL::Surface_mesh_topology::Curves_on_surface_topology::is_homotopic_to_simple_cycle()`](https://doc.cgal.org/5.3/Surface_mesh_topology/classCGAL_1_1Surface__mesh__topology_1_1Curves__on__surface__topology.html#a8d7c4cba2cf2cff542f5cd93117233db), - which can be used to determine whehter a closed path on a surface mesh can be continously - transformed to a cycle without self intersection. - -### [Surface Mesh Simplification](https://doc.cgal.org/5.3/Manual/packages.html#PkgSurfaceMeshSimplification) -- Added a filtering mechanism so that costly tests get only applied to the next candidate for the edge collapse. -- Added the class [`Polyhedral_envelope_filter`](https://doc.cgal.org/5.3/Surface_mesh_simplification/classCGAL_1_1Surface__mesh__simplification_1_1Polyhedral__envelope__filter.html), - which enables to perform mesh simplification inside a polyhedral envelope of the input mesh. - -### [2D Polyline Simplification](https://doc.cgal.org/5.3/Manual/packages.html#PkgPolylineSimplification2) -- When polylines have common subsequences of vertices, these subsequences may now be simplifified simultaneously. - -### [dD Triangulations](https://doc.cgal.org/5.3/Manual/packages.html#PkgTriangulations) -- Added the function [`insert_if_in_star()`](https://doc.cgal.org/5.3/Triangulation/classCGAL_1_1Regular__triangulation.html#aa8df2d138f341939e834bcdd7cb6c71a) - to the class [`CGAL::Regular_triangulation`](https://doc.cgal.org/5.3/Triangulation/classCGAL_1_1Regular__triangulation.html), - which enables users to insert a point `p` in a regular triangulation on the condition that `p` - appears post-insertion in the star of a user-specified, existing vertex. - -### [2D and 3D Alpha Shapes](https://doc.cgal.org/5.3/Manual/packages.html#PkgAlphaShapes2) -- **Breaking change**: The following deprecated classes have been removed: `Alpha_shape_euclidean_traits_2`, - `Weighted_alpha_shape_euclidean_traits_2`, `Alpha_shape_euclidean_traits_3`, and - `Weighted_alpha_shape_euclidean_traits_3`. All CGAL kernel can be used directly as models - of the concepts of the 2D and 3D Alpha Shape packages. - -### [Classification](https://doc.cgal.org/5.3/Manual/packages.html#PkgClassification) -- **Breaking change**: the support for TensorFlow has been dropped; the - classifier `CGAL::TensorFlow::Neural_network_classifier` has been removed. - diff --git a/Maintenance/public_release/announcement/mailing-beta.eml b/Maintenance/public_release/announcement/mailing-beta.eml index 7fea9721de1..e6de484eb6d 100644 --- a/Maintenance/public_release/announcement/mailing-beta.eml +++ b/Maintenance/public_release/announcement/mailing-beta.eml @@ -1,97 +1,133 @@ -Subject: CGAL 5.4 Beta 1 Released, Computational Geometry Algorithms Library +Subject: CGAL 5.3.2, 5.4.1, and 5.5 Beta 1 Released, Computational Geometry Algorithms Library Content-Type: text/plain; charset="utf-8" Body: -The CGAL Open Source Project is pleased to announce the release 5.4 Beta 1 -of CGAL, the Computational Geometry Algorithms Library. +The CGAL Open Source Project is pleased to announce today three new +releases: +- CGAL-5.3.2 is the second and last bug-fix release for CGAL-5.3, +- CGAL-5.4.1 is the first bug-fix release for CGAL-5.4, and +- CGAL-5.5-beta1 is the first beta release for CGAL-5.5. -CGAL version 5.4 Beta 1 is a public testing release. It should provide a +CGAL version 5.5 Beta 1 is a public testing release. It should provide a solid ground to report bugs that need to be tackled before the release -of the final version of CGAL 5.4 in January 2022. +of the final version of CGAL 5.5 in July 2022. + +Besides fixes and general enhancement to existing packages, the +following has changed since CGAL 5.4: + +3D Alpha Wrapping (new package) + +- This component takes a 3D triangle mesh, soup, or point set as + input, and generates a valid (watertight, intersection-free, and + combinatorially 2-manifold) surface triangle mesh that contains the + input. The algorithm proceeds by shrink-wrapping and refining a 3D + Delaunay triangulation, starting from a loose bounding box of the + input. Two user-defined parameters, alpha and offset, offer control + over the maximum size of cavities where the shrink-wrapping process + can enter, and the tightness of the final surface mesh to the input, + respectively. Once combined, these parameters provide a means to + trade fidelity to the input for complexity of the output. + + See also https://www.cgal.org/2022/05/18/alpha_wrap/. + +3D Convex Hulls + +- Added an overload of the function CGAL::convex_hull_3(), which + writes the result in an indexed triangle set. + +2D Polygons + +- Add vertex, edge, and hole ranges. +- The concept GeneralPolygonWithHoles_2 now requires the nested type + Polygon_2 instead of General_polygon_2. + +2D Regularized Boolean Set-Operations + +- The concept GeneralPolygonSetTraits_2 now requires the nested type + Construct_polygon_with_holes_2 instead of + Construct_general_polygon_with_holes_2. + +Combinatorial Maps + +- Removed old code deprecated in CGAL 4.9 and 4.10 (global functions, + and information associated with darts). + +2D Arrangements + +- Fixed the intersect_2, compare_y_at_x_right, and compare_y_at_x_left + function objects of the traits class template + Arr_geodesic_arc_on_sphere_traits_2 that handles geodesic arcs on + sphere and applied a small syntactical fix to the tracing traits. + +Tetrahedral Mesh Generation + +- Added the function remove_isolated_vertices() as a post-processing + step for the tetrahedral mesh generation. + +Polygon Mesh Processing + +- Added the function + CGAL::Polygon_mesh_processing::orient_triangle_soup_with_reference_triangle_soup(), + which enables re-orienting the faces of a triangle soup based on the + orientation of the nearest face in a reference triangle soup. +- Added the function + CGAL::Polygon_mesh_processing::compatible_orientations(), which + enables to retrieve the (in)compatibility of orientations of faces + from different connected components. +- Added the function + CGAL::Polygon_mesh_processing::tangential_relaxation(), which + applies an area-based tangential mesh smoothing to the vertices of a + surface triangle mesh. +- Added the named parameter visitor to the function + triangulate_hole(), which enables to track progress with callbacks. +- Added more functions in the visitor of the corefinement based + methods to track progress. + +Surface Mesh Simplification + +- Introduced four variations of the Garland-Heckbert simplification + algorithm based on the probabilistic approach of Trettner and + Kobbelt (Fast and Robust QEF Minimization using Probabilistic + Quadrics): GarlandHeckbert_plane_policies, + GarlandHeckbert_probabilistic_plane_policies, + GarlandHeckbert_triangle_policies, and + GarlandHeckbert_probabilistic_triangle_policies. +- The class GarlandHeckbert_policies has been deprecated, + GarlandHeckbert_plane_policies replaces it. + +Point Set Processing + +- A new optional named parameter, min_points_per_cell has been added + to grid_simplify_point_set(). By adding a minimal number of points + in a cell such that a point is retained, one can also filter out low + density areas and outliers: in the case of densely sampled point + clouds, this yields better results than using grid simplification + and then outlier removal, while being very vast. The default value + is 1 to keep the previous behavior as default. + +dD Spatial Searching + +- Added the member function write_graphviz() to the class Kd_tree that + writes the tree in a stream in the Graphviz format. + +CGAL and the Boost Graph Library (BGL) + +- Added the function invert_selection() in the class + Face_filtered_graph, which toggles the selected status of a graph: + selected faces are deselected, and unselected faces are selected. -Besides fixes and general enhancement to existing packages, the following -has changed since CGAL 5.3: - - -General changes - -- Added the cmake target CGAL::CGAL_Basic_viewer to ease the - compilation of programs using the basic viewer-based function - CGAL::draw(). This target will define the macro and link with - CGAL_Qt5 target when linked with it. - -- The kernel providing exact constructions and exact predicates - (CGAL::Exact_predicates_exact_constructions_kernel) is now - thread-safe. - more details. - - -Shape Regularization (new package) - -- This package enables to regularize a set of segments and open or - closed contours in 2D and a set of planes in 3D such that all input - objects are rotated and aligned with respect to the user-specified - conditions. In addition, it provides a global regularization - framework that can be adjusted for the user needs and any type of - geometric objects. - - https://www.cgal.org/2021/11/16/shape-regularization/ - - https://doc.cgal.org/5.4/Manual/packages.html#PkgShapeRegularization - - -Weights (new package) - -- This package provides a simple and unified interface to different - types of weights. In particular, it groups all weights into three - category: analytic weights including all basic weights which can be - computed analytically for a query point with respect to its local - neighbors in 2D and 3D; barycentric weights, including all weights - which can be computed for a query point with respect to the vertices - of a planar polygon; and weighting regions, including all weights - which are used to balance other weights. - - https://doc.cgal.org/5.4/Manual/packages.html#PkgWeights - - -2D Generalized Barycentric Coordinates (major changes) - -- Breaking change: The headers Segment_coordinates_2.h and - Triangle_coordinates_2.h are renamed to segment_coordinates_2.h and - triangle_coordinates_2.h. -- The classes Segment_coordinates_2 and Triangle_coordinates_2 are - deprecated. The free functions compute_segment_coordinates_2() and - compute_triangle_coordinates_2() are deprecated as well. Instead, - the free functions segment_coordinates_2() and - triangle_coordinates_2() should be used. -- The enums Query_point_location and Type_of_algorithm are deprecated. - Instead, the enum Computation_policy_2 should be used. -- The classes Wachspress_2, Discrete_harmonic_2, Mean_value_2, and - Generalized_barycentric_coordinates_2 are deprecated. As - consequence, the concept BarycentricCoordinates_2 is deprecated as - well. Instead, the classes Wachspress_coordinates_2, - Discrete_harmonic_coordinates_2, and Mean_value_coordinates_2 should - be used. -- Added the class Harmonic_coordinates_2 to compute approximate - harmonic coordinates in 2D. These coordinates satisfy all properties - of barycentric coordinates inside any simple polygon. -- Added a new concept DiscretizedDomain_2 and a model of this concept - called Delaunay_domain_2, which is based on the Mesh 2 package. A - model of this concept is required to use Harmonic_coordinates_2. -- Added free functions to compute Wachspress, discrete harmonic, and - mean value coordinates. -- All free functions and classes are now using ranges and property - maps. - - https://doc.cgal.org/5.4/Manual/packages.html#PkgBarycentricCoordinates2 - - -See https://www.cgal.org/2021/12/17/cgal54-beta1/ for a +See https://www.cgal.org/2022/06/06/cgal55-beta1/ for a complete list of changes. +The development of CGAL will then now on the future CGAL-5.6 (planned +for December 2022), with bug-fixes regularly backported to the branches +for CGAL-5.4.x and CGAL-5.5.x. + + + The CGAL project is a collaborative effort to develop a robust, easy-to-use, and efficient C++ software library of geometric data structures and algorithms, like From 37390bb6b8533b07444b2873b9a577678812aaea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Wed, 8 Jun 2022 12:03:25 +0200 Subject: [PATCH 091/107] Add dialog-less QGLviewer::saveSnapshot --- GraphicsView/include/CGAL/Qt/qglviewer.h | 15 +++++++++++++ GraphicsView/include/CGAL/Qt/qglviewer_impl.h | 21 +++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/GraphicsView/include/CGAL/Qt/qglviewer.h b/GraphicsView/include/CGAL/Qt/qglviewer.h index da0dbace517..e353c8de66e 100644 --- a/GraphicsView/include/CGAL/Qt/qglviewer.h +++ b/GraphicsView/include/CGAL/Qt/qglviewer.h @@ -563,6 +563,21 @@ public: */ void saveSnapshot(); + /*! + * Takes a snapshot without any dialog + */ + void saveSnapshot(const QString& fileName, + const qreal finalWidth, + const qreal finalHeight, + const bool expand = false, + const double oversampling = 1., + qglviewer::SnapShotBackground background_color = qglviewer::CURRENT_BACKGROUND); + + void saveSnapshot(const QString& fileName) + { + return saveSnapshot(fileName, this->width(), this->height()); + } + public: Q_SIGNALS: /*! Signal emitted by the default init() method. diff --git a/GraphicsView/include/CGAL/Qt/qglviewer_impl.h b/GraphicsView/include/CGAL/Qt/qglviewer_impl.h index 07eb161909e..1e10b72d0b0 100644 --- a/GraphicsView/include/CGAL/Qt/qglviewer_impl.h +++ b/GraphicsView/include/CGAL/Qt/qglviewer_impl.h @@ -3761,8 +3761,29 @@ void CGAL::QGLViewer::saveSnapshot() } } +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::saveSnapshot(const QString& fileName, + const qreal finalWidth, const qreal finalHeight, + const bool expand, + const double oversampling, + qglviewer::SnapShotBackground background_color) +{ + if(fileName.isEmpty()) + return; + + QSize finalSize(finalWidth, finalHeight); + + QImage* image = takeSnapshot(qglviewer::SnapShotBackground(background_color), + finalSize, oversampling, expand); + if(image) + { + image->save(fileName); + delete image; + } } +} // namespace CGAL + CGAL_INLINE_FUNCTION bool CGAL::QGLViewer::isSharing() const { From beeae185a78f85de44cab5abdda05f24931b0be2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Wed, 8 Jun 2022 12:04:02 +0200 Subject: [PATCH 092/107] Add a basic visitor to AW3 --- .../CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h index 3d09b2a8dff..e88e00fafe0 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h @@ -103,13 +103,26 @@ struct Wrapping_default_visitor { Wrapping_default_visitor() { } + template + void on_alpha_wrapping_begin(const AlphaWrapper&) { } + + template + void on_flood_fill_begin(const AlphaWrapper&) { } + + template + void before_facet_treatment(const AlphaWrapper&, const Gate&) { } + template void before_Steiner_point_insertion(const Wrapper&, const Point&) { } template void after_Steiner_point_insertion(const Wrapper&, VertexHandle) { } - void after_alpha_wrapping() { } + template + void on_flood_fill_end(const AlphaWrapper&) { } + + template + void on_alpha_wrapping_end(const AlphaWrapper&) { }; }; template @@ -187,6 +200,7 @@ public: const Geom_traits& geom_traits() const { return m_dt.geom_traits(); } Dt& triangulation() { return m_dt; } const Dt& triangulation() const { return m_dt; } + const Alpha_PQ& queue() const { return m_queue; } double default_alpha() const { @@ -252,6 +266,8 @@ public: t.start(); #endif + visitor.on_alpha_wrapping_begin(*this); + if(!initialize(alpha, offset, seeds)) return; @@ -340,7 +356,7 @@ public: #endif #endif - visitor.after_alpha_wrapping(); + visitor.on_alpha_wrapping_end(*this); } // Convenience overloads @@ -1029,6 +1045,8 @@ private: std::cout << "> Flood fill..." << std::endl; #endif + visitor.on_flood_fill_begin(*this); + // Explore all finite cells that are reachable from one of the initial outside cells. while(!m_queue.empty()) { @@ -1055,6 +1073,8 @@ private: std::cout << "Priority: " << gate.priority() << std::endl; #endif + visitor.before_facet_treatment(*this, gate); + m_queue.pop(); #ifdef CGAL_AW3_DEBUG_DUMP_EVERY_STEP @@ -1170,6 +1190,8 @@ private: } } // while(!queue.empty()) + visitor.on_flood_fill_end(*this); + // Check that no useful facet has been ignored CGAL_postcondition_code(for(auto fit=m_dt.finite_facets_begin(), fend=m_dt.finite_facets_end(); fit!=fend; ++fit) {) CGAL_postcondition_code( if(fit->first->info().is_outside == fit->first->neighbor(fit->second)->info().is_outside) continue;) From 801d9668532677ebc16d7c440ea8c7648e44deeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Wed, 8 Jun 2022 12:15:47 +0200 Subject: [PATCH 093/107] Enhance AW3 demo with iteration visualization & snapshot capabilities --- .../Alpha_wrap_3/Alpha_wrap_3_plugin.cpp | 214 ++++++++------ .../Alpha_wrap_3/alpha_wrap_3_dialog.ui | 265 ++++++++++++------ 2 files changed, 302 insertions(+), 177 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp index eeda371c185..49738f0f571 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp @@ -12,13 +12,15 @@ #include #include -#include #include -#include #include -#include #include +#include +#include #include +#include +#include +#include #include #include @@ -29,50 +31,57 @@ #include "ui_alpha_wrap_3_dialog.h" -template -struct AW3_visu_visitor +struct Iterative_AW3_visualization_visitor { - AW3_visu_visitor(Scene* scene, - WrapItem* wrap_item) - : m_scene(scene), - m_wrap_item(wrap_item) - { } +private: + bool m_do_snapshot; + Scene_polygon_soup_item* m_iterative_wrap_item = nullptr; + int sid = 0; public: + template + Iterative_AW3_visualization_visitor(Scene* scene, + const bool visualize_iterations, + const bool do_snapshot) + : m_do_snapshot(do_snapshot) + { + if(!visualize_iterations) + return; + + m_iterative_wrap_item = new Scene_polygon_soup_item(); + m_iterative_wrap_item->setName(QString("Iterative wrap")); + scene->addItem(m_iterative_wrap_item); + } + +public: + template + void on_alpha_wrapping_begin(const AlphaWrapper&) { } + + template + void on_flood_fill_begin(const AlphaWrapper&) { } + + template + void before_facet_treatment(const AlphaWrapper&, + const Facet&) { } + template void before_Steiner_point_insertion(const AlphaWrapper& wrapper, const Point& p) { - // @todo something nicer & smarter - if(wrapper.triangulation().number_of_vertices() < 500) - { - // Do all iterations - } - else if(wrapper.triangulation().number_of_vertices() < 5000) - { - if(wrapper.triangulation().number_of_vertices() % 10 != 0) - return; - } - else if(wrapper.triangulation().number_of_vertices() < 10000) - { - if(wrapper.triangulation().number_of_vertices() % 100 != 0) - return; - } - else if(wrapper.triangulation().number_of_vertices() < 1000000) - { - if(wrapper.triangulation().number_of_vertices() % 1000 != 0) - return; - } - - if(!m_wrap_item) + if(m_iterative_wrap_item == nullptr) return; -// for(auto cit=wrapper.triangulation().finite_cells_begin(), cend=wrapper.triangulation().finite_cells_end(); cit!=cend; ++cit) -// std::cout << cit->time_stamp() << std::endl; + // If the next top of the queue has vertices on the bbox, don't draw (as to avoid producing + // spikes in the visualization) +// const auto& gate = wrapper.queue().top(); +// if(wrapper.triangulation().number_of_vertices() > 500 && gate.is_artificial_facet()) +// return; - std::cout << "on_Steiner_point_insert (" << wrapper.triangulation().number_of_vertices() << ")" << std::endl; + // Skip some... + if(wrapper.triangulation().number_of_vertices() % 50 != 0) + return; - // EXTRACT --- + // Extract the wrap as a triangle soup using Dt = typename std::decay::type; using Vertex_handle = typename Dt::Vertex_handle; @@ -85,6 +94,8 @@ public: std::unordered_map vertex_to_id; std::size_t nv = 0; + // This is used to compute colors depending on what is old and what is new. + // It is not currently used (a uniform gray color is used), but leaving it as it might be useful. std::size_t min_time_stamp = -1, max_time_stamp = 0; for(auto cit=wrapper.triangulation().finite_cells_begin(), cend=wrapper.triangulation().finite_cells_end(); cit!=cend; ++cit) { @@ -128,64 +139,74 @@ public: faces.emplace_back(std::vector{ids[0], ids[1], ids[2]}); double color_val = double(c->time_stamp() - min_time_stamp) / double(max_time_stamp - min_time_stamp); color_val = int(256. * color_val); + // fcolors.push_back(CGAL::IO::Color(color_val, 10, 150)); // young is red, old is blue // fcolors.push_back(CGAL::IO::Color(256 - color_val, 256 - color_val, 256 - color_val)); // young is light, old is dark - fcolors.push_back(CGAL::IO::Color(100, 100, 100)); // darkish gray + fcolors.push_back(CGAL::IO::Color(100, 100, 100)); // uniform darkish gray } -// std::cout << "DT NV " << wrapper.triangulation().number_of_vertices() << " vs " << nv << " vs " << points.size() << std::endl; -// std::cout << "DT NF " << wrapper.triangulation().number_of_finite_facets() << " vs " << fi << " vs " << faces.size() << std::endl; + // Update the wrap item's visualization + m_iterative_wrap_item->load(points, faces, fcolors, vcolors); + m_iterative_wrap_item->setName(QString("Iterative wrap #%1").arg(sid)); + m_iterative_wrap_item->setAlpha(255 / 2); - // --- EXTRACT - - m_wrap_item->load(points, faces, fcolors, vcolors); - m_wrap_item->setAlpha(255 / 2); - - m_wrap_item->invalidateOpenGLBuffers(); - m_wrap_item->redraw(); - m_wrap_item->itemChanged(); - -// SMesh wrap; -// auto vpm = get(CGAL::vertex_point, wrap); -// wrapper.extract_surface(wrap, vpm, true /*tolerate non manifoldness*/); - -// Scene_surface_mesh_item* new_wrap_item = new Scene_surface_mesh_item(wrap); -// new_wrap_item->setName(QString("Wrap")); -// new_wrap_item->setColor(Qt::gray); - -// new_wrap_item->setName(m_wrap_item->name()); -// new_wrap_item->setColor(m_wrap_item->color()); -// new_wrap_item->setRenderingMode(m_wrap_item->renderingMode()); -// new_wrap_item->setVisible(m_wrap_item->visible()); -// Scene_item_with_properties *property_item = dynamic_cast(new_wrap_item); -// m_scene->replaceItem(m_scene->item_id(m_wrap_item), new_wrap_item, true); -// if(property_item) -// property_item->copyProperties(m_wrap_item); -// new_wrap_item->invalidateOpenGLBuffers(); -// m_wrap_item->deleteLater(); + m_iterative_wrap_item->invalidateOpenGLBuffers(); + m_iterative_wrap_item->redraw(); + m_iterative_wrap_item->itemChanged(); + // Refresh the view QApplication::processEvents(); + + if(m_do_snapshot) + { + std::stringstream oss; + oss << "Wrap_iteration-" << sid << ".png" << std::ends; + QString filename = QString::fromStdString(oss.str().c_str()); + + CGAL::Three::Viewer_interface* viewer = CGAL::Three::Three::activeViewer(); + viewer->saveSnapshot(filename, 1920, 1080, true /*expand*/, 2.0 /*oversampling*/); + } + + ++sid; } template - void after_Steiner_point_insertion(const AlphaWrapper& wrapper, - const VertexHandle vh) - { + void after_Steiner_point_insertion(const AlphaWrapper&, + const VertexHandle) { } - } + template + void on_flood_fill_end(const AlphaWrapper&) { } - void after_alpha_wrapping() + template + void on_alpha_wrapping_end(const AlphaWrapper&) { - m_wrap_item->setAlpha(255); - m_wrap_item->invalidateOpenGLBuffers(); - m_wrap_item->redraw(); - m_wrap_item->itemChanged(); + if(m_iterative_wrap_item == nullptr) + return; + + m_iterative_wrap_item->setName(QString("Iterative wrap #%1").arg(sid)); + + m_iterative_wrap_item->setAlpha(255); + m_iterative_wrap_item->invalidateOpenGLBuffers(); + m_iterative_wrap_item->redraw(); + m_iterative_wrap_item->itemChanged(); + + QApplication::processEvents(); + + if(m_do_snapshot) + { + std::stringstream oss; + oss << "Wrap_iteration-" << sid << ".png" << std::ends; + QString filename = QString::fromStdString(oss.str().c_str()); + + CGAL::Three::Viewer_interface* viewer = CGAL::Three::Three::activeViewer(); + viewer->saveSnapshot(filename); + } + + m_iterative_wrap_item->setVisible(false); + + // Refresh the view QApplication::processEvents(); } - -private: - Scene* m_scene; - WrapItem* m_wrap_item; }; class Polyhedron_demo_alpha_wrap_3_plugin @@ -249,6 +270,9 @@ private: connect(ui.wrapEdges, SIGNAL(clicked(bool)), this, SLOT(toggle_wrap_faces())); connect(ui.wrapFaces, SIGNAL(clicked(bool)), this, SLOT(toggle_wrap_edges())); + connect(ui.visualizeIterations, SIGNAL(clicked(bool)), + this, SLOT(update_iteration_snapshot_checkbox())); + connect(ui.buttonBox, SIGNAL(accepted()), dialog, SLOT(accept())); connect(ui.buttonBox, SIGNAL(rejected()), dialog, SLOT(reject())); @@ -268,6 +292,11 @@ public Q_SLOTS: ui.wrapEdges->setChecked(true); } + void update_iteration_snapshot_checkbox() + { + ui.snapshotIterations->setCheckable(ui.visualizeIterations->isChecked()); + } + void on_actionAlpha_wrap_3_triggered() { using Triangles = std::vector; @@ -291,11 +320,13 @@ public Q_SLOTS: const bool enforce_manifoldness = ui.runManifoldness->isChecked(); double alpha = ui.alphaValue->value(); double offset = ui.offsetValue->value(); + const bool visualize_iterations = ui.visualizeIterations->isChecked(); + const bool do_snapshot_iterations = ui.snapshotIterations->isChecked(); if(alpha <= 0. || offset <= 0.) return; -// QApplication::setOverrideCursor(Qt::WaitCursor); + QApplication::setOverrideCursor(Qt::WaitCursor); TS_Oracle ts_oracle; SS_Oracle ss_oracle(ts_oracle); @@ -453,7 +484,7 @@ public Q_SLOTS: std::cout << triangles.size() << " triangles" << std::endl; std::cout << segments.size() << " edges" << std::endl; std::cout << points.size() << " points" << std::endl; - std::cout << "wrap s/tr: " << wrap_segments << " " << wrap_triangles << std::endl; + std::cout << "do wrap edges/faces: " << wrap_segments << " " << wrap_triangles << std::endl; if(wrap_triangles) oracle.add_triangle_soup(triangles); @@ -464,7 +495,7 @@ public Q_SLOTS: if(!oracle.do_call()) { print_message("Warning: empty input - nothing to wrap"); -// QApplication::restoreOverrideCursor(); + QApplication::restoreOverrideCursor(); return; } @@ -482,24 +513,21 @@ public Q_SLOTS: CGAL::Alpha_wraps_3::internal::Alpha_wrap_3 aw3(oracle); - Scene_polygon_soup_item* iterative_wrap_item = new Scene_polygon_soup_item(); - iterative_wrap_item->setName(tr("Iterative wrap").arg(alpha).arg(offset)); - scene->addItem(iterative_wrap_item); - - AW3_visu_visitorscene))>::type, - Scene_polygon_soup_item> visitor(scene, iterative_wrap_item); + Iterative_AW3_visualization_visitor visitor(scene, + visualize_iterations, + do_snapshot_iterations); SMesh wrap; aw3(alpha, offset, wrap, CGAL::parameters::do_enforce_manifoldness(enforce_manifoldness) .visitor(visitor)); -// Scene_surface_mesh_item* wrap_item = new Scene_surface_mesh_item(wrap); -// wrap_item->setName(tr("Wrap alpha %2 offset %3").arg(alpha).arg(offset)); -// wrap_item->setColor(Qt::gray); -// scene->addItem(wrap_item); + Scene_surface_mesh_item* wrap_item = new Scene_surface_mesh_item(wrap); + wrap_item->setName(tr("Wrap with alpha %2 offset %3").arg(alpha).arg(offset)); + wrap_item->setColor(Qt::gray); + scene->addItem(wrap_item); -// QApplication::restoreOverrideCursor(); + QApplication::restoreOverrideCursor(); } private: diff --git a/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/alpha_wrap_3_dialog.ui b/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/alpha_wrap_3_dialog.ui index 6877e6a99e5..bbf25c4b345 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/alpha_wrap_3_dialog.ui +++ b/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/alpha_wrap_3_dialog.ui @@ -10,31 +10,21 @@ 0 0 646 - 432 + 673 3D Alpha Wrapping - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - 3D Alpha Wrapping - - + + @@ -62,71 +52,21 @@ - + true - Enforce 2-manifoldness + <html><head/><body><p>Enforce 2-manifold output</p></body></html> Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - true - - - - - - - - - - true - - - - - - - - - - true - - - - - - - Offset value: - - - - - + + Qt::Vertical @@ -148,27 +88,59 @@ - - + + - Qt::Horizontal + Qt::Vertical - + + + 20 + 40 + + + - - + + + + Qt::Vertical + + + + 20 + 40 + + + + + + - <html><head/><body><p>Wrap edges<br/><span style=" font-size:9pt;">If deactivated, only extremities of the edges are taken into account</span></p></body></html> + Visualize iterations - <html><head/><body><p>Use relative-to-bbox offset<br/><span style=" font-size:9pt;">As ratio of the length of the bbox's diagonal<br/>(value </span><span style=" font-size:9pt; font-style:italic;">x </span><span style=" font-size:9pt;">means </span><span style=" font-size:9pt; font-style:italic;">offset := bbox_diag_l / x)</span></p></body></html> + <html><head/><body><p>Use relative-to-bbox offset<br/><span style=" font-size:9pt;">As ratio of the length of the bbox's diagonal<br/>(i.e., value </span><span style=" font-size:9pt; font-style:italic;">x </span><span style=" font-size:9pt;">means </span><span style=" font-size:9pt; font-style:italic;">offset := bbox_diag_l / x)</span></p></body></html> + + + + Qt::Vertical + + + + 20 + 40 + + + + @@ -188,8 +160,29 @@ - - + + + + Qt::Horizontal + + + + + + + <html><head/><body><p>Wrap faces<br/><span style=" font-size:9pt;">If deactivated, only edges of the faces are taken into account</span></p></body></html> + + + + + + + <html><head/><body><p>Wrap edges<br/><span style=" font-size:9pt;">If deactivated, only extremities of the edges are taken into account</span></p></body></html> + + + + + @@ -198,17 +191,47 @@ - - - - <html><head/><body><p>Wrap faces<br/><span style=" font-size:9pt;">If deactivated, only edges of the faces are taken into account</span></p></body></html> + + + + Qt::Vertical - + + + 20 + 40 + + + - <html><head/><body><p>Use relative-to-bbox alpha<br/><span style=" font-size:9pt;">As ratio of the length of the bbox's diagonal<br/>(value </span><span style=" font-size:9pt; font-style:italic;">x </span><span style=" font-size:9pt;">means alpha</span><span style=" font-size:9pt; font-style:italic;"> := bbox_diag_l / x)</span></p></body></html> + <html><head/><body><p>Use relative-to-bbox alpha<br/><span style=" font-size:9pt;">As ratio of the length of the bbox's diagonal<br/>(i.e., value </span><span style=" font-size:9pt; font-style:italic;">x </span><span style=" font-size:9pt;">means alpha</span><span style=" font-size:9pt; font-style:italic;"> := bbox_diag_l / x)</span></p></body></html> + + + + + + + Qt::Vertical + + + + + + + + + + + + + + + + + true @@ -225,16 +248,90 @@ - + + + + + + + true + + + + + + + Qt::Horizontal + + + + + + + Offset value: + + + + Qt::Horizontal + + + + + + + true + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + <html><head/><body><p>Snapshot iterations<br/><span style=" font-size:9pt;">For each iteration, save a snapshot of the viewer <br/>to a file named </span><span style=" font-size:9pt; font-style:italic;">Wrap-iteration_i.png</span></p></body></html> + + + + + + + + + + false + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + From f438a2ed3a2fe0fd44e8b9f99aa7b6e63388c0ba Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Wed, 8 Jun 2022 15:52:01 +0200 Subject: [PATCH 094/107] Fix a use-after-free In an `unordered_map`, any insertion can invalidate iterators, when the load factor triggers a rehashing. --- Triangulation_3/include/CGAL/Triangulation_3.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Triangulation_3/include/CGAL/Triangulation_3.h b/Triangulation_3/include/CGAL/Triangulation_3.h index 07518932ccc..9d4cf51321c 100644 --- a/Triangulation_3/include/CGAL/Triangulation_3.h +++ b/Triangulation_3/include/CGAL/Triangulation_3.h @@ -5170,6 +5170,7 @@ remove_3D(Vertex_handle v, VertexRemover& remover) } typename Vertex_triple_Facet_map::value_type o_vt_f_pair = *oit; + outer_map.erase(oit); Cell_handle o_ch = o_vt_f_pair.second.first; unsigned int o_i = o_vt_f_pair.second.second; @@ -5215,7 +5216,6 @@ remove_3D(Vertex_handle v, VertexRemover& remover) } } } - outer_map.erase(oit); } tds().delete_vertex(v); tds().delete_cells(hole.begin(), hole.end()); @@ -6059,6 +6059,7 @@ move_if_no_collision(Vertex_handle v, const Point& p, } typename Vertex_triple_Facet_map::value_type o_vt_f_pair = *oit; + outer_map.erase(oit); Cell_handle o_ch = o_vt_f_pair.second.first; unsigned int o_i = o_vt_f_pair.second.second; @@ -6105,7 +6106,6 @@ move_if_no_collision(Vertex_handle v, const Point& p, } } } - outer_map.erase(oit); } // fixing pointer @@ -6511,6 +6511,7 @@ move_if_no_collision_and_give_new_cells(Vertex_handle v, const Point& p, } typename Vertex_triple_Facet_map::value_type o_vt_f_pair = *oit; + outer_map.erase(oit); Cell_handle o_ch = o_vt_f_pair.second.first; unsigned int o_i = o_vt_f_pair.second.second; @@ -6558,7 +6559,6 @@ move_if_no_collision_and_give_new_cells(Vertex_handle v, const Point& p, } } } - outer_map.erase(oit); } // fixing pointer From f8f48f262d6cb1d2aab26043958c04c06e839756 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Wed, 8 Jun 2022 16:08:03 +0200 Subject: [PATCH 095/107] Add #include --- .../include/CGAL/Polygon_mesh_processing/repair_polygon_soup.h | 1 + 1 file changed, 1 insertion(+) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair_polygon_soup.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair_polygon_soup.h index 6af8c8cbdbc..a0ded8d2cc8 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair_polygon_soup.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair_polygon_soup.h @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include From a40be70ff7cc856f98399b5da511febd46b883fd Mon Sep 17 00:00:00 2001 From: Kevin Athey Date: Wed, 8 Jun 2022 15:28:25 -0700 Subject: [PATCH 096/107] change initialized value to -1. --- Triangulation_3/include/CGAL/Delaunay_triangulation_3.h | 2 +- Triangulation_3/include/CGAL/Triangulation_3.h | 2 +- Triangulation_3/include/CGAL/Triangulation_hierarchy_3.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Triangulation_3/include/CGAL/Delaunay_triangulation_3.h b/Triangulation_3/include/CGAL/Delaunay_triangulation_3.h index e723a744729..a83ac381aea 100644 --- a/Triangulation_3/include/CGAL/Delaunay_triangulation_3.h +++ b/Triangulation_3/include/CGAL/Delaunay_triangulation_3.h @@ -1076,7 +1076,7 @@ Delaunay_triangulation_3:: insert(const Point& p, Cell_handle start, bool *could_lock_zone) { Locate_type lt; - int li = 0, lj = 0; + int li = -1, lj = -1; // Parallel if(could_lock_zone) diff --git a/Triangulation_3/include/CGAL/Triangulation_3.h b/Triangulation_3/include/CGAL/Triangulation_3.h index df6b6190243..b2274146062 100644 --- a/Triangulation_3/include/CGAL/Triangulation_3.h +++ b/Triangulation_3/include/CGAL/Triangulation_3.h @@ -3862,7 +3862,7 @@ Triangulation_3:: insert(const Point& p, Cell_handle start) { Locate_type lt; - int li = 0, lj = 0; + int li = -1, lj = -1; Cell_handle c = locate(p, lt, li, lj, start); return insert(p, lt, c, li, lj); } diff --git a/Triangulation_3/include/CGAL/Triangulation_hierarchy_3.h b/Triangulation_3/include/CGAL/Triangulation_hierarchy_3.h index abbd99d0d03..ac69e874982 100644 --- a/Triangulation_3/include/CGAL/Triangulation_hierarchy_3.h +++ b/Triangulation_3/include/CGAL/Triangulation_hierarchy_3.h @@ -538,7 +538,7 @@ insert(const Point &p, Cell_handle start) { int vertex_level = random_level(); Locate_type lt; - int i = 0, j = 0; + int i = -1, j = -1; // locate using hierarchy locs positions[maxlevel]; locate(p, lt, i, j, positions, start); @@ -578,7 +578,7 @@ insert_and_give_new_cells(const Point &p, OutputItCells fit, Cell_handle start) Locate_type lt; int i, j; // locate using hierarchy - locs positions[maxlevel] = {0}; + locs positions[maxlevel] = {-1}; locate(p, lt, i, j, positions, start); // insert at level 0 Vertex_handle vertex = hierarchy[0]->insert_and_give_new_cells(p, From d6b0efbea411978710fe4989ba1c861893cd2dfe Mon Sep 17 00:00:00 2001 From: Kevin Athey Date: Wed, 8 Jun 2022 16:06:20 -0700 Subject: [PATCH 097/107] initialize members of 'loc' instead of the array. --- Triangulation_3/include/CGAL/Triangulation_hierarchy_3.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Triangulation_3/include/CGAL/Triangulation_hierarchy_3.h b/Triangulation_3/include/CGAL/Triangulation_hierarchy_3.h index ac69e874982..7281a4d316b 100644 --- a/Triangulation_3/include/CGAL/Triangulation_hierarchy_3.h +++ b/Triangulation_3/include/CGAL/Triangulation_hierarchy_3.h @@ -439,7 +439,7 @@ protected: struct locs { Cell_handle pos; - int li, lj; + int li = -1, lj = -1; Locate_type lt; }; @@ -578,7 +578,7 @@ insert_and_give_new_cells(const Point &p, OutputItCells fit, Cell_handle start) Locate_type lt; int i, j; // locate using hierarchy - locs positions[maxlevel] = {-1}; + locs positions[maxlevel]; locate(p, lt, i, j, positions, start); // insert at level 0 Vertex_handle vertex = hierarchy[0]->insert_and_give_new_cells(p, From 89c4b509e1b43f194a1e6d509da839097f1d9908 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Thu, 9 Jun 2022 09:33:33 +0100 Subject: [PATCH 098/107] STL_extension: Fix URL to boost libs --- STL_Extension/doc/STL_Extension/Concepts/Hashable.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/STL_Extension/doc/STL_Extension/Concepts/Hashable.h b/STL_Extension/doc/STL_Extension/Concepts/Hashable.h index d07c14cdf83..17fa2304230 100644 --- a/STL_Extension/doc/STL_Extension/Concepts/Hashable.h +++ b/STL_Extension/doc/STL_Extension/Concepts/Hashable.h @@ -14,12 +14,11 @@ They can be disables by defining the macro `CGAL_DISABLE_HASH_OPENMESH`. \sa `CGAL::Unique_hash_map` \sa `std::unordered_set` \sa `std::unordered_map` -\sa `boost::unordered_set` -\sa `boost::unordered_map` +\sa `boost::unordered_set` +\sa `boost::unordered_map` */ class Hashable { }; - From 60df88453f2281835f8e4a5c93cb00344396c31d Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Thu, 9 Jun 2022 12:44:10 +0100 Subject: [PATCH 099/107] No longer use the link to boost::result_of --- .../doc/Documentation/Developer_manual/Chapter_code_format.txt | 2 +- Documentation/doc/Documentation/Preliminaries.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/doc/Documentation/Developer_manual/Chapter_code_format.txt b/Documentation/doc/Documentation/Developer_manual/Chapter_code_format.txt index 77e994d0270..fbc3a325b89 100644 --- a/Documentation/doc/Documentation/Developer_manual/Chapter_code_format.txt +++ b/Documentation/doc/Documentation/Developer_manual/Chapter_code_format.txt @@ -258,7 +258,7 @@ The first list of items are meant as rules, i.e., you should follow them. #endif // CGAL_THIS_IS_AN_EXAMPLE_H \endcode - Support the - result_of + result_of protocol whenever your functors have more than one return type otherwise provide a `result_type` member typedef. An example for this is a C++03 style `identity` functor: diff --git a/Documentation/doc/Documentation/Preliminaries.txt b/Documentation/doc/Documentation/Preliminaries.txt index e07d90e9e37..e194f3d46ec 100644 --- a/Documentation/doc/Documentation/Preliminaries.txt +++ b/Documentation/doc/Documentation/Preliminaries.txt @@ -47,7 +47,7 @@ After being based on the \CC standard released in 1998 (and later refined in 200 \section Preliminaries_functor Functor Return Types \cgal functors support the -result_of +result_of protocol. If a functor `F` has the same return type across all overloads of `operator()`, the nested type `F::result_type` is defined to be that type. Otherwise the From c46e1d2d243db70c0f7f06056ae55cf2bf7679d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 9 Jun 2022 16:14:22 +0200 Subject: [PATCH 100/107] fix warnings --- .../Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp index 49738f0f571..8a190360c42 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp @@ -66,7 +66,7 @@ public: template void before_Steiner_point_insertion(const AlphaWrapper& wrapper, - const Point& p) + const Point& /* p */) { if(m_iterative_wrap_item == nullptr) return; @@ -108,7 +108,6 @@ public: std::vector vcolors; std::vector fcolors; - std::size_t vi = 0, fi = 0; for(auto fit=wrapper.triangulation().finite_facets_begin(), fend=wrapper.triangulation().finite_facets_end(); fit!=fend; ++fit) { Facet f = *fit; From 14b582f83de2bb73a743742724f8ded08682f033 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Fri, 10 Jun 2022 09:15:11 +0200 Subject: [PATCH 101/107] More use our free of `outer_map` --- Triangulation_3/include/CGAL/Triangulation_3.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Triangulation_3/include/CGAL/Triangulation_3.h b/Triangulation_3/include/CGAL/Triangulation_3.h index 9d4cf51321c..5797358941f 100644 --- a/Triangulation_3/include/CGAL/Triangulation_3.h +++ b/Triangulation_3/include/CGAL/Triangulation_3.h @@ -5367,6 +5367,7 @@ remove_3D(Vertex_handle v, VertexRemover& remover, } typename Vertex_triple_Facet_map::value_type o_vt_f_pair = *oit; + outer_map.erase(oit); Cell_handle o_ch = o_vt_f_pair.second.first; unsigned int o_i = o_vt_f_pair.second.second; @@ -5413,7 +5414,6 @@ remove_3D(Vertex_handle v, VertexRemover& remover, } } } - outer_map.erase(oit); } tds().delete_vertex(v); tds().delete_cells(inc_cells.begin(), inc_cells.end()); @@ -5670,6 +5670,7 @@ remove_3D(Vertex_handle v, VertexRemover& remover, OutputItCells fit) } typename Vertex_triple_Facet_map::value_type o_vt_f_pair = *oit; + outer_map.erase(oit); Cell_handle o_ch = o_vt_f_pair.second.first; unsigned int o_i = o_vt_f_pair.second.second; @@ -5717,7 +5718,6 @@ remove_3D(Vertex_handle v, VertexRemover& remover, OutputItCells fit) } } } - outer_map.erase(oit); } tds().delete_vertex(v); tds().delete_cells(hole.begin(), hole.end()); @@ -6851,6 +6851,7 @@ _remove_cluster_3D(InputIterator first, InputIterator beyond, VertexRemover& rem } typename Vertex_triple_Facet_map::value_type o_vt_f_pair = *oit; + outer_map.erase(oit); Cell_handle o_ch = o_vt_f_pair.second.first; unsigned int o_i = o_vt_f_pair.second.second; @@ -6900,7 +6901,6 @@ _remove_cluster_3D(InputIterator first, InputIterator beyond, VertexRemover& rem } } - outer_map.erase(oit); } this->tds().delete_cells(hole.begin(), hole.end()); From 81ac3b9a11aaaf36149f72875ea97ae49395aada Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Fri, 10 Jun 2022 09:46:09 +0200 Subject: [PATCH 102/107] One more use-after-free in P3T3 --- .../include/CGAL/Periodic_3_triangulation_3.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Periodic_3_triangulation_3/include/CGAL/Periodic_3_triangulation_3.h b/Periodic_3_triangulation_3/include/CGAL/Periodic_3_triangulation_3.h index 6c9e6936070..60ead7714a3 100644 --- a/Periodic_3_triangulation_3/include/CGAL/Periodic_3_triangulation_3.h +++ b/Periodic_3_triangulation_3/include/CGAL/Periodic_3_triangulation_3.h @@ -3256,6 +3256,7 @@ periodic_remove(Vertex_handle v, PointRemover& remover, CoverManager& cover_mana typename Vertex_triple_Facet_map::iterator oit = outer_map.begin(); typename Vertex_triple_Facet_map::value_type o_vt_f_pair = *oit; + outer_map.erase(oit); Cell_handle o_ch = o_vt_f_pair.second.first; unsigned int o_i = o_vt_f_pair.second.second; @@ -3314,7 +3315,6 @@ periodic_remove(Vertex_handle v, PointRemover& remover, CoverManager& cover_mana } } } - outer_map.erase(oit); } // finally set the neighboring relations From 05c9dbfe8c2d2e2d322a03f5a14c23e7619a4a6f Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Fri, 10 Jun 2022 17:10:00 +0200 Subject: [PATCH 103/107] Simplify the code using `=default` for special member functions --- Polygon/include/CGAL/Polygon_2.h | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/Polygon/include/CGAL/Polygon_2.h b/Polygon/include/CGAL/Polygon_2.h index 02cdadac65b..be5ca8c9ef0 100644 --- a/Polygon/include/CGAL/Polygon_2.h +++ b/Polygon/include/CGAL/Polygon_2.h @@ -154,21 +154,16 @@ class Polygon_2 { /// @{ /// Creates an empty polygon. - Polygon_2() : traits() {} + Polygon_2() = default; /// Creates an empty polygon. Polygon_2(const Traits & p_traits) : traits(p_traits) {} /// Copy constructor. - Polygon_2(const Polygon_2& polygon) - : d_container(polygon.d_container), traits(polygon.traits) {} + Polygon_2(const Polygon_2& polygon) = default; /// Move constructor - Polygon_2(Polygon_2&& polygon) - : d_container(std::move(polygon.d_container)), traits(polygon.traits) - { - CGAL_assertion(polygon.is_empty()); - } + Polygon_2(Polygon_2&& polygon) = default; /// Creates a polygon with vertices from the sequence /// defined by the range \c [first,last). @@ -180,12 +175,8 @@ class Polygon_2 { {} #ifndef DOXYGEN_RUNNING - Polygon_2& operator=(const Polygon_2&)=default; - Polygon_2& operator=(Polygon_2&& p) - { - d_container = std::move(p.d_container); - return *this; - } + Polygon_2& operator=(const Polygon_2&) = default; + Polygon_2& operator=(Polygon_2&& p) = default; #endif /// @} From 198977cf4622c031ff4e246d75502bc105061d22 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Fri, 10 Jun 2022 17:10:26 +0200 Subject: [PATCH 104/107] Test move construction/assignment of Polygon_with_holes_2 --- Polygon/test/Polygon/Polygon_with_holes_test.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Polygon/test/Polygon/Polygon_with_holes_test.cpp b/Polygon/test/Polygon/Polygon_with_holes_test.cpp index 148088e09fb..97a3fc80fd1 100644 --- a/Polygon/test/Polygon/Polygon_with_holes_test.cpp +++ b/Polygon/test/Polygon/Polygon_with_holes_test.cpp @@ -33,5 +33,13 @@ int main() assert(pouter.is_empty()); assert(holes[0].is_empty()); assert(holes[1].is_empty()); + + Polygon_with_holes_2 pwh_copy(pwh); + assert(pwh_copy == pwh); + Polygon_with_holes_2 pwh_move_cstructed(std::move(pwh)); + assert(pwh.holes().empty()); + assert(pwh.outer_boundary().is_empty()); + Polygon_with_holes_2 pwh_move_assigned; + pwh_move_assigned = std::move(pwh_copy); return 0; } From d9245b9cd63d024d401522fe32afd5d0126460b1 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Fri, 10 Jun 2022 17:26:44 +0200 Subject: [PATCH 105/107] Remove any mention of result_of in the documentation --- .../Developer_manual/Chapter_code_format.txt | 23 ------------------- .../doc/Documentation/Preliminaries.txt | 10 -------- 2 files changed, 33 deletions(-) diff --git a/Documentation/doc/Documentation/Developer_manual/Chapter_code_format.txt b/Documentation/doc/Documentation/Developer_manual/Chapter_code_format.txt index fbc3a325b89..4d639ee7263 100644 --- a/Documentation/doc/Documentation/Developer_manual/Chapter_code_format.txt +++ b/Documentation/doc/Documentation/Developer_manual/Chapter_code_format.txt @@ -257,29 +257,6 @@ The first list of items are meant as rules, i.e., you should follow them. ... #endif // CGAL_THIS_IS_AN_EXAMPLE_H \endcode -- Support the - result_of - protocol whenever your functors have more than one return type - otherwise provide a `result_type` member typedef. - An example for this is a C++03 style `identity` functor: - \code{.cpp} - struct Identity { - template - T& operator()(T& t) { return t; } - template - const T& operator()(const T& t) { return t; } - template - struct result; - template - struct result { - typedef T& type; - }; - template - struct result { - typedef const T& type; - }; - }; - \endcode The following items can be seen as recommendations in contrast to the rules of previous paragraph. diff --git a/Documentation/doc/Documentation/Preliminaries.txt b/Documentation/doc/Documentation/Preliminaries.txt index e194f3d46ec..a2ed83f6740 100644 --- a/Documentation/doc/Documentation/Preliminaries.txt +++ b/Documentation/doc/Documentation/Preliminaries.txt @@ -44,16 +44,6 @@ also avoid CMake to link with the native threads support library on your system. After being based on the \CC standard released in 1998 (and later refined in 2003) for a long time, \cgal is now based on a newer major version of the standard, C++14. -\section Preliminaries_functor Functor Return Types - -\cgal functors support the -result_of -protocol. If a functor `F` has the same return type across all -overloads of `operator()`, the nested type -`F::result_type` is defined to be that type. Otherwise the -return type of calling the functor with an argument of type -`Arg` can be accessed through \link CGAL::cpp11::result_of::type `CGAL::cpp11::result_of::type` \endlink. - \section preliminaries_secchecks Checks Much of the \cgal code contains assert statements for preconditions, and postconditions of functions From 2644e1425549aae58c6d3315534d2bf2a6fd427f Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Mon, 13 Jun 2022 11:18:02 +0200 Subject: [PATCH 106/107] updated crontab (automated commit) --- Maintenance/infrastructure/cgal.geometryfactory.com/crontab | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Maintenance/infrastructure/cgal.geometryfactory.com/crontab b/Maintenance/infrastructure/cgal.geometryfactory.com/crontab index a55ba1a43b5..27a85b47672 100644 --- a/Maintenance/infrastructure/cgal.geometryfactory.com/crontab +++ b/Maintenance/infrastructure/cgal.geometryfactory.com/crontab @@ -23,7 +23,7 @@ LC_CTYPE=en_US.UTF-8 # "integration" 0 21 * * Mon,Tue,Wed,Thu cd $HOME/CGAL/create_internal_release && /usr/bin/time scl enable rh-git29 -- $HOME/bin/create_release $HOME/CGAL/branches/integration.git $HOME/CGAL/branches/empty-dir --do-it || echo ERROR # from branch 5.5 -0 21 * * Fri cd $HOME/CGAL/create_internal_release-5.5-branch && /usr/bin/time scl enable rh-git29 -- $HOME/bin/create_release $HOME/CGAL/branches/CGAL-5.4-branch.git --public --do-it || echo ERROR +0 21 * * Fri cd $HOME/CGAL/create_internal_release-5.5-branch && /usr/bin/time scl enable rh-git29 -- $HOME/bin/create_release $HOME/CGAL/branches/CGAL-5.5-branch.git --public --do-it || echo ERROR # from branch 5.4 0 21 * * Sat cd $HOME/CGAL/create_internal_release-5.4-branch && /usr/bin/time scl enable rh-git29 -- $HOME/bin/create_release $HOME/CGAL/branches/CGAL-5.4-branch.git --public --do-it || echo ERROR From c8654724e2aa2fd2f7c224b1c1274a18d1c17a52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Mon, 13 Jun 2022 12:41:57 +0200 Subject: [PATCH 107/107] update test to check we can prevent collapses and flips --- .../test_remove_caps_needles.cpp | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_remove_caps_needles.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_remove_caps_needles.cpp index ed99bc0b0b7..b57a3dc8e8d 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_remove_caps_needles.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_remove_caps_needles.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -116,7 +117,49 @@ void test_with_envelope(std::string filename, double eps) std::cout << " Output mesh has self-intersections\n"; } +bool same_meshes(const Mesh& m1, const Mesh& m2) +{ + std::size_t c=0, m1_only=0, m2_only=0; + PMP::match_faces(m1, m2, CGAL::Counting_output_iterator(&c) + , CGAL::Counting_output_iterator(&m1_only) + , CGAL::Counting_output_iterator(&m2_only)); + return m1_only==0 && m2_only==0; +} +void test_parameters_on_pig(std::string filename) +{ + std::ifstream input(filename); + Mesh mesh, bk; + if (!input || !(input >> mesh) || !CGAL::is_triangle_mesh(mesh)) { + std::cerr << "Not a valid input file." << std::endl; + exit(EXIT_FAILURE); + } + + bk=mesh; + + PMP::experimental::remove_almost_degenerate_faces(mesh, + std::cos(160. / 180 * CGAL_PI), + 4, + 9999 /*no_constraints*/); + assert(vertices(mesh).size()!=vertices(bk).size()); + + mesh=bk; + PMP::experimental::remove_almost_degenerate_faces(mesh, + std::cos(160. / 180 * CGAL_PI), + 4, + 0.000000000000001); // no-collapse but flips + assert(vertices(mesh).size()==vertices(bk).size()); + assert(!same_meshes(mesh,bk)); + + mesh=bk; + PMP::experimental::remove_almost_degenerate_faces(mesh, + std::cos(160. / 180 * CGAL_PI), + 4, + 0.000000000000001, + CGAL::parameters::flip_triangle_height_threshold(0.000000000000001)); // no-collapse and no flip + assert(vertices(mesh).size()==vertices(bk).size()); + assert(same_meshes(mesh,bk)); +} int main(int argc, char** argv) { @@ -129,5 +172,9 @@ int main(int argc, char** argv) if (argc==3) test_with_envelope(filename, atof(argv[2])); + // only run that test with pig.off + if (argc==1) + test_parameters_on_pig(filename); + return 0; }