lbs_matrix.cpp 4.1 KB

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