mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-24 12:54:40 +01:00
Merge branch 'develop' into enhancement/fill_gaps_in_extract_review
This commit is contained in:
commit
7e73b7d1ad
5 changed files with 219 additions and 10 deletions
|
|
@ -52,15 +52,15 @@ def get_product_name_template(
|
|||
# TODO remove formatting keys replacement
|
||||
template = (
|
||||
matching_profile["template"]
|
||||
.replace("{task[name]}", "{task}")
|
||||
.replace("{Task[name]}", "{Task}")
|
||||
.replace("{TASK[NAME]}", "{TASK}")
|
||||
.replace("{product[type]}", "{family}")
|
||||
.replace("{Product[type]}", "{Family}")
|
||||
.replace("{PRODUCT[TYPE]}", "{FAMILY}")
|
||||
.replace("{folder[name]}", "{asset}")
|
||||
.replace("{Folder[name]}", "{Asset}")
|
||||
.replace("{FOLDER[NAME]}", "{ASSET}")
|
||||
.replace("{task}", "{task[name]}")
|
||||
.replace("{Task}", "{Task[name]}")
|
||||
.replace("{TASK}", "{TASK[NAME]}")
|
||||
.replace("{family}", "{product[type]}")
|
||||
.replace("{Family}", "{Product[type]}")
|
||||
.replace("{FAMILY}", "{PRODUCT[TYPE]}")
|
||||
.replace("{asset}", "{folder[name]}")
|
||||
.replace("{Asset}", "{Folder[name]}")
|
||||
.replace("{ASSET}", "{FOLDER[NAME]}")
|
||||
)
|
||||
|
||||
# Make sure template is set (matching may have empty string)
|
||||
|
|
|
|||
106
client/ayon_core/plugins/publish/collect_explicit_resolution.py
Normal file
106
client/ayon_core/plugins/publish/collect_explicit_resolution.py
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
import pyblish.api
|
||||
from ayon_core.lib import EnumDef
|
||||
from ayon_core.pipeline import publish
|
||||
from ayon_core.pipeline.publish import PublishError
|
||||
|
||||
|
||||
class CollectExplicitResolution(
|
||||
pyblish.api.InstancePlugin,
|
||||
publish.AYONPyblishPluginMixin,
|
||||
):
|
||||
"""Collect explicit user defined resolution attributes for instances"""
|
||||
|
||||
label = "Choose Explicit Resolution"
|
||||
order = pyblish.api.CollectorOrder - 0.091
|
||||
settings_category = "core"
|
||||
|
||||
enabled = False
|
||||
|
||||
default_resolution_item = (None, "Don't override")
|
||||
# Settings
|
||||
product_types = []
|
||||
options = []
|
||||
|
||||
# caching resoluton items
|
||||
resolution_items = None
|
||||
|
||||
def process(self, instance):
|
||||
"""Process the instance and collect explicit resolution attributes"""
|
||||
|
||||
# Get the values from the instance data
|
||||
values = self.get_attr_values_from_data(instance.data)
|
||||
resolution_value = values.get("explicit_resolution", None)
|
||||
if resolution_value is None:
|
||||
return
|
||||
|
||||
# Get the width, height and pixel_aspect from the resolution value
|
||||
resolution_data = self._get_resolution_values(resolution_value)
|
||||
|
||||
# Set the values to the instance data
|
||||
instance.data.update(resolution_data)
|
||||
|
||||
def _get_resolution_values(self, resolution_value):
|
||||
"""
|
||||
Returns width, height and pixel_aspect from the resolution value
|
||||
|
||||
Arguments:
|
||||
resolution_value (str): resolution value
|
||||
|
||||
Returns:
|
||||
dict: dictionary with width, height and pixel_aspect
|
||||
"""
|
||||
resolution_items = self._get_resolution_items()
|
||||
# ensure resolution_value is part of expected items
|
||||
item_values = resolution_items.get(resolution_value)
|
||||
|
||||
# if the item is in the cache, get the values from it
|
||||
if item_values:
|
||||
return {
|
||||
"resolutionWidth": item_values["width"],
|
||||
"resolutionHeight": item_values["height"],
|
||||
"pixelAspect": item_values["pixel_aspect"],
|
||||
}
|
||||
|
||||
raise PublishError(
|
||||
f"Invalid resolution value: {resolution_value} "
|
||||
f"expected choices: {resolution_items}"
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def _get_resolution_items(cls):
|
||||
if cls.resolution_items is None:
|
||||
resolution_items = {}
|
||||
for item in cls.options:
|
||||
item_text = (
|
||||
f"{item['width']}x{item['height']} "
|
||||
f"({item['pixel_aspect']})"
|
||||
)
|
||||
resolution_items[item_text] = item
|
||||
|
||||
cls.resolution_items = resolution_items
|
||||
|
||||
return cls.resolution_items
|
||||
|
||||
@classmethod
|
||||
def get_attr_defs_for_instance(
|
||||
cls, create_context, instance,
|
||||
):
|
||||
if instance.product_type not in cls.product_types:
|
||||
return []
|
||||
|
||||
# Get the resolution items
|
||||
resolution_items = cls._get_resolution_items()
|
||||
|
||||
items = [cls.default_resolution_item]
|
||||
# Add all cached resolution items to the dropdown options
|
||||
for item_text in resolution_items:
|
||||
items.append((item_text, item_text))
|
||||
|
||||
return [
|
||||
EnumDef(
|
||||
"explicit_resolution",
|
||||
items,
|
||||
default="Don't override",
|
||||
label="Force product resolution",
|
||||
),
|
||||
]
|
||||
|
|
@ -10,6 +10,7 @@ ayon_server_version = ">=1.7.6,<2.0.0"
|
|||
ayon_launcher_version = ">=1.0.2"
|
||||
ayon_required_addons = {}
|
||||
ayon_compatible_addons = {
|
||||
"ayon_ocio": ">=1.2.1",
|
||||
"harmony": ">0.4.0",
|
||||
"fusion": ">=0.3.3",
|
||||
"openrv": ">=1.0.2",
|
||||
|
|
|
|||
|
|
@ -71,6 +71,24 @@ def _fallback_ocio_config_profile_types():
|
|||
|
||||
def _ocio_built_in_paths():
|
||||
return [
|
||||
{
|
||||
"value": "{BUILTIN_OCIO_ROOT}/aces_2.0/studio-config-v3.0.0_aces-v2.0_ocio-v2.4.ocio", # noqa: E501
|
||||
"label": "ACES 2.0 Studio (OCIO v2.4)",
|
||||
"description": (
|
||||
"Aces 2.0 Studio OCIO config file. Requires OCIO v2.4.")
|
||||
},
|
||||
{
|
||||
"value": "{BUILTIN_OCIO_ROOT}/aces_1.3/studio-config-v1.0.0_aces-v1.3_ocio-v2.1.ocio", # noqa: E501
|
||||
"label": "ACES 1.3 Studio (OCIO v2.1)",
|
||||
"description": (
|
||||
"Aces 1.3 Studio OCIO config file. Requires OCIO v2.1.")
|
||||
},
|
||||
{
|
||||
"value": "{BUILTIN_OCIO_ROOT}/aces_1.3/studio-config-v1.0.0_aces-v1.3_ocio-v2.0.ocio", # noqa: E501
|
||||
"label": "ACES 1.3 Studio (OCIO v2)",
|
||||
"description": (
|
||||
"Aces 1.3 Studio OCIO config file. Requires OCIO v2.")
|
||||
},
|
||||
{
|
||||
"value": "{BUILTIN_OCIO_ROOT}/aces_1.2/config.ocio",
|
||||
"label": "ACES 1.2",
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
from pydantic import validator
|
||||
from typing import Any
|
||||
|
||||
from ayon_server.settings import (
|
||||
BaseSettingsModel,
|
||||
|
|
@ -9,7 +10,7 @@ from ayon_server.settings import (
|
|||
task_types_enum,
|
||||
anatomy_template_items_enum
|
||||
)
|
||||
|
||||
from ayon_server.exceptions import BadRequestException
|
||||
from ayon_server.types import ColorRGBA_uint8
|
||||
|
||||
|
||||
|
|
@ -167,6 +168,78 @@ class CollectUSDLayerContributionsModel(BaseSettingsModel):
|
|||
return value
|
||||
|
||||
|
||||
class ResolutionOptionsModel(BaseSettingsModel):
|
||||
_layout = "compact"
|
||||
width: int = SettingsField(
|
||||
1920,
|
||||
ge=0,
|
||||
le=100000,
|
||||
title="Width",
|
||||
description=(
|
||||
"Width resolution number value"),
|
||||
placeholder="Width"
|
||||
)
|
||||
height: int = SettingsField(
|
||||
1080,
|
||||
title="Height",
|
||||
ge=0,
|
||||
le=100000,
|
||||
description=(
|
||||
"Height resolution number value"),
|
||||
placeholder="Height"
|
||||
)
|
||||
pixel_aspect: float = SettingsField(
|
||||
1.0,
|
||||
title="Pixel aspect",
|
||||
ge=0.0,
|
||||
le=100000.0,
|
||||
description=(
|
||||
"Pixel Aspect resolution decimal number value"),
|
||||
placeholder="Pixel aspect"
|
||||
)
|
||||
|
||||
|
||||
def ensure_unique_resolution_option(
|
||||
objects: list[Any], field_name: str | None = None) -> None: # noqa: C901
|
||||
"""Ensure a list of objects have unique option attributes.
|
||||
|
||||
This function checks if the list of objects has unique 'width',
|
||||
'height' and 'pixel_aspect' properties.
|
||||
"""
|
||||
options = set()
|
||||
for obj in objects:
|
||||
item_test_text = f"{obj.width}x{obj.height}x{obj.pixel_aspect}"
|
||||
if item_test_text in options:
|
||||
raise BadRequestException(
|
||||
f"Duplicate option '{item_test_text}'")
|
||||
|
||||
options.add(item_test_text)
|
||||
|
||||
|
||||
class CollectExplicitResolutionModel(BaseSettingsModel):
|
||||
enabled: bool = SettingsField(True, title="Enabled")
|
||||
product_types: list[str] = SettingsField(
|
||||
default_factory=list,
|
||||
title="Product types",
|
||||
description=(
|
||||
"Only activate the attribute for following product types."
|
||||
)
|
||||
)
|
||||
options: list[ResolutionOptionsModel] = SettingsField(
|
||||
default_factory=list,
|
||||
title="Resolution choices",
|
||||
description=(
|
||||
"Available resolution choices to be displayed in "
|
||||
"the publishers attribute."
|
||||
)
|
||||
)
|
||||
|
||||
@validator("options")
|
||||
def validate_unique_resolution_options(cls, value):
|
||||
ensure_unique_resolution_option(value)
|
||||
return value
|
||||
|
||||
|
||||
class AyonEntityURIModel(BaseSettingsModel):
|
||||
use_ayon_entity_uri: bool = SettingsField(
|
||||
title="Use AYON Entity URI",
|
||||
|
|
@ -1012,6 +1085,10 @@ class PublishPuginsModel(BaseSettingsModel):
|
|||
title="Collect USD Layer Contributions",
|
||||
)
|
||||
)
|
||||
CollectExplicitResolution: CollectExplicitResolutionModel = SettingsField(
|
||||
default_factory=CollectExplicitResolutionModel,
|
||||
title="Collect Explicit Resolution"
|
||||
)
|
||||
ValidateEditorialAssetName: ValidateBaseModel = SettingsField(
|
||||
default_factory=ValidateBaseModel,
|
||||
title="Validate Editorial Asset Name"
|
||||
|
|
@ -1186,6 +1263,13 @@ DEFAULT_PUBLISH_VALUES = {
|
|||
},
|
||||
]
|
||||
},
|
||||
"CollectExplicitResolution": {
|
||||
"enabled": True,
|
||||
"product_types": [
|
||||
"shot"
|
||||
],
|
||||
"options": []
|
||||
},
|
||||
"ValidateEditorialAssetName": {
|
||||
"enabled": True,
|
||||
"optional": False,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue