2
0

main.cpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2020 Alec Jacobson <[email protected]>
  4. //
  5. // This Source Code Form is subject to the terms of the Mozilla Public License
  6. // v. 2.0. If a copy of the MPL was not distributed with this file, You can
  7. // obtain one at http://mozilla.org/MPL/2.0/.
  8. #include <igl/opengl/glfw/Viewer.h>
  9. #include <igl/read_triangle_mesh.h>
  10. #include <igl/blue_noise.h>
  11. #include <igl/per_vertex_normals.h>
  12. #include <igl/barycentric_interpolation.h>
  13. #include <igl/blue_noise.h>
  14. #include <igl/doublearea.h>
  15. #include <igl/random_points_on_mesh.h>
  16. #include <igl/PI.h>
  17. int main(int argc, char *argv[])
  18. {
  19. Eigen::MatrixXd V;
  20. Eigen::MatrixXi F;
  21. igl::read_triangle_mesh(
  22. argc>1?argv[1]: TUTORIAL_SHARED_PATH "/elephant.obj",V,F);
  23. Eigen::MatrixXd N;
  24. igl::per_vertex_normals(V,F,N);
  25. const double bbd = (V.colwise().maxCoeff()- V.colwise().minCoeff()).norm();
  26. Eigen::MatrixXd P_blue;
  27. Eigen::MatrixXd N_blue;
  28. Eigen::VectorXd A_blue;
  29. Eigen::MatrixXd C_blue;
  30. {
  31. const int n_desired = argc>2?atoi(argv[2]):50000;
  32. // Heuristic to determine radius from desired number
  33. const double r = [&V,&F](const int n)
  34. {
  35. Eigen::VectorXd A;
  36. igl::doublearea(V,F,A);
  37. return sqrt(((A.sum()*0.5/(n*0.6162910373))/igl::PI));
  38. }(n_desired);
  39. printf("blue noise radius: %g\n",r);
  40. Eigen::MatrixXd B;
  41. Eigen::VectorXi I;
  42. igl::blue_noise(V,F,r,B,I,P_blue);
  43. igl::barycentric_interpolation(N,F,B,I,N_blue);
  44. N_blue.rowwise().normalize();
  45. }
  46. Eigen::MatrixXd P_white;
  47. Eigen::MatrixXd N_white;
  48. Eigen::VectorXd A_white;
  49. Eigen::MatrixXd C_white;
  50. {
  51. Eigen::MatrixXd B;
  52. Eigen::VectorXi I;
  53. igl::random_points_on_mesh(P_blue.rows(),V,F,B,I,P_white);
  54. igl::barycentric_interpolation(N,F,B,I,N_white);
  55. N_white.rowwise().normalize();
  56. }
  57. // Color
  58. Eigen::RowVector3d C(1,1,1);
  59. // Plot the mesh
  60. igl::opengl::glfw::Viewer viewer;
  61. viewer.data().set_mesh(V,F);
  62. viewer.data().show_lines = false;
  63. viewer.data().show_faces = false;
  64. viewer.data().point_size = 4;
  65. bool use_blue = true;
  66. const auto update = [&]()
  67. {
  68. const Eigen::RowVector3d orange(1.0,0.7,0.2);
  69. if(use_blue)
  70. {
  71. viewer.data().set_points(P_blue,Eigen::RowVector3d(0.3,0.4,1.0));
  72. viewer.data().set_edges_from_vector_field(P_blue,bbd*0.01*N_blue,orange);
  73. }else
  74. {
  75. viewer.data().set_points(P_white,Eigen::RowVector3d(1,1,1));
  76. viewer.data().set_edges_from_vector_field(P_white,bbd*0.01*N_white,orange);
  77. }
  78. };
  79. update();
  80. viewer.callback_key_pressed =
  81. [&](igl::opengl::glfw::Viewer &,unsigned char key,int)->bool
  82. {
  83. switch(key)
  84. {
  85. case ' ':
  86. {
  87. use_blue = !use_blue;
  88. update();
  89. return true;
  90. }
  91. }
  92. return false;
  93. };
  94. std::cout<<R"(
  95. [space] toggle between blue and white noise samplings
  96. )";
  97. viewer.launch();
  98. }