mirror of
https://github.com/alicevision/Meshroom.git
synced 2025-07-18 17:17:18 +02:00
[core] Graph: rename nodesFromNode() to dfsOnDiscover()
This commit is contained in:
parent
49e33fb9ba
commit
f8bd40ad38
5 changed files with 52 additions and 52 deletions
|
@ -380,7 +380,7 @@ class Graph(BaseObject):
|
||||||
Returns:
|
Returns:
|
||||||
OrderedDict[Node, Node]: the source->duplicate map
|
OrderedDict[Node, Node]: the source->duplicate map
|
||||||
"""
|
"""
|
||||||
srcNodes, srcEdges = self.nodesFromNode(fromNode)
|
srcNodes, srcEdges = self.dfsOnDiscover(fromNode)
|
||||||
# use OrderedDict to keep duplicated nodes creation order
|
# use OrderedDict to keep duplicated nodes creation order
|
||||||
duplicates = OrderedDict()
|
duplicates = OrderedDict()
|
||||||
|
|
||||||
|
@ -714,6 +714,35 @@ class Graph(BaseObject):
|
||||||
self.dfs(visitor=visitor, startNodes=startNodes)
|
self.dfs(visitor=visitor, startNodes=startNodes)
|
||||||
return nodes, edges
|
return nodes, edges
|
||||||
|
|
||||||
|
def dfsOnDiscover(self, startNode, filterTypes=None, longestPathFirst=False, reverse=True):
|
||||||
|
"""
|
||||||
|
Return the node chain from startNode to the graph leaves.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
startNode (Node): the node to start the visit from.
|
||||||
|
filterTypes (str list): (optional) only return the nodes of the given types
|
||||||
|
(does not stop the visit, this is a post-process only)
|
||||||
|
longestPathFirst (bool): (optional) if multiple paths, nodes belonging to
|
||||||
|
the longest one will be visited first.
|
||||||
|
reverse (bool): (optional) direction of visit.
|
||||||
|
True is for getting nodes depending on the startNode.
|
||||||
|
False is for getting nodes required for the startNode.
|
||||||
|
Returns:
|
||||||
|
The list of nodes and edges, from startNode to the graph leaves following edges.
|
||||||
|
"""
|
||||||
|
nodes = []
|
||||||
|
edges = []
|
||||||
|
visitor = Visitor()
|
||||||
|
|
||||||
|
def discoverVertex(vertex, graph):
|
||||||
|
if not filterTypes or vertex.nodeType in filterTypes:
|
||||||
|
nodes.append(vertex)
|
||||||
|
|
||||||
|
visitor.discoverVertex = discoverVertex
|
||||||
|
visitor.examineEdge = lambda edge, graph: edges.append(edge)
|
||||||
|
self.dfs(visitor=visitor, startNodes=[startNode], longestPathFirst=longestPathFirst, reverse=reverse)
|
||||||
|
return nodes, edges
|
||||||
|
|
||||||
def dfsToProcess(self, startNodes=None):
|
def dfsToProcess(self, startNodes=None):
|
||||||
"""
|
"""
|
||||||
Return the full list of predecessor nodes to process in order to compute the given nodes.
|
Return the full list of predecessor nodes to process in order to compute the given nodes.
|
||||||
|
@ -876,41 +905,12 @@ class Graph(BaseObject):
|
||||||
flowEdges.append(link)
|
flowEdges.append(link)
|
||||||
return flowEdges
|
return flowEdges
|
||||||
|
|
||||||
def nodesFromNode(self, startNode, filterTypes=None, longestPathFirst=False, reverse=True):
|
|
||||||
"""
|
|
||||||
Return the node chain from startNode to the graph leaves.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
startNode (Node): the node to start the visit from.
|
|
||||||
filterTypes (str list): (optional) only return the nodes of the given types
|
|
||||||
(does not stop the visit, this is a post-process only)
|
|
||||||
longestPathFirst (bool): (optional) if multiple paths, nodes belonging to
|
|
||||||
the longest one will be visited first.
|
|
||||||
reverse (bool): (optional) direction of visit.
|
|
||||||
True is for getting nodes depending on the startNode.
|
|
||||||
False is for getting nodes required for the startNode.
|
|
||||||
Returns:
|
|
||||||
The list of nodes and edges, from startNode to the graph leaves following edges.
|
|
||||||
"""
|
|
||||||
nodes = []
|
|
||||||
edges = []
|
|
||||||
visitor = Visitor()
|
|
||||||
|
|
||||||
def discoverVertex(vertex, graph):
|
|
||||||
if not filterTypes or vertex.nodeType in filterTypes:
|
|
||||||
nodes.append(vertex)
|
|
||||||
|
|
||||||
visitor.discoverVertex = discoverVertex
|
|
||||||
visitor.examineEdge = lambda edge, graph: edges.append(edge)
|
|
||||||
self.dfs(visitor=visitor, startNodes=[startNode], longestPathFirst=longestPathFirst, reverse=reverse)
|
|
||||||
return nodes, edges
|
|
||||||
|
|
||||||
def getInputNodes(self, node, recursive=False):
|
def getInputNodes(self, node, recursive=False):
|
||||||
""" Return either the first level input nodes of a node or the whole chain. """
|
""" Return either the first level input nodes of a node or the whole chain. """
|
||||||
if not recursive:
|
if not recursive:
|
||||||
return set([edge.src.node for edge in self.edges if edge.dst.node is node])
|
return set([edge.src.node for edge in self.edges if edge.dst.node is node])
|
||||||
|
|
||||||
inputNodes, edges = self.nodesFromNode(node, filterTypes=None, reverse=False)
|
inputNodes, edges = self.dfsOnDiscover(node, filterTypes=None, reverse=False)
|
||||||
return inputNodes[1:] # exclude current node
|
return inputNodes[1:] # exclude current node
|
||||||
|
|
||||||
def getOutputNodes(self, node, recursive=False):
|
def getOutputNodes(self, node, recursive=False):
|
||||||
|
@ -918,7 +918,7 @@ class Graph(BaseObject):
|
||||||
if not recursive:
|
if not recursive:
|
||||||
return set([edge.dst.node for edge in self.edges if edge.src.node is node])
|
return set([edge.dst.node for edge in self.edges if edge.src.node is node])
|
||||||
|
|
||||||
outputNodes, edges = self.nodesFromNode(node, filterTypes=None, reverse=True)
|
outputNodes, edges = self.dfsOnDiscover(node, filterTypes=None, reverse=True)
|
||||||
return outputNodes[1:] # exclude current node
|
return outputNodes[1:] # exclude current node
|
||||||
|
|
||||||
@Slot(Node, result=int)
|
@Slot(Node, result=int)
|
||||||
|
@ -1074,7 +1074,7 @@ class Graph(BaseObject):
|
||||||
See Also:
|
See Also:
|
||||||
Graph.update, Graph.updateInternals, Graph.updateStatusFromCache
|
Graph.update, Graph.updateInternals, Graph.updateStatusFromCache
|
||||||
"""
|
"""
|
||||||
nodes, edges = self.nodesFromNode(fromNode)
|
nodes, edges = self.dfsOnDiscover(fromNode)
|
||||||
for node in nodes:
|
for node in nodes:
|
||||||
node.dirty = True
|
node.dirty = True
|
||||||
|
|
||||||
|
@ -1098,7 +1098,7 @@ class Graph(BaseObject):
|
||||||
|
|
||||||
@Slot(Node)
|
@Slot(Node)
|
||||||
def clearDataFrom(self, startNode):
|
def clearDataFrom(self, startNode):
|
||||||
for node in self.nodesFromNode(startNode)[0]:
|
for node in self.dfsOnDiscover(startNode)[0]:
|
||||||
node.clearData()
|
node.clearData()
|
||||||
|
|
||||||
def iterChunksByStatus(self, status):
|
def iterChunksByStatus(self, status):
|
||||||
|
|
|
@ -69,7 +69,7 @@ class TaskThread(Thread):
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
logging.error("Error on node computation: {}".format(e))
|
logging.error("Error on node computation: {}".format(e))
|
||||||
nodesToRemove, _ = self._manager._graph.nodesFromNode(node)
|
nodesToRemove, _ = self._manager._graph.dfsOnDiscover(node)
|
||||||
# remove following nodes from the task queue
|
# remove following nodes from the task queue
|
||||||
for n in nodesToRemove[1:]: # exclude current node
|
for n in nodesToRemove[1:]: # exclude current node
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -526,7 +526,7 @@ class UIGraph(QObject):
|
||||||
with self.groupedGraphModification("Remove Nodes from {}".format(startNode.name)):
|
with self.groupedGraphModification("Remove Nodes from {}".format(startNode.name)):
|
||||||
# Perform nodes removal from leaves to start node so that edges
|
# Perform nodes removal from leaves to start node so that edges
|
||||||
# can be re-created in correct order on redo.
|
# can be re-created in correct order on redo.
|
||||||
[self.removeNode(node) for node in reversed(self._graph.nodesFromNode(startNode)[0])]
|
[self.removeNode(node) for node in reversed(self._graph.dfsOnDiscover(startNode)[0])]
|
||||||
|
|
||||||
@Slot(Attribute, Attribute)
|
@Slot(Attribute, Attribute)
|
||||||
def addEdge(self, src, dst):
|
def addEdge(self, src, dst):
|
||||||
|
|
|
@ -473,7 +473,7 @@ class Reconstruction(UIGraph):
|
||||||
|
|
||||||
def onCameraInitChanged(self):
|
def onCameraInitChanged(self):
|
||||||
# Update active nodes when CameraInit changes
|
# Update active nodes when CameraInit changes
|
||||||
nodes = self._graph.nodesFromNode(self._cameraInit)[0]
|
nodes = self._graph.dfsOnDiscover(self._cameraInit)[0]
|
||||||
self.setActiveNodes(nodes)
|
self.setActiveNodes(nodes)
|
||||||
|
|
||||||
@Slot()
|
@Slot()
|
||||||
|
@ -651,7 +651,7 @@ class Reconstruction(UIGraph):
|
||||||
"""
|
"""
|
||||||
if not startNode:
|
if not startNode:
|
||||||
return None
|
return None
|
||||||
nodes = self._graph.nodesFromNode(startNode, nodeTypes)[0]
|
nodes = self._graph.dfsOnDiscover(startNode, nodeTypes)[0]
|
||||||
if not nodes:
|
if not nodes:
|
||||||
return None
|
return None
|
||||||
node = nodes[-1]
|
node = nodes[-1]
|
||||||
|
|
|
@ -158,8 +158,8 @@ def test_transitive_reduction():
|
||||||
assert node.depth == maxDepth
|
assert node.depth == maxDepth
|
||||||
|
|
||||||
|
|
||||||
def test_graph_reverse_nodesFromNode():
|
def test_graph_reverse_dfsOnDiscover():
|
||||||
graph = Graph('Test nodesFromNode(reverse=True)')
|
graph = Graph('Test dfsOnDiscover(reverse=True)')
|
||||||
|
|
||||||
# ------------\
|
# ------------\
|
||||||
# / ~ C - E - F
|
# / ~ C - E - F
|
||||||
|
@ -174,21 +174,21 @@ def test_graph_reverse_nodesFromNode():
|
||||||
F = graph.addNewNode('AppendText', input=A.output, inputText=E.output)
|
F = graph.addNewNode('AppendText', input=A.output, inputText=E.output)
|
||||||
|
|
||||||
# Get all nodes from A (use set, order not guaranteed)
|
# Get all nodes from A (use set, order not guaranteed)
|
||||||
nodes = graph.nodesFromNode(A)[0]
|
nodes = graph.dfsOnDiscover(A)[0]
|
||||||
assert set(nodes) == {A, B, D, C, E, F}
|
assert set(nodes) == {A, B, D, C, E, F}
|
||||||
# Get all nodes from B
|
# Get all nodes from B
|
||||||
nodes = graph.nodesFromNode(B)[0]
|
nodes = graph.dfsOnDiscover(B)[0]
|
||||||
assert set(nodes) == {B, D, C, E, F}
|
assert set(nodes) == {B, D, C, E, F}
|
||||||
# Get all nodes of type AppendText from B
|
# Get all nodes of type AppendText from B
|
||||||
nodes = graph.nodesFromNode(B, filterTypes=['AppendText'])[0]
|
nodes = graph.dfsOnDiscover(B, filterTypes=['AppendText'])[0]
|
||||||
assert set(nodes) == {B, D, C, F}
|
assert set(nodes) == {B, D, C, F}
|
||||||
# Get all nodes from C (order guaranteed)
|
# Get all nodes from C (order guaranteed)
|
||||||
nodes = graph.nodesFromNode(C)[0]
|
nodes = graph.dfsOnDiscover(C)[0]
|
||||||
assert nodes == [C, E, F]
|
assert nodes == [C, E, F]
|
||||||
|
|
||||||
|
|
||||||
def test_graph_nodesFromNode():
|
def test_graph_dfsOnDiscover():
|
||||||
graph = Graph('Test nodesFromNode(reverse=False)')
|
graph = Graph('Test dfsOnDiscover(reverse=False)')
|
||||||
|
|
||||||
# ------------\
|
# ------------\
|
||||||
# / ~ C - E - F
|
# / ~ C - E - F
|
||||||
|
@ -205,22 +205,22 @@ def test_graph_nodesFromNode():
|
||||||
F = graph.addNewNode('AppendText', input=A.output, inputText=E.output)
|
F = graph.addNewNode('AppendText', input=A.output, inputText=E.output)
|
||||||
|
|
||||||
# Get all nodes from A (use set, order not guaranteed)
|
# Get all nodes from A (use set, order not guaranteed)
|
||||||
nodes = graph.nodesFromNode(A, reverse=False)[0]
|
nodes = graph.dfsOnDiscover(A, reverse=False)[0]
|
||||||
assert set(nodes) == {A}
|
assert set(nodes) == {A}
|
||||||
# Get all nodes from D
|
# Get all nodes from D
|
||||||
nodes = graph.nodesFromNode(D, reverse=False)[0]
|
nodes = graph.dfsOnDiscover(D, reverse=False)[0]
|
||||||
assert set(nodes) == {A, B, D, G}
|
assert set(nodes) == {A, B, D, G}
|
||||||
# Get all nodes from E
|
# Get all nodes from E
|
||||||
nodes = graph.nodesFromNode(E, reverse=False)[0]
|
nodes = graph.dfsOnDiscover(E, reverse=False)[0]
|
||||||
assert set(nodes) == {A, B, C, E}
|
assert set(nodes) == {A, B, C, E}
|
||||||
# Get all nodes from F
|
# Get all nodes from F
|
||||||
nodes = graph.nodesFromNode(F, reverse=False)[0]
|
nodes = graph.dfsOnDiscover(F, reverse=False)[0]
|
||||||
assert set(nodes) == {A, B, C, E, F}
|
assert set(nodes) == {A, B, C, E, F}
|
||||||
# Get all nodes of type AppendText from C
|
# Get all nodes of type AppendText from C
|
||||||
nodes = graph.nodesFromNode(C, filterTypes=['AppendText'], reverse=False)[0]
|
nodes = graph.dfsOnDiscover(C, filterTypes=['AppendText'], reverse=False)[0]
|
||||||
assert set(nodes) == {B, C}
|
assert set(nodes) == {B, C}
|
||||||
# Get all nodes from D (order guaranteed)
|
# Get all nodes from D (order guaranteed)
|
||||||
nodes = graph.nodesFromNode(D, longestPathFirst=True, reverse=False)[0]
|
nodes = graph.dfsOnDiscover(D, longestPathFirst=True, reverse=False)[0]
|
||||||
assert nodes == [D, B, A, G]
|
assert nodes == [D, B, A, G]
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue