diff --git a/Surface_mesh_deformation/include/CGAL/Surface_mesh_deformation.h b/Surface_mesh_deformation/include/CGAL/Surface_mesh_deformation.h index a715accf733..a536e13ddae 100644 --- a/Surface_mesh_deformation/include/CGAL/Surface_mesh_deformation.h +++ b/Surface_mesh_deformation/include/CGAL/Surface_mesh_deformation.h @@ -86,8 +86,7 @@ struct Types_selectors; template struct Types_selectors { - typedef SC_on_the_fly_pmap Wrapped_VertexPointMap; - typedef CGAL::Weights::Single_cotangent_weight Weight_calculator; + typedef CGAL::Weights::Single_cotangent_weight Weight_calculator; struct ARAP_visitor { @@ -107,8 +106,7 @@ struct Types_selectors template struct Types_selectors { - typedef SC_on_the_fly_pmap Wrapped_VertexPointMap; - typedef CGAL::Weights::Cotangent_weight Weight_calculator; + typedef CGAL::Weights::Cotangent_weight Weight_calculator; typedef typename Types_selectors::ARAP_visitor ARAP_visitor; }; @@ -116,8 +114,7 @@ struct Types_selectors template struct Types_selectors { - typedef SC_on_the_fly_pmap Wrapped_VertexPointMap; - typedef CGAL::Weights::Cotangent_weight Weight_calculator; + typedef CGAL::Weights::Cotangent_weight Weight_calculator; class ARAP_visitor { @@ -384,7 +381,7 @@ public: vertex_index_map, hedge_index_map, vertex_point_map, - Weight_calculator(triangle_mesh, internal::SC_on_the_fly_pmap(vertex_point_map))) + Weight_calculator()) { } Surface_mesh_deformation(Triangle_mesh& triangle_mesh, @@ -437,9 +434,10 @@ public: private: void init() { + typedef internal::SC_on_the_fly_pmap Wrapper; hedge_weight.reserve(num_halfedges(m_triangle_mesh)); for(halfedge_descriptor he : halfedges(m_triangle_mesh)) - hedge_weight.push_back(this->weight_calculator(he)); + hedge_weight.push_back(this->weight_calculator(he, m_triangle_mesh, Wrapper(vertex_point_map))); arap_visitor.init(m_triangle_mesh, vertex_point_map); } @@ -823,6 +821,7 @@ public: */ void overwrite_initial_geometry() { + typedef internal::SC_on_the_fly_pmap Wrapper; if(roi.empty()) { return; } // no ROI to overwrite region_of_solution(); // the roi should be preprocessed since we are using original_position vec @@ -843,13 +842,13 @@ public: std::size_t id_e = id(he); if(is_weight_computed[id_e]) { continue; } - hedge_weight[id_e] = weight_calculator(he); + hedge_weight[id_e] = weight_calculator(he, m_triangle_mesh, Wrapper(vertex_point_map)); is_weight_computed[id_e] = true; halfedge_descriptor e_opp = opposite(he, m_triangle_mesh); std::size_t id_e_opp = id(e_opp); - hedge_weight[id_e_opp] = weight_calculator(e_opp); + hedge_weight[id_e_opp] = weight_calculator(e_opp, m_triangle_mesh, Wrapper(vertex_point_map)); is_weight_computed[id_e_opp] = true; } } diff --git a/Weights/include/CGAL/Weights/cotangent_weights.h b/Weights/include/CGAL/Weights/cotangent_weights.h index d462c3f5174..ce3471550b5 100644 --- a/Weights/include/CGAL/Weights/cotangent_weights.h +++ b/Weights/include/CGAL/Weights/cotangent_weights.h @@ -147,44 +147,38 @@ typename Kernel::FT cotangent_weight(const CGAL::Point_3& p0, // For border edges it returns zero. // This version is currently used in: // Surface_mesh_deformation -> Surface_mesh_deformation.h -template::value_type>::type> +template class Single_cotangent_weight { using vertex_descriptor = typename boost::graph_traits::vertex_descriptor; using halfedge_descriptor = typename boost::graph_traits::halfedge_descriptor; - using Point_ref = typename boost::property_traits::reference; - using FT = typename GeomTraits::FT; - -private: - const PolygonMesh& m_pmesh; - const VertexPointMap m_vpm; - const GeomTraits m_traits; - public: - Single_cotangent_weight(const PolygonMesh& pmesh, - const VertexPointMap vpm, - const GeomTraits& traits = GeomTraits()) - : m_pmesh(pmesh), m_vpm(vpm), m_traits(traits) - { } - - decltype(auto) operator()(const halfedge_descriptor he) const + // Returns the cotangent of the opposite angle of the edge + // 0 for border edges (which does not have an opposite angle). + template + auto operator()(halfedge_descriptor he, + PolygonMesh& pmesh, + VPM vpm) { - if (is_border(he, m_pmesh)) + using Point = typename boost::property_traits::value_type; + using Point_ref = typename boost::property_traits::reference; + + using GeomTraits = typename Kernel_traits::type; + using FT = typename GeomTraits::FT; + + if(is_border(he, pmesh)) return FT{0}; - const vertex_descriptor v0 = target(he, m_pmesh); - const vertex_descriptor v1 = source(he, m_pmesh); - const vertex_descriptor v2 = target(next(he, m_pmesh), m_pmesh); + const vertex_descriptor v0 = target(he, pmesh); + const vertex_descriptor v1 = source(he, pmesh); + const vertex_descriptor v2 = target(next(he, pmesh), pmesh); - const Point_ref p0 = get(m_vpm, v0); - const Point_ref p1 = get(m_vpm, v1); - const Point_ref p2 = get(m_vpm, v2); + const Point_ref p0 = get(vpm, v0); + const Point_ref p1 = get(vpm, v1); + const Point_ref p2 = get(vpm, v2); - return cotangent_3(p0, p2, p1, m_traits); + return cotangent(p0, p2, p1); } }; @@ -200,7 +194,7 @@ public: // Surface_mesh_parameterizer -> Orbifold_Tutte_parameterizer_3.h (default version) // Surface_mesh_skeletonization -> Mean_curvature_flow_skeletonization.h (clamped version) template::type, typename GeomTraits = typename Kernel_traits< typename boost::property_traits::value_type>::type> class Cotangent_weight @@ -208,11 +202,14 @@ class Cotangent_weight using vertex_descriptor = typename boost::graph_traits::vertex_descriptor; using halfedge_descriptor = typename boost::graph_traits::halfedge_descriptor; - using Point_ref = typename boost::property_traits::reference; using FT = typename GeomTraits::FT; private: - const PolygonMesh& m_pmesh; + // These class members are used only when the constructor initializing them + // is used, but Surface_mesh_deformation has its own weight API locked + // by the concept SurfaceMeshDeformationWeights. + // A bit awkward, but better than duplicating code... + PolygonMesh* const* m_pmesh_ptr; const VertexPointMap m_vpm; const GeomTraits m_traits; @@ -220,39 +217,41 @@ private: bool m_bound_from_below; public: - Cotangent_weight(const PolygonMesh& pmesh, - const VertexPointMap vpm, - const GeomTraits& traits = GeomTraits(), - const bool use_clamped_version = false, - const bool bound_from_below = true) - : m_pmesh(pmesh), m_vpm(vpm), m_traits(traits), - m_use_clamped_version(use_clamped_version), - m_bound_from_below(bound_from_below) + Cotangent_weight() + : m_pmesh_ptr(nullptr), m_vpm(), m_traits(), m_use_clamped_version(false), m_bound_from_below(true) { } - decltype(auto) operator()(const halfedge_descriptor he) const + // Common API whether mesh/vpm/traits are initialized in the constructor, + // or passed in the operator() + template + FT operator()(const halfedge_descriptor he, + const PolygonMesh& pmesh, + const VPM vpm, + const GT& traits) const { - if(is_border(he, m_pmesh)) + using Point_ref = typename boost::property_traits::reference; + + if(is_border(he, pmesh)) return FT{0}; auto half_weight = [&] (const halfedge_descriptor he) -> FT { - if(is_border(he, m_pmesh)) + if(is_border(he, pmesh)) return FT{0}; - const vertex_descriptor v0 = target(he, m_pmesh); - const vertex_descriptor v1 = source(he, m_pmesh); - const vertex_descriptor v2 = target(next(he, m_pmesh), m_pmesh); + const vertex_descriptor v0 = target(he, pmesh); + const vertex_descriptor v1 = source(he, pmesh); + const vertex_descriptor v2 = target(next(he, pmesh), pmesh); - const Point_ref p0 = get(m_vpm, v0); - const Point_ref p1 = get(m_vpm, v1); - const Point_ref p2 = get(m_vpm, v2); + const Point_ref p0 = get(vpm, v0); + const Point_ref p1 = get(vpm, v1); + const Point_ref p2 = get(vpm, v2); FT weight = 0; if (m_use_clamped_version) - weight = cotangent_3_clamped(p1, p2, p0, m_traits); + weight = cotangent_3_clamped(p1, p2, p0, traits); else - weight = cotangent_3(p1, p2, p0, m_traits); + weight = cotangent_3(p1, p2, p0, traits); if(m_bound_from_below) weight = (CGAL::max)(FT(0), weight); @@ -260,9 +259,38 @@ public: return weight / FT(2); }; - FT weight = half_weight(he) + half_weight(opposite(he, m_pmesh)); + FT weight = half_weight(he) + half_weight(opposite(he, pmesh)); return weight; } + + // That is the API called by Surface_mesh_deformation + template + FT operator()(const halfedge_descriptor he, + const PolygonMesh& pmesh, + const VPM vpm) const + { + using Point = typename boost::property_traits::value_type; + using GT = typename Kernel_traits::type; + return this->operator()(he, pmesh, vpm, GT()); + } + +public: + // This is the "normal" API: give all info to the constructor, and operator()(halfedge) + Cotangent_weight(const PolygonMesh& pmesh, + const VertexPointMap vpm, + const GeomTraits& traits = GeomTraits(), + const bool use_clamped_version = false, + const bool bound_from_below = true) + : m_pmesh_ptr(&pmesh), m_vpm(vpm), m_traits(traits), + m_use_clamped_version(use_clamped_version), + m_bound_from_below(bound_from_below) + { } + + FT operator()(const halfedge_descriptor he) const + { + CGAL_precondition(m_pmesh_ptr != nullptr); + return this->operator()(he, *m_pmesh_ptr, m_vpm, m_traits); + } }; // Undocumented cotangent weight class. diff --git a/Weights/include/CGAL/Weights/internal/pmp_weights_deprecated.h b/Weights/include/CGAL/Weights/internal/pmp_weights_deprecated.h index 7a7cd14a4c2..40984d8bc0f 100644 --- a/Weights/include/CGAL/Weights/internal/pmp_weights_deprecated.h +++ b/Weights/include/CGAL/Weights/internal/pmp_weights_deprecated.h @@ -51,7 +51,7 @@ struct Cotangent_value_Meyer_impl double operator()(vertex_descriptor v0, vertex_descriptor v1, vertex_descriptor v2, - const VertexPointMap& ppmap) + VertexPointMap ppmap) { typedef typename Kernel_traits< typename boost::property_traits::value_type >::Kernel::Vector_3 Vector; @@ -94,17 +94,17 @@ protected: typedef typename boost::property_traits::value_type Point; typedef typename Kernel_traits::Kernel::Vector_3 Vector; - PolygonMesh& pmesh_; + const PolygonMesh& pmesh_; Point_property_map ppmap_; public: - Cotangent_value_Meyer(PolygonMesh& pmesh_, + Cotangent_value_Meyer(const PolygonMesh& pmesh_, VertexPointMap vpmap_) : pmesh_(pmesh_), ppmap_(vpmap_) { } - PolygonMesh& pmesh() { return pmesh_; } - Point_property_map& ppmap() { return ppmap_; } + const PolygonMesh& pmesh() { return pmesh_; } + Point_property_map ppmap() { return ppmap_; } double operator()(vertex_descriptor v0, vertex_descriptor v1, @@ -128,13 +128,13 @@ class Cotangent_value_Meyer_secure Point_property_map ppmap_; public: - Cotangent_value_Meyer_secure(PolygonMesh& pmesh_, + Cotangent_value_Meyer_secure(const PolygonMesh& pmesh_, VertexPointMap vpmap_) : pmesh_(pmesh_), ppmap_(vpmap_) { } - PolygonMesh& pmesh() { return pmesh_; } - Point_property_map& ppmap() { return ppmap_; } + const PolygonMesh& pmesh() { return pmesh_; } + Point_property_map ppmap() { return ppmap_; } double operator()(vertex_descriptor v0, vertex_descriptor v1, @@ -165,13 +165,13 @@ class Cotangent_value_clamped : CotangentValue Cotangent_value_clamped() { } public: - Cotangent_value_clamped(PolygonMesh& pmesh_, + Cotangent_value_clamped(const PolygonMesh& pmesh_, VertexPointMap vpmap_) : CotangentValue(pmesh_, vpmap_) { } - PolygonMesh& pmesh() { return CotangentValue::pmesh(); } - VertexPointMap& ppmap() { return CotangentValue::ppmap(); } + const PolygonMesh& pmesh() { return CotangentValue::pmesh(); } + VertexPointMap ppmap() { return CotangentValue::ppmap(); } typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; @@ -194,13 +194,13 @@ class Cotangent_value_clamped_2 : CotangentValue Cotangent_value_clamped_2() { } public: - Cotangent_value_clamped_2(PolygonMesh& pmesh_, + Cotangent_value_clamped_2(const PolygonMesh& pmesh_, VertexPointMap vpmap_) : CotangentValue(pmesh_, vpmap_) { } - PolygonMesh& pmesh() { return CotangentValue::pmesh(); } - VertexPointMap& ppmap() { return CotangentValue::ppmap(); } + const PolygonMesh& pmesh() { return CotangentValue::pmesh(); } + VertexPointMap ppmap() { return CotangentValue::ppmap(); } typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; @@ -238,17 +238,16 @@ template > class Cotangent_value_minimum_zero : CotangentValue { - Cotangent_value_minimum_zero() - { } - public: - Cotangent_value_minimum_zero(PolygonMesh& pmesh_, + Cotangent_value_minimum_zero() { } + + Cotangent_value_minimum_zero(const PolygonMesh& pmesh_, VertexPointMap vpmap_) : CotangentValue(pmesh_, vpmap_) { } - PolygonMesh& pmesh() { return CotangentValue::pmesh(); } - VertexPointMap& ppmap() { return CotangentValue::ppmap(); } + const PolygonMesh& pmesh() { return CotangentValue::pmesh(); } + VertexPointMap ppmap() { return CotangentValue::ppmap(); } typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; @@ -268,13 +267,13 @@ class Voronoi_area : CotangentValue { public: - Voronoi_area(PolygonMesh& pmesh_, + Voronoi_area(const PolygonMesh& pmesh_, VertexPointMap vpmap_) : CotangentValue(pmesh_, vpmap_) { } - PolygonMesh& pmesh() { return CotangentValue::pmesh(); } - VertexPointMap& ppmap() { return CotangentValue::ppmap(); } + const PolygonMesh& pmesh() { return CotangentValue::pmesh(); } + VertexPointMap ppmap() { return CotangentValue::ppmap(); } typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; typedef typename boost::graph_traits::in_edge_iterator in_edge_iterator; @@ -348,13 +347,13 @@ class Cotangent_value_area_weighted Cotangent_value_area_weighted() { } public: - Cotangent_value_area_weighted(PolygonMesh& pmesh_, + Cotangent_value_area_weighted(const PolygonMesh& pmesh_, VertexPointMap vpmap_) : CotangentValue(pmesh_, vpmap_) { } - PolygonMesh& pmesh() { return CotangentValue::pmesh(); } - VertexPointMap& ppmap() { return CotangentValue::ppmap(); } + const PolygonMesh& pmesh() { return CotangentValue::pmesh(); } + VertexPointMap ppmap() { return CotangentValue::ppmap(); } typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; @@ -385,7 +384,7 @@ struct Cotangent_weight_impl template double operator()(halfedge_descriptor he, PolygonMesh& pmesh, - const VertexPointMap& ppmap) + VertexPointMap ppmap) { const vertex_descriptor v0 = target(he, pmesh); const vertex_descriptor v1 = source(he, pmesh); @@ -422,20 +421,20 @@ template::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; @@ -512,13 +511,13 @@ class Single_cotangent_weight Single_cotangent_weight() { } public: - Single_cotangent_weight(PolygonMesh& pmesh_, + Single_cotangent_weight(const PolygonMesh& pmesh_, VertexPointMap vpmap_) : CotangentValue(pmesh_, vpmap_) { } - PolygonMesh& pmesh() { return CotangentValue::pmesh(); } - VertexPointMap& ppmap() { return CotangentValue::ppmap(); } + const PolygonMesh& pmesh() { return CotangentValue::pmesh(); } + VertexPointMap ppmap() { return CotangentValue::ppmap(); } typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; @@ -557,13 +556,13 @@ class Cotangent_weight_with_triangle_area Cotangent_weight_with_triangle_area() { } public: - Cotangent_weight_with_triangle_area(PolygonMesh& pmesh_, + Cotangent_weight_with_triangle_area(const PolygonMesh& pmesh_, VertexPointMap vpmap_) : CotangentValue(pmesh_, vpmap_) { } - PolygonMesh& pmesh() { return CotangentValue::pmesh(); } - VertexPointMap& ppmap() { return CotangentValue::ppmap(); } + const PolygonMesh& pmesh() { return CotangentValue::pmesh(); } + VertexPointMap ppmap() { return CotangentValue::ppmap(); } double operator()(halfedge_descriptor he) { @@ -614,18 +613,16 @@ template::type> class Mean_value_weight { - // Mean_value_weight() {} - - PolygonMesh& pmesh_; + const PolygonMesh& pmesh_; VertexPointMap vpmap_; public: - Mean_value_weight(PolygonMesh& pmesh_, + Mean_value_weight(const PolygonMesh& pmesh_, VertexPointMap vpmap) : pmesh_(pmesh_), vpmap_(vpmap) { } - PolygonMesh& pmesh() { return pmesh_; } + const PolygonMesh& pmesh() { return pmesh_; } typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; @@ -722,11 +719,11 @@ class Hybrid_weight Hybrid_weight() { } public: - Hybrid_weight(PolygonMesh& pmesh_) + Hybrid_weight(const PolygonMesh& pmesh_) : primary(pmesh_), secondary(pmesh_) { } - PolygonMesh& pmesh() { return primary.pmesh(); } + const PolygonMesh& pmesh() { return primary.pmesh(); } typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; @@ -751,14 +748,14 @@ public: template class Scale_dependent_weight_fairing { - PolygonMesh& pmesh_; + const PolygonMesh& pmesh_; public: - Scale_dependent_weight_fairing(PolygonMesh& pmesh_) + Scale_dependent_weight_fairing(const PolygonMesh& pmesh_) : pmesh_(pmesh_) { } - PolygonMesh& pmesh() { return pmesh_; } + const PolygonMesh& pmesh() { return pmesh_; } typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; @@ -800,7 +797,7 @@ public: Cotangent_weight_with_voronoi_area_fairing(PM& pmesh_, VPMap vpmap_) - : voronoi_functor(pmesh_, vpmap_), + : voronoi_functor(pmesh_, vpmap_), cotangent_functor(pmesh_, vpmap_) { } @@ -867,7 +864,7 @@ public: typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; - Uniform_weight_fairing(PolygonMesh&) { } + Uniform_weight_fairing(const PolygonMesh&) { } double w_ij(halfedge_descriptor /* e */) { return 1.0; } double w_i(vertex_descriptor /* v_i */) { return 1.0; } diff --git a/Weights/include/CGAL/Weights/internal/utils.h b/Weights/include/CGAL/Weights/internal/utils.h index 744af8be2d3..850fccff1e8 100644 --- a/Weights/include/CGAL/Weights/internal/utils.h +++ b/Weights/include/CGAL/Weights/internal/utils.h @@ -214,7 +214,6 @@ typename GeomTraits::Point_3 rotate_point_3(const double angle_rad, const GeomTraits& traits) { using FT = typename GeomTraits::FT; - using Point_3 = typename GeomTraits::Point_3; auto point_3 = traits.construct_point_3_object(); @@ -274,7 +273,6 @@ typename GeomTraits::Point_2 to_2d(const typename GeomTraits::Vector_3& b1, const GeomTraits& traits) { using FT = typename GeomTraits::FT; - using Point_2 = typename GeomTraits::Point_2; using Vector_3 = typename GeomTraits::Vector_3; auto dot_product_3 = traits.compute_scalar_product_3_object(); @@ -447,7 +445,6 @@ typename GeomTraits::FT area_3(const typename GeomTraits::Point_3& p, const typename GeomTraits::Point_3& r, const GeomTraits& traits) { - using FT = typename GeomTraits::FT; using Point_2 = typename GeomTraits::Point_2; using Point_3 = typename GeomTraits::Point_3; using Vector_3 = typename GeomTraits::Vector_3; @@ -493,7 +490,6 @@ typename GeomTraits::FT positive_area_3(const typename GeomTraits::Point_3& p, const typename GeomTraits::Point_3& r, const GeomTraits& traits) { - using FT = typename GeomTraits::FT; using Get_sqrt = Get_sqrt; auto sqrt = Get_sqrt::sqrt_object(traits);