diff --git a/openpype/hosts/fusion/plugins/create/create_saver.py b/openpype/hosts/fusion/plugins/create/create_saver.py index 39edca4de3..fccd8b2965 100644 --- a/openpype/hosts/fusion/plugins/create/create_saver.py +++ b/openpype/hosts/fusion/plugins/create/create_saver.py @@ -123,6 +123,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 @@ -188,6 +191,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): diff --git a/openpype/hosts/houdini/api/plugin.py b/openpype/hosts/houdini/api/plugin.py index 730a627dc3..a0a7dcc2e4 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. diff --git a/openpype/hosts/maya/api/plugin.py b/openpype/hosts/maya/api/plugin.py index 79fcf9bc8b..8468985178 100644 --- a/openpype/hosts/maya/api/plugin.py +++ b/openpype/hosts/maya/api/plugin.py @@ -151,6 +151,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) # Don't store `families` since it's up to the creator itself # to define the initial publish families - not a stored attribute of @@ -227,6 +228,7 @@ class MayaCreatorBase(object): # Explicitly re-parse the node name node_data["instance_node"] = node + node_data["instance_id"] = node # If the creator plug-in specifies families = self.get_publish_families() 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 == "":