main.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. #include <igl/colon.h>
  2. #include <igl/harmonic.h>
  3. #include <igl/readOBJ.h>
  4. #include <igl/readDMAT.h>
  5. #include <igl/viewer/Viewer.h>
  6. #include <algorithm>
  7. #include <iostream>
  8. #include "tutorial_shared_path.h"
  9. double bc_frac = 1.0;
  10. double bc_dir = -0.03;
  11. bool deformation_field = false;
  12. Eigen::MatrixXd V,U,V_bc,U_bc;
  13. Eigen::VectorXd Z;
  14. Eigen::MatrixXi F;
  15. Eigen::VectorXi b;
  16. bool pre_draw(igl::viewer::Viewer & viewer)
  17. {
  18. using namespace Eigen;
  19. // Determine boundary conditions
  20. if(viewer.core.is_animating)
  21. {
  22. bc_frac += bc_dir;
  23. bc_dir *= (bc_frac>=1.0 || bc_frac<=0.0?-1.0:1.0);
  24. }
  25. const MatrixXd U_bc_anim = V_bc+bc_frac*(U_bc-V_bc);
  26. if(deformation_field)
  27. {
  28. MatrixXd D;
  29. MatrixXd D_bc = U_bc_anim - V_bc;
  30. igl::harmonic(V,F,b,D_bc,2,D);
  31. U = V+D;
  32. }else
  33. {
  34. igl::harmonic(V,F,b,U_bc_anim,2,U);
  35. }
  36. viewer.data.set_vertices(U);
  37. viewer.data.compute_normals();
  38. return false;
  39. }
  40. bool key_down(igl::viewer::Viewer &viewer, unsigned char key, int mods)
  41. {
  42. switch(key)
  43. {
  44. case ' ':
  45. viewer.core.is_animating = !viewer.core.is_animating;
  46. return true;
  47. case 'D':
  48. case 'd':
  49. deformation_field = !deformation_field;
  50. return true;
  51. }
  52. return false;
  53. }
  54. int main(int argc, char *argv[])
  55. {
  56. using namespace Eigen;
  57. using namespace std;
  58. igl::readOBJ(TUTORIAL_SHARED_PATH "/decimated-max.obj",V,F);
  59. U=V;
  60. // S(i) = j: j<0 (vertex i not in handle), j >= 0 (vertex i in handle j)
  61. VectorXi S;
  62. igl::readDMAT(TUTORIAL_SHARED_PATH "/decimated-max-selection.dmat",S);
  63. igl::colon<int>(0,V.rows()-1,b);
  64. b.conservativeResize(stable_partition( b.data(), b.data()+b.size(),
  65. [&S](int i)->bool{return S(i)>=0;})-b.data());
  66. // Boundary conditions directly on deformed positions
  67. U_bc.resize(b.size(),V.cols());
  68. V_bc.resize(b.size(),V.cols());
  69. for(int bi = 0;bi<b.size();bi++)
  70. {
  71. V_bc.row(bi) = V.row(b(bi));
  72. switch(S(b(bi)))
  73. {
  74. case 0:
  75. // Don't move handle 0
  76. U_bc.row(bi) = V.row(b(bi));
  77. break;
  78. case 1:
  79. // move handle 1 down
  80. U_bc.row(bi) = V.row(b(bi)) + RowVector3d(0,-50,0);
  81. break;
  82. case 2:
  83. default:
  84. // move other handles forward
  85. U_bc.row(bi) = V.row(b(bi)) + RowVector3d(0,0,-25);
  86. break;
  87. }
  88. }
  89. // Pseudo-color based on selection
  90. MatrixXd C(F.rows(),3);
  91. RowVector3d purple(80.0/255.0,64.0/255.0,255.0/255.0);
  92. RowVector3d gold(255.0/255.0,228.0/255.0,58.0/255.0);
  93. for(int f = 0;f<F.rows();f++)
  94. {
  95. if( S(F(f,0))>=0 && S(F(f,1))>=0 && S(F(f,2))>=0)
  96. {
  97. C.row(f) = purple;
  98. }else
  99. {
  100. C.row(f) = gold;
  101. }
  102. }
  103. // Plot the mesh with pseudocolors
  104. igl::viewer::Viewer viewer;
  105. viewer.data.set_mesh(U, F);
  106. viewer.core.show_lines = false;
  107. viewer.data.set_colors(C);
  108. viewer.core.trackball_angle = Eigen::Quaternionf(sqrt(2.0),0,sqrt(2.0),0);
  109. viewer.core.trackball_angle.normalize();
  110. viewer.callback_pre_draw = &pre_draw;
  111. viewer.callback_key_down = &key_down;
  112. //viewer.core.is_animating = true;
  113. viewer.core.animation_max_fps = 30.;
  114. cout<<
  115. "Press [space] to toggle deformation."<<endl<<
  116. "Press 'd' to toggle between biharmonic surface or displacements."<<endl;
  117. viewer.launch();
  118. }