mirror of
https://github.com/alicevision/Meshroom.git
synced 2025-06-11 07:11:52 +02:00
[ui.graph] fix node duplication method
* duplicate all nodes before re-creating edges * add unit test
This commit is contained in:
parent
d187a84f5f
commit
dbf2649621
2 changed files with 62 additions and 13 deletions
|
@ -304,8 +304,7 @@ class UIGraph(QObject):
|
|||
node = self.addNewNode(serialized["nodeType"], **serialized["attributes"])
|
||||
return node
|
||||
|
||||
@Slot(Node, result="QVariantList")
|
||||
def duplicateNodes(self, fromNode):
|
||||
def duplicateNodesFromNode(self, fromNode):
|
||||
"""
|
||||
Duplicate 'fromNode' and all the following nodes towards graph's leaves.
|
||||
|
||||
|
@ -313,30 +312,46 @@ class UIGraph(QObject):
|
|||
fromNode (Node): the node to start the duplication from
|
||||
|
||||
Returns:
|
||||
[Nodes]: the duplicated nodes
|
||||
{Nodes: Node}: the source->duplicate nodes map
|
||||
"""
|
||||
srcNodes, srcEdges = self._graph.nodesFromNode(fromNode)
|
||||
srcNodes = srcNodes[1:] # skip fromNode
|
||||
duplicates = {}
|
||||
|
||||
with self.groupedGraphModification("Duplicate {} Nodes".format(len(srcNodes))):
|
||||
# duplicate the first node with its external edges
|
||||
duplicates[fromNode.name] = self.duplicateNode(fromNode)
|
||||
# duplicate all the following nodes and remap their edges internally
|
||||
# duplicate all nodes without edges and keep a 'source=>duplicate' map
|
||||
for srcNode in srcNodes:
|
||||
duplicate = self.duplicateNode(srcNode, createEdges=False)
|
||||
duplicates[srcNode.name] = duplicate # original node to duplicate map
|
||||
duplicates[srcNode] = duplicate # original node to duplicate map
|
||||
|
||||
# re-create edges taking into account what has been duplicated
|
||||
for srcNode, duplicate in duplicates.items():
|
||||
# get link attributes
|
||||
links = {k: v for k, v in srcNode.toDict()["attributes"].items() if Attribute.isLinkExpression(v)}
|
||||
for attr, link in links.items():
|
||||
link = link[1:-1] # remove starting '{' and trailing '}'
|
||||
# get source node and attribute name
|
||||
edgeSrcNode, edgeSrcAttrName = link.split(".", 1)
|
||||
# if the edge's source node has been duplicated, use the duplicate
|
||||
# otherwise use the original node
|
||||
edgeSrcNode = duplicates.get(edgeSrcNode, self._graph.node(edgeSrcNode))
|
||||
edgeSrcNodeName, edgeSrcAttrName = link.split(".", 1)
|
||||
edgeSrcNode = self._graph.node(edgeSrcNodeName)
|
||||
# if the edge's source node has been duplicated, use the duplicate; otherwise use the original node
|
||||
edgeSrcNode = duplicates.get(edgeSrcNode, edgeSrcNode)
|
||||
self.addEdge(edgeSrcNode.attribute(edgeSrcAttrName), duplicate.attribute(attr))
|
||||
|
||||
return duplicates.values()
|
||||
return duplicates
|
||||
|
||||
@Slot(Node, result="QVariantList")
|
||||
def duplicateNodes(self, fromNode):
|
||||
"""
|
||||
Slot accessor to 'duplicateNodesFromNode'. Returns the list of created nodes, usable from QML.
|
||||
|
||||
Args:
|
||||
fromNode (Node): node to start the duplication from
|
||||
|
||||
See Also: duplicateNodesFromNode
|
||||
|
||||
Returns:
|
||||
[Nodes]: the list of duplicated nodes
|
||||
"""
|
||||
return self.duplicateNodesFromNode(fromNode).values()
|
||||
|
||||
@Slot(Attribute, QJsonValue)
|
||||
def appendAttribute(self, attribute, value=QJsonValue()):
|
||||
|
|
34
tests/test_ui_graph.py
Normal file
34
tests/test_ui_graph.py
Normal file
|
@ -0,0 +1,34 @@
|
|||
#!/usr/bin/env python
|
||||
# coding:utf-8
|
||||
|
||||
from meshroom.ui.graph import UIGraph
|
||||
|
||||
|
||||
def test_duplicate_nodes():
|
||||
"""
|
||||
Test nodes duplication.
|
||||
"""
|
||||
|
||||
# n0 -- n1 -- n2
|
||||
# \ \
|
||||
# ---------- n3
|
||||
|
||||
g = UIGraph()
|
||||
n0 = g.addNewNode('Ls', input='/tmp')
|
||||
n1 = g.addNewNode('Ls', input=n0.output)
|
||||
n2 = g.addNewNode('Ls', input=n1.output)
|
||||
n3 = g.addNewNode('AppendFiles', input=n1.output, input2=n2.output)
|
||||
|
||||
# duplicate from n1
|
||||
nMap = g.duplicateNodesFromNode(fromNode=n1)
|
||||
for s, d in nMap.items():
|
||||
assert s.nodeType == d.nodeType
|
||||
|
||||
# check number of duplicated nodes
|
||||
assert len(nMap) == 3
|
||||
|
||||
# check connections
|
||||
assert nMap[n1].input.getLinkParam() == n0.output
|
||||
assert nMap[n2].input.getLinkParam() == nMap[n1].output
|
||||
assert nMap[n3].input.getLinkParam() == nMap[n1].output
|
||||
assert nMap[n3].input2.getLinkParam() == nMap[n2].output
|
Loading…
Add table
Add a link
Reference in a new issue