diff --git a/meshroom/core/graphIO.py b/meshroom/core/graphIO.py index 5bcd63213b..c2cdd5085a 100644 --- a/meshroom/core/graphIO.py +++ b/meshroom/core/graphIO.py @@ -200,9 +200,13 @@ def _serializeAttribute(self, attribute: Attribute) -> Any: Serialize `attribute` (recursively for list/groups) and deal with attributes being connected to nodes that are not part of the partial list of nodes to serialize. """ - # If the attribute is connected to a node that is not in the list of nodes to serialize, - # the link expression should not be serialized. - if attribute.isLink and attribute.getLinkParam().node not in self.nodes: + linkParam = attribute.getLinkParam() + + if linkParam is not None: + # Use standard link serialization if upstream node is part of the serialization. + if linkParam.node in self.nodes: + return attribute.getExportValue() + # Skip link serialization otherwise. # If part of a list, this entry can be discarded. if isinstance(attribute.root, ListAttribute): return None diff --git a/tests/test_graphIO.py b/tests/test_graphIO.py index 95d72021e6..b742069192 100644 --- a/tests/test_graphIO.py +++ b/tests/test_graphIO.py @@ -243,6 +243,20 @@ def test_serializeAllNodesIsSimilarToStandardSerialization(self): assert compareGraphsContent(graph, graphA) assert compareGraphsContent(graphA, graphB) + def test_listAttributeToListAttributeConnectionIsSerialized(self): + graph = Graph("") + + with registeredNodeTypes([NodeWithListAttributes]): + nodeA = graph.addNewNode(NodeWithListAttributes.__name__) + nodeB = graph.addNewNode(NodeWithListAttributes.__name__) + + graph.addEdge(nodeA.listInput, nodeB.listInput) + + otherGraph = Graph("") + otherGraph._deserialize(graph.serializePartial([nodeA, nodeB])) + + assert otherGraph.node(nodeB.name).listInput.linkParam == otherGraph.node(nodeA.name).listInput + def test_singleNodeWithInputConnectionFromNonSerializedNodeRemovesEdge(self): graph = Graph("")