lbs_matrix.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. #include "lbs_matrix.h"
  2. IGL_INLINE void igl::lbs_matrix(
  3. const Eigen::MatrixXd & V,
  4. const Eigen::MatrixXd & W,
  5. Eigen::SparseMatrix<double>& M)
  6. {
  7. // number of mesh vertices
  8. int n = V.rows();
  9. assert(n == W.rows());
  10. // dimension of mesh
  11. int dim = V.cols();
  12. // number of handles
  13. int m = W.cols();
  14. M.resize(n*dim,m*dim*(dim+1));
  15. // loop over coordinates of mesh vertices
  16. for(int x = 0; x < dim; x++)
  17. {
  18. // loop over mesh vertices
  19. for(int j = 0; j < n; j++)
  20. {
  21. // loop over handles
  22. for(int i = 0; i < m; i++)
  23. {
  24. // loop over cols of affine transformations
  25. for(int c = 0; c < (dim+1); c++)
  26. {
  27. double value = W(j,i);
  28. if(c<dim)
  29. {
  30. value *= V(j,c);
  31. }
  32. M.insert(x*n + j,x*m + c*m*dim + i) = value;
  33. }
  34. }
  35. }
  36. }
  37. M.makeCompressed();
  38. }
  39. IGL_INLINE void igl::lbs_matrix(
  40. const Eigen::MatrixXd & V,
  41. const Eigen::MatrixXd & W,
  42. Eigen::MatrixXd & 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(x*n + j,x*m + c*m*dim + i) = value;
  70. }
  71. }
  72. }
  73. }
  74. }
  75. IGL_INLINE void igl::lbs_matrix(
  76. const Eigen::MatrixXd & V,
  77. const Eigen::MatrixXd & W,
  78. const Eigen::MatrixXi & WI,
  79. Eigen::SparseMatrix<double>& M)
  80. {
  81. // number of mesh vertices
  82. int n = V.rows();
  83. assert(n == W.rows());
  84. assert(n == WI.rows());
  85. // dimension of mesh
  86. int dim = V.cols();
  87. // number of handles
  88. int m = WI.maxCoeff()+1;
  89. // max number of influencing handles
  90. int k = W.cols();
  91. assert(k == WI.cols());
  92. M.resize(n*dim,m*dim*(dim+1));
  93. // loop over coordinates of mesh vertices
  94. for(int x = 0; x < dim; x++)
  95. {
  96. // loop over mesh vertices
  97. for(int j = 0; j < n; j++)
  98. {
  99. // loop over handles
  100. for(int i = 0; i < k; i++)
  101. {
  102. // loop over cols of affine transformations
  103. for(int c = 0; c < (dim+1); c++)
  104. {
  105. double value = W(j,i);
  106. if(c<dim)
  107. {
  108. value *= V(j,c);
  109. }
  110. if(value != 0)
  111. {
  112. M.insert(x*n + j,x*m + c*m*dim + WI(j,i)) = value;
  113. }
  114. }
  115. }
  116. }
  117. }
  118. M.makeCompressed();
  119. }
  120. IGL_INLINE void igl::lbs_matrix(
  121. const Eigen::MatrixXd & V,
  122. const Eigen::MatrixXd & W,
  123. const Eigen::MatrixXi & WI,
  124. Eigen::MatrixXd & M)
  125. {
  126. // Cheapskate wrapper
  127. using namespace Eigen;
  128. SparseMatrix<double> sM;
  129. lbs_matrix(V,W,WI,sM);
  130. M = MatrixXd(sM);
  131. }