// This file is part of libigl, a simple c++ geometry processing library. // // Copyright (C) 2020 Oded Stein // // This Source Code Form is subject to the terms of the Mozilla Public License // v. 2.0. If a copy of the MPL was not distributed with this file, You can // obtain one at http://mozilla.org/MPL/2.0/. #include "curved_hessian_energy.h" #include "orient_halfedges.h" #include "doublearea.h" #include "squared_edge_lengths.h" #include "cr_vector_laplacian.h" #include "cr_vector_mass.h" #include "cr_vector_curvature_correction.h" #include "scalar_to_cr_vector_gradient.h" template IGL_INLINE void igl::curved_hessian_energy( const Eigen::MatrixBase& V, const Eigen::MatrixBase& F, Eigen::SparseMatrix& Q) { Eigen::MatrixXi E, oE; curved_hessian_energy(V, F, E, oE, Q); } template IGL_INLINE void igl::curved_hessian_energy( const Eigen::MatrixBase& V, const Eigen::MatrixBase& F, const Eigen::MatrixBase& E, const Eigen::MatrixBase& oE, Eigen::SparseMatrix& Q) { Eigen::Matrix l_sq; squared_edge_lengths(V, F, l_sq); curved_hessian_energy_intrinsic(F, l_sq, E, oE, Q); } template IGL_INLINE void igl::curved_hessian_energy( const Eigen::MatrixBase& V, const Eigen::MatrixBase& F, Eigen::PlainObjectBase& E, Eigen::PlainObjectBase& oE, Eigen::SparseMatrix& Q) { if(E.rows()!=F.rows() || E.cols()!=F.cols() || oE.rows()!=F.rows() || oE.cols()!=F.cols()) { orient_halfedges(F, E, oE); } const Eigen::PlainObjectBase& cE = E; const Eigen::PlainObjectBase& coE = oE; curved_hessian_energy(V, F, cE, coE, Q); } template IGL_INLINE void igl::curved_hessian_energy_intrinsic( const Eigen::MatrixBase& F, const Eigen::MatrixBase& l_sq, const Eigen::MatrixBase& E, const Eigen::MatrixBase& oE, Eigen::SparseMatrix& Q) { Eigen::Matrix dA; Eigen::Matrix l_sqrt = l_sq.array().sqrt().matrix(); doublearea(l_sqrt, dA); curved_hessian_energy_intrinsic(F, l_sq, dA, E, oE, Q); } template IGL_INLINE void igl::curved_hessian_energy_intrinsic( const Eigen::MatrixBase& F, const Eigen::MatrixBase& l_sq, const Eigen::MatrixBase& dA, const Eigen::MatrixBase& E, const Eigen::MatrixBase& oE, Eigen::SparseMatrix& Q) { //Matrices that need to be combined Eigen::SparseMatrix M, D, L, K; cr_vector_mass_intrinsic(F, dA, E, M); scalar_to_cr_vector_gradient_intrinsic(F, l_sq, dA, E, oE, D); cr_vector_laplacian_intrinsic(F, l_sq, dA, E, oE, L); cr_vector_curvature_correction_intrinsic(F, l_sq, E, oE, K); //Invert M std::vector > tripletListMi; for(Eigen::Index k=0; k::InnerIterator it(M,k); it; ++it) { if(it.value() > 0) { tripletListMi.emplace_back(it.row(), it.col(), 1./it.value()); } } } Eigen::SparseMatrix Mi(M.rows(), M.cols()); Mi.setFromTriplets(tripletListMi.begin(), tripletListMi.end()); //Hessian energy matrix Q = D.transpose()*Mi*(L + K)*Mi*D; } #ifdef IGL_STATIC_LIBRARY // Explicit template instantiation template void igl::curved_hessian_energy, Eigen::Matrix, double>(Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::SparseMatrix&); #endif