Merge branch 'develop' into enhancement/1470-yn-0067-publisher-crashed-plugins

This commit is contained in:
Jakub Trllo 2025-12-17 14:09:09 +01:00 committed by GitHub
commit 3e100408c3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 84 additions and 39 deletions

View file

@ -2,6 +2,7 @@ from operator import attrgetter
import dataclasses import dataclasses
import os import os
import platform import platform
from collections import defaultdict
from typing import Any, Dict, List from typing import Any, Dict, List
import pyblish.api import pyblish.api
@ -13,10 +14,11 @@ except ImportError:
from ayon_core.lib import ( from ayon_core.lib import (
TextDef, TextDef,
BoolDef, BoolDef,
NumberDef,
UISeparatorDef, UISeparatorDef,
UILabelDef, UILabelDef,
EnumDef, EnumDef,
filter_profiles, NumberDef filter_profiles,
) )
try: try:
from ayon_core.pipeline.usdlib import ( from ayon_core.pipeline.usdlib import (
@ -278,20 +280,24 @@ class CollectUSDLayerContributions(pyblish.api.InstancePlugin,
# level, you can add it directly from the publisher at that particular # level, you can add it directly from the publisher at that particular
# order. Future publishes will then see the existing contribution and will # order. Future publishes will then see the existing contribution and will
# persist adding it to future bootstraps at that order # persist adding it to future bootstraps at that order
contribution_layers: Dict[str, int] = { contribution_layers: Dict[str, Dict[str, int]] = {
# asset layers # asset layers
"asset": {
"model": 100, "model": 100,
"assembly": 150, "assembly": 150,
"groom": 175, "groom": 175,
"look": 200, "look": 200,
"rig": 300, "rig": 300,
},
# shot layers # shot layers
"shot": {
"layout": 200, "layout": 200,
"animation": 300, "animation": 300,
"simulation": 400, "simulation": 400,
"fx": 500, "fx": 500,
"lighting": 600, "lighting": 600,
} }
}
# Default profiles to set certain instance attribute defaults based on # Default profiles to set certain instance attribute defaults based on
# profiles in settings # profiles in settings
profiles: List[Dict[str, Any]] = [] profiles: List[Dict[str, Any]] = []
@ -305,12 +311,18 @@ class CollectUSDLayerContributions(pyblish.api.InstancePlugin,
cls.enabled = plugin_settings.get("enabled", cls.enabled) cls.enabled = plugin_settings.get("enabled", cls.enabled)
# Define contribution layers via settings # Define contribution layers via settings by their scope
contribution_layers = {} contribution_layers = defaultdict(dict)
for entry in plugin_settings.get("contribution_layers", []): for entry in plugin_settings.get("contribution_layers", []):
contribution_layers[entry["name"]] = int(entry["order"]) for scope in entry.get("scope", []):
contribution_layers[scope][entry["name"]] = int(entry["order"])
if contribution_layers: if contribution_layers:
cls.contribution_layers = contribution_layers cls.contribution_layers = dict(contribution_layers)
else:
cls.log.warning(
"No scoped contribution layers found in settings, falling back"
" to CollectUSDLayerContributions plug-in defaults..."
)
cls.profiles = plugin_settings.get("profiles", []) cls.profiles = plugin_settings.get("profiles", [])
@ -355,10 +367,11 @@ class CollectUSDLayerContributions(pyblish.api.InstancePlugin,
asset_product = contribution.target_product asset_product = contribution.target_product
layer_product = "{}_{}".format(asset_product, contribution.layer_id) layer_product = "{}_{}".format(asset_product, contribution.layer_id)
layer_order: int = self.contribution_layers.get(
attr_values["contribution_layer"], 0
)
scope: str = attr_values["contribution_target_product_init"]
layer_order: int = (
self.contribution_layers[scope][attr_values["contribution_layer"]]
)
# Layer contribution instance # Layer contribution instance
layer_instance = self.get_or_create_instance( layer_instance = self.get_or_create_instance(
product_name=layer_product, product_name=layer_product,
@ -489,14 +502,14 @@ class CollectUSDLayerContributions(pyblish.api.InstancePlugin,
profile = {} profile = {}
# Define defaults # Define defaults
default_enabled = profile.get("contribution_enabled", True) default_enabled: bool = profile.get("contribution_enabled", True)
default_contribution_layer = profile.get( default_contribution_layer = profile.get(
"contribution_layer", None) "contribution_layer", None)
default_apply_as_variant = profile.get( default_apply_as_variant: bool = profile.get(
"contribution_apply_as_variant", False) "contribution_apply_as_variant", False)
default_target_product = profile.get( default_target_product: str = profile.get(
"contribution_target_product", "usdAsset") "contribution_target_product", "usdAsset")
default_init_as = ( default_init_as: str = (
"asset" "asset"
if profile.get("contribution_target_product") == "usdAsset" if profile.get("contribution_target_product") == "usdAsset"
else "shot") else "shot")
@ -509,6 +522,12 @@ class CollectUSDLayerContributions(pyblish.api.InstancePlugin,
visible = publish_attributes.get("contribution_enabled", True) visible = publish_attributes.get("contribution_enabled", True)
variant_visible = visible and publish_attributes.get( variant_visible = visible and publish_attributes.get(
"contribution_apply_as_variant", True) "contribution_apply_as_variant", True)
init_as: str = publish_attributes.get(
"contribution_target_product_init", default_init_as)
contribution_layers = cls.contribution_layers.get(
init_as, {}
)
return [ return [
UISeparatorDef("usd_container_settings1"), UISeparatorDef("usd_container_settings1"),
@ -558,7 +577,7 @@ class CollectUSDLayerContributions(pyblish.api.InstancePlugin,
"predefined ordering.\nA higher order (further down " "predefined ordering.\nA higher order (further down "
"the list) will contribute as a stronger opinion." "the list) will contribute as a stronger opinion."
), ),
items=list(cls.contribution_layers.keys()), items=list(contribution_layers.keys()),
default=default_contribution_layer, default=default_contribution_layer,
visible=visible), visible=visible),
# TODO: We may want to make the visibility of this optional # TODO: We may want to make the visibility of this optional
@ -619,7 +638,11 @@ class CollectUSDLayerContributions(pyblish.api.InstancePlugin,
# Update attributes if any of the following plug-in attributes # Update attributes if any of the following plug-in attributes
# change: # change:
keys = ["contribution_enabled", "contribution_apply_as_variant"] keys = {
"contribution_enabled",
"contribution_apply_as_variant",
"contribution_target_product_init",
}
for instance_change in event["changes"]: for instance_change in event["changes"]:
instance = instance_change["instance"] instance = instance_change["instance"]

View file

@ -74,13 +74,35 @@ class CollectFramesFixDefModel(BaseSettingsModel):
) )
def usd_contribution_layer_types():
return [
{"value": "asset", "label": "Asset"},
{"value": "shot", "label": "Shot"},
]
class ContributionLayersModel(BaseSettingsModel): class ContributionLayersModel(BaseSettingsModel):
_layout = "compact" _layout = "compact"
name: str = SettingsField(title="Name") name: str = SettingsField(
order: str = SettingsField( default="",
regex="[A-Za-z0-9_-]+",
title="Name")
scope: list[str] = SettingsField(
# This should actually be returned from a callable to `default_factory`
# because lists are mutable. However, the frontend can't interpret
# the callable. It will fail to apply it as the default. Specifying
# this default directly did not show any ill side effects.
default=["asset", "shot"],
title="Scope",
min_items=1,
enum_resolver=usd_contribution_layer_types)
order: int = SettingsField(
default=0,
title="Order", title="Order",
description="Higher order means a higher strength and stacks the " description=(
"layer on top.") "Higher order means a higher strength and stacks the layer on top."
)
)
class CollectUSDLayerContributionsProfileModel(BaseSettingsModel): class CollectUSDLayerContributionsProfileModel(BaseSettingsModel):
@ -1382,17 +1404,17 @@ DEFAULT_PUBLISH_VALUES = {
"enabled": True, "enabled": True,
"contribution_layers": [ "contribution_layers": [
# Asset layers # Asset layers
{"name": "model", "order": 100}, {"name": "model", "order": 100, "scope": ["asset"]},
{"name": "assembly", "order": 150}, {"name": "assembly", "order": 150, "scope": ["asset"]},
{"name": "groom", "order": 175}, {"name": "groom", "order": 175, "scope": ["asset"]},
{"name": "look", "order": 200}, {"name": "look", "order": 200, "scope": ["asset"]},
{"name": "rig", "order": 300}, {"name": "rig", "order": 300, "scope": ["asset"]},
# Shot layers # Shot layers
{"name": "layout", "order": 200}, {"name": "layout", "order": 200, "scope": ["shot"]},
{"name": "animation", "order": 300}, {"name": "animation", "order": 300, "scope": ["shot"]},
{"name": "simulation", "order": 400}, {"name": "simulation", "order": 400, "scope": ["shot"]},
{"name": "fx", "order": 500}, {"name": "fx", "order": 500, "scope": ["shot"]},
{"name": "lighting", "order": 600}, {"name": "lighting", "order": 600, "scope": ["shot"]},
], ],
"profiles": [ "profiles": [
{ {