diff --git a/client/ayon_houdini/plugins/publish/extract_usd.py b/client/ayon_houdini/plugins/publish/extract_usd.py index e8e7d6a583..9a8c755926 100644 --- a/client/ayon_houdini/plugins/publish/extract_usd.py +++ b/client/ayon_houdini/plugins/publish/extract_usd.py @@ -3,6 +3,7 @@ import pyblish.api +from ayon_core.pipeline.entity_uri import construct_ayon_entity_uri from ayon_core.pipeline.publish.lib import get_instance_expected_output_path from ayon_houdini.api import plugin from ayon_houdini.api.lib import render_rop @@ -17,6 +18,8 @@ class ExtractUSD(plugin.HoudiniExtractorPlugin): label = "Extract USD" families = ["usdrop"] + use_ayon_entity_uri = False + def process(self, instance): ropnode = hou.node(instance.data.get("instance_node")) @@ -30,6 +33,8 @@ def process(self, instance): self.log.info("Writing USD '%s' to '%s'" % (file_name, staging_dir)) mapping = self.get_source_to_publish_paths(instance.context) + if mapping: + self.log.debug(f"Remapping paths: {mapping}") # Allow instance-specific path remapping overrides, e.g. changing # paths on used resources/textures for looks @@ -55,10 +60,19 @@ def process(self, instance): } instance.data["representations"].append(representation) - def get_source_to_publish_paths(self, context): + def get_source_to_publish_paths(self, + context): """Define a mapping of all current instances in context from source file to publish file so this can be used on the USD save to remap - asset layer paths on publish via AyonRemapPaths output processor""" + asset layer paths on publish via AyonRemapPaths output processor + + Arguments: + context (pyblish.api.Context): Publish context. + + Returns: + dict[str, str]: Mapping from source path to remapped path. + + """ mapping = {} for instance in context: @@ -76,9 +90,22 @@ def get_source_to_publish_paths(self, context): # asset paths that are set use e.g. $F # TODO: If the representation has multiple files we might need # to define the path remapping per file of the sequence - path = get_instance_expected_output_path( - instance, representation_name=name, ext=ext - ) + if self.use_ayon_entity_uri: + # Construct AYON entity URI + # Note: entity does not exist yet + path = construct_ayon_entity_uri( + project_name=context.data["projectName"], + folder_path=instance.data["folderPath"], + product=instance.data["productName"], + version=instance.data["version"], + representation_name=name + ) + else: + # Resolved publish filepath + path = get_instance_expected_output_path( + instance, representation_name=name, ext=ext + ) + for source_path in get_source_paths(instance, repre): source_path = os.path.normpath(source_path) mapping[source_path] = path diff --git a/server/settings/publish.py b/server/settings/publish.py index 9936dd880d..68cfa70ed3 100644 --- a/server/settings/publish.py +++ b/server/settings/publish.py @@ -115,6 +115,17 @@ class BasicEnabledStatesModel(BaseSettingsModel): active: bool = SettingsField(title="Active") +class ExtractUsdModel(BaseSettingsModel): + use_ayon_entity_uri: bool = SettingsField( + False, + title="Remap save layers to AYON Entity URI", + description=( + "Remap explicit save layers to AYON Entity URI on publish " + "instead of the resolved publish filepaths." + ) + ) + + class PublishPluginsModel(BaseSettingsModel): CollectAssetHandles: CollectAssetHandlesModel = SettingsField( default_factory=CollectAssetHandlesModel, @@ -164,6 +175,10 @@ class PublishPluginsModel(BaseSettingsModel): title="Extract Active View Thumbnail", section="Extractors" ) + ExtractUSD: ExtractUsdModel = SettingsField( + default_factory=ExtractUsdModel, + title="Extract USD" + ) DEFAULT_HOUDINI_PUBLISH_SETTINGS = { @@ -243,5 +258,8 @@ class PublishPluginsModel(BaseSettingsModel): "enabled": True, "optional": False, "active": True + }, + "ExtractUSD": { + "use_ayon_entity_uri": False } }