7 #include "fwData/Graph.hpp" 9 #include "fwData/Edge.hpp" 10 #include "fwData/Exception.hpp" 11 #include "fwData/Node.hpp" 12 #include "fwData/Port.hpp" 13 #include "fwData/registry/macros.hpp" 15 #include <fwCom/Signal.hpp> 16 #include <fwCom/Signal.hxx> 17 #include <fwCom/Signals.hpp> 26 const bool Graph::UP_STREAM =
true;
27 const bool Graph::DOWN_STREAM =
false;
53 return m_nodes.insert(node).second;
65 return (m_nodes.erase( Node::constCast(node) ) > 0 );
86 for(
const auto& connection : m_connections)
88 if ( connection.second.first == node || connection.second.second == node)
99 Node::csptr nodeSource,
100 std::string nodeSourceOutputPortID,
101 Node::csptr nodeDestination,
102 std::string nodeDestinationInputPortID,
103 std::string EdgeNature )
105 ::fwData::Edge::sptr nEdge = ::fwData::Edge::New();
106 nEdge->setIdentifiers( nodeSourceOutputPortID, nodeDestinationInputPortID );
107 nEdge->setNature( EdgeNature );
108 if (
addEdge( nEdge, nodeSource, nodeDestination ) )
114 return ::fwData::Edge::sptr();
120 bool Graph::addEdge(Edge::sptr edge, Node::csptr nodeSource, Node::csptr nodeDestination)
123 if (m_connections.find( edge ) != m_connections.end() )
128 if (m_nodes.find( Node::constCast(nodeSource) ) == m_nodes.end() )
133 if ( m_nodes.find( Node::constCast(nodeDestination) ) == m_nodes.end() )
139 Port::sptr sourcePort = nodeSource->findPort( edge->getIdentifiers().first, DOWN_STREAM );
146 Port::sptr sourceDest = nodeDestination->findPort( edge->getIdentifiers().second, UP_STREAM );
153 if ( sourcePort->getType() != sourceDest->getType() )
158 m_connections[ edge ] = std::make_pair( Node::constCast(nodeSource), Node::constCast(nodeDestination) );
167 return ( m_connections.erase(edge) != 0 );
174 return getNode( edge, UP_STREAM );
181 return getNode( edge, DOWN_STREAM );
188 ConnectionContainer::iterator i;
189 i = m_connections.find( edge );
192 if ( i == m_connections.end() )
199 return (*i).second.first;
203 return (*i).second.second;
218 return getEdges( node, DOWN_STREAM );
224 const std::string& nature,
225 const std::string& portID
228 SLM_ASSERT(
"Node " + node->getID() +
" not found in graph", m_nodes.find( Node::constCast(node) ) !=
230 SLM_ASSERT(
"Port " + portID +
" not found on node" + node->getID(),
231 portID.empty() || node->findPort(portID, upStream));
233 std::vector< Edge::sptr > result;
236 for(
const auto& connection : m_connections)
238 const Edge::sptr& edge = connection.first;
239 const Node::sptr& nodeFrom = connection.second.first;
240 const Node::sptr& nodeTo = connection.second.second;
242 bool isConnectedEdge = ( upStream ? nodeTo : nodeFrom ) == node;
243 if( !isConnectedEdge)
248 bool isCorrectPort = portID.empty() || portID == ( upStream ? edge->getToPortID() : edge->getFromPortID() );
254 bool isCorrectNature = nature.empty() || edge->getNature() == nature;
255 if( !isCorrectNature)
260 result.push_back( edge );
268 std::vector< ::fwData::Node::sptr >
Graph::getNodes( const ::fwData::Node::csptr& node,
270 const std::string& nature,
271 const std::string& portID )
273 std::vector< Edge::sptr > edges;
274 edges =
getEdges( node, upStream, nature, portID);
276 std::vector< Node::sptr > nodes;
277 for(
const Edge::sptr& edge : edges )
279 Node::sptr distantNode;
280 distantNode = ( upStream ? m_connections[edge].first : m_connections[edge].second );
282 if( std::find( nodes.begin(), nodes.end(), distantNode ) == nodes.end() )
284 nodes.push_back(distantNode);
295 return m_nodes.size();
302 return m_connections.size();
309 return m_connections;
316 return m_connections;
321 void Graph::shallowCopy(
const Object::csptr& _source )
323 Graph::csptr other = Graph::dynamicConstCast(_source);
325 "Unable to copy" + (_source ? _source->getClassname() : std::string(
"<NULL>"))
328 m_nodes = other->m_nodes;
329 m_connections = other->m_connections;
334 void Graph::cachedDeepCopy(
const Object::csptr& _source, DeepCopyCacheType& cache)
336 Graph::csptr other = Graph::dynamicConstCast(_source);
338 "Unable to copy" + (_source ? _source->getClassname() : std::string(
"<NULL>"))
342 std::map< ::fwData::Node::sptr, ::fwData::Node::sptr > correspondenceBetweenNodes;
343 typedef std::pair< Edge::sptr, std::pair< Node::sptr, Node::sptr > > ConnectionContainerElt;
346 for(const ::fwData::Node::sptr& node : other->m_nodes)
349 bool addOK = this->
addNode(newNode);
350 OSLM_ASSERT(
"Node "<<newNode->getID() <<
" can't be added ", addOK );
351 FwCoreNotUsedMacro(addOK);
352 correspondenceBetweenNodes.insert(std::make_pair(node, newNode));
355 m_connections.clear();
356 for(
const ConnectionContainerElt& connection : other->m_connections)
360 ::fwData::Node::sptr oldNode1 = (connection.second).first;
361 ::fwData::Node::sptr oldNode2 = (connection.second).second;
362 if ((correspondenceBetweenNodes.find(Node::constCast(oldNode1)) != correspondenceBetweenNodes.end())
363 && (correspondenceBetweenNodes.find(Node::constCast(oldNode2)) != correspondenceBetweenNodes.end()))
366 this->
addEdge(newEdge, correspondenceBetweenNodes[oldNode1], correspondenceBetweenNodes[oldNode2]);
369 correspondenceBetweenNodes.clear();
This class defines a graph object.
FWDATA_API size_t getNbNodes() const
virtual const std::string & getClassname() const override
return full object's classname with its namespace, i.e. fwCore::BaseObject
FWDATA_API size_t getNbEdges() const
#define OSLM_ASSERT(message, cond)
work like 'assert' from 'cassert', with in addition a message logged by spylog (with FATAL loglevel) ...
Key class used to restrict access to Object construction. See http://www.drdobbs.com/184402053.
Implements data exception class.
virtual FWDATA_API ~Graph()
Destructor.
FWDATA_API std::vector< Edge::sptr > getOutputEdges(Node::csptr _node)
Get output edges.
FWDATA_API std::vector< Edge::sptr > getEdges(const Node::csptr &_node, bool _upStream, const std::string &_nature="", const std::string &_portID="")
Get a vector of edges.
FWDATA_API bool removeNode(Node::csptr _node)
remove a node
FWDATA_API bool haveConnectedEdges(Node::csptr _node) const
Check if an edge is connected to the node.
FWDATA_API Edge::sptr makeConnection(Node::csptr _nodeSource, std::string _nodeSourceOutputPortID, Node::csptr _nodeDestination, std::string _nodeDestinationInputPortID, std::string _EdgeNature)
create an edge from given info and add edge in the graph
FWDATA_API bool removeEdge(Edge::sptr _edge)
remove an edge
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_UPDATED_SIG
Updated signal key.
FWDATA_API void fieldDeepCopy(const ::fwData::Object::csptr &source)
A deep copy of fields (objects in m_children)
FWDATA_API bool addEdge(Edge::sptr _edge, Node::csptr _nodeSource, Node::csptr _nodeDestination)
Add and edge.
#define SLM_ASSERT(message, cond)
work like 'assert' from 'cassert', with in addition a message logged by spylog (with FATAL loglevel) ...
static FWDATA_API::fwData::Object::sptr copy(const ::fwData::Object::csptr &source)
return a copy of the source. if source is a null pointer, return a null pointer.
FWDATA_API std::vector< Edge::sptr > getInputEdges(Node::csptr _node)
Get input edges.
FWDATA_API Node::sptr getNode(Edge::sptr _edge, bool _upStream)
Get node.
FWDATA_API Node::sptr getSourceNode(Edge::sptr _edge)
Get source node.
FWDATA_API Graph(::fwData::Object::Key key)
Constructor.
UpdatedSignalType::sptr m_sigUpdated
Updated signal.
FWDATA_API Node::sptr getDestinationNode(Edge::sptr _edge)
Get destination node.
Contains the representation of the data objects used in the framework.
FWDATA_API void fieldShallowCopy(const ::fwData::Object::csptr &source)
A shallow copy of fields (objects in m_children)
FWDATA_API NodeContainer & getNodes()
Get the node container.
FWDATA_API bool addNode(Node::sptr _node)
add a node
FWDATA_API const ConnectionContainer & getConnections() const
Get the connection container.