GNode.cpp

Go to the documentation of this file.
00001 /******************************************************************************
00002 *       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 3      *
00003 *                (c) 2006-2008 MGH, INRIA, USTL, UJF, CNRS                    *
00004 *                                                                             *
00005 * This library is free software; you can redistribute it and/or modify it     *
00006 * under the terms of the GNU Lesser General Public License as published by    *
00007 * the Free Software Foundation; either version 2.1 of the License, or (at     *
00008 * your option) any later version.                                             *
00009 *                                                                             *
00010 * This library is distributed in the hope that it will be useful, but WITHOUT *
00011 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
00012 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
00013 * for more details.                                                           *
00014 *                                                                             *
00015 * You should have received a copy of the GNU Lesser General Public License    *
00016 * along with this library; if not, write to the Free Software Foundation,     *
00017 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
00018 *******************************************************************************
00019 *                               SOFA :: Modules                               *
00020 *                                                                             *
00021 * Authors: The SOFA Team and external contributors (see Authors.txt)          *
00022 *                                                                             *
00023 * Contact information: contact@sofa-framework.org                             *
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; // we are the root, search down from here.
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; // we are the root, search down from here.
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             // remove time from calling action log
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     // return this->topology;
00415     // CHANGE 12/01/06 (Jeremie A.): Inherit parent topology if no local topology is defined
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     // return this->mechanicalModel;
00450     // CHANGE 12/01/06 (Jeremie A.): Inherit parent mechanical model if no local model is defined
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); //only display gravity for the root: it will be propagated at each time step
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         //cerr<<"node "<<getName()<<", copy context, time = "<<getTime()<<endl;
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     // make sure we don't add the same listener twice
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 } // namespace tree
00635 
00636 } // namespace simulation
00637 
00638 } // namespace sofa
00639 

Generated on Sun Nov 23 04:05:48 2008 for Sofa by  doxygen 1.5.7.1