mirror of https://github.com/CGAL/cgal
user-defined mv weight is replaced with the edge tangent weight
This commit is contained in:
parent
c9955fb773
commit
9e89439645
|
|
@ -35,7 +35,7 @@
|
||||||
#include <CGAL/Polygon_mesh_processing/connected_components.h>
|
#include <CGAL/Polygon_mesh_processing/connected_components.h>
|
||||||
// #include <CGAL/Weights/authalic_weights.h>
|
// #include <CGAL/Weights/authalic_weights.h>
|
||||||
#include <CGAL/Weights/cotangent_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>
|
#include <CGAL/number_type_config.h>
|
||||||
|
|
||||||
#if defined(CGAL_EIGEN3_ENABLED)
|
#if defined(CGAL_EIGEN3_ENABLED)
|
||||||
|
|
@ -723,7 +723,7 @@ private:
|
||||||
VertexIndexMap& vimap) const
|
VertexIndexMap& vimap) const
|
||||||
{
|
{
|
||||||
auto vpm = get_const_property_map(CGAL::vertex_point, tmesh);
|
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);
|
const int i = get(vimap, v);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -188,99 +188,6 @@ namespace Weights {
|
||||||
|
|
||||||
} // namespace internal
|
} // 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
|
/// \endcond
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
|
||||||
|
|
@ -372,6 +372,67 @@ namespace Weights {
|
||||||
return tangent_weight(t, r, p, q, traits);
|
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.
|
// Undocumented tangent weight class.
|
||||||
// Its constructor takes three points either in 2D or 3D.
|
// Its constructor takes three points either in 2D or 3D.
|
||||||
// This version is currently used in:
|
// This version is currently used in:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue