main.cpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  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. int main(int argc, char *argv[])
  17. {
  18. Eigen::MatrixXd V;
  19. Eigen::MatrixXi F;
  20. igl::read_triangle_mesh(
  21. argc>1?argv[1]: TUTORIAL_SHARED_PATH "/elephant.obj",V,F);
  22. Eigen::MatrixXd N;
  23. igl::per_vertex_normals(V,F,N);
  24. const double bbd = (V.colwise().maxCoeff()- V.colwise().minCoeff()).norm();
  25. Eigen::MatrixXd P_blue;
  26. Eigen::MatrixXd N_blue;
  27. Eigen::VectorXd A_blue;
  28. Eigen::MatrixXd C_blue;
  29. {
  30. const int n_desired = argc>2?atoi(argv[2]):50000;
  31. // Heuristic to determine radius from desired number
  32. const double r = [&V,&F](const int n)
  33. {
  34. Eigen::VectorXd A;
  35. igl::doublearea(V,F,A);
  36. return sqrt(((A.sum()*0.5/(n*0.6162910373))/M_PI));
  37. }(n_desired);
  38. printf("blue noise radius: %g\n",r);
  39. Eigen::MatrixXd B;
  40. Eigen::VectorXi I;
  41. igl::blue_noise(V,F,r,B,I,P_blue);
  42. igl::barycentric_interpolation(N,F,B,I,N_blue);
  43. N_blue.rowwise().normalize();
  44. }
  45. Eigen::MatrixXd P_white;
  46. Eigen::MatrixXd N_white;
  47. Eigen::VectorXd A_white;
  48. Eigen::MatrixXd C_white;
  49. {
  50. Eigen::MatrixXd B;
  51. Eigen::VectorXi I;
  52. igl::random_points_on_mesh(P_blue.rows(),V,F,B,I,P_white);
  53. igl::barycentric_interpolation(N,F,B,I,N_white);
  54. N_white.rowwise().normalize();
  55. }
  56. // Color
  57. Eigen::RowVector3d C(1,1,1);
  58. // Plot the mesh
  59. igl::opengl::glfw::Viewer viewer;
  60. viewer.data().set_mesh(V,F);
  61. viewer.data().show_lines = false;
  62. viewer.data().show_faces = false;
  63. viewer.data().point_size = 4;
  64. bool use_blue = true;
  65. const auto update = [&]()
  66. {
  67. const Eigen::RowVector3d orange(1.0,0.7,0.2);
  68. if(use_blue)
  69. {
  70. viewer.data().set_points(P_blue,Eigen::RowVector3d(0.3,0.4,1.0));
  71. viewer.data().set_edges_from_vector_field(P_blue,bbd*0.01*N_blue,orange);
  72. }else
  73. {
  74. viewer.data().set_points(P_white,Eigen::RowVector3d(1,1,1));
  75. viewer.data().set_edges_from_vector_field(P_white,bbd*0.01*N_white,orange);
  76. }
  77. };
  78. update();
  79. viewer.callback_key_pressed =
  80. [&](igl::opengl::glfw::Viewer &,unsigned char key,int)->bool
  81. {
  82. switch(key)
  83. {
  84. case ' ':
  85. {
  86. use_blue = !use_blue;
  87. update();
  88. return true;
  89. }
  90. }
  91. return false;
  92. };
  93. std::cout<<R"(
  94. [space] toggle between blue and white noise samplings
  95. )";
  96. viewer.launch();
  97. }