#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include struct Mesh { Eigen::MatrixXd V,U; Eigen::MatrixXi T,F; } low,high,scene; Eigen::MatrixXd W; igl::ARAPData arap_data; int main(int argc, char * argv[]) { using namespace Eigen; using namespace std; using namespace igl; // read the mesh, if the code is prepared outside of tutorial, the TUTORIAL_SHARED_PATH // should be the data folder if(!readMESH(TUTORIAL_SHARED_PATH "/octopus-low.mesh",low.V,low.T,low.F)) { cout<<"failed to load mesh"< list of singleton lists std::vector > S; // S will hav size of low.V.rows() and each list inside will have 1 element igl::matrix_to_list(b,S); cout<<"Computing weights for "< M; igl::massmatrix(low.V,low.T,igl::MASSMATRIX_TYPE_DEFAULT,M); const size_t n = low.V.rows(); // f = ma arap_data.f_ext = M * RowVector3d(0,-9.8,0).replicate(n,1); // Random initial velocities to wiggle things arap_data.vel = MatrixXd::Random(n,3); igl::opengl::glfw::Viewer viewer; // Create one huge mesh containing both meshes igl::cat(1,low.U,high.U,scene.U); // need to remap the indices since we cat the V matrices igl::cat(1,low.F,MatrixXi(high.F.array()+low.V.rows()),scene.F); // Color each mesh viewer.data().set_mesh(scene.U,scene.F); MatrixXd C(scene.F.rows(),3); C<< RowVector3d(0.8,0.5,0.2).replicate(low.F.rows(),1), RowVector3d(0.3,0.4,1.0).replicate(high.F.rows(),1); viewer.data().set_colors(C); viewer.callback_key_pressed = [&](igl::opengl::glfw::Viewer & viewer,unsigned int key,int mods)->bool { switch(key) { default: return false; case ' ': viewer.core().is_animating = !viewer.core().is_animating; return true; case 'r': low.U = low.V; return true; } }; viewer.callback_pre_draw = [&](igl::opengl::glfw::Viewer & viewer)->bool { glEnable(GL_CULL_FACE); if(viewer.core().is_animating) { arap_solve(MatrixXd(0,3),arap_data,low.U); for(int v = 0;v