main.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. #include <igl/avg_edge_length.h>
  2. #include <igl/barycenter.h>
  3. #include <igl/local_basis.h>
  4. #include <igl/readOFF.h>
  5. #include <igl/copyleft/comiso/nrosy.h>
  6. #include <igl/opengl/glfw/Viewer.h>
  7. #include <igl/PI.h>
  8. #include "tutorial_shared_path.h"
  9. // Mesh
  10. Eigen::MatrixXd V;
  11. Eigen::MatrixXi F;
  12. // Constrained faces id
  13. Eigen::VectorXi b;
  14. // Cosntrained faces representative vector
  15. Eigen::MatrixXd bc;
  16. // Degree of the N-RoSy field
  17. int N = 4;
  18. // Converts a representative vector per face in the full set of vectors that describe
  19. // an N-RoSy field
  20. void representative_to_nrosy(
  21. const Eigen::MatrixXd& V,
  22. const Eigen::MatrixXi& F,
  23. const Eigen::MatrixXd& R,
  24. const int N,
  25. Eigen::MatrixXd& Y)
  26. {
  27. using namespace Eigen;
  28. using namespace std;
  29. MatrixXd B1, B2, B3;
  30. igl::local_basis(V,F,B1,B2,B3);
  31. Y.resize(F.rows()*N,3);
  32. for (unsigned i=0;i<F.rows();++i)
  33. {
  34. double x = R.row(i) * B1.row(i).transpose();
  35. double y = R.row(i) * B2.row(i).transpose();
  36. double angle = atan2(y,x);
  37. for (unsigned j=0; j<N;++j)
  38. {
  39. double anglej = angle + 2*igl::PI*double(j)/double(N);
  40. double xj = cos(anglej);
  41. double yj = sin(anglej);
  42. Y.row(i*N+j) = xj * B1.row(i) + yj * B2.row(i);
  43. }
  44. }
  45. }
  46. // Plots the mesh with an N-RoSy field and its singularities on top
  47. // The constrained faces (b) are colored in red.
  48. void plot_mesh_nrosy(
  49. igl::opengl::glfw::Viewer& viewer,
  50. Eigen::MatrixXd& V,
  51. Eigen::MatrixXi& F,
  52. int N,
  53. Eigen::MatrixXd& PD1,
  54. Eigen::VectorXd& S,
  55. Eigen::VectorXi& b)
  56. {
  57. using namespace Eigen;
  58. using namespace std;
  59. // Clear the mesh
  60. viewer.data().clear();
  61. viewer.data().set_mesh(V,F);
  62. // Expand the representative vectors in the full vector set and plot them as lines
  63. double avg = igl::avg_edge_length(V, F);
  64. MatrixXd Y;
  65. representative_to_nrosy(V, F, PD1, N, Y);
  66. MatrixXd B;
  67. igl::barycenter(V,F,B);
  68. MatrixXd Be(B.rows()*N,3);
  69. for(unsigned i=0; i<B.rows();++i)
  70. for(unsigned j=0; j<N; ++j)
  71. Be.row(i*N+j) = B.row(i);
  72. viewer.data().add_edges(Be,Be+Y*(avg/2),RowVector3d(0,0,1));
  73. // Plot the singularities as colored dots (red for negative, blue for positive)
  74. for (unsigned i=0; i<S.size();++i)
  75. {
  76. if (S(i) < -0.001)
  77. viewer.data().add_points(V.row(i),RowVector3d(1,0,0));
  78. else if (S(i) > 0.001)
  79. viewer.data().add_points(V.row(i),RowVector3d(0,1,0));
  80. }
  81. // Highlight in red the constrained faces
  82. MatrixXd C = MatrixXd::Constant(F.rows(),3,1);
  83. for (unsigned i=0; i<b.size();++i)
  84. C.row(b(i)) << 1, 0, 0;
  85. viewer.data().set_colors(C);
  86. }
  87. // It allows to change the degree of the field when a number is pressed
  88. bool key_down(igl::opengl::glfw::Viewer& viewer, unsigned char key, int modifier)
  89. {
  90. using namespace Eigen;
  91. using namespace std;
  92. if (key >= '1' && key <= '9')
  93. N = key - '0';
  94. MatrixXd R;
  95. VectorXd S;
  96. igl::copyleft::comiso::nrosy(V,F,b,bc,VectorXi(),VectorXd(),MatrixXd(),N,0.5,R,S);
  97. plot_mesh_nrosy(viewer,V,F,N,R,S,b);
  98. return false;
  99. }
  100. int main(int argc, char *argv[])
  101. {
  102. using namespace std;
  103. using namespace Eigen;
  104. // Load a mesh in OFF format
  105. igl::readOFF(TUTORIAL_SHARED_PATH "/bumpy.off", V, F);
  106. // Threshold faces with high anisotropy
  107. b.resize(1);
  108. b << 0;
  109. bc.resize(1,3);
  110. bc << 1,1,1;
  111. igl::opengl::glfw::Viewer viewer;
  112. // Interpolate the field and plot
  113. key_down(viewer, '4', 0);
  114. // Plot the mesh
  115. viewer.data().set_mesh(V, F);
  116. viewer.callback_key_down = &key_down;
  117. // Disable wireframe
  118. viewer.data().show_lines = false;
  119. // Launch the viewer
  120. viewer.launch();
  121. }