main.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. #include "precomputation.h"
  2. #include <igl/readDMAT.h>
  3. #include <igl/readOBJ.h>
  4. #include <igl/placeholders.h>
  5. #include <igl/arap.h>
  6. #include <igl/arap_dof.h>
  7. #include <igl/opengl/glfw/Viewer.h>
  8. #include <Eigen/Geometry>
  9. #include <Eigen/StdVector>
  10. #include <vector>
  11. #include <algorithm>
  12. #include <iostream>
  13. typedef
  14. std::vector<Eigen::Quaterniond,Eigen::aligned_allocator<Eigen::Quaterniond> >
  15. RotationList;
  16. const Eigen::RowVector3d sea_green(70./255.,252./255.,167./255.);
  17. Eigen::MatrixXd V,U,M;
  18. Eigen::MatrixXi F;
  19. Eigen::VectorXi S,b;
  20. Eigen::MatrixXd L;
  21. Eigen::RowVector3d mid;
  22. double anim_t = 0.0;
  23. double anim_t_dir = 0.03;
  24. double bbd = 1.0;
  25. bool resolve = true;
  26. igl::ARAPData arap_data,arap_grouped_data;
  27. igl::ArapDOFData<Eigen::MatrixXd,double> arap_dof_data;
  28. enum ModeType
  29. {
  30. MODE_TYPE_ARAP = 0,
  31. MODE_TYPE_ARAP_GROUPED = 1,
  32. MODE_TYPE_ARAP_DOF = 2,
  33. NUM_MODE_TYPES = 4
  34. } mode = MODE_TYPE_ARAP;
  35. bool pre_draw(igl::opengl::glfw::Viewer & viewer)
  36. {
  37. using namespace Eigen;
  38. using namespace std;
  39. if(resolve)
  40. {
  41. MatrixXd bc(b.size(),V.cols());
  42. VectorXd Beq(3*b.size());
  43. for(int i = 0;i<b.size();i++)
  44. {
  45. bc.row(i) = V.row(b(i));
  46. switch(i%4)
  47. {
  48. case 2:
  49. bc(i,0) += 0.15*bbd*sin(0.5*anim_t);
  50. bc(i,1) += 0.15*bbd*(1.-cos(0.5*anim_t));
  51. break;
  52. case 1:
  53. bc(i,1) += 0.10*bbd*sin(1.*anim_t*(i+1));
  54. bc(i,2) += 0.10*bbd*(1.-cos(1.*anim_t*(i+1)));
  55. break;
  56. case 0:
  57. bc(i,0) += 0.20*bbd*sin(2.*anim_t*(i+1));
  58. break;
  59. }
  60. Beq(3*i+0) = bc(i,0);
  61. Beq(3*i+1) = bc(i,1);
  62. Beq(3*i+2) = bc(i,2);
  63. }
  64. switch(mode)
  65. {
  66. default:
  67. assert("unknown mode");
  68. case MODE_TYPE_ARAP:
  69. igl::arap_solve(bc,arap_data,U);
  70. break;
  71. case MODE_TYPE_ARAP_GROUPED:
  72. igl::arap_solve(bc,arap_grouped_data,U);
  73. break;
  74. case MODE_TYPE_ARAP_DOF:
  75. {
  76. VectorXd L0 = L;
  77. arap_dof_update(arap_dof_data,Beq,L0,30,0,L);
  78. const auto & Ucol = M*L;
  79. U.col(0) = Ucol.block(0*U.rows(),0,U.rows(),1);
  80. U.col(1) = Ucol.block(1*U.rows(),0,U.rows(),1);
  81. U.col(2) = Ucol.block(2*U.rows(),0,U.rows(),1);
  82. break;
  83. }
  84. }
  85. viewer.data().set_vertices(U);
  86. viewer.data().set_points(bc,sea_green);
  87. viewer.data().compute_normals();
  88. if(viewer.core().is_animating)
  89. {
  90. anim_t += anim_t_dir;
  91. }else
  92. {
  93. resolve = false;
  94. }
  95. }
  96. return false;
  97. }
  98. bool key_down(igl::opengl::glfw::Viewer &viewer, unsigned char key, int mods)
  99. {
  100. switch(key)
  101. {
  102. case '0':
  103. anim_t = 0;
  104. resolve = true;
  105. return true;
  106. case '.':
  107. mode = (ModeType)(((int)mode+1)%((int)NUM_MODE_TYPES-1));
  108. resolve = true;
  109. return true;
  110. case ',':
  111. mode = (ModeType)(((int)mode-1)%((int)NUM_MODE_TYPES-1));
  112. resolve = true;
  113. return true;
  114. case ' ':
  115. viewer.core().is_animating = !viewer.core().is_animating;
  116. if(viewer.core().is_animating)
  117. {
  118. resolve = true;
  119. }
  120. return true;
  121. }
  122. return false;
  123. }
  124. int main(int argc, char *argv[])
  125. {
  126. using namespace Eigen;
  127. using namespace std;
  128. igl::readOBJ(TUTORIAL_SHARED_PATH "/armadillo.obj",V,F);
  129. U=V;
  130. MatrixXd W;
  131. igl::readDMAT(TUTORIAL_SHARED_PATH "/armadillo-weights.dmat",W);
  132. precomputation(V,F,W,M,b,L,arap_data,arap_grouped_data,arap_dof_data);
  133. // bounding box diagonal
  134. bbd = (V.colwise().maxCoeff()- V.colwise().minCoeff()).norm();
  135. // Plot the mesh with pseudocolors
  136. igl::opengl::glfw::Viewer viewer;
  137. viewer.data().set_mesh(U, F);
  138. viewer.data().add_points(V(b,igl::placeholders::all),sea_green);
  139. viewer.data().show_lines = false;
  140. viewer.callback_pre_draw = &pre_draw;
  141. viewer.callback_key_down = &key_down;
  142. viewer.core().is_animating = false;
  143. viewer.core().animation_max_fps = 30.;
  144. cout<<
  145. "Press [space] to toggle animation."<<endl<<
  146. "Press '0' to reset pose."<<endl<<
  147. "Press '.' to switch to next deformation method."<<endl<<
  148. "Press ',' to switch to previous deformation method."<<endl;
  149. viewer.launch();
  150. }