Wildmeshing Toolkit
Loading...
Searching...
No Matches
amips.hpp
Go to the documentation of this file.
1#pragma once
2#include <Eigen/Dense>
3#include <wmtk/Types.hpp>
4
5namespace wmtk::function::utils {
6
7namespace detail {
8// returns v0,v1,v2 of the target triangle as row vectors
9extern const Eigen::Matrix<double, 2, 3> amips_target_triangle;
10// maps from the embedding of the reference triangle to the barycentric coordinates
11extern const Eigen::Matrix2d amips_reference_to_barycentric;
12
13} // namespace detail
14
15
16// Given an basis vectors following a "v1-v0,v2-v0" convention for a triangle (v0,v1,v2)
17// return the AMIPS energy for a triangle.
18// Input are assumed to be column vectors, opposite of the standard IGL formation
19template <typename Derived>
20auto amips(const Eigen::MatrixBase<Derived>& B)
21{
22 using Scalar = typename Derived::Scalar;
23 constexpr static int Rows = Derived::RowsAtCompileTime;
24 constexpr static int Cols = Derived::ColsAtCompileTime;
25
26
27 // check that these are vectors
28 static_assert(Cols == 2);
29 static_assert(Rows == 2);
30
31
32 // MTAO: Why can't this work with more than 2 rows?
33 // define of transform matrix F = Dm@Ds.inv
34 Eigen::Matrix<Scalar, Rows, 2> J;
35 J = B * detail::amips_reference_to_barycentric.template cast<Scalar>();
36
37 auto Jdet = J.determinant();
38 if (abs(Jdet) < std::numeric_limits<double>::denorm_min()) {
39 return static_cast<Scalar>(std::numeric_limits<double>::infinity());
40 }
41 assert(Jdet >= 0);
42
43 return (J * J.transpose()).trace() / Jdet;
44}
45
46
47//
48template <typename V0Type, typename V1Type, typename V2Type>
49auto amips(
50 const Eigen::MatrixBase<V0Type>& v0,
51 const Eigen::MatrixBase<V1Type>& v1,
52 const Eigen::MatrixBase<V2Type>& v2)
53{
54 using Scalar = typename V0Type::Scalar;
55 constexpr static int Rows = V0Type::RowsAtCompileTime;
56 constexpr static int Cols0 = V0Type::ColsAtCompileTime;
57 constexpr static int Cols1 = V1Type::ColsAtCompileTime;
58 constexpr static int Cols2 = V1Type::ColsAtCompileTime;
59
60
61 // check that these are vectors
62 static_assert(Cols0 == 1);
63 static_assert(Cols1 == 1);
64 static_assert(Cols2 == 1);
65
66 // just check that the inputs had the right dimensions
67 constexpr static int Rows1 = V1Type::RowsAtCompileTime;
68 constexpr static int Rows2 = V1Type::RowsAtCompileTime;
69 static_assert(Rows == Rows1);
70 static_assert(Rows == Rows2);
71
72 Eigen::Matrix<Scalar, 2, 2> Dm;
73
74
75 static_assert(Rows == 2 || Rows == 3);
76
77 if constexpr (Rows == 2) {
78 Dm.col(0) = (v1.template cast<Scalar>() - v0);
79 Dm.col(1) = (v2.template cast<Scalar>() - v0);
80 } else if constexpr (Rows == 3) {
81 // in 3d we compute a basis
82 // local vectors
83 Eigen::Matrix<Scalar, Rows, 2> V;
84 V.col(0) = v1.template cast<Scalar>() - v0;
85 V.col(1) = v2.template cast<Scalar>() - v0;
86
87 // compute a basis plane
88 Eigen::Matrix<Scalar, 3, 2> B = V;
89
90 auto e0 = B.col(0);
91 auto e1 = B.col(1);
92
93 // TODO: shouldnt we make sure the normms are over some eps instead of 0?
94 auto e0norm = e0.norm();
95 assert(e0norm > 0); // check norm is not 0
96 e0 = e0 / e0norm;
97
98 Vector3<Scalar> n = e0.cross(e1);
99 e1 = n.cross(e0);
100 auto e1norm = e1.norm();
101 assert(e1norm > 0); // check norm is not 0
102 e1 = e1 / e1norm;
103
104
105 Dm = (B.transpose() * V).eval();
106 }
107
108
109 return amips(Dm);
110}
111
112double Tet_AMIPS_energy(const std::array<double, 12>& T);
113void Tet_AMIPS_hessian(const std::array<double, 12>& T, Eigen::Matrix3d& result_0);
114void Tet_AMIPS_jacobian(const std::array<double, 12>& T, Eigen::Vector3d& result_0);
115
116} // namespace wmtk::function::utils
const Eigen::Matrix2d amips_reference_to_barycentric
Definition amips.cpp:42
const Eigen::Matrix< double, 2, 3 > amips_target_triangle
Definition amips.cpp:30
void Tet_AMIPS_jacobian(const std::array< double, 12 > &T, Eigen::Vector3d &result_0)
Definition amips.cpp:108
auto amips(const Eigen::MatrixBase< Derived > &B)
Definition amips.hpp:20
double Tet_AMIPS_energy(const std::array< double, 12 > &T)
Definition amips.cpp:380
void Tet_AMIPS_hessian(const std::array< double, 12 > &T, Eigen::Matrix3d &result_0)
Definition amips.cpp:205
Vector< T, 3 > Vector3
Definition Types.hpp:24
Rational abs(const Rational &r0)
Definition Rational.cpp:328