From b6e9806258086f260c604ee1ad5a932d93e85b70 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 23 Aug 2023 22:39:13 +0200 Subject: [PATCH 1/4] Allow duplicating publish instance by defining `instance_node` and `instance_id` from `node.path()` instead of parms. --- openpype/hosts/houdini/api/plugin.py | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/openpype/hosts/houdini/api/plugin.py b/openpype/hosts/houdini/api/plugin.py index 70c837205e..c3fd313a0b 100644 --- a/openpype/hosts/houdini/api/plugin.py +++ b/openpype/hosts/houdini/api/plugin.py @@ -187,13 +187,14 @@ class HoudiniCreator(NewCreator, HoudiniCreatorBase): self.customize_node_look(instance_node) instance_data["instance_node"] = instance_node.path() + instance_data["instance_id"] = instance_node.path() instance = CreatedInstance( self.family, subset_name, instance_data, self) self._add_instance_to_context(instance) - imprint(instance_node, instance.data_to_store()) + self.imprint(instance_node, instance.data_to_store()) return instance except hou.Error as er: @@ -222,25 +223,41 @@ class HoudiniCreator(NewCreator, HoudiniCreatorBase): self.cache_subsets(self.collection_shared_data) for instance in self.collection_shared_data[ "houdini_cached_subsets"].get(self.identifier, []): + + node_data = read(instance) + + # Node paths are always the full node path since that is unique + # Because it's the node's path it's not written into attributes + # but explicitly collected + node_path = instance.path() + node_data["instance_id"] = node_path + node_data["instance_node"] = node_path + created_instance = CreatedInstance.from_existing( - read(instance), self + node_data, self ) self._add_instance_to_context(created_instance) def update_instances(self, update_list): for created_inst, changes in update_list: instance_node = hou.node(created_inst.get("instance_node")) - new_values = { key: changes[key].new_value for key in changes.changed_keys } - imprint( + self.imprint( instance_node, new_values, update=True ) + def imprint(self, node, values, update=False): + # Never store instance node and instance id since that data comes + # from the node's path + values.pop("instance_node", None) + values.pop("instance_id", None) + imprint(node, values, update=update) + def remove_instances(self, instances): """Remove specified instance from the scene. From 5ff66afff7b91b1d1583be28c0da99cc088a3300 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 23 Aug 2023 22:40:25 +0200 Subject: [PATCH 2/4] Allow duplicating publish instances in Maya by not storin instance id as an attribute but using the (unique) node's name instead. --- openpype/hosts/maya/api/plugin.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openpype/hosts/maya/api/plugin.py b/openpype/hosts/maya/api/plugin.py index 00d6602ef9..00a2c899a2 100644 --- a/openpype/hosts/maya/api/plugin.py +++ b/openpype/hosts/maya/api/plugin.py @@ -134,6 +134,7 @@ class MayaCreatorBase(object): # We never store the instance_node as value on the node since # it's the node name itself data.pop("instance_node", None) + data.pop("instance_id", None) # We store creator attributes at the root level and assume they # will not clash in names with `subset`, `task`, etc. and other @@ -185,6 +186,7 @@ class MayaCreatorBase(object): # Explicitly re-parse the node name node_data["instance_node"] = node + node_data["instance_id"] = node return node_data From 6da94d4f27be41a974b8f6348c45060510f74032 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 23 Aug 2023 22:41:25 +0200 Subject: [PATCH 3/4] Allow to duplicate publish instances in Fusion, by not relying on `instance_id` data but have the unique identifier be the node's name. --- openpype/hosts/fusion/plugins/create/create_saver.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/openpype/hosts/fusion/plugins/create/create_saver.py b/openpype/hosts/fusion/plugins/create/create_saver.py index 04898d0a45..590a678a3d 100644 --- a/openpype/hosts/fusion/plugins/create/create_saver.py +++ b/openpype/hosts/fusion/plugins/create/create_saver.py @@ -127,6 +127,9 @@ class CreateSaver(NewCreator): def _imprint(self, tool, data): # Save all data in a "openpype.{key}" = value data + # Instance id is the tool's name so we don't need to imprint as data + data.pop("instance_id", None) + active = data.pop("active", None) if active is not None: # Use active value to set the passthrough state @@ -192,6 +195,10 @@ class CreateSaver(NewCreator): passthrough = attrs["TOOLB_PassThrough"] data["active"] = not passthrough + # Override publisher's UUID generation because tool names are + # already unique in Fusion in a comp + data["instance_id"] = tool.Name + return data def get_pre_create_attr_defs(self): From 090f1e041b14bfaa6e903f3f1fe836f84acb4253 Mon Sep 17 00:00:00 2001 From: Claudio Hickstein <122775550+spmhickstein@users.noreply.github.com> Date: Wed, 4 Oct 2023 11:17:22 +0200 Subject: [PATCH 4/4] Deadline: handle all valid paths in RenderExecutable (#5694) * handle all valid paths in RenderExecutable * Update openpype/modules/deadline/repository/custom/plugins/Ayon/Ayon.py Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --------- Co-authored-by: Petr Kalis Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --- .../modules/deadline/repository/custom/plugins/Ayon/Ayon.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/modules/deadline/repository/custom/plugins/Ayon/Ayon.py b/openpype/modules/deadline/repository/custom/plugins/Ayon/Ayon.py index a29acf9823..2c55e7c951 100644 --- a/openpype/modules/deadline/repository/custom/plugins/Ayon/Ayon.py +++ b/openpype/modules/deadline/repository/custom/plugins/Ayon/Ayon.py @@ -96,7 +96,7 @@ class AyonDeadlinePlugin(DeadlinePlugin): for path in exe_list.split(";"): if path.startswith("~"): path = os.path.expanduser(path) - expanded_paths.append(path) + expanded_paths.append(path) exe = FileUtils.SearchFileList(";".join(expanded_paths)) if exe == "":