slim.h 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2016 Michael Rabinovich
  4. //
  5. // This Source Code Form is subject to the terms of the Mozilla Public License
  6. // v. 2.0. If a copy of the MPL was not distributed with this file, You can
  7. // obtain one at http://mozilla.org/MPL/2.0/.
  8. #ifndef SLIM_H
  9. #define SLIM_H
  10. #include "igl_inline.h"
  11. #include "MappingEnergyType.h"
  12. #include <Eigen/Dense>
  13. #include <Eigen/Sparse>
  14. // This option makes the iterations faster (all except the first) by caching the
  15. // 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.
  16. #define SLIM_CACHED
  17. #ifdef SLIM_CACHED
  18. #include <igl/AtA_cached.h>
  19. #endif
  20. namespace igl
  21. {
  22. // Compute a SLIM map as derived in "Scalable Locally Injective Maps" [Rabinovich et al. 2016].
  23. struct SLIMData
  24. {
  25. // Input
  26. Eigen::MatrixXd V; // #V by 3 list of mesh vertex positions
  27. Eigen::MatrixXi F; // #F by 3/3 list of mesh faces (triangles/tets)
  28. MappingEnergyType slim_energy;
  29. // Optional Input
  30. // soft constraints
  31. Eigen::VectorXi b;
  32. Eigen::MatrixXd bc;
  33. double soft_const_p;
  34. double exp_factor; // used for exponential energies, ignored otherwise
  35. bool mesh_improvement_3d; // only supported for 3d
  36. // Output
  37. Eigen::MatrixXd V_o; // #V by dim list of mesh vertex positions (dim = 2 for parametrization, 3 otherwise)
  38. double energy; // objective value
  39. // INTERNAL
  40. Eigen::VectorXd M;
  41. double mesh_area;
  42. double avg_edge_length;
  43. int v_num;
  44. int f_num;
  45. double proximal_p;
  46. Eigen::VectorXd WGL_M;
  47. Eigen::VectorXd rhs;
  48. Eigen::MatrixXd Ri,Ji;
  49. Eigen::MatrixXd W;
  50. Eigen::SparseMatrix<double> Dx,Dy,Dz;
  51. int f_n,v_n;
  52. bool first_solve;
  53. bool has_pre_calc = false;
  54. int dim;
  55. #ifdef SLIM_CACHED
  56. Eigen::SparseMatrix<double> A;
  57. Eigen::VectorXi A_data;
  58. Eigen::SparseMatrix<double> AtA;
  59. igl::AtA_cached_data AtA_data;
  60. #endif
  61. };
  62. // Compute necessary information to start using SLIM
  63. // Inputs:
  64. // V #V by 3 list of mesh vertex positions
  65. // F #F by 3/3 list of mesh faces (triangles/tets)
  66. // b list of boundary indices into V
  67. // bc #b by dim list of boundary conditions
  68. // soft_p Soft penalty factor (can be zero)
  69. // slim_energy Energy to minimize
  70. IGL_INLINE void slim_precompute(
  71. const Eigen::MatrixXd& V,
  72. const Eigen::MatrixXi& F,
  73. const Eigen::MatrixXd& V_init,
  74. SLIMData& data,
  75. MappingEnergyType slim_energy,
  76. Eigen::VectorXi& b,
  77. Eigen::MatrixXd& bc,
  78. double soft_p);
  79. // Run iter_num iterations of SLIM
  80. // Outputs:
  81. // V_o (in SLIMData): #V by dim list of mesh vertex positions
  82. IGL_INLINE Eigen::MatrixXd slim_solve(SLIMData& data, int iter_num);
  83. // Internal Routine. Exposed for Integration with SCAF
  84. IGL_INLINE void slim_update_weights_and_closest_rotations_with_jacobians(const Eigen::MatrixXd &Ji,
  85. igl::MappingEnergyType slim_energy,
  86. double exp_factor,
  87. Eigen::MatrixXd &W,
  88. Eigen::MatrixXd &Ri);
  89. IGL_INLINE void slim_buildA(const Eigen::SparseMatrix<double> &Dx,
  90. const Eigen::SparseMatrix<double> &Dy,
  91. const Eigen::SparseMatrix<double> &Dz,
  92. const Eigen::MatrixXd &W,
  93. std::vector<Eigen::Triplet<double> > & IJV);
  94. } // END NAMESPACE
  95. #ifndef IGL_STATIC_LIBRARY
  96. # include "slim.cpp"
  97. #endif
  98. #endif // SLIM_H