17#include <lagrange/Mesh.h>
18#include <lagrange/MeshTrait.h>
19#include <lagrange/attributes/attribute_utils.h>
20#include <lagrange/common.h>
21#include <lagrange/legacy/inline.h>
22#include <lagrange/utils/safe_cast.h>
38template <
typename MeshType>
41 static_assert(MeshTrait<MeshType>::is_mesh(),
"Input type is not Mesh");
42 if (mesh.get_vertex_per_facet() != 3) {
43 throw std::runtime_error(
"Input mesh must be a triangle mesh.");
46 using Scalar =
typename MeshType::Scalar;
47 using Index =
typename MeshType::Index;
48 using AttributeArray =
typename MeshType::AttributeArray;
50 if (mesh.has_vertex_attribute(
"uv") && !mesh.has_corner_attribute(
"uv")) {
51 map_vertex_attribute_to_corner_attribute(mesh,
"uv");
53 if (!mesh.has_corner_attribute(
"uv")) {
54 throw std::runtime_error(
"UV vertex attribute is missing.");
58 const Index num_facets = mesh.get_num_facets();
59 const Index vertex_per_facet = mesh.get_vertex_per_facet();
60 const auto& vertices = mesh.get_vertices();
61 const auto& facets = mesh.get_facets();
63 const auto& uv = mesh.get_corner_attribute(
"uv");
66 const Scalar INVALID = std::numeric_limits<Scalar>::max();
68 AttributeArray distortion(num_facets, 1);
69 distortion.setConstant(INVALID);
71 for (Index i = 0; i < num_facets; i++) {
72 Eigen::Matrix<Index, 1, 3> f = facets.row(i);
73 Eigen::Matrix<Scalar, 1, 3> v0, v1, v2;
74 Eigen::Matrix<Scalar, 1, 2> V0, V1, V2;
75 v0 << vertices.row(f[0]);
76 v1 << vertices.row(f[1]);
77 v2 << vertices.row(f[2]);
78 V0 << uv.row(i * 3 + 0);
79 V1 << uv.row(i * 3 + 1);
80 V2 << uv.row(i * 3 + 2);
82 if (V0.minCoeff() < 0.0 || V0.maxCoeff() > 1.0)
continue;
83 if (V1.minCoeff() < 0.0 || V1.maxCoeff() > 1.0)
continue;
84 if (V2.minCoeff() < 0.0 || V2.maxCoeff() > 1.0)
continue;
89 const Eigen::Matrix<Scalar, 1, 3> e0 = v1 - v2;
90 const Eigen::Matrix<Scalar, 1, 3> e1 = v2 - v0;
91 const Eigen::Matrix<Scalar, 1, 3> e2 = v0 - v1;
92 const Scalar l0 = e0.norm();
93 const Scalar l1 = e1.norm();
94 const Scalar l2 = e2.norm();
95 const Scalar s = 0.5f * (l0 + l1 + l2);
96 const Scalar a = sqrt(s * (s - l0) * (s - l1) * (s - l2));
98 const Eigen::Matrix<Scalar, 1, 2> E0 = V1 - V2;
99 const Eigen::Matrix<Scalar, 1, 2> E1 = V2 - V0;
100 const Eigen::Matrix<Scalar, 1, 2> E2 = V0 - V1;
101 const Scalar L0 = E0.norm();
102 const Scalar L1 = E1.norm();
103 const Scalar L2 = E2.norm();
104 const Scalar S = 0.5f * (L0 + L1 + L2);
105 const Scalar A = sqrt(S * (S - L0) * (S - L1) * (S - L2));
107 const Scalar area_ratio = A / a;
109 const Scalar cot_0 = e1.dot(-e2) / e1.cross(-e2).norm();
110 const Scalar cot_1 = e2.dot(-e0) / e2.cross(-e0).norm();
111 const Scalar cot_2 = e0.dot(-e1) / e0.cross(-e1).norm();
114 const Scalar dirichlet = 0.5f * (cot_0 * L0 * L0 + cot_1 * L1 * L1 + cot_2 * L2 * L2) / a;
118 distortion(i, 0) = dirichlet / area_ratio;
121 mesh.add_facet_attribute(
"distortion");
122 mesh.set_facet_attribute(
"distortion", distortion);
AttributeId compute_uv_distortion(SurfaceMesh< Scalar, Index > &mesh, const UVDistortionOptions &options={})
Compute uv distortion using the selected distortion measure.
Definition: compute_uv_distortion.cpp:30
#define la_runtime_assert(...)
Runtime assertion check.
Definition: assert.h:169
Main namespace for Lagrange.
Definition: AABBIGL.h:30