void checkDeprecatedAttribute() { EXPECT_MSG_EMIT(Deprecated) ; std::stringstream scene ; scene << "<?xml version='1.0'?>" "<Node name='Root' gravity='0 -9.81 0' time='0' animate='0' > \n" " <OglLabel name='label1' color='contrast' printLog='true'/> \n" "</Node> \n" ; Node::SPtr root = SceneLoaderXML::loadFromMemory ("testscene", scene.str().c_str(), scene.str().size()) ; ASSERT_NE(nullptr, root.get()) ; root->init(ExecParams::defaultInstance()) ; BaseObject* lm = root->getObject("label1") ; ASSERT_NE(nullptr, lm) ; OglLabel* ogllabel = dynamic_cast<OglLabel*>(lm); ASSERT_NE(nullptr, ogllabel) ; EXPECT_TRUE(ogllabel->d_selectContrastingColor.getValue()) ; EXPECT_EQ(RGBAColor::fromFloat(1,1,1,1), ogllabel->d_color.getValue()) ; }
typename Component::SPtr addNew( Node::SPtr parentNode, std::string name="" ) { typename Component::SPtr component = New<Component>(); parentNode->addObject(component); component->setName(parentNode->getName()+"_"+name); return component; }
/// Test isPointInPlane computation with a simple example void isPointInPlaneTest() { m_node2->getChild("node")->getObject("PlaneROI")->findData("position")->read("1. 0. 0. 1. 1. 0. -1 0 0"); m_node2->getChild("node")->getObject("PlaneROI")->init(); EXPECT_EQ(m_node2->getChild("node")->getObject("PlaneROI")->findData("indices")->getValueString(),"0 1"); }
void SofaModeler::fileOpen(std::string filename) { if ( sofa::helper::system::DataRepository.findFile ( filename ) ) { filename = sofa::helper::system::DataRepository.getFile ( filename ); openPath = sofa::helper::system::SetDirectory::GetParentDir(filename.c_str()); Node::SPtr root = NULL; root = down_cast<sofa::simulation::Node>( sofa::simulation::getSimulation()->load(filename.c_str()).get() ); if (root) { createTab(); fileNew(root.get()); sceneTab->setCurrentIndex(sceneTab->count()-1); graph->setFilename(filename); changeTabName(graph,QString(sofa::helper::system::SetDirectory::GetFileName(filename.c_str()).c_str())); changeNameWindow(graph->getFilename()); QAction* act = windowMenu->addAction(graph->getFilename().c_str()); mapWindow.insert(std::make_pair(act, tabGraph)); recentlyOpenedFilesManager.openFile(filename); } } displayHelpModeler(); }
void checkAttributes() { std::stringstream scene ; scene << "<?xml version='1.0'?>" "<Node name='Root' gravity='0 -9.81 0' time='0' animate='0' > \n" " <OglLabel name='label1'/> \n" "</Node> \n" ; Node::SPtr root = SceneLoaderXML::loadFromMemory ("testscene", scene.str().c_str(), scene.str().size()) ; ASSERT_NE(root.get(), nullptr) ; root->init(ExecParams::defaultInstance()) ; BaseObject* lm = root->getObject("label1") ; ASSERT_NE(lm, nullptr) ; /// List of the supported attributes the user expect to find /// This list needs to be updated if you add an attribute. vector<string> attrnames = { "prefix", "label", "suffix", "x", "y", "fontsize", "color", "selectContrastingColor", "updateLabelEveryNbSteps", "visible"}; for(auto& attrname : attrnames) EXPECT_NE( lm->findData(attrname), nullptr ) << "Missing attribute with name '" << attrname << "'." ; }
Node::SPtr GraphModeler::buildNodeFromBaseElement(Node::SPtr node,xml::BaseElement *elem, bool saveHistory) { const bool displayWarning=true; Node::SPtr newNode = Node::create(""); //Configure the new Node configureElement(newNode.get(), elem); if (newNode->getName() == "Group") { //We can't use the parent node, as it is null if (!node) return NULL; //delete newNode; newNode = node; } else { // if (node) { //Add as a child addNode(node,newNode,saveHistory); } } typedef xml::BaseElement::child_iterator<> elem_iterator; for (elem_iterator it=elem->begin(); it != elem->end(); ++it) { if (std::string(it->getClass()) == std::string("Node")) { buildNodeFromBaseElement(newNode, it,true); } else { const ComponentLibrary *component = sofaLibrary->getComponent(it->getType()); //Configure the new Component const std::string templateAttribute("template"); std::string templatename; templatename = it->getAttribute(templateAttribute, ""); const ClassEntry::SPtr info = component->getEntry(); BaseObject::SPtr newComponent=addComponent(newNode, info, templatename, saveHistory,displayWarning); if (!newComponent) continue; configureElement(newComponent.get(), it); QTreeWidgetItem* itemGraph = graphListener->items[newComponent.get()]; std::string name=itemGraph->text(0).toStdString(); std::string::size_type pos = name.find(' '); if (pos != std::string::npos) name.resize(pos); name += " "; name+=newComponent->getName(); itemGraph->setText(0,name.c_str()); } } newNode->clearWarnings(); return newNode; }
OSG::NodeTransitPtr OSGSofaShadowGraph::build( Node::SPtr root, bool ignoreLights ) { _scene = NULL; _chunkOverrideGroup = NULL; _shadowStage = NULL; VisualParams* vparams = VisualParams::defaultInstance(); OSG::NodeUnrecPtr shadowStageNode; _chunkOverrideGroup = OSG::ChunkOverrideGroup::create(); _scene = OSG::makeNodeFor(_chunkOverrideGroup); sofa::simulation::OSGVisualUpdateVisitor vm_visitor( vparams); vm_visitor.setChunkOverrideGroupNode(_scene); // get lights if (!ignoreLights) { if (!_shadowStage) _shadowStage = OSG::ShadowStage::create(); _shadowStage->setMapSize(1024); _shadowStage->setShadowSmoothness(0.5f); _shadowStage->setShadowMode(OSG::ShadowStage::NO_SHADOW); _shadowStage->setAutoSearchForLights(true); shadowStageNode = OSG::makeNodeFor(_shadowStage); sofa::simulation::OSGLightVisitor light_visitor( vparams); //light_visitor.setTurnOffLights(ignoreLights); light_visitor.setOSG2Parent(_scene); light_visitor.setOSG2ShadowStage(_shadowStage); light_visitor.setAttachNode(_scene); root->execute(&light_visitor); if (light_visitor.getAttachNode()) { vm_visitor.setOSG2Parent(light_visitor.getAttachNode()); root->execute(&vm_visitor); } } else { vm_visitor.setOSG2Parent(_scene); root->execute(&vm_visitor); } if (shadowStageNode && !ignoreLights) { shadowStageNode->addChild(_scene); return OSG::NodeTransitPtr(shadowStageNode); } return OSG::NodeTransitPtr(_scene); }
/// Test isTriangleInPlane computation with a simple example void isTriangleInPlaneTest() { m_node2->getChild("node")->getObject("PlaneROI")->findData("position")->read("0. 0. 0. 1. 0. 0. 1. 1. 0. 3. 0. 0."); m_node2->getChild("node")->getObject("PlaneROI")->findData("triangles")->read("0 1 2 1 3 2"); m_node2->getChild("node")->getObject("PlaneROI")->init(); EXPECT_EQ(m_node2->getChild("node")->getObject("PlaneROI")->findData("triangleIndices")->getValueString(),"0"); EXPECT_EQ(m_node2->getChild("node")->getObject("PlaneROI")->findData("trianglesInROI")->getValueString(),"0 1 2"); }
/// Test isTetrahedraInPlane computation with a simple example void isTetrahedraInPlaneTest() { m_node2->getChild("node")->getObject("PlaneROI")->findData("position")->read("0. 0. 0. 1. 0. 0. 1. 1. 0. 1. 0. 1. 3. 0. 0."); m_node2->getChild("node")->getObject("PlaneROI")->findData("tetrahedra")->read("0 1 2 3 1 2 4 3"); m_node2->getChild("node")->getObject("PlaneROI")->init(); EXPECT_EQ(m_node2->getChild("node")->getObject("PlaneROI")->findData("tetrahedronIndices")->getValueString(),"0"); EXPECT_EQ(m_node2->getChild("node")->getObject("PlaneROI")->findData("tetrahedraInROI")->getValueString(),"0 1 2 3"); }
/** * @brief The root and two children: \f$ \begin{array}{ccc} & R & \\ \diagup & & \diagdown \\ A & & B \end{array} \f$ Expected output: RAABBR */ void traverse_simple_tree() { Node::SPtr root = clearScene(); root->setName("R"); root->createChild("A"); root->createChild("B"); traverse_test( root, "RAABBR", "RAABBR", "RAABBR", "RAB" ); }
void loadFromAFileForNonRigid(){ string scene = "<?xml version='1.0'?>" "<Node name='Root' gravity='0 0 0' time='0' animate='0' > " " <MechanicalObject position='0 0 0'/> " " <UniformMass filename='BehaviorModels/card.rigid'/> " "</Node> " ; Node::SPtr root = SceneLoaderXML::loadFromMemory ("loadFromAValidFile", scene.c_str(), (int)scene.size()) ; root->init(ExecParams::defaultInstance()) ; }
void loadFromAnInvalidPathname(){ string scene = "<?xml version='1.0'?>" "<Node name='Root' gravity='0 0 0' time='0' animate='0' > " " <MechanicalObject position='0 0 0'/> " " <UniformMass filename='invalid_uniformmatrix.txt'/> " "</Node> " ; Node::SPtr root = SceneLoaderXML::loadFromMemory ("loadFromAnInValidFile", scene.c_str(), (int)scene.size()) ; root->init(ExecParams::defaultInstance()) ; }
Node::SPtr createRootNode(Simulation::SPtr s, const std::string& name, const std::map<std::string, std::string>& params) { Node::SPtr root = s->createNewNode(name) ; BaseObjectDescription desc(name.c_str(), "Node"); for(auto& kv : params) { desc.setAttribute(kv.first.c_str(), kv.second); } root->parse(&desc) ; return root ; }
/// Load a scene from a file Node::SPtr SceneLoaderXML::processXML(xml::BaseElement* xml, const char *filename) { loadSucceed = true; if ( xml==NULL ) { return NULL; } sofa::core::ExecParams* params = sofa::core::ExecParams::defaultInstance(); // We go the the current file's directory so that all relative path are correct helper::system::SetDirectory chdir ( filename ); // Temporarily set the numeric formatting locale to ensure that // floating-point values are interpreted correctly by tinyXML. (I.e. the // decimal separator is a dot '.'). helper::system::TemporaryLocale locale(LC_NUMERIC, "C"); sofa::simulation::xml::NodeElement* nodeElt = dynamic_cast<sofa::simulation::xml::NodeElement *>(xml); if( nodeElt==NULL ) { std::cerr << "LOAD ERROR: XML Root Node is not an Element."<<std::endl; loadSucceed = false; std::exit(EXIT_FAILURE); } else if( !(nodeElt->init()) ) { std::cerr << "LOAD ERROR: Node initialization failed."<<std::endl; loadSucceed = false; } core::objectmodel::BaseNode* baseroot = xml->getObject()->toBaseNode(); if ( baseroot == NULL ) { std::cerr << "LOAD ERROR: Objects initialization failed."<<std::endl; loadSucceed = false; return NULL; } Node::SPtr root = down_cast<Node> ( baseroot ); // Find the Simulation component in the scene FindByTypeVisitor<Simulation> findSimu(params); findSimu.execute(root.get()); if( !findSimu.found.empty() ) setSimulation( findSimu.found[0] ); return root; }
void DeleteVisitor::processNodeBottomUp(Node* node) { while (!node->child.empty()) { Node::SPtr child = *node->child.begin(); node->removeChild(child); child.reset(); } while (!node->object.empty()) { core::objectmodel::BaseObject::SPtr object = *node->object.begin(); node->removeObject(object); object.reset(); } }
void SetUp() { setSimulation(m_simu = new DAGSimulation()); m_node = m_simu->createNewGraph("root"); m_thisObject = New<ThisClass >() ; m_node->addObject(m_thisObject) ; }
BaseObject::SPtr createObject(Node::SPtr parent, BaseObjectDescription& desc) { /// Create the object. BaseObject::SPtr obj = ObjectFactory::getInstance()->createObject(parent.get(), &desc); if (obj==nullptr) { std::stringstream msg; msg << "Component '" << desc.getName() << "' of type '" << desc.getAttribute("type","") << "' failed:" << msgendl ; for (std::vector< std::string >::const_iterator it = desc.getErrors().begin(); it != desc.getErrors().end(); ++it) msg << " " << *it << msgendl ; msg_error(parent.get()) << msg.str() ; return nullptr; } return obj ; }
void testNoParameter() { EXPECT_MSG_EMIT(Error) ; std::stringstream scene ; scene << "<?xml version='1.0'?>" "<Node name='Root' gravity='0 -9.81 0' time='0' animate='0' > \n" " <RequiredPlugin /> \n" "</Node> \n" ; Node::SPtr root = SceneLoaderXML::loadFromMemory ("testscene", scene.str().c_str(), scene.str().size()) ; ASSERT_NE(root.get(), nullptr) ; root->init(ExecParams::defaultInstance()) ; }
/// utility function testing a scene graph traversals with given expected results void traverse_test( Node::SPtr node, std::string treeTraverse, std::string treeTraverseRepeatAll, std::string treeTraverseRepeatOnce, std::string dagTopDown ) { // dagBottumUp must be the exact inverse of dagTopDown std::string dagBottomUp(dagTopDown); std::reverse(dagBottomUp.begin(), dagBottomUp.end()); TestVisitor t; t.tree = true; // visitor as TREE traversal w/o repetition t.execute( node.get() ); // cout<<"traverse_simple_tree: visited = " << t.visited << endl; if( t.visited != treeTraverse ){ ADD_FAILURE() << "Dag_test::traverse_test treeTraverse: wrong traversal order, expected "<<treeTraverse<<", got " << t.visited; } t.clear(); t.repeat = simulation::Visitor::REPEAT_ALL; // visitor as TREE traversal with repetitions t.execute( node.get() ); // cout<<"traverse_simple_tree: visited = " << t.visited << endl; if( t.visited != treeTraverseRepeatAll ){ ADD_FAILURE() << "Dag_test::traverse_test treeTraverseRepeatAll: wrong traversal order, expected "<<treeTraverseRepeatAll<<", got " << t.visited; } t.clear(); t.repeat = simulation::Visitor::REPEAT_ONCE; // visitor as TREE traversal with first repetition t.execute( node.get() ); // cout<<"traverse_simple_tree: visited = " << t.visited << endl; if( t.visited != treeTraverseRepeatOnce ){ ADD_FAILURE() << "Dag_test::traverse_test treeTraverseRepeatOnce: wrong traversal order, expected "<<treeTraverseRepeatOnce<<", got " << t.visited; } t.clear(); t.tree = false; // visitor as DAG traversal t.execute(node.get()); // cout<<"traverse_test: visited = " << t.visited << endl; if( t.topdown != dagTopDown ){ ADD_FAILURE() << "Dag_test::traverse_test dagTopDown: wrong traversal order, expected "<<dagTopDown<<", got " << t.topdown; } if( t.bottomup != dagBottomUp ){ ADD_FAILURE() << "Dag_test::traverse_test dagBottomUp: wrong traversal order, expected "<<dagBottomUp<<", got " << t.bottomup; } // sofa::simulation::getSimulation()->print(node.get()); }
void loadFromAFileForRigid(){ string scene = "<?xml version='1.0'?>" "<Node name='Root' gravity='0 0 0' time='0' animate='0' > " " <MechanicalObject template='Rigid3' position='0 0 0 1 0 0 1 0 0 0 1 0 0 1'/> " " <UniformMass filename='BehaviorModels/card.rigid'/> " "</Node> " ; Node::SPtr root = SceneLoaderXML::loadFromMemory ("loadFromAValidFile", scene.c_str(), (int)scene.size()) ; root->init(ExecParams::defaultInstance()) ; UniformMassRigid* mass = root->getTreeObject<UniformMassRigid>() ; EXPECT_TRUE( mass != nullptr ) ; if(mass!=nullptr){ EXPECT_EQ( mass->getMass(), 40.0 ) ; EXPECT_EQ( mass->getTotalMass(), 80.0 ) ; } }
void SetUp() { setSimulation(m_simu = new DAGSimulation()); m_node = m_simu->createNewGraph("root"); m_thisObject = New<ThisClass>() ; m_mecaobject = New<MechanicalObject<DataTypes>>() ; m_mecaobject->init() ; m_node->addObject(m_mecaobject) ; m_node->addObject(m_thisObject) ; }
/// Delete a scene from memory. After this call the pointer is invalid void Simulation::unload(Node::SPtr root) { if ( !root ) return; sofa::core::ExecParams* params = sofa::core::ExecParams::defaultInstance(); //if (dynamic_cast<Node*>(this->getContext()) == root) //{ // this->setContext(NULL); //} root->detachFromGraph(); root->execute<CleanupVisitor>(params); root->execute<DeleteVisitor>(params); }
void QSofaListView::RemoveNode() { if( object_.type == typeNode) { emit Lock(true); Node::SPtr node = object_.ptr.Node; if ( node == node->getRoot() ) { if ( QMessageBox::warning ( this, "Removing root", "root node cannot be removed" ) ) return; } else { node->detachFromGraph(); node->execute<simulation::DeleteVisitor>(sofa::core::ExecParams::defaultInstance()); emit NodeRemoved(); } emit Lock(false); } }
/** * @brief Diamond-shaped graph: \f$ \begin{array}{ccc} & R & \\ \diagup & & \diagdown \\ A & & B \\ \diagdown & & \diagup \\ & C \end{array} \f$ Expected output: RABCCBAR */ void traverse_simple_diamond() { Node::SPtr root = clearScene(); root->setName("R"); Node::SPtr A = root->createChild("A"); Node::SPtr B = root->createChild("B"); Node::SPtr C = A->createChild("C"); B->addChild(C); traverse_test( root, "RACCABBR", "RACCABCCBR", "RACCABCCBR", "RABC" ); }
/// if masses are negative we refuse them and use the default values. void checkNegativeMassNotAllowed(){ string scene = "<?xml version='1.0'?>" "<Node name='Root' gravity='0 0 0' time='0' animate='0' > " " <MechanicalObject position='0 0 0 4 5 6'/> " " <UniformMass name='m_mass' totalmass='-1.0' mass=-3.0/> " "</Node> " ; Node::SPtr root = SceneLoaderXML::loadFromMemory ("loadWithNoParam", scene.c_str(), scene.size()) ; root->init(ExecParams::defaultInstance()) ; TheUniformMass* mass = root->getTreeObject<TheUniformMass>() ; EXPECT_TRUE( mass != nullptr ) ; if(mass!=nullptr){ EXPECT_EQ( mass->getMass(), 1.0 ) ; EXPECT_EQ( mass->getTotalMass(), 2.0 ) ; } }
/// It is important to freeze what are the available Data field /// of a component and rise warning/errors when some one removed. /// void attributesTests(){ m_node = m_root->createChild("node") ; m_mass = New< TheUniformMass >() ; m_node->addObject(m_mass) ; EXPECT_TRUE( m_mass->findData("mass") != nullptr ) ; EXPECT_TRUE( m_mass->findData("totalmass") != nullptr ) ; EXPECT_TRUE( m_mass->findData("filename") != nullptr ) ; EXPECT_TRUE( m_mass->findData("localRange") != nullptr ) ; EXPECT_TRUE( m_mass->findData("showGravityCenter") != nullptr ) ; EXPECT_TRUE( m_mass->findData("showAxisSizeFactor") != nullptr ) ; EXPECT_TRUE( m_mass->findData("showInitialCenterOfGravity") != nullptr ) ; EXPECT_TRUE( m_mass->findData("indices") != nullptr ) ; EXPECT_TRUE( m_mass->findData("handleTopoChange") != nullptr ) ; EXPECT_TRUE( m_mass->findData("preserveTotalMass") != nullptr ) ; EXPECT_TRUE( m_mass->findData("compute_mapping_inertia") != nullptr ) ; EXPECT_TRUE( m_mass->findData("totalMass") != nullptr ) ; return ; }
int TestDefaultPipeLine::checkDefaultPipelineWithMonkeyValueForDepth(int dvalue) { std::stringstream scene ; scene << "<?xml version='1.0'?> \n" "<Node name='Root' gravity='0 -9.81 0' time='0' animate='0' > \n" " <DefaultPipeline name='pipeline' depth='"<< dvalue <<"'/> \n" " <DiscreteIntersection name='interaction'/> \n" "</Node> \n" ; Node::SPtr root = SceneLoaderXML::loadFromMemory ("testscene", scene.str().c_str(), scene.str().size()) ; //EXPECT_NE( (root.get()), NULL) ; root->init(ExecParams::defaultInstance()) ; DefaultPipeline* clp = dynamic_cast<DefaultPipeline*>(root->getObject("pipeline")) ; //ASSERT_NE( (clp), nullptr) ; int rv = clp->d_depth.getValue() ; clearSceneGraph(); return rv; }
void QSofaListView::RemoveNode() { if( object_.type == typeNode) { emit Lock(true); Node* node = object_.ptr.Node; if ( node == node->getRoot() ) { //Attempt to destroy the Root node : create an empty node to handle new graph interaction Node::SPtr root = simulation::getSimulation()->createNewGraph( "Root" ); graphListener_->removeChild ( NULL, node); graphListener_->addChild ( NULL, root.get() ); emit RootNodeChanged(root.get(),NULL); } else { node->detachFromGraph(); node->execute<simulation::DeleteVisitor>(sofa::core::ExecParams::defaultInstance()); emit NodeRemoved(); } emit Lock(false); } }
void TestDefaultPipeLine::checkDefaultPipelineWithMissingIntersection() { EXPECT_MSG_EMIT(Warning) ; EXPECT_MSG_NOEMIT(Error) ; std::stringstream scene ; scene << "<?xml version='1.0'?> \n" "<Node name='Root' gravity='0 -9.81 0' time='0' animate='0' > \n" " <DefaultPipeline name='pipeline'/> \n" "</Node> \n" ; Node::SPtr root = SceneLoaderXML::loadFromMemory ("testscene", scene.str().c_str(), scene.str().size()) ; ASSERT_NE(root.get(), nullptr) ; root->init(ExecParams::defaultInstance()) ; BaseObject* clp = root->getObject("pipeline") ; ASSERT_NE(clp, nullptr) ; clearSceneGraph(); }
Node::SPtr createCard(Node::SPtr parent, const Coord3& position, const Coord3& rotation) { const std::string visualModel="mesh/card.obj"; const std::string collisionModel="mesh/cardCollision.obj"; const std::string inertiaMatrix="BehaviorModels/card.rigid"; static int colorIdx=0; std::vector<std::string> modelTypes; modelTypes.push_back("Triangle"); modelTypes.push_back("Line"); modelTypes.push_back("Point"); Node::SPtr card = sofa::modeling::createEulerSolverNode(parent,"Rigid","Implicit"); sofa::component::odesolver::EulerImplicitSolver *odeSolver; card->get(odeSolver); odeSolver->f_rayleighStiffness.setValue(0.1); odeSolver->f_rayleighMass.setValue(0.1); CGLinearSolverGraph *cgLinearSolver; card->get(cgLinearSolver); cgLinearSolver->f_maxIter.setValue(15); cgLinearSolver->f_tolerance.setValue(1e-5); cgLinearSolver->f_smallDenominatorThreshold.setValue(1e-5); sofa::component::constraintset::LMConstraintSolver::SPtr constraintSolver = sofa::core::objectmodel::New<sofa::component::constraintset::LMConstraintSolver>(); constraintSolver->constraintVel.setValue(true); constraintSolver->constraintPos.setValue(true); constraintSolver->numIterations.setValue(25); card->addObject(constraintSolver); MechanicalObjectRigid3::SPtr dofRigid = sofa::core::objectmodel::New<MechanicalObjectRigid3>(); dofRigid->setName("Rigid Object"); dofRigid->setTranslation(position[0],position[1],position[2]); dofRigid->setRotation(rotation[0],rotation[1],rotation[2]); card->addObject(dofRigid); UniformMassRigid3::SPtr uniMassRigid = sofa::core::objectmodel::New<UniformMassRigid3>(); uniMassRigid->setTotalMass(0.5); uniMassRigid->setFileMass(inertiaMatrix); card->addObject(uniMassRigid); //Node VISUAL Node::SPtr RigidVisualNode = sofa::modeling::createVisualNodeRigid(card, dofRigid.get(), visualModel,colors[(colorIdx++)%7]); //Node COLLISION Node::SPtr RigidCollisionNode = sofa::modeling::createCollisionNodeRigid(card, dofRigid.get(),collisionModel,modelTypes); return card; }