main.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. #include <igl/barycenter.h>
  2. #include <igl/edge_topology.h>
  3. #include <igl/local_basis.h>
  4. #include <igl/parula.h>
  5. #include <igl/per_face_normals.h>
  6. #include <igl/per_vertex_normals.h>
  7. #include <igl/polyvector_field_matchings.h>
  8. #include <igl/read_triangle_mesh.h>
  9. #include <igl/readOFF.h>
  10. #include <igl/slice.h>
  11. #include <igl/sort_vectors_ccw.h>
  12. #include <igl/streamlines.h>
  13. #include <igl/copyleft/comiso/nrosy.h>
  14. #include <igl/opengl/glfw/Viewer.h>
  15. #include <cstdlib>
  16. #include <iostream>
  17. #include <vector>
  18. #include <fstream>
  19. // Mesh
  20. Eigen::MatrixXd V;
  21. Eigen::MatrixXi F;
  22. igl::StreamlineData sl_data;
  23. igl::StreamlineState sl_state;
  24. int degree; // degree of the vector field
  25. int half_degree; // degree/2 if treat_as_symmetric
  26. bool treat_as_symmetric = true;
  27. int anim_t = 0;
  28. int anim_t_dir = 1;
  29. void representative_to_nrosy(
  30. const Eigen::MatrixXd &V,
  31. const Eigen::MatrixXi &F,
  32. const Eigen::MatrixXd &R,
  33. const int N,
  34. Eigen::MatrixXd &Y)
  35. {
  36. using namespace Eigen;
  37. using namespace std;
  38. MatrixXd B1, B2, B3;
  39. igl::local_basis(V, F, B1, B2, B3);
  40. Y.resize(F.rows(), 3 * N);
  41. for (unsigned i = 0; i < F.rows(); ++i)
  42. {
  43. double x = R.row(i) * B1.row(i).transpose();
  44. double y = R.row(i) * B2.row(i).transpose();
  45. double angle = atan2(y, x);
  46. for (unsigned j = 0; j < N; ++j)
  47. {
  48. double anglej = angle + M_PI * double(j) / double(N);
  49. double xj = cos(anglej);
  50. double yj = sin(anglej);
  51. Y.block(i, j * 3, 1, 3) = xj * B1.row(i) + yj * B2.row(i);
  52. }
  53. }
  54. }
  55. bool pre_draw(igl::opengl::glfw::Viewer &viewer)
  56. {
  57. using namespace Eigen;
  58. using namespace std;
  59. if (!viewer.core.is_animating)
  60. return false;
  61. igl::streamlines_next(V, F, sl_data, sl_state);
  62. Eigen::RowVector3d color = Eigen::RowVector3d::Zero();
  63. double value = ((anim_t) % 100) / 100.;
  64. if (value > 0.5)
  65. value = 1 - value;
  66. value = value / 0.5;
  67. igl::parula(value, color[0], color[1], color[2]);
  68. viewer.data().add_edges(sl_state.start_point, sl_state.end_point, color);
  69. anim_t += anim_t_dir;
  70. return false;
  71. }
  72. bool key_down(igl::opengl::glfw::Viewer &viewer, unsigned char key, int modifier)
  73. {
  74. if (key == ' ')
  75. {
  76. viewer.core.is_animating = !viewer.core.is_animating;
  77. return true;
  78. }
  79. return false;
  80. }
  81. int main(int argc, char *argv[])
  82. {
  83. using namespace Eigen;
  84. using namespace std;
  85. // Load a mesh in OFF format
  86. igl::readOFF(TUTORIAL_SHARED_PATH "/bumpy.off", V, F);
  87. // Create a Vector Field
  88. Eigen::VectorXi b;
  89. Eigen::MatrixXd bc;
  90. Eigen::VectorXd S; // unused
  91. b.resize(1);
  92. b << 0;
  93. bc.resize(1, 3);
  94. bc << 1, 1, 1;
  95. half_degree = 3;
  96. treat_as_symmetric = true;
  97. Eigen::MatrixXd temp_field, temp_field2;
  98. igl::copyleft::comiso::nrosy(V, F, b, bc, VectorXi(), VectorXd(), MatrixXd(), 1, 0.5, temp_field, S);
  99. representative_to_nrosy(V, F, temp_field, half_degree, temp_field2);
  100. igl::streamlines_init(V, F, temp_field2, treat_as_symmetric, sl_data, sl_state);
  101. // Viewer Settings
  102. igl::opengl::glfw::Viewer viewer;
  103. viewer.data().set_mesh(V, F);
  104. viewer.callback_pre_draw = &pre_draw;
  105. viewer.callback_key_down = &key_down;
  106. viewer.data().show_lines = false;
  107. viewer.core.is_animating = false;
  108. viewer.core.animation_max_fps = 30.;
  109. // Paint mesh grayish
  110. Eigen::MatrixXd C;
  111. C.setConstant(viewer.data().V.rows(), 3, .9);
  112. viewer.data().set_colors(C);
  113. // Draw vector field on sample points
  114. igl::StreamlineState sl_state0;
  115. sl_state0 = sl_state;
  116. igl::streamlines_next(V, F, sl_data, sl_state0);
  117. Eigen::MatrixXd v = sl_state0.end_point - sl_state0.start_point;
  118. v.rowwise().normalize();
  119. viewer.data().add_edges(sl_state0.start_point,
  120. sl_state0.start_point + 0.059 * v,
  121. Eigen::RowVector3d::Constant(1.0f));
  122. cout <<
  123. "Press [space] to toggle animation" << endl;
  124. viewer.launch();
  125. }