main.cpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. #include <igl/circulation.h>
  2. #include <igl/collapse_edge.h>
  3. #include <igl/edge_flaps.h>
  4. #include <igl/shortest_edge_and_midpoint.h>
  5. #include <igl/read_triangle_mesh.h>
  6. #include <igl/opengl/glfw/Viewer.h>
  7. #include <Eigen/Core>
  8. #include <iostream>
  9. #include <set>
  10. #include "tutorial_shared_path.h"
  11. int main(int argc, char * argv[])
  12. {
  13. using namespace std;
  14. using namespace Eigen;
  15. using namespace igl;
  16. cout<<"Usage: ./703_Decimation_bin [filename.(off|obj|ply)]"<<endl;
  17. cout<<" [space] toggle animation."<<endl;
  18. cout<<" 'r' reset."<<endl;
  19. // Load a closed manifold mesh
  20. string filename(TUTORIAL_SHARED_PATH "/fertility.off");
  21. if(argc>=2)
  22. {
  23. filename = argv[1];
  24. }
  25. MatrixXd V,OV;
  26. MatrixXi F,OF;
  27. read_triangle_mesh(filename,OV,OF);
  28. igl::opengl::glfw::Viewer viewer;
  29. // Prepare array-based edge data structures and priority queue
  30. VectorXi EMAP;
  31. MatrixXi E,EF,EI;
  32. typedef std::set<std::pair<double,int> > PriorityQueue;
  33. PriorityQueue Q;
  34. std::vector<PriorityQueue::iterator > Qit;
  35. // If an edge were collapsed, we'd collapse it to these points:
  36. MatrixXd C;
  37. int num_collapsed;
  38. // Function to reset original mesh and data structures
  39. const auto & reset = [&]()
  40. {
  41. F = OF;
  42. V = OV;
  43. edge_flaps(F,E,EMAP,EF,EI);
  44. Qit.resize(E.rows());
  45. C.resize(E.rows(),V.cols());
  46. VectorXd costs(E.rows());
  47. Q.clear();
  48. for(int e = 0;e<E.rows();e++)
  49. {
  50. double cost = e;
  51. RowVectorXd p(1,3);
  52. shortest_edge_and_midpoint(e,V,F,E,EMAP,EF,EI,cost,p);
  53. C.row(e) = p;
  54. Qit[e] = Q.insert(std::pair<double,int>(cost,e)).first;
  55. }
  56. num_collapsed = 0;
  57. viewer.data().clear();
  58. viewer.data().set_mesh(V,F);
  59. viewer.data().set_face_based(true);
  60. };
  61. const auto &pre_draw = [&](igl::opengl::glfw::Viewer & viewer)->bool
  62. {
  63. // If animating then collapse 10% of edges
  64. if(viewer.core().is_animating && !Q.empty())
  65. {
  66. bool something_collapsed = false;
  67. // collapse edge
  68. const int max_iter = std::ceil(0.01*Q.size());
  69. for(int j = 0;j<max_iter;j++)
  70. {
  71. if(!collapse_edge(
  72. shortest_edge_and_midpoint, V,F,E,EMAP,EF,EI,Q,Qit,C))
  73. {
  74. break;
  75. }
  76. something_collapsed = true;
  77. num_collapsed++;
  78. }
  79. if(something_collapsed)
  80. {
  81. viewer.data().clear();
  82. viewer.data().set_mesh(V,F);
  83. viewer.data().set_face_based(true);
  84. }
  85. }
  86. return false;
  87. };
  88. const auto &key_down =
  89. [&](igl::opengl::glfw::Viewer &viewer,unsigned char key,int mod)->bool
  90. {
  91. switch(key)
  92. {
  93. case ' ':
  94. viewer.core().is_animating ^= 1;
  95. break;
  96. case 'R':
  97. case 'r':
  98. reset();
  99. break;
  100. default:
  101. return false;
  102. }
  103. return true;
  104. };
  105. reset();
  106. viewer.core().background_color.setConstant(1);
  107. viewer.core().is_animating = true;
  108. viewer.callback_key_down = key_down;
  109. viewer.callback_pre_draw = pre_draw;
  110. return viewer.launch();
  111. }