From 1cf33ba28615847c69b47e3d08fcdab75345dbb6 Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Sun, 23 Jun 2024 18:35:26 -0400 Subject: [PATCH] Allow `NodeTree`s to be reused in the `pre_export` phase. Logic trees can be shared, so it is conceivable that a logic tree might be pre-exported more than once. They can already be created by artists and referenced from multiple Advanced Logic modifiers, so this is good for consistency. --- korman/exporter/convert.py | 8 ++++++-- korman/properties/modifiers/base.py | 28 ++++++++++++++++------------ 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/korman/exporter/convert.py b/korman/exporter/convert.py index 644e100..df8d366 100644 --- a/korman/exporter/convert.py +++ b/korman/exporter/convert.py @@ -510,8 +510,12 @@ class Exporter: @handle_temporary.register(bpy.types.NodeTree) def _(temporary, parent): - self.exit_stack.enter_context(TemporaryObject(temporary, bpy.data.node_groups.remove)) - log_msg(f"'{parent.name}' generated NodeTree '{temporary.name}'") + # NodeTrees are reuseable, so make sure we haven't already encountered it. + if not temporary.name in self.want_node_trees: + self.exit_stack.enter_context(TemporaryObject(temporary, bpy.data.node_groups.remove)) + log_msg(f"'{parent.name}' generated NodeTree '{temporary.name}'") + else: + log_msg(f"'{parent.name}' reused NodeTree '{temporary.name}'") if temporary.bl_idname == "PlasmaNodeTree": parent_so = self.mgr.find_create_object(plSceneObject, bl=parent) self.want_node_trees[temporary.name].add((parent, parent_so)) diff --git a/korman/properties/modifiers/base.py b/korman/properties/modifiers/base.py index 1495c86..dc90484 100644 --- a/korman/properties/modifiers/base.py +++ b/korman/properties/modifiers/base.py @@ -181,20 +181,24 @@ class PlasmaModifierProperties(bpy.types.PropertyGroup): class PlasmaModifierLogicWiz: def convert_logic(self, bo, **kwargs): - """Creates, converts, and returns an unmanaged NodeTree for this logic wizard. If the wizard - fails during conversion, the temporary tree is deleted for you. However, on success, you - are responsible for removing the tree from Blender, if applicable.""" + """Attempts to look up an already existing logic tree matching the name provided and returns + it, if found. If not, creates, converts, and returns an unmanaged NodeTree for this wizard. + If the wizard fails during conversion, the temporary tree is deleted for you. However, on + success, you are responsible for removing the tree from Blender, if applicable.""" name = kwargs.pop("name", self.key_name) assert not "tree" in kwargs - tree = bpy.data.node_groups.new(name, "PlasmaNodeTree") - kwargs["tree"] = tree - try: - self.logicwiz(bo, **kwargs) - except: - bpy.data.node_groups.remove(tree) - raise - else: - return tree + + node_groups = bpy.data.node_groups + tree = node_groups.get(name) + if tree is None: + tree = node_groups.new(name, "PlasmaNodeTree") + kwargs["tree"] = tree + try: + self.logicwiz(bo, **kwargs) + except: + bpy.data.node_groups.remove(tree) + raise + return tree def _create_python_file_node(self, tree, filename: str, attributes: Dict[str, Any]) -> bpy.types.Node: pfm_node = tree.nodes.new("PlasmaPythonFileNode")