main.cpp 4.0 KB

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