main.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  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/viewer/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::viewer::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::viewer::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(shortest_edge_and_midpoint,V,F,E,EMAP,EF,EI,Q,Qit,C))
  72. {
  73. break;
  74. }
  75. something_collapsed = true;
  76. num_collapsed++;
  77. }
  78. if(something_collapsed)
  79. {
  80. viewer.data.clear();
  81. viewer.data.set_mesh(V,F);
  82. viewer.data.set_face_based(true);
  83. }
  84. }
  85. return false;
  86. };
  87. const auto &key_down =
  88. [&](igl::viewer::Viewer &viewer,unsigned char key,int mod)->bool
  89. {
  90. switch(key)
  91. {
  92. case ' ':
  93. viewer.core.is_animating ^= 1;
  94. break;
  95. case 'R':
  96. case 'r':
  97. reset();
  98. break;
  99. default:
  100. return false;
  101. }
  102. return true;
  103. };
  104. reset();
  105. viewer.core.is_animating = true;
  106. viewer.callback_key_down = key_down;
  107. viewer.callback_pre_draw = pre_draw;
  108. return viewer.launch();
  109. }