user-defined mv weight is replaced with the edge tangent weight

This commit is contained in:
Dmitry Anisimov 2021-08-04 13:57:30 +02:00
parent c9955fb773
commit 9e89439645
3 changed files with 63 additions and 95 deletions

View File

@ -35,7 +35,7 @@
#include <CGAL/Polygon_mesh_processing/connected_components.h>
// #include <CGAL/Weights/authalic_weights.h>
#include <CGAL/Weights/cotangent_weights.h>
#include <CGAL/Weights/mean_value_weights.h>
#include <CGAL/Weights/tangent_weights.h>
#include <CGAL/number_type_config.h>
#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<Triangle_mesh, decltype(vpm)> compute_mvc(tmesh, vpm);
const CGAL::Weights::Edge_tangent_weight<Triangle_mesh, decltype(vpm)> compute_mvc(tmesh, vpm);
const int i = get(vimap, v);

View File

@ -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<PolygonMesh, CGAL::vertex_point_t>::type>
class Mean_value_weight {
using GeomTraits = typename CGAL::Kernel_traits<
typename boost::property_traits<VertexPointMap>::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<PolygonMesh>::vertex_descriptor;
using halfedge_descriptor = typename boost::graph_traits<PolygonMesh>::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<GeomTraits>;
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
/*!

View File

@ -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<PolygonMesh, CGAL::vertex_point_t>::type>
class Edge_tangent_weight {
using GeomTraits = typename CGAL::Kernel_traits<
typename boost::property_traits<VertexPointMap>::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<PolygonMesh>::vertex_descriptor;
using halfedge_descriptor = typename boost::graph_traits<PolygonMesh>::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: