#include #include #include #include #include #include #include #include #include #include #include int main(int argc, char * argv[]) { using namespace std; using namespace Eigen; using namespace igl; cout<<"Usage: ./703_Decimation_bin [filename.(off|obj|ply)]"<=2) { filename = argv[1]; } MatrixXd V,OV; MatrixXi F,OF; read_triangle_mesh(filename,OV,OF); igl::opengl::glfw::Viewer viewer; // Prepare array-based edge data structures and priority queue VectorXi EMAP; MatrixXi E,EF,EI; igl::min_heap< std::tuple > Q; Eigen::VectorXi EQ; // If an edge were collapsed, we'd collapse it to these points: MatrixXd C; int num_collapsed; // Function to reset original mesh and data structures const auto & reset = [&]() { F = OF; V = OV; edge_flaps(F,E,EMAP,EF,EI); C.resize(E.rows(),V.cols()); VectorXd costs(E.rows()); // https://stackoverflow.com/questions/2852140/priority-queue-clear-method // Q.clear(); Q = {}; EQ = Eigen::VectorXi::Zero(E.rows()); { Eigen::VectorXd costs(E.rows()); igl::parallel_for(E.rows(),[&](const int e) { double cost = e; RowVectorXd p(1,3); shortest_edge_and_midpoint(e,V,F,E,EMAP,EF,EI,cost,p); C.row(e) = p; costs(e) = cost; },10000); for(int e = 0;ebool { // If animating then collapse 10% of edges if(viewer.core().is_animating && !Q.empty()) { bool something_collapsed = false; // collapse edge const int max_iter = std::ceil(0.01*Q.size()); for(int j = 0;jbool { switch(key) { case ' ': viewer.core().is_animating ^= 1; break; case 'R': case 'r': reset(); break; default: return false; } return true; }; reset(); viewer.core().background_color.setConstant(1); viewer.core().is_animating = true; viewer.callback_key_down = key_down; viewer.callback_pre_draw = pre_draw; return viewer.launch(); }