#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: ./progressive_hulls [filename.(off|obj|ply)]"<=2) { filename = argv[1]; } MatrixXd V,OV; MatrixXi F,OF; read_triangle_mesh(filename,OV,OF); igl::Viewer viewer; // Prepare array-based edge data structures and priority queue VectorXi EMAP; MatrixXi E,EF,EI; typedef std::set > PriorityQueue; PriorityQueue Q; std::vector Qit; // If an edge were collapsed, we'd collapse it to these points: MatrixXd C; int num_collapsed; // Function for computing cost of collapsing edge (lenght) and placement // (midpoint) const auto & shortest_edge_and_midpoint = []( const int e, const Eigen::MatrixXd & V, const Eigen::MatrixXi & /*F*/, const Eigen::MatrixXi & E, const Eigen::VectorXi & /*EMAP*/, const Eigen::MatrixXi & /*EF*/, const Eigen::MatrixXi & /*EI*/, double & cost, RowVectorXd & p) { cost = (V.row(E(e,0))-V.row(E(e,1))).norm(); p = 0.5*(V.row(E(e,0))+V.row(E(e,1))); }; // Function to reset original mesh and data structures const auto & reset = [&]() { F = OF; V = OV; edge_flaps(F,E,EMAP,EF,EI); Qit.resize(E.rows()); C.resize(E.rows(),V.cols()); VectorXd costs(E.rows()); for(int e = 0;e(cost,e)).first; } num_collapsed = 0; viewer.data.clear(); viewer.data.set_mesh(V,F); viewer.data.set_face_based(true); }; const auto &pre_draw = [&](igl::Viewer & viewer)->bool { // 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.is_animating = true; viewer.callback_key_down = key_down; viewer.callback_pre_draw = pre_draw; return viewer.launch(); }