Skip to content

Commit a5c8022

Browse files
authored
Merge pull request #3079 from alicevision/fix/saveAsTemplate
[core] Fix: Correctly serialize backdrop nodes for templates
2 parents 760a240 + f77d38f commit a5c8022

3 files changed

Lines changed: 77 additions & 9 deletions

File tree

meshroom/core/graphIO.py

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -135,12 +135,8 @@ def serializeNode(self, node: Node) -> dict:
135135
# For now, implemented as a post-process to update the default serialization.
136136
nodeData = super().serializeNode(node)
137137

138-
inputKeys = list(nodeData["inputs"].keys())
139-
140-
internalInputKeys = []
141-
internalInputs = nodeData.get("internalInputs", None)
142-
if internalInputs:
143-
internalInputKeys = list(internalInputs.keys())
138+
inputKeys = list(nodeData.get("inputs", {}).keys())
139+
internalInputKeys = list(nodeData.get("internalInputs", {}).keys())
144140

145141
for attrName in inputKeys:
146142
attribute = node.attribute(attrName)
@@ -158,9 +154,9 @@ def serializeNode(self, node: Node) -> dict:
158154
if len(nodeData["internalInputs"]) == 0:
159155
del nodeData["internalInputs"]
160156

161-
del nodeData["outputs"]
162-
del nodeData["uid"]
163-
del nodeData["parallelization"]
157+
nodeData.pop("outputs", None)
158+
nodeData.pop("uid", None)
159+
nodeData.pop("parallelization", None)
164160

165161
return nodeData
166162

tests/test_graphIO.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,3 +408,43 @@ def test_connectionsToMissingNodesAreDiscarded(self):
408408
}
409409
""")
410410
graph._deserialize(json.loads(sampleGraphContent))
411+
412+
413+
class TestTemplateSerialization:
414+
415+
def test_templateSerializationStripsOutputsUidAndParallelization(self):
416+
"""Test that template serialization removes outputs, uid, and parallelization."""
417+
with registeredNodeTypes([SimpleNode]):
418+
graph = Graph("")
419+
graph.addNewNode("SimpleNode")
420+
421+
data = graph.serialize(asTemplate=True)
422+
nodeData = data["graph"]["SimpleNode_1"]
423+
424+
assert "outputs" not in nodeData
425+
assert "uid" not in nodeData
426+
assert "parallelization" not in nodeData
427+
428+
def test_templateSerializationStripsDefaultInputs(self):
429+
"""Test that default-valued inputs are stripped from template serialization."""
430+
with registeredNodeTypes([SimpleNode]):
431+
graph = Graph("")
432+
graph.addNewNode("SimpleNode")
433+
434+
data = graph.serialize(asTemplate=True)
435+
nodeData = data["graph"]["SimpleNode_1"]
436+
437+
# All inputs are at default, so inputs should be empty or absent
438+
assert nodeData.get("inputs", {}) == {}
439+
440+
def test_templateSerializationPreservesNonDefaultInputs(self):
441+
"""Test that non-default attribute values are preserved in template serialization."""
442+
with registeredNodeTypes([SimpleNode]):
443+
graph = Graph("")
444+
node = graph.addNewNode("SimpleNode")
445+
node.attribute("input").value = "/some/path"
446+
447+
data = graph.serialize(asTemplate=True)
448+
nodeData = data["graph"]["SimpleNode_1"]
449+
450+
assert nodeData["inputs"]["input"] == "/some/path"

tests/test_nodes.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,38 @@ def test_backdropNode_customSerialization(self):
274274
assert backdrop.color == "#FF0000"
275275
assert backdrop.comment == "hello world"
276276

277+
def test_backdropNode_templateSerialization(self):
278+
""" Test that a graph with a backdrop node can be saved as a template. """
279+
g = Graph("Backdrop node template serialization")
280+
backdrop = g.addNewNode("Backdrop")
281+
282+
# Save the graph as a template
283+
templateFile = os.path.join(tempfile.mkdtemp(), "test_backdrop_template.mg")
284+
g.save(templateFile, template=True)
285+
286+
# Reload the graph and check both nodes are present
287+
g = loadGraph(templateFile)
288+
assert g.node("Backdrop_1") is not None
289+
290+
def test_backdropNode_templateSerialization_customAttributes(self):
291+
""" Test that a backdrop node with custom values is correctly saved as a template. """
292+
g = Graph("Backdrop node template custom serialization")
293+
backdrop = g.addNewNode("Backdrop")
294+
295+
# Set custom values
296+
backdrop.internalAttribute("nodeWidth").value = 400
297+
backdrop.internalAttribute("comment").value = "Template backdrop"
298+
299+
templateFile = os.path.join(tempfile.mkdtemp(), "test_backdrop_template_custom.mg")
300+
g.save(templateFile, template=True)
301+
302+
# Reload and verify custom values are preserved
303+
g = loadGraph(templateFile)
304+
backdrop = g.node("Backdrop_1")
305+
assert backdrop is not None
306+
assert backdrop.nodeWidth == 400
307+
assert backdrop.comment == "Template backdrop"
308+
277309

278310
class TestResourceLevels:
279311
""" Test that cpu, gpu, and ram descriptor attributes support both static Level values and callables. """

0 commit comments

Comments
 (0)