From 3d321b48960722a54baa74c7c833d739ffd9eda2 Mon Sep 17 00:00:00 2001 From: Vincent Ullmann Date: Tue, 9 Dec 2025 15:21:23 +0000 Subject: [PATCH 1/7] add verbose-flag to get_oiio_info_for_input and changed oiio_color_convert to use verbose=False --- client/ayon_core/lib/transcoding.py | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/client/ayon_core/lib/transcoding.py b/client/ayon_core/lib/transcoding.py index b4a3e77f5a..feb31a46e1 100644 --- a/client/ayon_core/lib/transcoding.py +++ b/client/ayon_core/lib/transcoding.py @@ -131,16 +131,28 @@ def get_transcode_temp_directory(): ) -def get_oiio_info_for_input(filepath, logger=None, subimages=False): +def get_oiio_info_for_input( + filepath, + logger=None, + subimages=False, + verbose=True, +): """Call oiiotool to get information about input and return stdout. + Args: + filepath (str): Path to file. + logger (logging.Logger): Logger used for logging. + subimages (bool): include info about subimages in the output. + verbose (bool): get the full metadata about each input image. + Stdout should contain xml format string. """ args = get_oiio_tool_args( "oiiotool", "--info", - "-v" ) + if verbose: + args.append("-v") if subimages: args.append("-a") @@ -1178,7 +1190,11 @@ def oiio_color_convert( if logger is None: logger = logging.getLogger(__name__) - input_info = get_oiio_info_for_input(input_path, logger=logger) + input_info = get_oiio_info_for_input( + input_path, + logger=logger, + verbose=False, + ) # Collect channels to export input_arg, channels_arg = get_oiio_input_and_channel_args(input_info) From 97a8b13a4e5c7687190d4699caae7483d2fecff8 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 10 Dec 2025 12:56:42 +0100 Subject: [PATCH 2/7] Allow specifying a strength ordering offset for each contribution to a single department layer --- client/ayon_core/pipeline/usdlib.py | 24 ++++++++------- .../extract_usd_layer_contributions.py | 29 ++++++++++++++----- 2 files changed, 36 insertions(+), 17 deletions(-) diff --git a/client/ayon_core/pipeline/usdlib.py b/client/ayon_core/pipeline/usdlib.py index 095f6fdc57..6b9d19fd35 100644 --- a/client/ayon_core/pipeline/usdlib.py +++ b/client/ayon_core/pipeline/usdlib.py @@ -299,7 +299,6 @@ def add_ordered_sublayer(layer, contribution_path, layer_id, order=None, sdf format args metadata if enabled) """ - # Add the order with the contribution path so that for future # contributions we can again use it to magically fit into the # ordering. We put this in the path because sublayer paths do @@ -317,20 +316,25 @@ def add_ordered_sublayer(layer, contribution_path, layer_id, order=None, # If the layer was already in the layers, then replace it for index, existing_path in enumerate(layer.subLayerPaths): args = get_sdf_format_args(existing_path) - existing_layer = args.get("layer_id") - if existing_layer == layer_id: + existing_layer_id = args.get("layer_id") + if existing_layer_id == layer_id: + existing_layer = layer.subLayerPaths[index] + existing_order = args.get("order") + existing_order = int(existing_order) if existing_order else None + if order is not None and order != existing_order: + # We need to move the layer, so we will remove this index + # and then re-insert it below at the right order + log.debug(f"Removing existing layer: {existing_layer}") + del layer.subLayerPaths[index] + break + # Put it in the same position where it was before when swapping # it with the original, also take over its order metadata - order = args.get("order") - if order is not None: - order = int(order) - else: - order = None contribution_path = _format_path(contribution_path, - order=order, + order=existing_order, layer_id=layer_id) log.debug( - f"Replacing existing layer: {layer.subLayerPaths[index]} " + f"Replacing existing layer: {existing_layer} " f"-> {contribution_path}" ) layer.subLayerPaths[index] = contribution_path 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 2c4cc5aac2..12e0931e89 100644 --- a/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py +++ b/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py @@ -16,7 +16,7 @@ from ayon_core.lib import ( UISeparatorDef, UILabelDef, EnumDef, - filter_profiles + filter_profiles, NumberDef ) try: from ayon_core.pipeline.usdlib import ( @@ -275,7 +275,7 @@ class CollectUSDLayerContributions(pyblish.api.InstancePlugin, # the contributions so that we can design a system where custom # contributions outside the predefined orders are possible to be # managed. So that if a particular asset requires an extra contribution - # level, you can add itdirectly 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 # persist adding it to future bootstraps at that order contribution_layers: Dict[str, int] = { @@ -334,10 +334,12 @@ class CollectUSDLayerContributions(pyblish.api.InstancePlugin, attr_values[key] = attr_values[key].format(**data) # Define contribution - order = self.contribution_layers.get( + order: int = self.contribution_layers.get( attr_values["contribution_layer"], 0 ) + # Allow offsetting the order to the contribution to department layer + order_offset: int = attr_values.get("contribution_order_offset", 0) if attr_values["contribution_apply_as_variant"]: contribution = VariantContribution( instance=instance, @@ -346,14 +348,14 @@ class CollectUSDLayerContributions(pyblish.api.InstancePlugin, variant_set_name=attr_values["contribution_variant_set_name"], variant_name=attr_values["contribution_variant"], variant_is_default=attr_values["contribution_variant_is_default"], # noqa: E501 - order=order + order=order + order_offset ) else: contribution = SublayerContribution( instance=instance, layer_id=attr_values["contribution_layer"], target_product=attr_values["contribution_target_product"], - order=order + order=order + order_offset ) asset_product = contribution.target_product @@ -370,7 +372,7 @@ class CollectUSDLayerContributions(pyblish.api.InstancePlugin, contribution ) layer_instance.data["usd_layer_id"] = contribution.layer_id - layer_instance.data["usd_layer_order"] = contribution.order + layer_instance.data["usd_layer_order"] = order layer_instance.data["productGroup"] = ( instance.data.get("productGroup") or "USD Layer" @@ -561,6 +563,19 @@ class CollectUSDLayerContributions(pyblish.api.InstancePlugin, items=list(cls.contribution_layers.keys()), default=default_contribution_layer, visible=visible), + # TODO: We may want to make the visibility of this optional + # based on studio preference, to avoid complexity when not needed + NumberDef("contribution_order_offset", + label="Strength order offset", + tooltip=( + "The contribution to the department layer will be " + "made with this offset applied. A higher number means " + "a stronger opinion." + ), + default=0, + minimum=-99999, + maximum=99999, + visible=visible), BoolDef("contribution_apply_as_variant", label="Add as variant", tooltip=( @@ -729,7 +744,7 @@ class ExtractUSDLayerContribution(publish.Extractor): layer=sdf_layer, contribution_path=path, layer_id=product_name, - order=None, # unordered + order=contribution.order, add_sdf_arguments_metadata=True ) else: From ced9eadd3d3d182df5341cd3f60897058dfdf9b3 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 10 Dec 2025 16:31:05 +0100 Subject: [PATCH 3/7] Use the instance attribute `Strength order` as the in-layer order completely so that it's the exact value, not an offset to the department layer order --- .../extract_usd_layer_contributions.py | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 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 12e0931e89..01162fc481 100644 --- a/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py +++ b/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py @@ -334,12 +334,7 @@ class CollectUSDLayerContributions(pyblish.api.InstancePlugin, attr_values[key] = attr_values[key].format(**data) # Define contribution - order: int = self.contribution_layers.get( - attr_values["contribution_layer"], 0 - ) - - # Allow offsetting the order to the contribution to department layer - order_offset: int = attr_values.get("contribution_order_offset", 0) + in_layer_order: int = attr_values.get("contribution_in_layer_order", 0) if attr_values["contribution_apply_as_variant"]: contribution = VariantContribution( instance=instance, @@ -348,18 +343,21 @@ class CollectUSDLayerContributions(pyblish.api.InstancePlugin, variant_set_name=attr_values["contribution_variant_set_name"], variant_name=attr_values["contribution_variant"], variant_is_default=attr_values["contribution_variant_is_default"], # noqa: E501 - order=order + order_offset + order=in_layer_order ) else: contribution = SublayerContribution( instance=instance, layer_id=attr_values["contribution_layer"], target_product=attr_values["contribution_target_product"], - order=order + order_offset + order=in_layer_order ) asset_product = contribution.target_product layer_product = "{}_{}".format(asset_product, contribution.layer_id) + layer_order: int = self.contribution_layers.get( + attr_values["contribution_layer"], 0 + ) # Layer contribution instance layer_instance = self.get_or_create_instance( @@ -372,7 +370,7 @@ class CollectUSDLayerContributions(pyblish.api.InstancePlugin, contribution ) layer_instance.data["usd_layer_id"] = contribution.layer_id - layer_instance.data["usd_layer_order"] = order + layer_instance.data["usd_layer_order"] = layer_order layer_instance.data["productGroup"] = ( instance.data.get("productGroup") or "USD Layer" @@ -565,10 +563,10 @@ class CollectUSDLayerContributions(pyblish.api.InstancePlugin, visible=visible), # TODO: We may want to make the visibility of this optional # based on studio preference, to avoid complexity when not needed - NumberDef("contribution_order_offset", - label="Strength order offset", + NumberDef("contribution_in_layer_order", + label="Strength order", tooltip=( - "The contribution to the department layer will be " + "The contribution inside the department layer will be " "made with this offset applied. A higher number means " "a stronger opinion." ), From 3dacfec4ecfe9cbda62a21981b95e8fe45172a3c Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Mon, 15 Dec 2025 10:24:49 +0100 Subject: [PATCH 4/7] allow to change registry name in controller --- .../tools/console_interpreter/abstract.py | 14 ++++++++------ .../tools/console_interpreter/control.py | 17 ++++++++++------- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/client/ayon_core/tools/console_interpreter/abstract.py b/client/ayon_core/tools/console_interpreter/abstract.py index a945e6e498..953365d18c 100644 --- a/client/ayon_core/tools/console_interpreter/abstract.py +++ b/client/ayon_core/tools/console_interpreter/abstract.py @@ -1,6 +1,8 @@ +from __future__ import annotations + from abc import ABC, abstractmethod from dataclasses import dataclass, field -from typing import List, Dict, Optional +from typing import Optional @dataclass @@ -13,8 +15,8 @@ class TabItem: class InterpreterConfig: width: Optional[int] height: Optional[int] - splitter_sizes: List[int] = field(default_factory=list) - tabs: List[TabItem] = field(default_factory=list) + splitter_sizes: list[int] = field(default_factory=list) + tabs: list[TabItem] = field(default_factory=list) class AbstractInterpreterController(ABC): @@ -27,7 +29,7 @@ class AbstractInterpreterController(ABC): self, width: int, height: int, - splitter_sizes: List[int], - tabs: List[Dict[str, str]], - ): + splitter_sizes: list[int], + tabs: list[dict[str, str]], + ) -> None: pass diff --git a/client/ayon_core/tools/console_interpreter/control.py b/client/ayon_core/tools/console_interpreter/control.py index b931b6252c..4c5a4b3419 100644 --- a/client/ayon_core/tools/console_interpreter/control.py +++ b/client/ayon_core/tools/console_interpreter/control.py @@ -1,4 +1,5 @@ -from typing import List, Dict +from __future__ import annotations +from typing import Optional from ayon_core.lib import JSONSettingRegistry from ayon_core.lib.local_settings import get_launcher_local_dir @@ -11,13 +12,15 @@ from .abstract import ( class InterpreterController(AbstractInterpreterController): - def __init__(self): + def __init__(self, name: Optional[str] = None) -> None: + if name is None: + name = "python_interpreter_tool" self._registry = JSONSettingRegistry( - "python_interpreter_tool", + name, get_launcher_local_dir(), ) - def get_config(self): + def get_config(self) -> InterpreterConfig: width = None height = None splitter_sizes = [] @@ -54,9 +57,9 @@ class InterpreterController(AbstractInterpreterController): self, width: int, height: int, - splitter_sizes: List[int], - tabs: List[Dict[str, str]], - ): + splitter_sizes: list[int], + tabs: list[dict[str, str]], + ) -> None: self._registry.set_item("width", width) self._registry.set_item("height", height) self._registry.set_item("splitter_sizes", splitter_sizes) From bd2e26ea50453fd26b51b7c43c77fa17c5953d28 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Mon, 15 Dec 2025 14:03:27 +0100 Subject: [PATCH 5/7] use 'verbose=False' at other places --- client/ayon_core/lib/transcoding.py | 13 ++++++++++--- .../ayon_core/plugins/publish/extract_thumbnail.py | 6 +++++- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/client/ayon_core/lib/transcoding.py b/client/ayon_core/lib/transcoding.py index feb31a46e1..c712472998 100644 --- a/client/ayon_core/lib/transcoding.py +++ b/client/ayon_core/lib/transcoding.py @@ -582,7 +582,7 @@ def get_review_layer_name(src_filepath): return None # Load info about file from oiio tool - input_info = get_oiio_info_for_input(src_filepath) + input_info = get_oiio_info_for_input(src_filepath, verbose=False) if not input_info: return None @@ -1389,7 +1389,11 @@ def get_rescaled_command_arguments( command_args.extend(["-vf", "{0},{1}".format(scale, pad)]) elif application == "oiiotool": - input_info = get_oiio_info_for_input(input_path, logger=log) + input_info = get_oiio_info_for_input( + input_path, + logger=log, + verbose=False, + ) # Collect channels to export _, channels_arg = get_oiio_input_and_channel_args( input_info, alpha_default=1.0) @@ -1529,10 +1533,13 @@ def get_oiio_input_and_channel_args(oiio_input_info, alpha_default=None): """Get input and channel arguments for oiiotool. Args: oiio_input_info (dict): Information about input from oiio tool. - Should be output of function `get_oiio_info_for_input`. + Should be output of function 'get_oiio_info_for_input' (can be + called with 'verbose=False'). alpha_default (float, optional): Default value for alpha channel. + Returns: tuple[str, str]: Tuple of input and channel arguments. + """ channel_names = oiio_input_info["channelnames"] review_channels = get_convert_rgb_channels(channel_names) diff --git a/client/ayon_core/plugins/publish/extract_thumbnail.py b/client/ayon_core/plugins/publish/extract_thumbnail.py index adfb4298b9..2cc1c53d57 100644 --- a/client/ayon_core/plugins/publish/extract_thumbnail.py +++ b/client/ayon_core/plugins/publish/extract_thumbnail.py @@ -478,7 +478,11 @@ class ExtractThumbnail(pyblish.api.InstancePlugin): ) return False - input_info = get_oiio_info_for_input(src_path, logger=self.log) + input_info = get_oiio_info_for_input( + src_path, + logger=self.log, + verbose=False, + ) try: input_arg, channels_arg = get_oiio_input_and_channel_args( input_info From a2387d185619cf1007e629db99278b32581c604d Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Mon, 15 Dec 2025 14:09:27 +0100 Subject: [PATCH 6/7] require kwargs --- client/ayon_core/lib/transcoding.py | 1 + 1 file changed, 1 insertion(+) diff --git a/client/ayon_core/lib/transcoding.py b/client/ayon_core/lib/transcoding.py index ed30a58f98..fcd68fafc7 100644 --- a/client/ayon_core/lib/transcoding.py +++ b/client/ayon_core/lib/transcoding.py @@ -136,6 +136,7 @@ def get_transcode_temp_directory(): def get_oiio_info_for_input( filepath: str, + *, subimages: bool = False, verbose: bool = True, logger: logging.Logger = None, From 0cfc9598750992c80e30897e07c636ececa27cbf Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Mon, 15 Dec 2025 14:25:51 +0100 Subject: [PATCH 7/7] swap order of kwargs --- client/ayon_core/lib/transcoding.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/ayon_core/lib/transcoding.py b/client/ayon_core/lib/transcoding.py index fcd68fafc7..8e9ed90d1a 100644 --- a/client/ayon_core/lib/transcoding.py +++ b/client/ayon_core/lib/transcoding.py @@ -145,9 +145,9 @@ def get_oiio_info_for_input( Args: filepath (str): Path to file. - logger (logging.Logger): Logger used for logging. subimages (bool): include info about subimages in the output. verbose (bool): get the full metadata about each input image. + logger (logging.Logger): Logger used for logging. Stdout should contain xml format string. """ @@ -1252,8 +1252,8 @@ def oiio_color_convert( input_info = get_oiio_info_for_input( first_input_path, - logger=logger, verbose=False, + logger=logger, ) # Collect channels to export