main.cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. #include <igl/colon.h>
  2. #include <igl/harmonic.h>
  3. #include <igl/readOBJ.h>
  4. #include <igl/viewer/Viewer.h>
  5. #include <algorithm>
  6. #include <iostream>
  7. #include "tutorial_shared_path.h"
  8. double z_max = 1.0;
  9. double z_dir = -0.03;
  10. int k = 2;
  11. bool resolve = true;
  12. Eigen::MatrixXd V,U;
  13. Eigen::VectorXd Z;
  14. Eigen::MatrixXi F;
  15. Eigen::VectorXi b;
  16. Eigen::VectorXd bc;
  17. bool pre_draw(igl::viewer::Viewer & viewer)
  18. {
  19. using namespace Eigen;
  20. if(resolve)
  21. {
  22. igl::harmonic(V,F,b,bc,k,Z);
  23. resolve = false;
  24. }
  25. U.col(2) = z_max*Z;
  26. viewer.data.set_vertices(U);
  27. viewer.data.compute_normals();
  28. if(viewer.core.is_animating)
  29. {
  30. z_max += z_dir;
  31. z_dir *= (z_max>=1.0 || z_max<=0.0?-1.0:1.0);
  32. }
  33. return false;
  34. }
  35. bool key_down(igl::viewer::Viewer &viewer, unsigned char key, int mods)
  36. {
  37. switch(key)
  38. {
  39. case ' ':
  40. viewer.core.is_animating = !viewer.core.is_animating;
  41. break;
  42. case '.':
  43. k++;
  44. k = (k>4?4:k);
  45. resolve = true;
  46. break;
  47. case ',':
  48. k--;
  49. k = (k<1?1:k);
  50. resolve = true;
  51. break;
  52. }
  53. return true;
  54. }
  55. int main(int argc, char *argv[])
  56. {
  57. using namespace Eigen;
  58. using namespace std;
  59. igl::readOBJ(TUTORIAL_SHARED_PATH "/bump-domain.obj",V,F);
  60. U=V;
  61. // Find boundary vertices outside annulus
  62. typedef Matrix<bool,Dynamic,1> VectorXb;
  63. VectorXb is_outer = (V.rowwise().norm().array()-1.0)>-1e-15;
  64. VectorXb is_inner = (V.rowwise().norm().array()-0.15)<1e-15;
  65. VectorXb in_b = is_outer.array() || is_inner.array();
  66. igl::colon<int>(0,V.rows()-1,b);
  67. b.conservativeResize(stable_partition( b.data(), b.data()+b.size(),
  68. [&in_b](int i)->bool{return in_b(i);})-b.data());
  69. bc.resize(b.size(),1);
  70. for(int bi = 0;bi<b.size();bi++)
  71. {
  72. bc(bi) = (is_outer(b(bi))?0.0:1.0);
  73. }
  74. // Pseudo-color based on selection
  75. MatrixXd C(F.rows(),3);
  76. RowVector3d purple(80.0/255.0,64.0/255.0,255.0/255.0);
  77. RowVector3d gold(255.0/255.0,228.0/255.0,58.0/255.0);
  78. for(int f = 0;f<F.rows();f++)
  79. {
  80. if( in_b(F(f,0)) && in_b(F(f,1)) && in_b(F(f,2)))
  81. {
  82. C.row(f) = purple;
  83. }else
  84. {
  85. C.row(f) = gold;
  86. }
  87. }
  88. // Plot the mesh with pseudocolors
  89. igl::viewer::Viewer viewer;
  90. viewer.data.set_mesh(U, F);
  91. viewer.core.show_lines = false;
  92. viewer.data.set_colors(C);
  93. viewer.core.trackball_angle = Eigen::Quaternionf(0.81,-0.58,-0.03,-0.03);
  94. viewer.core.trackball_angle.normalize();
  95. viewer.callback_pre_draw = &pre_draw;
  96. viewer.callback_key_down = &key_down;
  97. viewer.core.is_animating = true;
  98. viewer.core.animation_max_fps = 30.;
  99. cout<<
  100. "Press [space] to toggle animation."<<endl<<
  101. "Press '.' to increase k."<<endl<<
  102. "Press ',' to decrease k."<<endl;
  103. viewer.launch();
  104. }