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
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
|
|
|