lbs_matrix.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. #include "lbs_matrix.h"
  2. IGL_INLINE void igl::lbs_matrix(
  3. const Eigen::MatrixXd & V,
  4. const Eigen::MatrixXd & W,
  5. Eigen::MatrixXd & M)
  6. {
  7. using namespace Eigen;
  8. // Number of dimensions
  9. const int dim = V.cols();
  10. // Number of model points
  11. const int n = V.rows();
  12. // Number of skinning transformations/weights
  13. const int m = W.cols();
  14. // Assumes that first n rows of weights correspond to V
  15. assert(W.rows() >= n);
  16. M.resize(n,(dim+1)*m);
  17. for(int j = 0;j<m;j++)
  18. {
  19. VectorXd Wj = W.block(0,j,V.rows(),1);
  20. for(int i = 0;i<(dim+1);i++)
  21. {
  22. if(i<dim)
  23. {
  24. M.col(i + j*(dim+1)) =
  25. Wj.cwiseProduct(V.col(i));
  26. }else
  27. {
  28. M.col(i + j*(dim+1)).array() = W.block(0,j,V.rows(),1).array();
  29. }
  30. }
  31. }
  32. }
  33. IGL_INLINE void igl::lbs_matrix_column(
  34. const Eigen::MatrixXd & V,
  35. const Eigen::MatrixXd & W,
  36. Eigen::SparseMatrix<double>& M)
  37. {
  38. // number of mesh vertices
  39. int n = V.rows();
  40. assert(n == W.rows());
  41. // dimension of mesh
  42. int dim = V.cols();
  43. // number of handles
  44. int m = W.cols();
  45. M.resize(n*dim,m*dim*(dim+1));
  46. // loop over coordinates of mesh vertices
  47. for(int x = 0; x < dim; x++)
  48. {
  49. // loop over mesh vertices
  50. for(int j = 0; j < n; j++)
  51. {
  52. // loop over handles
  53. for(int i = 0; i < m; i++)
  54. {
  55. // loop over cols of affine transformations
  56. for(int c = 0; c < (dim+1); c++)
  57. {
  58. double value = W(j,i);
  59. if(c<dim)
  60. {
  61. value *= V(j,c);
  62. }
  63. M.insert(x*n + j,x*m + c*m*dim + i) = value;
  64. }
  65. }
  66. }
  67. }
  68. M.makeCompressed();
  69. }
  70. IGL_INLINE void igl::lbs_matrix_column(
  71. const Eigen::MatrixXd & V,
  72. const Eigen::MatrixXd & W,
  73. Eigen::MatrixXd & M)
  74. {
  75. // number of mesh vertices
  76. int n = V.rows();
  77. assert(n == W.rows());
  78. // dimension of mesh
  79. int dim = V.cols();
  80. // number of handles
  81. int m = W.cols();
  82. M.resize(n*dim,m*dim*(dim+1));
  83. // loop over coordinates of mesh vertices
  84. for(int x = 0; x < dim; x++)
  85. {
  86. // loop over mesh vertices
  87. for(int j = 0; j < n; j++)
  88. {
  89. // loop over handles
  90. for(int i = 0; i < m; i++)
  91. {
  92. // loop over cols of affine transformations
  93. for(int c = 0; c < (dim+1); c++)
  94. {
  95. double value = W(j,i);
  96. if(c<dim)
  97. {
  98. value *= V(j,c);
  99. }
  100. M(x*n + j,x*m + c*m*dim + i) = value;
  101. }
  102. }
  103. }
  104. }
  105. }
  106. IGL_INLINE void igl::lbs_matrix_column(
  107. const Eigen::MatrixXd & V,
  108. const Eigen::MatrixXd & W,
  109. const Eigen::MatrixXi & WI,
  110. Eigen::SparseMatrix<double>& M)
  111. {
  112. // number of mesh vertices
  113. int n = V.rows();
  114. assert(n == W.rows());
  115. assert(n == WI.rows());
  116. // dimension of mesh
  117. int dim = V.cols();
  118. // number of handles
  119. int m = WI.maxCoeff()+1;
  120. // max number of influencing handles
  121. int k = W.cols();
  122. assert(k == WI.cols());
  123. M.resize(n*dim,m*dim*(dim+1));
  124. // loop over coordinates of mesh vertices
  125. for(int x = 0; x < dim; x++)
  126. {
  127. // loop over mesh vertices
  128. for(int j = 0; j < n; j++)
  129. {
  130. // loop over handles
  131. for(int i = 0; i < k; i++)
  132. {
  133. // loop over cols of affine transformations
  134. for(int c = 0; c < (dim+1); c++)
  135. {
  136. double value = W(j,i);
  137. if(c<dim)
  138. {
  139. value *= V(j,c);
  140. }
  141. if(value != 0)
  142. {
  143. M.insert(x*n + j,x*m + c*m*dim + WI(j,i)) = value;
  144. }
  145. }
  146. }
  147. }
  148. }
  149. M.makeCompressed();
  150. }
  151. IGL_INLINE void igl::lbs_matrix_column(
  152. const Eigen::MatrixXd & V,
  153. const Eigen::MatrixXd & W,
  154. const Eigen::MatrixXi & WI,
  155. Eigen::MatrixXd & M)
  156. {
  157. // Cheapskate wrapper
  158. using namespace Eigen;
  159. SparseMatrix<double> sM;
  160. lbs_matrix_column(V,W,WI,sM);
  161. M = MatrixXd(sM);
  162. }