47static inline void grad(
const Eigen::PlainObjectBase<DerivedV> &
V,
48 const Eigen::PlainObjectBase<DerivedF> &F,
49 Eigen::SparseMatrix<typename DerivedV::Scalar> &
G,
52 Eigen::Matrix<typename DerivedV::Scalar, Eigen::Dynamic, 3> eperp21(F.rows(), 3),
55 for (
int i = 0; i < F.rows(); ++i) {
62 Eigen::Matrix<typename DerivedV::Scalar, 1, 3> v32 =
V.row(i3) -
V.row(i2);
63 Eigen::Matrix<typename DerivedV::Scalar, 1, 3> v13 =
V.row(i1) -
V.row(i3);
64 Eigen::Matrix<typename DerivedV::Scalar, 1, 3> v21 =
V.row(i2) -
V.row(i1);
65 Eigen::Matrix<typename DerivedV::Scalar, 1, 3> n = v32.cross(v13);
70 double dblA = std::sqrt(n.dot(n));
71 Eigen::Matrix<typename DerivedV::Scalar, 1, 3> u;
80 double h =
sqrt((dblA) /
83 Eigen::VectorXd v1,
v2, v3;
86 v3 << h / 2., (
sqrt(3) / 2.) * h, 0;
96 double norm21 = std::sqrt(v21.dot(v21));
97 double norm13 = std::sqrt(v13.dot(v13));
98 eperp21.row(i) = u.cross(v21);
99 eperp21.row(i) = eperp21.row(i) / std::sqrt(eperp21.row(i).dot(eperp21.row(i)));
100 eperp21.row(i) *= norm21 / dblA;
101 eperp13.row(i) = u.cross(v13);
102 eperp13.row(i) = eperp13.row(i) / std::sqrt(eperp13.row(i).dot(eperp13.row(i)));
103 eperp13.row(i) *= norm13 / dblA;
107 rs.reserve(F.rows() * 4 * 3);
109 cs.reserve(F.rows() * 4 * 3);
110 std::vector<double> vs;
111 vs.reserve(F.rows() * 4 * 3);
114 for (
int r = 0; r < 3; r++) {
115 for (
int j = 0; j < 4; j++) {
116 for (
int i = r * F.rows(); i < (r + 1) * F.rows(); i++) {
123 for (
int r = 0; r < 3; r++) {
124 for (
int i = 0; i < F.rows(); i++) {
125 cs.push_back(
F(i, 1));
127 for (
int i = 0; i < F.rows(); i++) {
128 cs.push_back(
F(i, 0));
130 for (
int i = 0; i < F.rows(); i++) {
131 cs.push_back(
F(i, 2));
133 for (
int i = 0; i < F.rows(); i++) {
134 cs.push_back(
F(i, 0));
139 for (
int i = 0; i < F.rows(); i++) {
140 vs.push_back(eperp13(i, 0));
142 for (
int i = 0; i < F.rows(); i++) {
143 vs.push_back(-eperp13(i, 0));
145 for (
int i = 0; i < F.rows(); i++) {
146 vs.push_back(eperp21(i, 0));
148 for (
int i = 0; i < F.rows(); i++) {
149 vs.push_back(-eperp21(i, 0));
151 for (
int i = 0; i < F.rows(); i++) {
152 vs.push_back(eperp13(i, 1));
154 for (
int i = 0; i < F.rows(); i++) {
155 vs.push_back(-eperp13(i, 1));
157 for (
int i = 0; i < F.rows(); i++) {
158 vs.push_back(eperp21(i, 1));
160 for (
int i = 0; i < F.rows(); i++) {
161 vs.push_back(-eperp21(i, 1));
163 for (
int i = 0; i < F.rows(); i++) {
164 vs.push_back(eperp13(i, 2));
166 for (
int i = 0; i < F.rows(); i++) {
167 vs.push_back(-eperp13(i, 2));
169 for (
int i = 0; i < F.rows(); i++) {
170 vs.push_back(eperp21(i, 2));
172 for (
int i = 0; i < F.rows(); i++) {
173 vs.push_back(-eperp21(i, 2));
177 G.resize(3 * F.rows(),
V.rows());
178 std::vector<Eigen::Triplet<typename DerivedV::Scalar>> triplets;
179 for (
int i = 0; i < (int)vs.size(); ++i) {
180 triplets.push_back(Eigen::Triplet<typename DerivedV::Scalar>(rs[i], cs[i], vs[i]));
182 G.setFromTriplets(triplets.begin(), triplets.end());
232 const Eigen::MatrixXi &F,
233 const Eigen::MatrixXd &F1,
234 const Eigen::MatrixXd &F2,
235 Eigen::SparseMatrix<double> &D1,
236 Eigen::SparseMatrix<double> &D2)
238 Eigen::SparseMatrix<double>
G;
240 Eigen::SparseMatrix<double> Dx =
G.block(0, 0, F.rows(),
V.rows());
241 Eigen::SparseMatrix<double> Dy =
G.block(F.rows(), 0, F.rows(),
V.rows());
242 Eigen::SparseMatrix<double> Dz =
G.block(2 * F.rows(), 0, F.rows(),
V.rows());
244 D1 = F1.col(0).asDiagonal() * Dx + F1.col(1).asDiagonal() * Dy + F1.col(2).asDiagonal() * Dz;
245 D2 = F2.col(0).asDiagonal() * Dx + F2.col(1).asDiagonal() * Dy + F2.col(2).asDiagonal() * Dz;
294 const double eps = 1
e-8;
297 for (
int i = 0; i < s.
Ji.rows(); ++i) {
298 using Mat2 = Eigen::Matrix<double, 2, 2>;
299 using Vec2 = Eigen::Matrix<double, 2, 1>;
300 Mat2 ji, ri, ti, ui, vi;
302 Vec2 closest_sing_vec;
307 ji(0, 0) = s.
Ji(i, 0);
308 ji(0, 1) = s.
Ji(i, 1);
309 ji(1, 0) = s.
Ji(i, 2);
310 ji(1, 1) = s.
Ji(i, 3);
324 double s1_g = 2 * (s1 -
pow(s1, -3));
325 double s2_g = 2 * (s2 -
pow(s2, -3));
326 m_sing_new <<
sqrt(s1_g / (2 * (s1 - 1))),
sqrt(s2_g / (2 * (s2 - 1)));
330 double s1_g = 2 * (
log(s1) / s1);
331 double s2_g = 2 * (
log(s2) / s2);
332 m_sing_new <<
sqrt(s1_g / (2 * (s1 - 1))),
sqrt(s2_g / (2 * (s2 - 1)));
336 double s1_g = 1 / (2 * s2) - s2 / (2 *
pow(s1, 2));
337 double s2_g = 1 / (2 * s1) - s1 / (2 *
pow(s2, 2));
339 double geo_avg =
sqrt(s1 * s2);
340 double s1_min = geo_avg;
341 double s2_min = geo_avg;
343 m_sing_new <<
sqrt(s1_g / (2 * (s1 - s1_min))),
sqrt(s2_g / (2 * (s2 - s2_min)));
346 closest_sing_vec << s1_min, s2_min;
347 ri = ui * closest_sing_vec.asDiagonal() * vi.transpose();
351 double s1_g = 2 * (s1 -
pow(s1, -3));
352 double s2_g = 2 * (s2 -
pow(s2, -3));
354 double in_exp = exp_f * ((
pow(s1, 2) +
pow(s2, 2)) / (2 * s1 * s2));
355 double exp_thing =
exp(in_exp);
357 s1_g *= exp_thing * exp_f;
358 s2_g *= exp_thing * exp_f;
360 m_sing_new <<
sqrt(s1_g / (2 * (s1 - 1))),
sqrt(s2_g / (2 * (s2 - 1)));
364 double s1_g = 2 * (s1 -
pow(s1, -3));
365 double s2_g = 2 * (s2 -
pow(s2, -3));
367 double in_exp = exp_f * (
pow(s1, 2) +
pow(s1, -2) +
pow(s2, 2) +
pow(s2, -2));
368 double exp_thing =
exp(in_exp);
370 s1_g *= exp_thing * exp_f;
371 s2_g *= exp_thing * exp_f;
373 m_sing_new <<
sqrt(s1_g / (2 * (s1 - 1))),
sqrt(s2_g / (2 * (s2 - 1)));
378 if (std::abs(s1 - 1) <
eps) {
381 if (std::abs(s2 - 1) <
eps) {
384 mat_W = ui * m_sing_new.asDiagonal() * ui.transpose();
386 s.
W_11(i) = mat_W(0, 0);
387 s.
W_12(i) = mat_W(0, 1);
388 s.
W_21(i) = mat_W(1, 0);
389 s.
W_22(i) = mat_W(1, 1);
393 s.
Ri(i, 0) = ri(0, 0);
394 s.
Ri(i, 1) = ri(1, 0);
395 s.
Ri(i, 2) = ri(0, 1);
396 s.
Ri(i, 3) = ri(1, 1);
401static inline void local_basis(
const Eigen::PlainObjectBase<DerivedV> &
V,
402 const Eigen::PlainObjectBase<DerivedF> &F,
403 Eigen::PlainObjectBase<DerivedV> &B1,
404 Eigen::PlainObjectBase<DerivedV> &B2,
405 Eigen::PlainObjectBase<DerivedV> &B3)
407 using namespace Eigen;
409 B1.resize(F.rows(), 3);
410 B2.resize(F.rows(), 3);
411 B3.resize(F.rows(), 3);
413 for (
unsigned i = 0; i < F.rows(); ++i) {
414 Eigen::Matrix<typename DerivedV::Scalar, 1, 3> v1 =
416 Eigen::Matrix<typename DerivedV::Scalar, 1, 3> t =
V.row(
F(i, 2)) -
V.row(F(i, 0));
417 Eigen::Matrix<typename DerivedV::Scalar, 1, 3> v3 = v1.cross(t).normalized();
418 Eigen::Matrix<typename DerivedV::Scalar, 1, 3>
v2 = v1.cross(v3).normalized();
467 std::vector<Eigen::Triplet<double>> IJV;
469 IJV.reserve(4 * (s.
Dx.outerSize() + s.
Dy.outerSize()));
475 for (
int k = 0; k < s.
Dx.outerSize(); ++k) {
476 for (Eigen::SparseMatrix<double>::InnerIterator it(s.
Dx, k); it; ++it) {
479 double val = it.value();
482 IJV.emplace_back(dx_r, dx_c, weight * val * s.
W_11(dx_r));
483 IJV.emplace_back(dx_r, s.
v_n + dx_c, weight * val * s.
W_12(dx_r));
485 IJV.emplace_back(2 * s.
f_n + dx_r, dx_c, weight * val * s.
W_21(dx_r));
486 IJV.emplace_back(2 * s.
f_n + dx_r, s.
v_n + dx_c, weight * val * s.
W_22(dx_r));
490 for (
int k = 0; k < s.
Dy.outerSize(); ++k) {
491 for (Eigen::SparseMatrix<double>::InnerIterator it(s.
Dy, k); it; ++it) {
494 double val = it.value();
497 IJV.emplace_back(s.
f_n + dy_r, dy_c, weight * val * s.
W_11(dy_r));
498 IJV.emplace_back(s.
f_n + dy_r, s.
v_n + dy_c, weight * val * s.
W_12(dy_r));
500 IJV.emplace_back(3 * s.
f_n + dy_r, dy_c, weight * val * s.
W_21(dy_r));
501 IJV.emplace_back(3 * s.
f_n + dy_r, s.
v_n + dy_c, weight * val * s.
W_22(dy_r));
505 A.setFromTriplets(IJV.begin(), IJV.end());
711 Eigen::VectorXd &areas)
713 int nFaces = singularValues.rows() / 2;
715 Eigen::VectorXd areasChained(2 * nFaces);
716 areasChained << areas, areas;
741 Eigen::VectorXd squaredSingularValues = singularValues.cwiseProduct(singularValues);
742 Eigen::VectorXd inverseSquaredSingularValues =
743 singularValues.cwiseProduct(singularValues).cwiseInverse();
745 Eigen::VectorXd weightedSquaredSingularValues = squaredSingularValues.cwiseProduct(areasChained);
746 Eigen::VectorXd weightedInverseSquaredSingularValues = inverseSquaredSingularValues.cwiseProduct(
749 double s1 = weightedSquaredSingularValues.head(nFaces).sum();
750 double s2 = weightedSquaredSingularValues.tail(nFaces).sum();
752 double t1 = weightedInverseSquaredSingularValues.head(nFaces).sum();
753 double t2 = weightedInverseSquaredSingularValues.tail(nFaces).sum();