Node.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 //
00026 // C++ Implementation: Node
00027 //
00028 // Description:
00029 //
00030 //
00031 // Author: The SOFA team </www.sofa-framework.org>, (C) 2008
00032 //
00033 // Copyright: See COPYING file that comes with this distribution
00034 //
00035 //
00036 #include "Node.h"
00037 #include <sofa/simulation/common/PropagateEventVisitor.h>
00038 #include <sofa/simulation/common/AnimateVisitor.h>
00039 #include <sofa/simulation/common/DesactivatedNodeVisitor.h>
00040 #include <sofa/simulation/common/InitVisitor.h>
00041 #include <sofa/simulation/common/VisualVisitor.h>
00042 #include <sofa/simulation/common/UpdateMappingVisitor.h>
00043 #include <iostream>
00044 using std::cerr;
00045 using std::endl;
00046 
00047 #include <boost/graph/adjacency_list.hpp>
00048 //#include <sofa/core/objectmodel/BaseObject.h>
00049 #include <boost/graph/topological_sort.hpp>
00050 
00051 
00052 namespace sofa
00053 {
00054 
00055 namespace simulation
00056 {
00057 using core::objectmodel::BaseObject;
00058 using helper::system::thread::CTime;
00059 
00060 Node::Node(const std::string& name)
00061         : sofa::core::objectmodel::Context()
00062         , debug_(false), logTime_(false)
00063         , depend(initData(&depend,"depend","Dependencies between the nodes.\nname 1 name 2 name3 name4 means that name1 must be initialized before name2 and name3 before name4"))
00064 {
00065     _context = this;
00066     totalTime.nVisit = 0;
00067     totalTime.tNode = 0;
00068     totalTime.tTree = 0;
00069     setName(name);
00070 }
00071 
00072 
00073 Node::~Node()
00074 {
00075 }
00076 
00078 void Node::init()
00079 {
00080     //cerr<<"Node::init() begin node "<<getName()<<endl;
00081     execute<simulation::InitVisitor>();
00082     //cerr<<"Node::init() end node "<<getName()<<endl;
00083 }
00084 
00086 void Node::reinit()
00087 {
00088     sofa::simulation::DesactivationVisitor desactivate(isActive());
00089     desactivate.execute( this );
00090 }
00091 
00093 void Node::animate( double dt )
00094 {
00095     simulation::AnimateVisitor vis(dt);
00096     //cerr<<"Node::animate, start execute"<<endl;
00097     execute(vis);
00098     //cerr<<"Node::animate, end execute"<<endl;
00099     execute<simulation::UpdateMappingVisitor>();
00100 }
00101 
00102 void Node::glDraw()
00103 {
00104     execute<simulation::VisualUpdateVisitor>();
00105     execute<simulation::VisualDrawVisitor>();
00106 }
00107 
00108 
00109 
00110 
00111 
00113 bool Node::addObject(BaseObject* obj)
00114 {
00115     notifyAddObject(obj);
00116     doAddObject(obj);
00117     return true;
00118 }
00119 
00121 bool Node::removeObject(BaseObject* obj)
00122 {
00123     notifyRemoveObject(obj);
00124     doRemoveObject(obj);
00125     return true;
00126 }
00127 
00129 void Node::moveObject(BaseObject* obj)
00130 {
00131     Node* prev = dynamic_cast<Node*>(obj->getContext());
00132     if (prev==NULL)
00133     {
00134         obj->getContext()->removeObject(obj);
00135         addObject(obj);
00136     }
00137     else
00138     {
00139         notifyMoveObject(obj,prev);
00140         prev->doRemoveObject(obj);
00141         doAddObject(obj);
00142     }
00143 }
00144 
00146 core::objectmodel::BaseObject* Node::getObject(const std::string& name) const
00147 {
00148     for (ObjectIterator it = object.begin(), itend = object.end(); it != itend; ++it)
00149         if ((*it)->getName() == name)
00150             return *it;
00151     return NULL;
00152 }
00153 
00154 
00155 
00157 void Node::doAddObject(BaseObject* obj)
00158 {
00159     notifyAddObject(obj);
00160     obj->setContext(this);
00161     object.add(obj);
00162     int inserted=0;
00163     inserted+= masterSolver.add(dynamic_cast< core::componentmodel::behavior::MasterSolver* >(obj));
00164     inserted+= solver.add(dynamic_cast< core::componentmodel::behavior::OdeSolver* >(obj));
00165     inserted+= linearSolver.add(dynamic_cast< core::componentmodel::behavior::LinearSolver* >(obj));
00166     inserted+= mechanicalState.add(dynamic_cast< core::componentmodel::behavior::BaseMechanicalState* >(obj));
00167     bool isMechanicalMapping = mechanicalMapping.add(dynamic_cast< core::componentmodel::behavior::BaseMechanicalMapping* >(obj));
00168     inserted+= isMechanicalMapping;
00169     if (!isMechanicalMapping)
00170         inserted+= mapping.add(dynamic_cast< core::BaseMapping* >(obj));
00171     inserted+= mass.add(dynamic_cast< core::componentmodel::behavior::BaseMass* >(obj));
00172     inserted+= topology.add(dynamic_cast< core::componentmodel::topology::Topology* >(obj));
00173     inserted+= meshTopology.add(dynamic_cast< core::componentmodel::topology::BaseMeshTopology* >(obj));
00174     inserted+= shader.add(dynamic_cast< sofa::core::Shader* >(obj));
00175 
00176     bool isInteractionForceField = interactionForceField.add(dynamic_cast< core::componentmodel::behavior::InteractionForceField* >(obj));
00177     inserted+= isInteractionForceField;
00178     if (!isInteractionForceField)
00179         forceField.add(dynamic_cast< core::componentmodel::behavior::BaseForceField* >(obj));
00180     inserted+= constraint.add(dynamic_cast< core::componentmodel::behavior::BaseConstraint* >(obj));
00181     inserted+= behaviorModel.add(dynamic_cast< core::BehaviorModel* >(obj));
00182     inserted+= visualModel.add(dynamic_cast< core::VisualModel* >(obj));
00183     inserted+= collisionModel.add(dynamic_cast< core::CollisionModel* >(obj));
00184     inserted+= contextObject.add(dynamic_cast< core::objectmodel::ContextObject* >(obj));
00185     inserted+= collisionPipeline.add(dynamic_cast< core::componentmodel::collision::Pipeline* >(obj));
00186     inserted+= actionScheduler.add(dynamic_cast< VisitorScheduler* >(obj));
00187 
00188     if ( inserted==0 )
00189     {
00190         //cerr<<"Node::doAddObject, object "<<obj->getName()<<" is unsorted"<<endl;
00191         unsorted.add(obj);
00192     }
00193 
00194 }
00195 
00197 void Node::doRemoveObject(BaseObject* obj)
00198 {
00199     if (obj->getContext()==this)
00200     {
00201         obj->setContext(NULL);
00202     }
00203     object.remove(obj);
00204     masterSolver.remove(dynamic_cast< core::componentmodel::behavior::MasterSolver* >(obj));
00205     solver.remove(dynamic_cast< core::componentmodel::behavior::OdeSolver* >(obj));
00206     linearSolver.remove(dynamic_cast< core::componentmodel::behavior::LinearSolver* >(obj));
00207     mechanicalState.remove(dynamic_cast< core::componentmodel::behavior::BaseMechanicalState* >(obj));
00208     mechanicalMapping.remove(dynamic_cast< core::componentmodel::behavior::BaseMechanicalMapping* >(obj));
00209     mass.remove(dynamic_cast< core::componentmodel::behavior::BaseMass* >(obj));
00210     topology.remove(dynamic_cast< core::componentmodel::topology::Topology* >(obj));
00211     meshTopology.remove(dynamic_cast< core::componentmodel::topology::BaseMeshTopology* >(obj));
00212     shader.remove(dynamic_cast<sofa::core::Shader* >(obj));
00213 
00214     forceField.remove(dynamic_cast< core::componentmodel::behavior::BaseForceField* >(obj));
00215     interactionForceField.remove(dynamic_cast< core::componentmodel::behavior::InteractionForceField* >(obj));
00216     constraint.remove(dynamic_cast< core::componentmodel::behavior::BaseConstraint* >(obj));
00217     mapping.remove(dynamic_cast< core::BaseMapping* >(obj));
00218     behaviorModel.remove(dynamic_cast< core::BehaviorModel* >(obj));
00219     visualModel.remove(dynamic_cast< core::VisualModel* >(obj));
00220     collisionModel.remove(dynamic_cast< core::CollisionModel* >(obj));
00221     contextObject.remove(dynamic_cast<core::objectmodel::ContextObject* >(obj));
00222     collisionPipeline.remove(dynamic_cast< core::componentmodel::collision::Pipeline* >(obj));
00223 
00224     actionScheduler.remove(dynamic_cast< VisitorScheduler* >(obj));
00225     // Remove references to this object in time log tables
00226     if (!objectTime.empty())
00227     {
00228         for (std::map<std::string, std::map<core::objectmodel::BaseObject*, ObjectTimer> >::iterator it = objectTime.begin(); it != objectTime.end(); ++it)
00229         {
00230             it->second.erase(obj);
00231         }
00232     }
00233 }
00234 
00235 
00236 
00238 core::componentmodel::topology::Topology* Node::getTopology() const
00239 {
00240     return this->topology;
00241 }
00242 
00244 core::componentmodel::topology::BaseMeshTopology* Node::getMeshTopology() const
00245 {
00246     return this->meshTopology;
00247 }
00248 
00250 core::objectmodel::BaseObject* Node::getShader() const
00251 {
00252     return shader;
00253 }
00254 
00256 core::objectmodel::BaseObject* Node::getMechanicalState() const
00257 {
00258     return this->mechanicalState;
00259 }
00260 
00261 
00262 void Node::setLogTime(bool b)
00263 {
00264     logTime_=b;
00265 }
00266 
00267 Node::ctime_t Node::getTimeFreq() const
00268 {
00269     return CTime::getTicksPerSec();
00270 }
00271 
00272 void Node::resetTime()
00273 {
00274     totalTime.nVisit = 0;
00275     totalTime.tNode = 0;
00276     totalTime.tTree = 0;
00277     actionTime.clear();
00278     objectTime.clear();
00279 }
00280 
00282 Node::ctime_t Node::startTime() const
00283 {
00284     if (!getLogTime()) return 0;
00285     return CTime::getTime();
00286 }
00287 
00289 void Node::addTime(ctime_t t, const std::string& s, core::objectmodel::BaseObject* obj)
00290 {
00291     ObjectTimer& timer = objectTime[s][obj];
00292     timer.tObject += t;
00293     ++ timer.nVisit;
00294 }
00295 
00297 Node::ctime_t Node::endTime(ctime_t t0, const std::string& s, core::objectmodel::BaseObject* obj)
00298 {
00299     if (!getLogTime()) return 0;
00300     const ctime_t t1 = CTime::getTime();
00301     const ctime_t t = t1 - t0;
00302     addTime(t, s, obj);
00303     return t1;
00304 }
00305 
00307 void Node::addTime(ctime_t t, const std::string& s, core::objectmodel::BaseObject* obj, core::objectmodel::BaseObject* /*parent*/)
00308 {
00309     ObjectTimer& timer = objectTime[s][obj];
00310     timer.tObject += t;
00311     ++ timer.nVisit;
00312     //objectTime[s][parent].tObject -= t;
00313     cerr<<"Warning: Node::addTime(ctime_t t, const std::string& s, core::objectmodel::BaseObject* obj, core::objectmodel::BaseObject* parent) does not remove the computed time from the parent caller object (parent is ndefined)"<<endl;
00314 }
00315 
00317 Node::ctime_t Node::endTime(ctime_t /*t0*/, const std::string& /*s*/, core::objectmodel::BaseObject* /*obj*/, core::objectmodel::BaseObject* /*parent*/)
00318 {
00319     if (!getLogTime()) return 0;
00320     const ctime_t t1 = CTime::getTime();
00321     //const ctime_t t = t1 - t0;
00322     //addTime(t, s, obj, parent);
00323     cerr<<"Warning: Node::endTime(ctime_t t0, const std::string& s, core::objectmodel::BaseObject* obj, core::objectmodel::BaseObject* parent) does not add parent time (parent is ndefined)"<<endl;
00324     return t1;
00325 }
00326 
00327 Node* Node::setDebug(bool b)
00328 {
00329     debug_=b;
00330     return this;
00331 }
00332 
00333 bool Node::getDebug() const
00334 {
00335     return debug_;
00336 }
00337 
00338 
00339 
00340 
00341 void Node::removeControllers()
00342 {
00343     removeObject(masterSolver);
00344     typedef Sequence<core::componentmodel::behavior::OdeSolver> Solvers;
00345     Solvers solverRemove = solver;
00346     for ( Solvers::iterator i=solverRemove.begin(), iend=solverRemove.end(); i!=iend; i++ )
00347         removeObject( *i );
00348 }
00349 
00350 
00351 core::objectmodel::BaseContext* Node::getContext()
00352 {
00353     return _context;
00354 }
00355 const core::objectmodel::BaseContext* Node::getContext() const
00356 {
00357     return _context;
00358 }
00359 
00360 // void Node::setContext( core::objectmodel::BaseContext* c )
00361 // {
00362 //     _context=c;
00363 //  for( ObjectIterator i=object.begin(), iend=object.end(); i!=iend; i++ )
00364 //      (*i)->setContext(c);
00365 // }
00366 
00367 
00368 void Node::setDefaultVisualContextValue()
00369 {
00370     if (showVisualModels_.getValue() == -1)            showVisualModels_.setValue(true);
00371     if (showBehaviorModels_.getValue() == -1)          showBehaviorModels_.setValue(false);
00372     if (showCollisionModels_.getValue() == -1)         showCollisionModels_.setValue(false);
00373     if (showBoundingCollisionModels_.getValue() == -1) showBoundingCollisionModels_.setValue(false);
00374     if (showMappings_.getValue() == -1)                showMappings_.setValue(false);
00375     if (showMechanicalMappings_.getValue() == -1)      showMechanicalMappings_.setValue(false);
00376     if (showForceFields_.getValue() == -1)             showForceFields_.setValue(false);
00377     if (showInteractionForceFields_.getValue() == -1)  showInteractionForceFields_.setValue(false);
00378     if (showWireFrame_.getValue() == -1)               showWireFrame_.setValue(false);
00379     if (showNormals_.getValue() == -1)                 showNormals_.setValue(false);
00380 }
00381 
00382 void Node::initialize()
00383 {
00384     //cerr<<"Node::initialize()"<<endl;
00385 
00386     initVisualContext();
00387     sortComponents();
00388 //     // Put the OdeSolver, if any, in first position. This makes sure that the OdeSolver component is initialized only when all its sibling and children components are already initialized.
00389 //     /// @todo Putting the solver first means that it will be initialized *before* any sibling or childrens. Is that what we want? -- Jeremie A.
00390 //     Sequence<BaseObject>::iterator i=object.begin(), iend=object.end();
00391 //     for ( ; i!=iend && dynamic_cast<core::componentmodel::behavior::OdeSolver*>(*i)==NULL; i++ ) // find the OdeSolver
00392 //         {}
00393 //     if ( i!=iend && !object.empty() ) // found
00394 //     {
00395 //         // put it first
00396 //         // BUGFIX 01/12/06 (Jeremie A.): do not modify the order of the other objects
00397 //         // object.swap( i, object.begin() );
00398 //         while (i!=object.begin())
00399 //         {
00400 //             Sequence<BaseObject>::iterator i2 = i;
00401 //             --i;
00402 //             object.swap(i, i2);
00403 //         }
00404 //     }
00405 
00406     //
00407     updateSimulationContext();
00408 
00409     // this is now done by the InitVisitor
00410     //for (Sequence<Node>::iterator it = child.begin(); it != child.end(); it++) {
00411     //    (*it)->init();
00412     //}
00413 }
00414 
00415 void Node::updateContext()
00416 {
00417     //if( debug_ ) cerr<<"Node::updateContext, node = "<<getName()<<", incoming context = "<< *this->getContext() << endl;
00418 
00419     // Apply local modifications to the context
00420     if (getLogTime())
00421     {
00422         for ( unsigned i=0; i<contextObject.size(); ++i )
00423         {
00424             contextObject[i]->init();
00425             contextObject[i]->apply();
00426             //cerr<<"Node::updateContext, modified by node = "<<contextObject[i]->getName()<< endl;
00427         }
00428     }
00429     else
00430     {
00431         for ( unsigned i=0; i<contextObject.size(); ++i )
00432         {
00433             contextObject[i]->init();
00434             contextObject[i]->apply();
00435             //cerr<<"Node::updateContext, modified by node = "<<contextObject[i]->getName()<<endl;
00436         }
00437     }
00438 //  if( !mechanicalModel.empty() ) {
00439 //      mechanicalModel->updateContext(&context_);
00440 //  }
00441 
00442 
00443     // project the gravity to the local coordinate system
00444     /*        getContext()->setGravity( getContext()->getLocalFrame().backProjectVector(getContext()->getWorldGravity()) );*/
00445 
00446     if ( debug_ ) std::cerr<<"Node::updateContext, node = "<<getName()<<", updated context = "<< *static_cast<core::objectmodel::Context*>(this) << endl;
00447 }
00448 
00449 void Node::updateSimulationContext()
00450 {
00451     // Apply local modifications to the context
00452     if (getLogTime())
00453     {
00454         for ( unsigned i=0; i<contextObject.size(); ++i )
00455         {
00456             contextObject[i]->init();
00457             contextObject[i]->apply();
00458         }
00459     }
00460     else
00461     {
00462         for ( unsigned i=0; i<contextObject.size(); ++i )
00463         {
00464             contextObject[i]->init();
00465             contextObject[i]->apply();
00466         }
00467     }
00468     if ( debug_ ) std::cerr<<"Node::updateSimulationContext, node = "<<getName()<<", updated context = "<< *static_cast<core::objectmodel::Context*>(this) << endl;
00469 }
00470 
00471 void Node::updateVisualContext(int/* FILTER*/)
00472 {
00473     // Apply local modifications to the context
00474     if (getLogTime())
00475     {
00476         for ( unsigned i=0; i<contextObject.size(); ++i )
00477         {
00478             contextObject[i]->init();
00479             contextObject[i]->apply();
00480         }
00481     }
00482     else
00483     {
00484         for ( unsigned i=0; i<contextObject.size(); ++i )
00485         {
00486             contextObject[i]->init();
00487             contextObject[i]->apply();
00488         }
00489     }
00490     if ( debug_ ) std::cerr<<"Node::updateVisualContext, node = "<<getName()<<", updated context = "<< *static_cast<core::objectmodel::Context*>(this) << endl;
00491 }
00492 
00494 void Node::executeVisitor(Visitor* action)
00495 {
00496     if (!this->is_activated.getValue()) return;
00497     if (actionScheduler)
00498         actionScheduler->executeVisitor(this,action);
00499     else
00500         doExecuteVisitor(action);
00501 }
00502 
00504 void Node::propagateEvent( core::objectmodel::Event* event )
00505 {
00506     simulation::PropagateEventVisitor act(event);
00507     this->executeVisitor(&act);
00508 }
00509 
00510 
00511 
00512 
00513 
00514 void Node::printComponents()
00515 {
00516     using namespace sofa::core::componentmodel::behavior;
00517     using core::BaseMapping;
00518     using core::componentmodel::topology::Topology;
00519     using core::componentmodel::topology::BaseTopology;
00520     using core::componentmodel::topology::BaseMeshTopology;
00521     using core::Shader;
00522     using core::BehaviorModel;
00523     using core::VisualModel;
00524     using core::CollisionModel;
00525     using core::objectmodel::ContextObject;
00526     using core::componentmodel::collision::Pipeline;
00527 
00528     cerr<<"MasterSolver: ";
00529     for ( Single<MasterSolver>::iterator i=masterSolver.begin(), iend=masterSolver.end(); i!=iend; i++ )
00530         cerr<<(*i)->getName()<<" ";
00531     cerr<<endl<<"OdeSolver: ";
00532     for ( Sequence<OdeSolver>::iterator i=solver.begin(), iend=solver.end(); i!=iend; i++ )
00533         cerr<<(*i)->getName()<<" ";
00534     cerr<<endl<<"LinearSolver: ";
00535     for ( Sequence<LinearSolver>::iterator i=linearSolver.begin(), iend=linearSolver.end(); i!=iend; i++ )
00536         cerr<<(*i)->getName()<<" ";
00537     cerr<<endl<<"InteractionForceField: ";
00538     for ( Sequence<InteractionForceField>::iterator i=interactionForceField.begin(), iend=interactionForceField.end(); i!=iend; i++ )
00539         cerr<<(*i)->getName()<<" ";
00540     cerr<<endl<<"ForceField: ";
00541     for ( Sequence<BaseForceField>::iterator i=forceField.begin(), iend=forceField.end(); i!=iend; i++ )
00542         cerr<<(*i)->getName()<<" ";
00543     cerr<<endl<<"State: ";
00544     for ( Single<BaseMechanicalState>::iterator i=mechanicalState.begin(), iend=mechanicalState.end(); i!=iend; i++ )
00545         cerr<<(*i)->getName()<<" ";
00546     cerr<<endl<<"Mechanical Mapping: ";
00547     for ( Single<BaseMechanicalMapping>::iterator i=mechanicalMapping.begin(), iend=mechanicalMapping.end(); i!=iend; i++ )
00548         cerr<<(*i)->getName()<<" ";
00549     cerr<<endl<<"Mapping: ";
00550     for ( Sequence<BaseMapping>::iterator i=mapping.begin(), iend=mapping.end(); i!=iend; i++ )
00551         cerr<<(*i)->getName()<<" ";
00552     cerr<<endl<<"Topology: ";
00553     for ( Single<Topology>::iterator i=topology.begin(), iend=topology.end(); i!=iend; i++ )
00554         cerr<<(*i)->getName()<<" ";
00555     cerr<<endl<<"MeshTopology: ";
00556     for ( Single<BaseMeshTopology>::iterator i=meshTopology.begin(), iend=meshTopology.end(); i!=iend; i++ )
00557         cerr<<(*i)->getName()<<" ";
00558     cerr<<endl<<"Shader: ";
00559     for ( Single<Shader>::iterator i=shader.begin(), iend=shader.end(); i!=iend; i++ )
00560         cerr<<(*i)->getName()<<" ";
00561     cerr<<endl<<"Constraint: ";
00562     for ( Sequence<BaseConstraint>::iterator i=constraint.begin(), iend=constraint.end(); i!=iend; i++ )
00563         cerr<<(*i)->getName()<<" ";
00564     cerr<<endl<<"BehaviorModel: ";
00565     for ( Sequence<BehaviorModel>::iterator i=behaviorModel.begin(), iend=behaviorModel.end(); i!=iend; i++ )
00566         cerr<<(*i)->getName()<<" ";
00567     cerr<<endl<<"VisualModel: ";
00568     for ( Sequence<VisualModel>::iterator i=visualModel.begin(), iend=visualModel.end(); i!=iend; i++ )
00569         cerr<<(*i)->getName()<<" ";
00570     cerr<<endl<<"CollisionModel: ";
00571     for ( Sequence<CollisionModel>::iterator i=collisionModel.begin(), iend=collisionModel.end(); i!=iend; i++ )
00572         cerr<<(*i)->getName()<<" ";
00573     cerr<<endl<<"ContextObject: ";
00574     for ( Sequence<ContextObject>::iterator i=contextObject.begin(), iend=contextObject.end(); i!=iend; i++ )
00575         cerr<<(*i)->getName()<<" ";
00576     cerr<<endl<<"Pipeline: ";
00577     for ( Single<Pipeline>::iterator i=collisionPipeline.begin(), iend=collisionPipeline.end(); i!=iend; i++ )
00578         cerr<<(*i)->getName()<<" ";
00579     cerr<<endl<<"VisitorScheduler: ";
00580     for ( Single<VisitorScheduler>::iterator i=actionScheduler.begin(), iend=actionScheduler.end(); i!=iend; i++ )
00581         cerr<<(*i)->getName()<<" ";
00582     cerr<<endl;
00583 }
00584 
00588 
00589 // Vertices
00590 struct component_t
00591 {
00592     typedef boost::vertex_property_tag kind;
00593 };
00594 typedef boost::property<component_t, BaseObject*> VertexProperty;
00595 
00596 // Graph
00597 typedef ::boost::adjacency_list < ::boost::vecS, ::boost::vecS, ::boost::bidirectionalS, VertexProperty > DependencyGraph;
00598 
00599 void Node::sortComponents()
00600 {
00601     typedef DependencyGraph::vertex_descriptor Vertex;
00602     DependencyGraph dependencyGraph;
00603     // map vertex->component
00604     boost::property_map<DependencyGraph, component_t>::type  component_from_vertex = boost::get( component_t(), dependencyGraph );
00605     // map component->vertex
00606     std::map<BaseObject*,Vertex> vertex_from_component;
00607 
00608     // build the graph
00609     for ( int i=object.size()-1; i>=0; i-- ) // in the reverse order for a final order more similar to the current one
00610     {
00611         Vertex v = add_vertex( dependencyGraph );
00612         component_from_vertex[v] = object[i];
00613         vertex_from_component[object[i]] = v;
00614     }
00615     assert( depend.getValue().size()%2 == 0 ); // must contain only pairs
00616     for ( unsigned i=0; i<depend.getValue().size(); i+=2 )
00617     {
00618         BaseObject* o1 = getObject( depend.getValue()[i] );
00619         BaseObject* o2 = getObject( depend.getValue()[i+1] );
00620         if ( o1==NULL ) cerr<<"Node::sortComponent, could not fin object called "<<depend.getValue()[i]<<endl;
00621         else if ( o2==NULL ) cerr<<"Node::sortComponent, could not fin object called "<<depend.getValue()[i+1]<<endl;
00622         else
00623         {
00624             boost::add_edge( vertex_from_component[o1], vertex_from_component[o2], dependencyGraph );
00625             //cerr<<"Node::sortComponents, added edge "<<o1->getName()<<" -> "<<o2->getName()<<endl;
00626         }
00627     }
00628 
00629     // sort the components according to the dependencies
00630     typedef std::vector< Vertex > container;
00631     container c;
00632     boost::topological_sort(dependencyGraph, std::back_inserter(c));
00633 
00634     // remove all the components
00635     for ( container::reverse_iterator ii=c.rbegin(); ii!=c.rend(); ++ii)
00636     {
00637         removeObject(component_from_vertex[*ii]);
00638     }
00639 
00640     // put the components in the right order
00641     //cerr << "Node::sortComponents, New component order: ";
00642     for ( container::reverse_iterator ii=c.rbegin(); ii!=c.rend(); ++ii)
00643     {
00644         addObject(component_from_vertex[*ii]);
00645         //cerr << component_from_vertex[*ii]->getName() << " ";
00646     }
00647     //cerr << endl;
00648 }
00649 
00650 
00651 }
00652 
00653 }
00654 
00655 

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