diff --git a/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Iterative_authalic_parameterizer_3.h b/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Iterative_authalic_parameterizer_3.h index d0e20ad5a0b..2e475b11db8 100644 --- a/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Iterative_authalic_parameterizer_3.h +++ b/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Iterative_authalic_parameterizer_3.h @@ -35,7 +35,7 @@ #include // #include #include -#include +#include #include #if defined(CGAL_EIGEN3_ENABLED) @@ -723,7 +723,7 @@ private: VertexIndexMap& vimap) const { auto vpm = get_const_property_map(CGAL::vertex_point, tmesh); - const CGAL::Weights::Mean_value_weight compute_mvc(tmesh, vpm); + const CGAL::Weights::Edge_tangent_weight compute_mvc(tmesh, vpm); const int i = get(vimap, v); diff --git a/Weights/include/CGAL/Weights/mean_value_weights.h b/Weights/include/CGAL/Weights/mean_value_weights.h index d66d9bf3487..2fc9117247d 100644 --- a/Weights/include/CGAL/Weights/mean_value_weights.h +++ b/Weights/include/CGAL/Weights/mean_value_weights.h @@ -188,99 +188,6 @@ namespace Weights { } // namespace internal - // Undocumented mean value weight class. - // Its constructor takes a polygon mesh and a vertex to point map - // and its operator() is defined based on the halfedge_descriptor only. - // This version is currently used in: - // Surface_mesh_parameterizer -> Iterative_authalic_parameterizer_3.h - template< - typename PolygonMesh, - typename VertexPointMap = typename boost::property_map::type> - class Mean_value_weight { - - using GeomTraits = typename CGAL::Kernel_traits< - typename boost::property_traits::value_type>::type; - using FT = typename GeomTraits::FT; - - const PolygonMesh& m_pmesh; - const VertexPointMap m_pmap; - const GeomTraits m_traits; - - public: - using vertex_descriptor = typename boost::graph_traits::vertex_descriptor; - using halfedge_descriptor = typename boost::graph_traits::halfedge_descriptor; - - Mean_value_weight(const PolygonMesh& pmesh, const VertexPointMap pmap) : - m_pmesh(pmesh), m_pmap(pmap), m_traits() { } - - // Returns the mean-value coordinate of the specified halfedge_descriptor. - // Returns different values for different edge orientations (which is normal - // behavior according to the formula). - FT operator()(const halfedge_descriptor he) const { - - const vertex_descriptor v0 = target(he, m_pmesh); - const vertex_descriptor v1 = source(he, m_pmesh); - const auto& p0 = get(m_pmap, v0); - const auto& p1 = get(m_pmap, v1); - const FT norm = internal::distance_3(m_traits, p0, p1); - - // Only one triangle for border edges. - if (is_border_edge(he, m_pmesh)) { - const halfedge_descriptor he_cw = opposite(next(he, m_pmesh), m_pmesh); - vertex_descriptor v2 = source(he_cw, m_pmesh); - if (is_border_edge(he_cw, m_pmesh)) { - const halfedge_descriptor he_ccw = prev(opposite(he, m_pmesh), m_pmesh); - v2 = source(he_ccw, m_pmesh); - } - return half_tan_value_2(v1, v0, v2) / norm; - } else { - const halfedge_descriptor he_cw = opposite(next(he, m_pmesh), m_pmesh); - const vertex_descriptor v2 = source(he_cw, m_pmesh); - const halfedge_descriptor he_ccw = prev(opposite(he, m_pmesh), m_pmesh); - const vertex_descriptor v3 = source(he_ccw, m_pmesh); - return ( - half_tan_value_2(v1, v0, v2) / norm + - half_tan_value_2(v1, v0, v3) / norm ); - } - } - - private: - // The authors deviation built on Meyer_02. - FT half_tan_value_2( - const vertex_descriptor v0, - const vertex_descriptor v1, - const vertex_descriptor v2) const { - - using Get_sqrt = internal::Get_sqrt; - const auto sqrt = Get_sqrt::sqrt_object(m_traits); - - const auto squared_length_3 = - m_traits.compute_squared_length_3_object(); - const auto construct_vector_3 = - m_traits.construct_vector_3_object(); - - const auto& p0 = get(m_pmap, v0); - const auto& p1 = get(m_pmap, v1); - const auto& p2 = get(m_pmap, v2); - - const auto a = construct_vector_3(p1, p0); - const auto b = construct_vector_3(p1, p2); - - const FT dot_ab = a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; - const FT dot_aa = squared_length_3(a); - const FT dot_bb = squared_length_3(b); - const FT dot_aa_bb = dot_aa * dot_bb; - - const FT cos_rep = dot_ab; - const FT sin_rep = sqrt(dot_aa_bb - dot_ab * dot_ab); - const FT normalizer = sqrt(dot_aa_bb); // |a| * |b| - - // The formula from [Floater04] page 4: - // tan(Q / 2) = (1 - cos(Q)) / sin(Q). - return (normalizer - cos_rep) / sin_rep; - } - }; - /// \endcond /*! diff --git a/Weights/include/CGAL/Weights/tangent_weights.h b/Weights/include/CGAL/Weights/tangent_weights.h index a7e93109a02..47a7539ae8a 100644 --- a/Weights/include/CGAL/Weights/tangent_weights.h +++ b/Weights/include/CGAL/Weights/tangent_weights.h @@ -372,6 +372,67 @@ namespace Weights { return tangent_weight(t, r, p, q, traits); } + // Undocumented tangent weight class. + // Its constructor takes a polygon mesh and a vertex to point map + // and its operator() is defined based on the halfedge_descriptor only. + // This version is currently used in: + // Surface_mesh_parameterizer -> Iterative_authalic_parameterizer_3.h + template< + typename PolygonMesh, + typename VertexPointMap = typename boost::property_map::type> + class Edge_tangent_weight { + + using GeomTraits = typename CGAL::Kernel_traits< + typename boost::property_traits::value_type>::type; + using FT = typename GeomTraits::FT; + + const PolygonMesh& m_pmesh; + const VertexPointMap m_pmap; + const GeomTraits m_traits; + + public: + using vertex_descriptor = typename boost::graph_traits::vertex_descriptor; + using halfedge_descriptor = typename boost::graph_traits::halfedge_descriptor; + + Edge_tangent_weight(const PolygonMesh& pmesh, const VertexPointMap pmap) : + m_pmesh(pmesh), m_pmap(pmap), m_traits() { } + + FT operator()(const halfedge_descriptor he) const { + + FT weight = FT(0); + if (is_border_edge(he, m_pmesh)) { + const auto h1 = next(he, m_pmesh); + + const auto v0 = target(he, m_pmesh); + const auto v1 = source(he, m_pmesh); + const auto v2 = target(h1, m_pmesh); + + const auto& p0 = get(m_pmap, v0); + const auto& p1 = get(m_pmap, v1); + const auto& p2 = get(m_pmap, v2); + + weight = internal::tangent_3(m_traits, p0, p2, p1); + + } else { + const auto h1 = next(he, m_pmesh); + const auto h2 = prev(opposite(he, m_pmesh), m_pmesh); + + const auto v0 = target(he, m_pmesh); + const auto v1 = source(he, m_pmesh); + const auto v2 = target(h1, m_pmesh); + const auto v3 = source(h2, m_pmesh); + + const auto& p0 = get(m_pmap, v0); + const auto& p1 = get(m_pmap, v1); + const auto& p2 = get(m_pmap, v2); + const auto& p3 = get(m_pmap, v3); + + weight = tangent_weight(p2, p1, p3, p0) / FT(2); + } + return weight; + } + }; + // Undocumented tangent weight class. // Its constructor takes three points either in 2D or 3D. // This version is currently used in: