You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

155 lines
4.4 KiB

// 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 <Eigen/Dense>
#include <Eigen/Sparse>
// 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<double> Dx,Dy,Dz;
int f_n,v_n;
bool first_solve;
bool has_pre_calc = false;
int dim;
#ifdef SLIM_CACHED
Eigen::SparseMatrix<double> A;
Eigen::VectorXi A_data;
Eigen::SparseMatrix<double> 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<double> &Dx,
const Eigen::SparseMatrix<double> &Dy,
const Eigen::SparseMatrix<double> &Dz,
const Eigen::MatrixXd &W,
std::vector<Eigen::Triplet<double> > & IJV);
}
#ifndef IGL_STATIC_LIBRARY
# include "slim.cpp"
#endif
#endif