lbs_matrix.h 3.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
  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 IGL_LBS_MATRIX_H
  9. #define IGL_LBS_MATRIX_H
  10. #include "igl_inline.h"
  11. #include <Eigen/Dense>
  12. #include <Eigen/Sparse>
  13. namespace igl
  14. {
  15. // LBS_MATRIX Linear blend skinning can be expressed by V' = M * T where V' is
  16. // a #V by dim matrix of deformed vertex positions (one vertex per row), M is a
  17. // #V by (dim+1)*#T (composed of weights and rest positions) and T is a
  18. // #T*(dim+1) by dim matrix of #T stacked transposed transformation matrices.
  19. // See equations (1) and (2) in "Fast Automatic Skinning Transformations"
  20. // [Jacobson et al 2012]
  21. //
  22. // Inputs:
  23. // V #V by dim list of rest positions
  24. // W #V+ by #T list of weights
  25. // Outputs:
  26. // M #V by #T*(dim+1)
  27. //
  28. // In MATLAB:
  29. // kron(ones(1,size(W,2)),[V ones(size(V,1),1)]).*kron(W,ones(1,size(V,2)+1))
  30. IGL_INLINE void lbs_matrix(
  31. const Eigen::MatrixXd & V,
  32. const Eigen::MatrixXd & W,
  33. Eigen::MatrixXd & M);
  34. // LBS_MATRIX construct a matrix that when multiplied against a column of
  35. // affine transformation entries computes new coordinates of the vertices
  36. //
  37. // I'm not sure it makes since that the result is stored as a sparse matrix.
  38. // The number of non-zeros per row *is* dependent on the number of mesh
  39. // vertices and handles.
  40. //
  41. // Inputs:
  42. // V #V by dim list of vertex rest positions
  43. // W #V by #handles list of correspondence weights
  44. // Output:
  45. // M #V * dim by #handles * dim * (dim+1) matrix such that
  46. // new_V(:) = LBS(V,W,A) = reshape(M * A,size(V)), where A is a column
  47. // vectors formed by the entries in each handle's dim by dim+1
  48. // transformation matrix. Specifcally, A =
  49. // reshape(permute(Astack,[3 1 2]),n*dim*(dim+1),1)
  50. // or A = [Lxx;Lyx;Lxy;Lyy;tx;ty], and likewise for other dim
  51. // if Astack(:,:,i) is the dim by (dim+1) transformation at handle i
  52. IGL_INLINE void lbs_matrix_column(
  53. const Eigen::MatrixXd & V,
  54. const Eigen::MatrixXd & W,
  55. Eigen::SparseMatrix<double>& M);
  56. IGL_INLINE void lbs_matrix_column(
  57. const Eigen::MatrixXd & V,
  58. const Eigen::MatrixXd & W,
  59. Eigen::MatrixXd & M);
  60. // Same as LBS_MATRIX above but instead of giving W as a full matrix of weights
  61. // (each vertex has #handles weights), a constant number of weights are given
  62. // for each vertex.
  63. //
  64. // Inputs:
  65. // V #V by dim list of vertex rest positions
  66. // W #V by k list of k correspondence weights per vertex
  67. // WI #V by k list of k correspondence weight indices per vertex. Such that
  68. // W(j,WI(i)) gives the ith most significant correspondence weight on vertex j
  69. // Output:
  70. // M #V * dim by #handles * dim * (dim+1) matrix such that
  71. // new_V(:) = LBS(V,W,A) = reshape(M * A,size(V)), where A is a column
  72. // vectors formed by the entries in each handle's dim by dim+1
  73. // transformation matrix. Specifcally, A =
  74. // reshape(permute(Astack,[3 1 2]),n*dim*(dim+1),1)
  75. // or A = [Lxx;Lyx;Lxy;Lyy;tx;ty], and likewise for other dim
  76. // if Astack(:,:,i) is the dim by (dim+1) transformation at handle i
  77. //
  78. IGL_INLINE void lbs_matrix_column(
  79. const Eigen::MatrixXd & V,
  80. const Eigen::MatrixXd & W,
  81. const Eigen::MatrixXi & WI,
  82. Eigen::SparseMatrix<double>& M);
  83. IGL_INLINE void lbs_matrix_column(
  84. const Eigen::MatrixXd & V,
  85. const Eigen::MatrixXd & W,
  86. const Eigen::MatrixXi & WI,
  87. Eigen::MatrixXd & M);
  88. }
  89. #ifndef IGL_STATIC_LIBRARY
  90. #include "lbs_matrix.cpp"
  91. #endif
  92. #endif