void apply(const std::string& /*directory*/, std::vector<std::string>& files, bool /*reinit*/) { sofa::simulation::Simulation* simulation = sofa::simulation::getSimulation(); //Launch the comparison for each scenes for (unsigned int i = 0; i < files.size(); ++i) { const std::string& currentFile = files[i]; GNode::SPtr groot = sofa::core::objectmodel::SPtr_dynamic_cast<GNode> (simulation->load(currentFile.c_str())); if (groot == NULL) { std::cerr << "CANNOT open " << currentFile << " !" << std::endl; continue; } std::cout << "sec. Loading " << currentFile << std::endl; //Save the initial time clock_t curtime = clock(); simulation->init(groot.get()); double t = static_cast<double>(clock() - curtime) / (float)CLOCKS_PER_SEC; std::cout << "Init time " << t << " sec." << std::endl; //Clear and prepare for next scene simulation->unload(groot); groot.reset(); } }
// --------------------------------------------------------------------- // --- // --------------------------------------------------------------------- int main(int argc, char** argv) { glutInit(&argc,argv); sofa::helper::parse("This is a SOFA application.") (argc,argv); sofa::gui::GUIManager::Init(argv[0]); // The graph root node GNode::SPtr groot = sofa::core::objectmodel::New<GNode>(); groot->setName( "root" ); groot->setGravity( Coord3(0,-10,0) ); // One solver for all the graph EulerSolver::SPtr solver = sofa::core::objectmodel::New<EulerSolver>(); solver->setName("solver"); solver->f_printLog.setValue(false); groot->addObject(solver); // One node to define the particle GNode::SPtr particule_node = sofa::core::objectmodel::New<GNode>("particle_node", groot.get()); // The particule, i.e, its degrees of freedom : a point with a velocity MechanicalObject3::SPtr particle = sofa::core::objectmodel::New<MechanicalObject3>(); particle->setName("particle"); particule_node->addObject(particle); particle->resize(1); // get write access the particle positions vector WriteAccessor< Data<MechanicalObject3::VecCoord> > positions = *particle->write( VecId::position() ); positions[0] = Coord3(0,0,0); // get write access the particle velocities vector WriteAccessor< Data<MechanicalObject3::VecDeriv> > velocities = *particle->write( VecId::velocity() ); velocities[0] = Deriv3(0,0,0); // Its properties, i.e, a simple mass node UniformMass3::SPtr mass = sofa::core::objectmodel::New<UniformMass3>(); mass->setName("mass"); particule_node->addObject(mass); mass->setMass( 1 ); // Display Flags sofa::component::visualmodel::VisualStyle::SPtr style = sofa::core::objectmodel::New<sofa::component::visualmodel::VisualStyle>(); groot->addObject(style); sofa::core::visual::DisplayFlags& flags = *style->displayFlags.beginEdit(); flags.setShowBehaviorModels(true); style->displayFlags.endEdit(); sofa::simulation::tree::getSimulation()->init(groot.get()); groot->setAnimate(false); //======================================= // Run the main loop sofa::gui::GUIManager::MainLoop(groot); return 0; }
// --------------------------------------------------------------------- // --- // --------------------------------------------------------------------- int main(int argc, char** argv) { glutInit(&argc,argv); sofa::helper::parse("This is a SOFA application.") (argc,argv); sofa::gui::GUIManager::Init(argv[0]); // The graph root node : gravity already exists in a GNode by default GNode::SPtr groot = sofa::core::objectmodel::New<GNode>(); groot->setName( "root" ); groot->setGravity( Coord3(0,-10,0) ); // One solver for all the graph EulerSolver::SPtr solver = sofa::core::objectmodel::New<EulerSolver>(); solver->setName("solver"); solver->f_printLog.setValue(false); groot->addObject(solver); // Tetrahedron degrees of freedom MechanicalObject3::SPtr DOF = sofa::core::objectmodel::New<MechanicalObject3>(); groot->addObject(DOF); DOF->resize(4); DOF->setName("DOF"); //get write access to the position vector of mechanical object DOF WriteAccessor<Data<VecCoord3> > x = *DOF->write(VecId::position()); x[0] = Coord3(0,10,0); x[1] = Coord3(10,0,0); x[2] = Coord3(-10*0.5,0,10*0.866); x[3] = Coord3(-10*0.5,0,-10*0.866); // Tetrahedron uniform mass UniformMass3::SPtr mass = sofa::core::objectmodel::New<UniformMass3>(); groot->addObject(mass); mass->setMass(2); mass->setName("mass"); // Tetrahedron topology MeshTopology::SPtr topology = sofa::core::objectmodel::New<MeshTopology>(); topology->setName("mesh topology"); groot->addObject( topology ); topology->addTetra(0,1,2,3); // Tetrahedron constraints FixedConstraint3::SPtr constraints = sofa::core::objectmodel::New<FixedConstraint3>(); constraints->setName("constraints"); groot->addObject(constraints); constraints->addConstraint(0); // Tetrahedron force field TetrahedronFEMForceField3::SPtr fem = sofa::core::objectmodel::New<TetrahedronFEMForceField3>(); fem->setName("FEM"); groot->addObject(fem); fem->setMethod("polar"); fem->setUpdateStiffnessMatrix(true); fem->setYoungModulus(6); // Tetrahedron skin GNode::SPtr skin = sofa::core::objectmodel::New<GNode>("skin",groot.get());; // The visual model OglModel::SPtr visual = sofa::core::objectmodel::New<OglModel>(); visual->setName( "visual" ); visual->load(sofa::helper::system::DataRepository.getFile("mesh/liver-smooth.obj"), "", ""); visual->setColor("red"); visual->applyScale(0.7, 0.7, 0.7); visual->applyTranslation(1.2, 0.8, 0); skin->addObject(visual); // The mapping between the tetrahedron (DOF) and the liver (visual) BarycentricMapping3_to_Ext3::SPtr mapping = sofa::core::objectmodel::New<BarycentricMapping3_to_Ext3>(); mapping->setModels(DOF.get(), visual.get()); mapping->setName( "mapping" ); skin->addObject(mapping); // Display Flags sofa::component::visualmodel::VisualStyle::SPtr style = sofa::core::objectmodel::New<sofa::component::visualmodel::VisualStyle>(); groot->addObject(style); sofa::core::visual::DisplayFlags& flags = *style->displayFlags.beginEdit(); flags.setShowNormals(false); flags.setShowInteractionForceFields(false); flags.setShowMechanicalMappings(false); flags.setShowCollisionModels(false); flags.setShowBoundingCollisionModels(false); flags.setShowMappings(false); flags.setShowForceFields(true); flags.setShowWireFrame(true); flags.setShowVisualModels(true); flags.setShowBehaviorModels(true); style->displayFlags.endEdit(); // Init the scene sofa::simulation::tree::getSimulation()->init(groot.get()); groot->setAnimate(false); //======================================= // Run the main loop sofa::gui::GUIManager::MainLoop(groot); return 0; }
void apply(const std::string& directory, std::vector<std::string>& files, unsigned int iterations, bool reinit, bool useTopology) { sofa::component::init(); // ensures all components are initialized, also introduce a dependency to all libraries, avoiding problems with -Wl,--as-needed flag sofa::simulation::Simulation* simulation = sofa::simulation::getSimulation(); //Launch the comparison for each scenes for (unsigned int i = 0; i < files.size(); ++i) { const std::string& currentFile = files[i]; GNode::SPtr groot = sofa::core::objectmodel::SPtr_dynamic_cast<GNode> (simulation->load(currentFile.c_str())); if (groot == NULL) { std::cerr << "CANNOT open " << currentFile << " !" << std::endl; continue; } simulation->init(groot.get()); //Filename where the simulation of the current scene will be saved (in Sofa/applications/projects/sofaVerification/simulation/) std::string refFile; if(directory.empty()) { refFile += SetDirectory::GetParentDir(DataRepository.getFirstPath().c_str()); refFile += "/applications/projects/sofaVerification/simulation/"; refFile += SetDirectory::GetFileName(currentFile.c_str()); } else { refFile += directory; refFile += '/'; refFile += SetDirectory::GetFileName(currentFile.c_str()); } //If we initialize the system, we add only WriteState components, to store the reference states if (reinit) { if (useTopology) { sofa::component::misc::WriteTopologyCreator writeVisitor(sofa::core::ExecParams::defaultInstance()); writeVisitor.setCreateInMapping(true); writeVisitor.setSceneName(refFile); writeVisitor.execute(groot.get()); sofa::component::misc::WriteTopologyActivator v_write(sofa::core::ExecParams::defaultInstance() /* PARAMS FIRST */, true); v_write.execute(groot.get()); } else { sofa::component::misc::WriteStateCreator writeVisitor(sofa::core::ExecParams::defaultInstance()); writeVisitor.setCreateInMapping(true); writeVisitor.setSceneName(refFile); writeVisitor.execute(groot.get()); sofa::component::misc::WriteStateActivator v_write(sofa::core::ExecParams::defaultInstance() /* PARAMS FIRST */, true); v_write.execute(groot.get()); } } else { if (useTopology) { //We add CompareTopology components: as it derives from the ReadTopology, we use the ReadTopologyActivator to enable them. sofa::component::misc::CompareTopologyCreator compareVisitor(sofa::core::ExecParams::defaultInstance()); compareVisitor.setCreateInMapping(true); compareVisitor.setSceneName(refFile); compareVisitor.execute(groot.get()); sofa::component::misc::ReadTopologyActivator v_read(sofa::core::ExecParams::defaultInstance(),true); v_read.execute(groot.get()); } else { //We add CompareState components: as it derives from the ReadState, we use the ReadStateActivator to enable them. sofa::component::misc::CompareStateCreator compareVisitor(sofa::core::ExecParams::defaultInstance()); compareVisitor.setCreateInMapping(true); compareVisitor.setSceneName(refFile); compareVisitor.execute(groot.get()); sofa::component::misc::ReadStateActivator v_read(sofa::core::ExecParams::defaultInstance() /* PARAMS FIRST */, true); v_read.execute(groot.get()); } } //Do as many iterations as specified in entry of the program. At each step, the compare state will compare the computed states to the recorded states std::cout << "Computing " << iterations << " for " << currentFile << std::endl; //Save the initial time clock_t curtime = clock(); for (unsigned int i = 0; i < iterations; i++) { simulation->animate(groot.get()); } double t = static_cast<double>(clock() - curtime) / CLOCKS_PER_SEC; std::cout << "ITERATIONS " << iterations << " TIME " << t << " seconds "; //We read the final error: the summation of all the error made at each time step if (!reinit) { if (useTopology) { sofa::component::misc::CompareTopologyResult result(sofa::core::ExecParams::defaultInstance()); result.execute(groot.get()); std::cout << "ERROR " << result.getTotalError() << ' '; const std::vector<unsigned int>& listResult = result.getErrors(); if (listResult.size() != 5) { std::cerr << "ERROR while reading detail of errors by topological element." << std::endl; break; } std::cout << "ERROR by element type " << " EDGES " << static_cast<double>(listResult[0]) / result.getNumCompareTopology() << " TRIANGLES " << static_cast<double>(listResult[1]) / result.getNumCompareTopology() << " QUADS " << static_cast<double>(listResult[2]) / result.getNumCompareTopology() << " TETRAHEDRA " << static_cast<double>(listResult[3]) / result.getNumCompareTopology() << " HEXAHEDRA " << static_cast<double>(listResult[4]) / result.getNumCompareTopology(); } else { sofa::component::misc::CompareStateResult result(sofa::core::ExecParams::defaultInstance()); result.execute(groot.get()); std::cout << "ERROR " << result.getTotalError() << " ERRORBYDOF " << static_cast<double>(result.getErrorByDof()) / result.getNumCompareState() << std::endl; } } std::cout << std::endl; //Clear and prepare for next scene simulation->unload(groot.get()); groot.reset(); } }