Merge pull request #973 from BigRoy/enhancement/attributes_by_families

USD contribution: Set up different default values based on profiles
This commit is contained in:
Roy Nieterau 2025-02-18 21:23:48 +01:00 committed by GitHub
commit ad22c44df3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 133 additions and 32 deletions

View file

@ -1,7 +1,7 @@
from operator import attrgetter from operator import attrgetter
import dataclasses import dataclasses
import os import os
from typing import Dict from typing import Any, Dict, List
import pyblish.api import pyblish.api
try: try:
@ -14,7 +14,8 @@ from ayon_core.lib import (
BoolDef, BoolDef,
UISeparatorDef, UISeparatorDef,
UILabelDef, UILabelDef,
EnumDef EnumDef,
filter_profiles
) )
try: try:
from ayon_core.pipeline.usdlib import ( from ayon_core.pipeline.usdlib import (
@ -281,6 +282,9 @@ class CollectUSDLayerContributions(pyblish.api.InstancePlugin,
"fx": 500, "fx": 500,
"lighting": 600, "lighting": 600,
} }
# Default profiles to set certain instance attribute defaults based on
# profiles in settings
profiles: List[Dict[str, Any]] = []
@classmethod @classmethod
def apply_settings(cls, project_settings): def apply_settings(cls, project_settings):
@ -298,6 +302,8 @@ class CollectUSDLayerContributions(pyblish.api.InstancePlugin,
if contribution_layers: if contribution_layers:
cls.contribution_layers = contribution_layers cls.contribution_layers = contribution_layers
cls.profiles = plugin_settings.get("profiles", [])
def process(self, instance): def process(self, instance):
attr_values = self.get_attr_values_from_data(instance.data) attr_values = self.get_attr_values_from_data(instance.data)
@ -463,6 +469,28 @@ class CollectUSDLayerContributions(pyblish.api.InstancePlugin,
if not cls.instance_matches_plugin_families(instance): if not cls.instance_matches_plugin_families(instance):
return [] 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"],
"task_types": current_context_task_type
})
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 # Attributes logic
publish_attributes = instance["publish_attributes"].get( publish_attributes = instance["publish_attributes"].get(
cls.__name__, {}) cls.__name__, {})
@ -495,7 +523,7 @@ class CollectUSDLayerContributions(pyblish.api.InstancePlugin,
"the contribution itself will be added to the " "the contribution itself will be added to the "
"department layer." "department layer."
), ),
default="usdAsset", default=default_target_product,
visible=visible), visible=visible),
EnumDef("contribution_target_product_init", EnumDef("contribution_target_product_init",
label="Initialize as", label="Initialize as",
@ -507,8 +535,8 @@ class CollectUSDLayerContributions(pyblish.api.InstancePlugin,
"setting will do nothing." "setting will do nothing."
), ),
items=["asset", "shot"], items=["asset", "shot"],
default="asset", default=default_init_as,
visible=visible), visible=visible and init_as_visible),
# Asset layer, e.g. model.usd, look.usd, rig.usd # Asset layer, e.g. model.usd, look.usd, rig.usd
EnumDef("contribution_layer", EnumDef("contribution_layer",
@ -520,7 +548,7 @@ class CollectUSDLayerContributions(pyblish.api.InstancePlugin,
"the list) will contribute as a stronger opinion." "the list) will contribute as a stronger opinion."
), ),
items=list(cls.contribution_layers.keys()), items=list(cls.contribution_layers.keys()),
default="model", default=default_contribution_layer,
visible=visible), visible=visible),
BoolDef("contribution_apply_as_variant", BoolDef("contribution_apply_as_variant",
label="Add as variant", label="Add as variant",
@ -532,7 +560,7 @@ class CollectUSDLayerContributions(pyblish.api.InstancePlugin,
"appended to as a sublayer to the department layer " "appended to as a sublayer to the department layer "
"instead." "instead."
), ),
default=True, default=default_apply_as_variant,
visible=visible), visible=visible),
TextDef("contribution_variant_set_name", TextDef("contribution_variant_set_name",
label="Variant Set Name", label="Variant Set Name",
@ -588,31 +616,6 @@ class CollectUSDLayerContributions(pyblish.api.InstancePlugin,
instance.set_publish_plugin_attr_defs(cls.__name__, new_attrs) 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): class ValidateUSDDependencies(pyblish.api.InstancePlugin):
families = ["usdLayer"] families = ["usdLayer"]

View file

@ -68,6 +68,59 @@ class ContributionLayersModel(BaseSettingsModel):
"layer on top.") "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."
),
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(
"",
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."
),
section="Instance attribute defaults",
)
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): class CollectUSDLayerContributionsModel(BaseSettingsModel):
enabled: bool = SettingsField(True, title="Enabled") enabled: bool = SettingsField(True, title="Enabled")
contribution_layers: list[ContributionLayersModel] = SettingsField( contribution_layers: list[ContributionLayersModel] = SettingsField(
@ -77,6 +130,14 @@ class CollectUSDLayerContributionsModel(BaseSettingsModel):
"ordering inside the USD contribution workflow." "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") @validator("contribution_layers")
def validate_unique_outputs(cls, value): def validate_unique_outputs(cls, value):
@ -1017,6 +1078,43 @@ DEFAULT_PUBLISH_VALUES = {
{"name": "fx", "order": 500}, {"name": "fx", "order": 500},
{"name": "lighting", "order": 600}, {"name": "lighting", "order": 600},
], ],
"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"
},
]
}, },
"ValidateEditorialAssetName": { "ValidateEditorialAssetName": {
"enabled": True, "enabled": True,