int main(int argc, char *argv[]){ ArgParser parser(argc,argv); if( parser.exists("-h") || parser.exists("-help") || parser.exists("--h") || parser.exists("--help") || !parser.exists("-i") || !parser.exists("-dt") ){ help(); return EXIT_SUCCESS; } dir = parser.get<std::string>("-i"); if( dir.back()!='/' ){ dir += '/'; } unsigned int skipframe = 1; parser.get<unsigned int>( "-skip", &skipframe ); double dt = parser.get<double>("-dt"); if( skipframe > 2 ){ dt += 1.0 / double(skipframe); } bool save_frames = false; std::string frames_dir = ""; parser.get<std::string>( "-dump", &frames_dir ); if( frames_dir.length() > 0 ){ save_frames = true; } // Attempt to open conf.json to make sure the diretory is all dandy. if( !test_conf(dir) ){ return EXIT_FAILURE; } // Create the ABC file abc_name = get_name( dir ); abc_name = abc_name + ".abc"; parser.get<std::string>("-o", &abc_name); exporter = AlembicExporter( int(1.0/dt), abc_name ); // Get the number of meshes and obs int n_meshes = num_meshes( dir ); if( n_meshes <= 0 ){ return EXIT_FAILURE; } int n_obs = num_obs( dir ); std::cout << "ArcSim export has " << n_meshes << " meshes and " << n_obs << " obstacles." << std::endl; // If we're saving the frames out to a file (to make a video), we'll need a render window RenderWindow renderWindow; if( save_frames ){ std::shared_ptr<DumpController> c = std::make_shared<DumpController>(); renderWindow.set_controller( c ); GLFWwindow* window = renderWindow.init(); if( !window ){ return EXIT_FAILURE; } } // Load the obstacle meshes ahead of time. They are only transformed each frame. for( int i=0; i<n_obs; ++i ){ obstacles.emplace_back( TriangleMesh::create() ); std::string objfile = dir + "obs_" + pad_leading_zeros(2,i) + ".obj"; if( !meshio::load_obj( obstacles.back().get(), objfile, false, false, false ) ){ std::cerr << "\n**arcsimeToAlembic Error: Failed to load " << objfile << "\n" << std::endl; } std::string mesh_name = "obs"+std::to_string(i); obs_handles.emplace_back( exporter.add_object(mesh_name) ); obs_aabb.emplace_back( obstacles.back()->bounds() ); // Add the mesh to the render window if( save_frames ){ // render_meshes.emplace_back( mcl::RenderMesh::create( obstacles.back() ) ); // renderWindow.add_mesh( render_meshes.back(), RenderMesh::DYNAMIC ); } } // Create the objects so that the alembic exporter knows about them for( int i=0; i<n_meshes; ++i ){ std::string mesh_name = "mesh"+std::to_string(i); deform_handles.emplace_back( exporter.add_object(mesh_name) ); meshes.emplace_back( TriangleMesh::create() ); std::string meshstr = pad_leading_zeros(2,i); std::string objfile = dir + "000000_" + meshstr + ".obj"; if( !meshio::load_obj( meshes.back().get(), objfile, false, false, false ) ){ std::cerr << "\n**arcsimeToAlembic Error: Failed to load " << objfile << "\n" << std::endl; return EXIT_FAILURE; } // Add the mesh to the render window if( save_frames ){ render_meshes.emplace_back( mcl::RenderMesh::create( meshes.back(), RenderMesh::DYNAMIC ) ); renderWindow.add_mesh( render_meshes.back() ); } } if( save_frames ){ // Set the camera to a nice location based // on the meshes added to the renderWindow. renderWindow.nice_camera_location(); // Game loop int frame_num = 0; bool stop = false; int n_render_meshes = render_meshes.size(); int frame_output_count = 0; while( renderWindow.is_open() && !stop ){ if( framedump_running ){ std::cout << '\r'; std::cout << "frame " << frame_num << std::flush; if( !load_frame( frame_num, stop ) ){ return EXIT_FAILURE; } // Update rendering for( int i=0; i<n_render_meshes; ++i ){ render_meshes[i]->load_buffers(); } frame_num += skipframe; frame_output_count++; } renderWindow.draw(); if( framedump_running ){ // Save screenshot std::string ss_filename = make_screenshot_fn( frames_dir, frame_output_count ); renderWindow.save_screenshot( ss_filename ); } glfwPollEvents(); } // end game loop } else { // Loop frames of the simulation and add them to the exporter std::cout << "Saving ArcSim frames to " << abc_name << std::endl; std::cout << "(This will take a while...)" << std::endl; bool stop = false; for( int frame_num=0; frame_num<999999; frame_num += skipframe ){ std::cout << '\r'; std::cout << "frame " << frame_num << std::flush; if( !load_frame( frame_num, stop ) ){ return EXIT_FAILURE; } if( stop ){ break; } // all done! } } std::cout << "\nAll done!" << std::endl; return EXIT_SUCCESS; }