main.cpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. #include <igl/colon.h>
  2. #include <igl/directed_edge_orientations.h>
  3. #include <igl/directed_edge_parents.h>
  4. #include <igl/forward_kinematics.h>
  5. #include <igl/PI.h>
  6. #include <igl/partition.h>
  7. #include <igl/mat_max.h>
  8. #include <igl/lbs_matrix.h>
  9. #include <igl/slice.h>
  10. #include <igl/deform_skeleton.h>
  11. #include <igl/dqs.h>
  12. #include <igl/lbs_matrix.h>
  13. #include <igl/columnize.h>
  14. #include <igl/readDMAT.h>
  15. #include <igl/readOBJ.h>
  16. #include <igl/arap.h>
  17. #include <igl/arap_dof.h>
  18. #include <igl/opengl/glfw/Viewer.h>
  19. #include <Eigen/Geometry>
  20. #include <Eigen/StdVector>
  21. #include <vector>
  22. #include <algorithm>
  23. #include <iostream>
  24. #include "tutorial_shared_path.h"
  25. typedef
  26. std::vector<Eigen::Quaterniond,Eigen::aligned_allocator<Eigen::Quaterniond> >
  27. RotationList;
  28. const Eigen::RowVector3d sea_green(70./255.,252./255.,167./255.);
  29. Eigen::MatrixXd V,U,M;
  30. Eigen::MatrixXi F;
  31. Eigen::VectorXi S,b;
  32. Eigen::MatrixXd L;
  33. Eigen::RowVector3d mid;
  34. double anim_t = 0.0;
  35. double anim_t_dir = 0.03;
  36. double bbd = 1.0;
  37. bool resolve = true;
  38. igl::ARAPData arap_data,arap_grouped_data;
  39. igl::ArapDOFData<Eigen::MatrixXd,double> arap_dof_data;
  40. Eigen::SparseMatrix<double> Aeq;
  41. enum ModeType
  42. {
  43. MODE_TYPE_ARAP = 0,
  44. MODE_TYPE_ARAP_GROUPED = 1,
  45. MODE_TYPE_ARAP_DOF = 2,
  46. NUM_MODE_TYPES = 4
  47. } mode = MODE_TYPE_ARAP;
  48. bool pre_draw(igl::opengl::glfw::Viewer & viewer)
  49. {
  50. using namespace Eigen;
  51. using namespace std;
  52. if(resolve)
  53. {
  54. MatrixXd bc(b.size(),V.cols());
  55. VectorXd Beq(3*b.size());
  56. for(int i = 0;i<b.size();i++)
  57. {
  58. bc.row(i) = V.row(b(i));
  59. switch(i%4)
  60. {
  61. case 2:
  62. bc(i,0) += 0.15*bbd*sin(0.5*anim_t);
  63. bc(i,1) += 0.15*bbd*(1.-cos(0.5*anim_t));
  64. break;
  65. case 1:
  66. bc(i,1) += 0.10*bbd*sin(1.*anim_t*(i+1));
  67. bc(i,2) += 0.10*bbd*(1.-cos(1.*anim_t*(i+1)));
  68. break;
  69. case 0:
  70. bc(i,0) += 0.20*bbd*sin(2.*anim_t*(i+1));
  71. break;
  72. }
  73. Beq(3*i+0) = bc(i,0);
  74. Beq(3*i+1) = bc(i,1);
  75. Beq(3*i+2) = bc(i,2);
  76. }
  77. switch(mode)
  78. {
  79. default:
  80. assert("unknown mode");
  81. case MODE_TYPE_ARAP:
  82. igl::arap_solve(bc,arap_data,U);
  83. break;
  84. case MODE_TYPE_ARAP_GROUPED:
  85. igl::arap_solve(bc,arap_grouped_data,U);
  86. break;
  87. case MODE_TYPE_ARAP_DOF:
  88. {
  89. VectorXd L0 = L;
  90. arap_dof_update(arap_dof_data,Beq,L0,30,0,L);
  91. const auto & Ucol = M*L;
  92. U.col(0) = Ucol.block(0*U.rows(),0,U.rows(),1);
  93. U.col(1) = Ucol.block(1*U.rows(),0,U.rows(),1);
  94. U.col(2) = Ucol.block(2*U.rows(),0,U.rows(),1);
  95. break;
  96. }
  97. }
  98. viewer.data().set_vertices(U);
  99. viewer.data().set_points(bc,sea_green);
  100. viewer.data().compute_normals();
  101. if(viewer.core().is_animating)
  102. {
  103. anim_t += anim_t_dir;
  104. }else
  105. {
  106. resolve = false;
  107. }
  108. }
  109. return false;
  110. }
  111. bool key_down(igl::opengl::glfw::Viewer &viewer, unsigned char key, int mods)
  112. {
  113. switch(key)
  114. {
  115. case '0':
  116. anim_t = 0;
  117. resolve = true;
  118. return true;
  119. case '.':
  120. mode = (ModeType)(((int)mode+1)%((int)NUM_MODE_TYPES-1));
  121. resolve = true;
  122. return true;
  123. case ',':
  124. mode = (ModeType)(((int)mode-1)%((int)NUM_MODE_TYPES-1));
  125. resolve = true;
  126. return true;
  127. case ' ':
  128. viewer.core().is_animating = !viewer.core().is_animating;
  129. if(viewer.core().is_animating)
  130. {
  131. resolve = true;
  132. }
  133. return true;
  134. }
  135. return false;
  136. }
  137. int main(int argc, char *argv[])
  138. {
  139. using namespace Eigen;
  140. using namespace std;
  141. igl::readOBJ(TUTORIAL_SHARED_PATH "/armadillo.obj",V,F);
  142. U=V;
  143. MatrixXd W;
  144. igl::readDMAT(TUTORIAL_SHARED_PATH "/armadillo-weights.dmat",W);
  145. igl::lbs_matrix_column(V,W,M);
  146. // Cluster according to weights
  147. VectorXi G;
  148. {
  149. VectorXi S;
  150. VectorXd D;
  151. igl::partition(W,50,G,S,D);
  152. }
  153. // vertices corresponding to handles (those with maximum weight)
  154. {
  155. VectorXd maxW;
  156. igl::mat_max(W,1,maxW,b);
  157. }
  158. // Precomputation for FAST
  159. cout<<"Initializing Fast Automatic Skinning Transformations..."<<endl;
  160. // number of weights
  161. const int m = W.cols();
  162. Aeq.resize(m*3,m*3*(3+1));
  163. vector<Triplet<double> > ijv;
  164. for(int i = 0;i<m;i++)
  165. {
  166. RowVector4d homo;
  167. homo << V.row(b(i)),1.;
  168. for(int d = 0;d<3;d++)
  169. {
  170. for(int c = 0;c<(3+1);c++)
  171. {
  172. ijv.push_back(Triplet<double>(3*i + d,i + c*m*3 + d*m, homo(c)));
  173. }
  174. }
  175. }
  176. Aeq.setFromTriplets(ijv.begin(),ijv.end());
  177. igl::arap_dof_precomputation(V,F,M,G,arap_dof_data);
  178. igl::arap_dof_recomputation(VectorXi(),Aeq,arap_dof_data);
  179. // Initialize
  180. MatrixXd Istack = MatrixXd::Identity(3,3+1).replicate(1,m);
  181. igl::columnize(Istack,m,2,L);
  182. // Precomputation for ARAP
  183. cout<<"Initializing ARAP..."<<endl;
  184. arap_data.max_iter = 1;
  185. igl::arap_precomputation(V,F,V.cols(),b,arap_data);
  186. // Grouped arap
  187. cout<<"Initializing ARAP with grouped edge-sets..."<<endl;
  188. arap_grouped_data.max_iter = 2;
  189. arap_grouped_data.G = G;
  190. igl::arap_precomputation(V,F,V.cols(),b,arap_grouped_data);
  191. // bounding box diagonal
  192. bbd = (V.colwise().maxCoeff()- V.colwise().minCoeff()).norm();
  193. // Plot the mesh with pseudocolors
  194. igl::opengl::glfw::Viewer viewer;
  195. viewer.data().set_mesh(U, F);
  196. viewer.data().add_points(igl::slice(V,b,1),sea_green);
  197. viewer.data().show_lines = false;
  198. viewer.callback_pre_draw = &pre_draw;
  199. viewer.callback_key_down = &key_down;
  200. viewer.core().is_animating = false;
  201. viewer.core().animation_max_fps = 30.;
  202. cout<<
  203. "Press [space] to toggle animation."<<endl<<
  204. "Press '0' to reset pose."<<endl<<
  205. "Press '.' to switch to next deformation method."<<endl<<
  206. "Press ',' to switch to previous deformation method."<<endl;
  207. viewer.launch();
  208. }