00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <sofa/simulation/tree/GNode.h>
00026 #include <sofa/simulation/common/Visitor.h>
00027 #include <sofa/simulation/common/DesactivatedNodeVisitor.h>
00028 #include <sofa/simulation/tree/MutationListener.h>
00029 #include <iostream>
00030
00031 using std::cerr;
00032 using std::endl;
00033
00034 namespace sofa
00035 {
00036
00037 namespace simulation
00038 {
00039
00040 namespace tree
00041 {
00042
00043 using helper::system::thread::CTime;
00044 using namespace sofa::core::objectmodel;
00045
00046 GNode::GNode(const std::string& name, GNode* parent)
00047 : simulation::Node(name)
00048 {
00049 if( parent )
00050 parent->addChild(this);
00051 }
00052
00053 GNode::~GNode()
00054 {}
00055
00057 void GNode::doAddChild(GNode* node)
00058 {
00059 child.add(node);
00060 node->parent.add(this);
00061 }
00062
00064 void GNode::doRemoveChild(GNode* node)
00065 {
00066 child.remove(node);
00067 node->parent.remove(this);
00068 }
00069
00071 void GNode::addChild(GNode* node)
00072 {
00073 notifyAddChild(node);
00074 doAddChild(node);
00075 }
00076
00078 void GNode::removeChild(GNode* node)
00079 {
00080 notifyRemoveChild(node);
00081 doRemoveChild(node);
00082 }
00083
00085 void GNode::addChild(core::objectmodel::BaseNode* node)
00086 {
00087 this->addChild(dynamic_cast<GNode*>(node));
00088 }
00089
00091 void GNode::removeChild(core::objectmodel::BaseNode* node)
00092 {
00093 this->removeChild(dynamic_cast<GNode*>(node));
00094 }
00095
00097 void GNode::moveChild(GNode* node)
00098 {
00099 GNode* prev = node->parent;
00100 if (prev==NULL)
00101 {
00102 addChild(node);
00103 }
00104 else
00105 {
00106 notifyMoveChild(node,prev);
00107 prev->doRemoveChild(node);
00108 doAddChild(node);
00109 }
00110 }
00111
00112
00113
00117 void* GNode::getObject(const sofa::core::objectmodel::ClassInfo& class_info, SearchDirection dir) const
00118 {
00119 if (dir == SearchRoot)
00120 {
00121 if (parent != NULL) return parent->getObject(class_info, dir);
00122 else dir = SearchDown;
00123 }
00124 void *result = NULL;
00125 for (ObjectIterator it = this->object.begin(); it != this->object.end(); ++it)
00126 {
00127 result = class_info.dynamicCast(*it);
00128 if (result != NULL) break;
00129 }
00130 if (result == NULL)
00131 {
00132 switch(dir)
00133 {
00134 case Local:
00135 break;
00136 case SearchUp:
00137 if (parent) result = parent->getObject(class_info, dir);
00138 break;
00139 case SearchDown:
00140 for(ChildIterator it = child.begin(); it != child.end(); ++it)
00141 {
00142 result = (*it)->getObject(class_info, dir);
00143 if (result != NULL) break;
00144 }
00145 break;
00146 case SearchRoot:
00147 std::cerr << "SearchRoot SHOULD NOT BE POSSIBLE HERE!\n";
00148 break;
00149 }
00150 }
00151 return result;
00152 }
00153
00157 void* GNode::getObject(const sofa::core::objectmodel::ClassInfo& class_info, const std::string& path) const
00158 {
00159 if (path.empty())
00160 {
00161 return getObject(class_info, Local);
00162 }
00163 else if (path[0] == '/')
00164 {
00165 if (parent) return parent->getObject(class_info, path);
00166 else return getObject(class_info,std::string(path,1));
00167 }
00168 else if (std::string(path,0,2)==std::string("./"))
00169 {
00170 std::string newpath = std::string(path, 2);
00171 while (!newpath.empty() && path[0] == '/')
00172 newpath.erase(0);
00173 return simulation::Node::getObject(newpath);
00174 }
00175 else if (std::string(path,0,3)==std::string("../"))
00176 {
00177 std::string newpath = std::string(path, 3);
00178 while (!newpath.empty() && path[0] == '/')
00179 newpath.erase(0);
00180 if (parent) return parent->simulation::Node::getObject(newpath);
00181 else return simulation::Node::getObject(newpath);
00182 }
00183 else
00184 {
00185 std::string::size_type pend = path.find('/');
00186 if (pend == std::string::npos) pend = path.length();
00187 std::string name ( path, 0, pend );
00188 GNode* child = getChild(name);
00189 if (child)
00190 {
00191 while (pend < path.length() && path[pend] == '/')
00192 ++pend;
00193 return child->getObject(class_info, std::string(path, pend));
00194 }
00195 else if (pend < path.length())
00196 {
00197 std::cerr << "ERROR: child node "<<name<<" not found in "<<getPathName()<<std::endl;
00198 return NULL;
00199 }
00200 else
00201 {
00202 core::objectmodel::BaseObject* obj = simulation::Node::getObject(name);
00203 if (obj == NULL)
00204 {
00205 std::cerr << "ERROR: object "<<name<<" not found in "<<getPathName()<<std::endl;
00206 return NULL;
00207 }
00208 else
00209 {
00210 void* result = class_info.dynamicCast(obj);
00211 if (result == NULL)
00212 {
00213 std::cerr << "ERROR: object "<<name<<" in "<<getPathName()<<" does not implement class "<<class_info.name()<<std::endl;
00214 return NULL;
00215 }
00216 else
00217 {
00218 return result;
00219 }
00220 }
00221 }
00222 }
00223 }
00224
00225
00229 void GNode::getObjects(const sofa::core::objectmodel::ClassInfo& class_info, GetObjectsCallBack& container, SearchDirection dir) const
00230 {
00231 if (dir == SearchRoot)
00232 {
00233 if (parent != NULL)
00234 {
00235 if (parent->isActive())
00236 {
00237 parent->getObjects(class_info, container, dir);
00238 return;
00239 }
00240 else return;
00241 }
00242 else dir = SearchDown;
00243 }
00244 for (ObjectIterator it = this->object.begin(); it != this->object.end(); ++it)
00245 {
00246 void* result = class_info.dynamicCast(*it);
00247 if (result != NULL)
00248 container(result);
00249 }
00250
00251 {
00252 switch(dir)
00253 {
00254 case Local:
00255 break;
00256 case SearchUp:
00257 if (parent) parent->getObjects(class_info, container, dir);
00258 break;
00259 case SearchDown:
00260 for(ChildIterator it = child.begin(); it != child.end() && (*it)->isActive(); ++it)
00261 {
00262 (*it)->getObjects(class_info, container, dir);
00263 }
00264 break;
00265 case SearchRoot:
00266 std::cerr << "SearchRoot SHOULD NOT BE POSSIBLE HERE!\n";
00267 break;
00268 }
00269 }
00270 }
00271
00272
00273
00274
00276 core::objectmodel::BaseNode* GNode::getParent()
00277 {
00278 return parent;
00279 }
00280
00282 const core::objectmodel::BaseNode* GNode::getParent() const
00283 {
00284 return parent;
00285 }
00286
00288 sofa::helper::vector< core::objectmodel::BaseNode* > GNode::getChildren()
00289 {
00290 sofa::helper::vector< core::objectmodel::BaseNode* > list_children;
00291 for (ChildIterator it = child.begin(), itend = child.end(); it != itend; ++it)
00292 {
00293 list_children.push_back((*it));
00294 }
00295 return list_children;
00296 }
00297
00299 const sofa::helper::vector< core::objectmodel::BaseNode* > GNode::getChildren() const
00300 {
00301 sofa::helper::vector< core::objectmodel::BaseNode* > list_children;
00302 for (ChildIterator it = child.begin(), itend = child.end(); it != itend; ++it)
00303 {
00304 list_children.push_back((*it));
00305 }
00306 return list_children;
00307 }
00308
00309
00310
00313 void GNode::doExecuteVisitor(simulation::Visitor* action)
00314 {
00315 if (getLogTime())
00316 {
00317 const ctime_t t0 = CTime::getTime();
00318 ctime_t tChild = 0;
00319 actionStack.push(action);
00320 if(action->processNodeTopDown(this) != simulation::Visitor::RESULT_PRUNE) {
00321 ctime_t ct0 = CTime::getTime();
00322 for(ChildIterator it = child.begin(); it != child.end(); ++it) {
00323 (*it)->executeVisitor(action);
00324 }
00325 tChild = CTime::getTime() - ct0;
00326 }
00327 action->processNodeBottomUp(this);
00328 actionStack.pop();
00329 ctime_t tTree = CTime::getTime() - t0;
00330 ctime_t tNode = tTree - tChild;
00331 if (actionStack.empty())
00332 {
00333 totalTime.tNode += tNode;
00334 totalTime.tTree += tTree;
00335 ++totalTime.nVisit;
00336 }
00337 NodeTimer& t = actionTime[action->getCategoryName()];
00338 t.tNode += tNode;
00339 t.tTree += tTree;
00340 ++t.nVisit;
00341 if (!actionStack.empty())
00342 {
00343
00344 simulation::Visitor* prev = actionStack.top();
00345 NodeTimer& t = actionTime[prev->getCategoryName()];
00346 t.tNode -= tTree;
00347 t.tTree -= tTree;
00348 }
00349 }
00350 else
00351 {
00352 if(action->processNodeTopDown(this) != simulation::Visitor::RESULT_PRUNE)
00353 {
00354 for(unsigned int i = 0; i<child.size(); ++i)
00355 {
00356 child[i]->executeVisitor(action);
00357 }
00358 }
00359 action->processNodeBottomUp(this);
00360 }
00361 }
00362
00363
00365 GNode* GNode::getChild(const std::string& name) const
00366 {
00367 for (ChildIterator it = child.begin(), itend = child.end(); it != itend; ++it)
00368 if ((*it)->getName() == name)
00369 return *it;
00370 return NULL;
00371 }
00372
00374 GNode* GNode::getTreeNode(const std::string& name) const
00375 {
00376 GNode* result = NULL;
00377 result = getChild(name);
00378 for (ChildIterator it = child.begin(), itend = child.end(); result == NULL && it != itend; ++it)
00379 result = (*it)->getTreeNode(name);
00380 return result;
00381 }
00382
00383 void GNode::notifyAddChild(GNode* node)
00384 {
00385 for (Sequence<MutationListener>::iterator it = listener.begin(); it != listener.end(); ++it)
00386 (*it)->addChild(this, node);
00387 }
00388
00389 void GNode::notifyRemoveChild(GNode* node)
00390 {
00391 for (Sequence<MutationListener>::iterator it = listener.begin(); it != listener.end(); ++it)
00392 (*it)->removeChild(this, node);
00393 }
00394
00395 void GNode::notifyMoveChild(GNode* node, GNode* prev)
00396 {
00397 for (Sequence<MutationListener>::iterator it = listener.begin(); it != listener.end(); ++it)
00398 (*it)->moveChild(prev, this, node);
00399 }
00400
00402 std::string GNode::getPathName() const
00403 {
00404 std::string str;
00405 if (parent!=NULL) str = parent->getPathName();
00406 str += '/';
00407 str += getName();
00408 return str;
00409 }
00410
00412 core::componentmodel::topology::Topology* GNode::getTopology() const
00413 {
00414
00415
00416 if (this->topology)
00417 return this->topology;
00418 else if (parent)
00419 return parent->getTopology();
00420 else
00421 return NULL;
00422 }
00423
00425 core::componentmodel::topology::BaseMeshTopology* GNode::getMeshTopology() const
00426 {
00427 if (this->meshTopology)
00428 return this->meshTopology;
00429 else if (parent)
00430 return parent->getMeshTopology();
00431 else
00432 return NULL;
00433 }
00434
00436 core::objectmodel::BaseObject* GNode::getShader() const
00437 {
00438 if (shader)
00439 return shader;
00440 else if (parent)
00441 return parent->getShader();
00442 else
00443 return NULL;
00444 }
00445
00447 core::objectmodel::BaseObject* GNode::getMechanicalState() const
00448 {
00449
00450
00451 if (this->mechanicalState)
00452 return this->mechanicalState;
00453 else if (parent)
00454 return parent->getMechanicalState();
00455 else
00456 return NULL;
00457 }
00458
00460 void GNode::reinit()
00461 {
00462 sofa::simulation::DesactivationVisitor desactivate(isActive());
00463 desactivate.execute( this );
00464 }
00465
00466
00467 void GNode::initVisualContext()
00468 {
00469 if (getParent() != NULL)
00470 {
00471 this->worldGravity_.setDisplayed(false);
00472 if (showVisualModels_.getValue() == -1)
00473 showVisualModels_.setValue(static_cast<GNode *>(getParent())->showVisualModels_.getValue());
00474 if (showBehaviorModels_.getValue() == -1)
00475 showBehaviorModels_.setValue(static_cast<GNode *>(getParent())->showBehaviorModels_.getValue());
00476 if (showCollisionModels_.getValue() == -1)
00477 showCollisionModels_.setValue(static_cast<GNode *>(getParent())->showCollisionModels_.getValue());
00478 if (showBoundingCollisionModels_.getValue() == -1)
00479 showBoundingCollisionModels_.setValue(static_cast<GNode *>(getParent())->showBoundingCollisionModels_.getValue());
00480 if (showMappings_.getValue() == -1)
00481 showMappings_.setValue(static_cast<GNode *>(getParent())->showMappings_.getValue());
00482 if (showMechanicalMappings_.getValue() == -1)
00483 showMechanicalMappings_.setValue(static_cast<GNode *>(getParent())->showMechanicalMappings_.getValue());
00484 if (showForceFields_.getValue() == -1)
00485 showForceFields_.setValue(static_cast<GNode *>(getParent())->showForceFields_.getValue());
00486 if (showInteractionForceFields_.getValue() == -1)
00487 showInteractionForceFields_.setValue(static_cast<GNode *>(getParent())->showInteractionForceFields_.getValue());
00488 if (showWireFrame_.getValue() == -1)
00489 showWireFrame_.setValue(static_cast<GNode *>(getParent())->showWireFrame_.getValue());
00490 if (showNormals_.getValue() == -1)
00491 showNormals_.setValue(static_cast<GNode *>(getParent())->showNormals_.getValue());
00492 }
00493 }
00494
00495 void GNode::updateContext()
00496 {
00497 if ( getParent() != NULL )
00498 {
00499 copyContext(*parent);
00500
00501 }
00502 simulation::Node::updateContext();
00503 }
00504
00505 void GNode::updateSimulationContext()
00506 {
00507 if ( getParent() != NULL )
00508 {
00509 copySimulationContext(*parent);
00510 }
00511 simulation::Node::updateSimulationContext();
00512 }
00513
00514 void GNode::updateVisualContext(int FILTER)
00515 {
00516 if ( getParent() != NULL )
00517 {
00518 if (FILTER==10)
00519 copyVisualContext(*parent);
00520 else
00521 {
00522 switch (FILTER)
00523 {
00524 case 0:
00525 showVisualModels_.setValue((*parent).showVisualModels_.getValue());
00526 break;
00527 case 1:
00528 showBehaviorModels_.setValue((*parent).showBehaviorModels_.getValue());
00529 break;
00530 case 2:
00531 showCollisionModels_.setValue((*parent).showCollisionModels_.getValue());
00532 break;
00533 case 3:
00534 showBoundingCollisionModels_.setValue((*parent).showBoundingCollisionModels_.getValue());
00535 break;
00536 case 4:
00537 showMappings_.setValue((*parent).showMappings_.getValue());
00538 break;
00539 case 5:
00540 showMechanicalMappings_.setValue((*parent).showMechanicalMappings_.getValue());
00541 break;
00542 case 6:
00543 showForceFields_.setValue((*parent).showForceFields_.getValue());
00544 break;
00545 case 7:
00546 showInteractionForceFields_.setValue((*parent).showInteractionForceFields_.getValue());
00547 break;
00548 case 8:
00549 showWireFrame_.setValue((*parent).showWireFrame_.getValue());
00550 break;
00551 case 9:
00552 showNormals_.setValue((*parent).showNormals_.getValue());
00553 break;
00554 }
00555 }
00556 }
00557 simulation::Node::updateVisualContext(FILTER);
00558 }
00559
00561 void GNode::addTime(ctime_t t, const std::string& s, core::objectmodel::BaseObject* obj, core::objectmodel::BaseObject* parent)
00562 {
00563 ObjectTimer& timer = objectTime[s][obj];
00564 timer.tObject += t;
00565 ++ timer.nVisit;
00566 objectTime[s][parent].tObject -= t;
00567 }
00568
00570 GNode::ctime_t GNode::endTime(ctime_t t0, const std::string& s, core::objectmodel::BaseObject* obj, core::objectmodel::BaseObject* parent)
00571 {
00572 if (!getLogTime()) return 0;
00573 const ctime_t t1 = CTime::getTime();
00574 const ctime_t t = t1 - t0;
00575 addTime(t, s, obj, parent);
00576 return t1;
00577 }
00578
00580 void GNode::addTime(ctime_t t, const std::string& s, core::objectmodel::BaseObject* obj)
00581 {
00582 ObjectTimer& timer = objectTime[s][obj];
00583 timer.tObject += t;
00584 ++ timer.nVisit;
00585 }
00586
00588 GNode::ctime_t GNode::endTime(ctime_t t0, const std::string& s, core::objectmodel::BaseObject* obj)
00589 {
00590 if (!getLogTime()) return 0;
00591 const ctime_t t1 = CTime::getTime();
00592 const ctime_t t = t1 - t0;
00593 addTime(t, s, obj);
00594 return t1;
00595 }
00596
00597 void GNode::addListener(MutationListener* obj)
00598 {
00599
00600 Sequence< MutationListener >::iterator it = listener.begin();
00601 while (it != listener.end() && (*it)!=obj)
00602 ++it;
00603 if (it == listener.end())
00604 listener.add(obj);
00605 }
00606
00607 void GNode::removeListener(MutationListener* obj)
00608 {
00609 listener.remove(obj);
00610 }
00611
00612 void GNode::notifyAddObject(core::objectmodel::BaseObject* obj)
00613 {
00614 for (Sequence<MutationListener>::iterator it = listener.begin(); it != listener.end(); ++it)
00615 (*it)->addObject(this, obj);
00616 }
00617
00618 void GNode::notifyRemoveObject(core::objectmodel::BaseObject* obj)
00619 {
00620 for (Sequence<MutationListener>::iterator it = listener.begin(); it != listener.end(); ++it)
00621 (*it)->removeObject(this, obj);
00622 }
00623
00624 void GNode::notifyMoveObject(core::objectmodel::BaseObject* obj, GNode* prev)
00625 {
00626 for (Sequence<MutationListener>::iterator it = listener.begin(); it != listener.end(); ++it)
00627 (*it)->moveObject(prev, this, obj);
00628 }
00629
00630 SOFA_DECL_CLASS(GNode)
00631
00632 helper::Creator<xml::NodeElement::Factory, GNode> GNodeClass("default");
00633
00634 }
00635
00636 }
00637
00638 }
00639