// This file is part of libigl, a simple c++ geometry processing library. // // Copyright (C) 2016 Michael Rabinovich // // 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/. #ifndef SLIM_H #define SLIM_H #include "igl_inline.h" #include "MappingEnergyType.h" #include #include // This option makes the iterations faster (all except the first) by caching the // sparsity pattern of the matrix involved in the assembly. It should be on if // you plan to do many iterations, off if you have to change the matrix // structure at every iteration. #define SLIM_CACHED #ifdef SLIM_CACHED #include "AtA_cached.h" #endif namespace igl { /// Parameters and precomputed data for computing a SLIM map as derived in /// "Scalable Locally Injective Maps" [Rabinovich et al. 2016]. /// /// \fileinfo struct SLIMData { /// #V by 3 list of mesh vertex positions Eigen::MatrixXd V; /// #F by 3/4 list of mesh faces (triangles/tets) Eigen::MatrixXi F; /// Mapping energy type MappingEnergyType slim_energy; // Optional Input /// Fixed indices Eigen::VectorXi b; /// Fixed values Eigen::MatrixXd bc; /// Weight for enforcing fixed values as soft constraint double soft_const_p; /// used for exponential energies, ignored otherwise double exp_factor; /// only supported for 3d bool mesh_improvement_3d; // Output /// #V by dim list of mesh vertex positions (dim = 2 for parametrization, 3 otherwise) Eigen::MatrixXd V_o; /// objective value double energy; // INTERNAL Eigen::VectorXd M; double mesh_area; double avg_edge_length; int v_num; int f_num; double proximal_p; Eigen::VectorXd WGL_M; Eigen::VectorXd rhs; Eigen::MatrixXd Ri,Ji; Eigen::MatrixXd W; Eigen::SparseMatrix Dx,Dy,Dz; int f_n,v_n; bool first_solve; bool has_pre_calc = false; int dim; #ifdef SLIM_CACHED Eigen::SparseMatrix A; Eigen::VectorXi A_data; Eigen::SparseMatrix AtA; igl::AtA_cached_data AtA_data; #endif }; /// Compute necessary information to start using SLIM /// /// @param[in] V #V by 3 list of mesh vertex positions /// @param[in] F #F by 3/3 list of mesh faces (triangles/tets) /// @param[in] V_init #V by 3 list of initial mesh vertex positions /// @param[in,out] data Precomputation data structure /// @param[in] slim_energy Energy to minimize /// @param[in] b list of boundary indices into V /// @param[in] bc #b by dim list of boundary conditions /// @param[in] soft_p Soft penalty factor (can be zero) /// /// \fileinfo IGL_INLINE void slim_precompute( const Eigen::MatrixXd& V, const Eigen::MatrixXi& F, const Eigen::MatrixXd& V_init, SLIMData& data, MappingEnergyType slim_energy, const Eigen::VectorXi& b, const Eigen::MatrixXd& bc, double soft_p); /// Run iter_num iterations of SLIM /// /// @param[in,out] data Precomputation data structure /// @param[in] iter_num Number of iterations to run /// @return #V by dim list of mesh vertex positions /// /// \fileinfo IGL_INLINE Eigen::MatrixXd slim_solve( SLIMData& data, int iter_num); /// Internal Routine. Exposed for Integration with SCAF /// /// @param[in] Ji ?? by ?? list of Jacobians?? /// @param[in] slim_energy Energy to minimize /// @param[in] exp_factor ??? used for exponential energies, ignored otherwise /// @param[out] W ?? by ?? list of weights?? /// @param[out] Ri ?? by ?? list of rotations?? /// /// \fileinfo IGL_INLINE void slim_update_weights_and_closest_rotations_with_jacobians( const Eigen::MatrixXd &Ji, igl::MappingEnergyType slim_energy, double exp_factor, Eigen::MatrixXd &W, Eigen::MatrixXd &Ri); /// Undocumented function related to SLIM optimization /// /// @param[in] Dx ?? by ?? matrix to compute of x derivatives? /// @param[in] Dy ?? by ?? matrix to compute of y derivatives? /// @param[in] Dz ?? bz ?? matrix to compute of z derivatives? /// @param[in] W ?? by ?? list of weights?? /// @param[out] IJV ?? by ?? list of triplets to some A matrix?? IGL_INLINE void slim_buildA( const Eigen::SparseMatrix &Dx, const Eigen::SparseMatrix &Dy, const Eigen::SparseMatrix &Dz, const Eigen::MatrixXd &W, std::vector > & IJV); } #ifndef IGL_STATIC_LIBRARY # include "slim.cpp" #endif #endif