lbs_matrix.h 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  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 construct a matrix that when multiplied against a column of
  16. // affine transformation entries computes new coordinates of the vertices
  17. //
  18. // I'm not sure it makes since that the result is stored as a sparse matrix.
  19. // The number of non-zeros per row *is* dependent on the number of mesh
  20. // vertices and handles.
  21. //
  22. // Inputs:
  23. // V #V by dim list of vertex rest positions
  24. // W #V by #handles list of correspondence weights
  25. // Output:
  26. // M #V * dim by #handles * dim * (dim+1) matrix such that
  27. // new_V(:) = LBS(V,W,A) = reshape(M * A,size(V)), where A is a column
  28. // vectors formed by the entries in each handle's dim by dim+1
  29. // transformation matrix. Specifcally, A =
  30. // reshape(permute(Astack,[3 1 2]),n*dim*(dim+1),1)
  31. // or A = [Lxx;Lyx;Lxy;Lyy;tx;ty], and likewise for other dim
  32. // if Astack(:,:,i) is the dim by (dim+1) transformation at handle i
  33. //
  34. IGL_INLINE void lbs_matrix(
  35. const Eigen::MatrixXd & V,
  36. const Eigen::MatrixXd & W,
  37. Eigen::SparseMatrix<double>& M);
  38. IGL_INLINE void lbs_matrix(
  39. const Eigen::MatrixXd & V,
  40. const Eigen::MatrixXd & W,
  41. Eigen::MatrixXd & M);
  42. // Same as LBS_MATRIX above but instead of giving W as a full matrix of weights
  43. // (each vertex has #handles weights), a constant number of weights are given
  44. // for each vertex.
  45. //
  46. // Inputs:
  47. // V #V by dim list of vertex rest positions
  48. // W #V by k list of k correspondence weights per vertex
  49. // WI #V by k list of k correspondence weight indices per vertex. Such that
  50. // W(j,WI(i)) gives the ith most significant correspondence weight on vertex j
  51. // Output:
  52. // M #V * dim by #handles * dim * (dim+1) matrix such that
  53. // new_V(:) = LBS(V,W,A) = reshape(M * A,size(V)), where A is a column
  54. // vectors formed by the entries in each handle's dim by dim+1
  55. // transformation matrix. Specifcally, A =
  56. // reshape(permute(Astack,[3 1 2]),n*dim*(dim+1),1)
  57. // or A = [Lxx;Lyx;Lxy;Lyy;tx;ty], and likewise for other dim
  58. // if Astack(:,:,i) is the dim by (dim+1) transformation at handle i
  59. //
  60. IGL_INLINE void lbs_matrix(
  61. const Eigen::MatrixXd & V,
  62. const Eigen::MatrixXd & W,
  63. const Eigen::MatrixXi & WI,
  64. Eigen::SparseMatrix<double>& M);
  65. IGL_INLINE void lbs_matrix(
  66. const Eigen::MatrixXd & V,
  67. const Eigen::MatrixXd & W,
  68. const Eigen::MatrixXi & WI,
  69. Eigen::MatrixXd & M);
  70. }
  71. #ifdef IGL_HEADER_ONLY
  72. #include "lbs_matrix.cpp"
  73. #endif
  74. #endif