lbs_matrix.cpp 4.0 KB

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