main.cpp 3.2 KB

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