From 1790f078ffa18cf02788114419f85c9e6226d7d0 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Sat, 26 Oct 2024 19:13:43 +0200 Subject: [PATCH 1/3] Draft to set defaults using `profiles` --- .../extract_usd_layer_contributions.py | 91 ++++++++++++------- 1 file changed, 60 insertions(+), 31 deletions(-) diff --git a/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py b/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py index 180cb8bbf1..6f08df790f 100644 --- a/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py +++ b/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py @@ -14,7 +14,8 @@ from ayon_core.lib import ( BoolDef, UISeparatorDef, UILabelDef, - EnumDef + EnumDef, + filter_profiles ) try: from ayon_core.pipeline.usdlib import ( @@ -463,6 +464,59 @@ class CollectUSDLayerContributions(pyblish.api.InstancePlugin, if not cls.instance_matches_plugin_families(instance): return [] + # Set default target layer based on product type + # TODO: Define profiles in settings + profiles = [ + { + "productType": "model", + "contribution_layer": "model", + "contribution_apply_as_variant": True, + "contribution_target_product": "usdAsset" + }, + { + "productType": "look", + "contribution_layer": "look", + "contribution_apply_as_variant": True, + "contribution_target_product": "usdAsset" + }, + { + "productType": "groom", + "contribution_layer": "groom", + "contribution_apply_as_variant": True, + "contribution_target_product": "usdAsset" + }, + { + "productType": "rig", + "contribution_layer": "rig", + "contribution_apply_as_variant": True, + "contribution_target_product": "usdShot" + }, + { + "productType": "usd", + "contribution_layer": "assembly", + "contribution_apply_as_variant": False, + "contribution_target_product": "usdShot" + }, + ] + profile = filter_profiles(profiles, { + "productType": instance.data["productType"] + }) + if not profile: + profile = {} + + # Define defaults + default_contribution_layer = profile.get( + "contribution_layer", None) + default_apply_as_variant = profile.get( + "contribution_apply_as_variant", False) + default_target_product = profile.get( + "contribution_target_product", "usdAsset") + default_init_as = ( + "asset" + if profile.get("contribution_target_product") == "usdAsset" + else "shot") + init_as_visible = False + # Attributes logic publish_attributes = instance["publish_attributes"].get( cls.__name__, {}) @@ -495,7 +549,7 @@ class CollectUSDLayerContributions(pyblish.api.InstancePlugin, "the contribution itself will be added to the " "department layer." ), - default="usdAsset", + default=default_target_product, visible=visible), EnumDef("contribution_target_product_init", label="Initialize as", @@ -507,8 +561,8 @@ class CollectUSDLayerContributions(pyblish.api.InstancePlugin, "setting will do nothing." ), items=["asset", "shot"], - default="asset", - visible=visible), + default=default_init_as, + visible=visible and init_as_visible), # Asset layer, e.g. model.usd, look.usd, rig.usd EnumDef("contribution_layer", @@ -520,7 +574,7 @@ class CollectUSDLayerContributions(pyblish.api.InstancePlugin, "the list) will contribute as a stronger opinion." ), items=list(cls.contribution_layers.keys()), - default="model", + default=default_contribution_layer, visible=visible), BoolDef("contribution_apply_as_variant", label="Add as variant", @@ -532,7 +586,7 @@ class CollectUSDLayerContributions(pyblish.api.InstancePlugin, "appended to as a sublayer to the department layer " "instead." ), - default=True, + default=default_apply_as_variant, visible=visible), TextDef("contribution_variant_set_name", label="Variant Set Name", @@ -588,31 +642,6 @@ class CollectUSDLayerContributions(pyblish.api.InstancePlugin, instance.set_publish_plugin_attr_defs(cls.__name__, new_attrs) -class CollectUSDLayerContributionsHoudiniLook(CollectUSDLayerContributions): - """ - This is solely here to expose the attribute definitions for the - Houdini "look" family. - """ - # TODO: Improve how this is built for the look family - hosts = ["houdini"] - families = ["look"] - label = CollectUSDLayerContributions.label + " (Look)" - - @classmethod - def get_attr_defs_for_instance(cls, create_context, instance): - # Filtering of instance, if needed, can be customized - if not cls.instance_matches_plugin_families(instance): - return [] - - defs = super().get_attr_defs_for_instance(create_context, instance) - - # Update default for department layer to look - layer_def = next(d for d in defs if d.key == "contribution_layer") - layer_def.default = "look" - - return defs - - class ValidateUSDDependencies(pyblish.api.InstancePlugin): families = ["usdLayer"] From b9cc8c350733412589781a3eb58bd24fabe2e1f3 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Tue, 18 Feb 2025 17:28:10 +0100 Subject: [PATCH 2/3] Move the profile defaults to settings --- .../extract_usd_layer_contributions.py | 44 ++-------- server/settings/publish_plugins.py | 81 +++++++++++++++++++ 2 files changed, 89 insertions(+), 36 deletions(-) diff --git a/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py b/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py index 6f08df790f..bf4ca70afa 100644 --- a/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py +++ b/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py @@ -1,7 +1,7 @@ from operator import attrgetter import dataclasses import os -from typing import Dict +from typing import Any, Dict, List import pyblish.api try: @@ -282,6 +282,9 @@ class CollectUSDLayerContributions(pyblish.api.InstancePlugin, "fx": 500, "lighting": 600, } + # Default profiles to set certain instance attribute defaults based on + # profiles in settings + profiles: List[Dict[str, Any]] = [] @classmethod def apply_settings(cls, project_settings): @@ -299,6 +302,8 @@ class CollectUSDLayerContributions(pyblish.api.InstancePlugin, if contribution_layers: cls.contribution_layers = contribution_layers + cls.profiles = plugin_settings.get("profiles", []) + def process(self, instance): attr_values = self.get_attr_values_from_data(instance.data) @@ -465,41 +470,8 @@ class CollectUSDLayerContributions(pyblish.api.InstancePlugin, return [] # Set default target layer based on product type - # TODO: Define profiles in settings - profiles = [ - { - "productType": "model", - "contribution_layer": "model", - "contribution_apply_as_variant": True, - "contribution_target_product": "usdAsset" - }, - { - "productType": "look", - "contribution_layer": "look", - "contribution_apply_as_variant": True, - "contribution_target_product": "usdAsset" - }, - { - "productType": "groom", - "contribution_layer": "groom", - "contribution_apply_as_variant": True, - "contribution_target_product": "usdAsset" - }, - { - "productType": "rig", - "contribution_layer": "rig", - "contribution_apply_as_variant": True, - "contribution_target_product": "usdShot" - }, - { - "productType": "usd", - "contribution_layer": "assembly", - "contribution_apply_as_variant": False, - "contribution_target_product": "usdShot" - }, - ] - profile = filter_profiles(profiles, { - "productType": instance.data["productType"] + profile = filter_profiles(cls.profiles, { + "product_types": instance.data["productType"] }) if not profile: profile = {} diff --git a/server/settings/publish_plugins.py b/server/settings/publish_plugins.py index 18e7d67f90..462b1e2861 100644 --- a/server/settings/publish_plugins.py +++ b/server/settings/publish_plugins.py @@ -68,6 +68,47 @@ class ContributionLayersModel(BaseSettingsModel): "layer on top.") +class CollectUSDLayerContributionsProfileModel(BaseSettingsModel): + """Profiles to define instance attribute defaults for USD contribution.""" + _layout = "expanded" + product_types: list[str] = SettingsField( + default_factory=list, + title="Product types", + description=( + "The product types to match this profile to. When matched, the" + " settings below would apply to the instance as default" + " attributes." + ), + ) + contribution_layer: str = SettingsField( + "", + title="Contribution Department Layer", + description=( + "The default contribution layer to apply the contribution to when" + " matching this profile. The layer name should be in the" + " 'Department Layer Orders' list to get a sensible order." + ), + ) + contribution_apply_as_variant: bool = SettingsField( + True, + title="Apply as variant", + description=( + "The default 'Apply as variant' state for instances matching this" + " profile. Usually enabled for asset contributions and disabled" + " for shot contributions." + ), + ) + contribution_target_product: str = SettingsField( + "usdAsset", + title="Target Product", + description=( + "The default destination product name to apply the contribution to" + " when matching this profile." + " Usually e.g. 'usdAsset' or 'usdShot'." + ), + ) + + class CollectUSDLayerContributionsModel(BaseSettingsModel): enabled: bool = SettingsField(True, title="Enabled") contribution_layers: list[ContributionLayersModel] = SettingsField( @@ -77,6 +118,14 @@ class CollectUSDLayerContributionsModel(BaseSettingsModel): "ordering inside the USD contribution workflow." ) ) + profiles: list[CollectUSDLayerContributionsProfileModel] = SettingsField( + default_factory=list, + title="Profiles", + description=( + "Define attribute defaults for USD Contributions on publish" + " instances." + ) + ) @validator("contribution_layers") def validate_unique_outputs(cls, value): @@ -1017,6 +1066,38 @@ DEFAULT_PUBLISH_VALUES = { {"name": "fx", "order": 500}, {"name": "lighting", "order": 600}, ], + "profiles": [ + { + "product_types": ["model"], + "contribution_layer": "model", + "contribution_apply_as_variant": True, + "contribution_target_product": "usdAsset" + }, + { + "product_types": ["look"], + "contribution_layer": "look", + "contribution_apply_as_variant": True, + "contribution_target_product": "usdAsset" + }, + { + "product_types": ["groom"], + "contribution_layer": "groom", + "contribution_apply_as_variant": True, + "contribution_target_product": "usdAsset" + }, + { + "product_types": ["rig"], + "contribution_layer": "rig", + "contribution_apply_as_variant": True, + "contribution_target_product": "usdAsset" + }, + { + "product_types": ["usd"], + "contribution_layer": "assembly", + "contribution_apply_as_variant": False, + "contribution_target_product": "usdShot" + }, + ] }, "ValidateEditorialAssetName": { "enabled": True, From 602faa81dc75323cc34797ea1e4de5aab0b2e778 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Tue, 18 Feb 2025 17:41:52 +0100 Subject: [PATCH 3/3] Add Task Types profiles filtering for defaults (note that it uses current context, not the task type from the instance) --- .../publish/extract_usd_layer_contributions.py | 4 +++- server/settings/publish_plugins.py | 17 +++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py b/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py index bf4ca70afa..a2698b03de 100644 --- a/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py +++ b/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py @@ -470,8 +470,10 @@ class CollectUSDLayerContributions(pyblish.api.InstancePlugin, return [] # Set default target layer based on product type + current_context_task_type = create_context.get_current_task_type() profile = filter_profiles(cls.profiles, { - "product_types": instance.data["productType"] + "product_types": instance.data["productType"], + "task_types": current_context_task_type }) if not profile: profile = {} diff --git a/server/settings/publish_plugins.py b/server/settings/publish_plugins.py index 462b1e2861..d10a6b7507 100644 --- a/server/settings/publish_plugins.py +++ b/server/settings/publish_plugins.py @@ -79,6 +79,17 @@ class CollectUSDLayerContributionsProfileModel(BaseSettingsModel): " settings below would apply to the instance as default" " attributes." ), + section="Filter" + ) + task_types: list[str] = SettingsField( + default_factory=list, + title="Task Types", + enum_resolver=task_types_enum, + description=( + "The current create context task type to filter against. This" + " allows to filter the profile to only be valid if currently " + " creating from within that task type." + ), ) contribution_layer: str = SettingsField( "", @@ -88,6 +99,7 @@ class CollectUSDLayerContributionsProfileModel(BaseSettingsModel): " matching this profile. The layer name should be in the" " 'Department Layer Orders' list to get a sensible order." ), + section="Instance attribute defaults", ) contribution_apply_as_variant: bool = SettingsField( True, @@ -1069,30 +1081,35 @@ DEFAULT_PUBLISH_VALUES = { "profiles": [ { "product_types": ["model"], + "task_types": [], "contribution_layer": "model", "contribution_apply_as_variant": True, "contribution_target_product": "usdAsset" }, { "product_types": ["look"], + "task_types": [], "contribution_layer": "look", "contribution_apply_as_variant": True, "contribution_target_product": "usdAsset" }, { "product_types": ["groom"], + "task_types": [], "contribution_layer": "groom", "contribution_apply_as_variant": True, "contribution_target_product": "usdAsset" }, { "product_types": ["rig"], + "task_types": [], "contribution_layer": "rig", "contribution_apply_as_variant": True, "contribution_target_product": "usdAsset" }, { "product_types": ["usd"], + "task_types": [], "contribution_layer": "assembly", "contribution_apply_as_variant": False, "contribution_target_product": "usdShot"