Merge pull request #5497 from ynput/enhancement/abstracting_colorspace_publishing_functions

This commit is contained in:
Jakub Ježek 2023-09-07 14:54:24 +02:00 committed by GitHub
commit 0fa4acb98b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 140 additions and 113 deletions

View file

@ -13,12 +13,17 @@ from openpype.lib import (
Logger
)
from openpype.pipeline import Anatomy
from openpype.lib.transcoding import VIDEO_EXTENSIONS, IMAGE_EXTENSIONS
log = Logger.get_logger(__name__)
class CashedData:
remapping = None
class CachedData:
remapping = {}
allowed_exts = {
ext.lstrip(".") for ext in IMAGE_EXTENSIONS.union(VIDEO_EXTENSIONS)
}
@contextlib.contextmanager
@ -546,15 +551,15 @@ def get_remapped_colorspace_to_native(
Union[str, None]: native colorspace name defined in remapping or None
"""
CashedData.remapping.setdefault(host_name, {})
if CashedData.remapping[host_name].get("to_native") is None:
CachedData.remapping.setdefault(host_name, {})
if CachedData.remapping[host_name].get("to_native") is None:
remapping_rules = imageio_host_settings["remapping"]["rules"]
CashedData.remapping[host_name]["to_native"] = {
CachedData.remapping[host_name]["to_native"] = {
rule["ocio_name"]: rule["host_native_name"]
for rule in remapping_rules
}
return CashedData.remapping[host_name]["to_native"].get(
return CachedData.remapping[host_name]["to_native"].get(
ocio_colorspace_name)
@ -572,15 +577,15 @@ def get_remapped_colorspace_from_native(
Union[str, None]: Ocio colorspace name defined in remapping or None.
"""
CashedData.remapping.setdefault(host_name, {})
if CashedData.remapping[host_name].get("from_native") is None:
CachedData.remapping.setdefault(host_name, {})
if CachedData.remapping[host_name].get("from_native") is None:
remapping_rules = imageio_host_settings["remapping"]["rules"]
CashedData.remapping[host_name]["from_native"] = {
CachedData.remapping[host_name]["from_native"] = {
rule["host_native_name"]: rule["ocio_name"]
for rule in remapping_rules
}
return CashedData.remapping[host_name]["from_native"].get(
return CachedData.remapping[host_name]["from_native"].get(
host_native_colorspace_name)
@ -601,3 +606,118 @@ def _get_imageio_settings(project_settings, host_name):
imageio_host = project_settings.get(host_name, {}).get("imageio", {})
return imageio_global, imageio_host
def get_colorspace_settings_from_publish_context(context_data):
"""Returns solved settings for the host context.
Args:
context_data (publish.Context.data): publishing context data
Returns:
tuple | bool: config, file rules or None
"""
if "imageioSettings" in context_data and context_data["imageioSettings"]:
return context_data["imageioSettings"]
project_name = context_data["projectName"]
host_name = context_data["hostName"]
anatomy_data = context_data["anatomyData"]
project_settings_ = context_data["project_settings"]
config_data = get_imageio_config(
project_name, host_name,
project_settings=project_settings_,
anatomy_data=anatomy_data
)
# caching invalid state, so it's not recalculated all the time
file_rules = None
if config_data:
file_rules = get_imageio_file_rules(
project_name, host_name,
project_settings=project_settings_
)
# caching settings for future instance processing
context_data["imageioSettings"] = (config_data, file_rules)
return config_data, file_rules
def set_colorspace_data_to_representation(
representation, context_data,
colorspace=None,
log=None
):
"""Sets colorspace data to representation.
Args:
representation (dict): publishing representation
context_data (publish.Context.data): publishing context data
colorspace (str, optional): colorspace name. Defaults to None.
log (logging.Logger, optional): logger instance. Defaults to None.
Example:
```
{
# for other publish plugins and loaders
"colorspace": "linear",
"config": {
# for future references in case need
"path": "/abs/path/to/config.ocio",
# for other plugins within remote publish cases
"template": "{project[root]}/path/to/config.ocio"
}
}
```
"""
log = log or Logger.get_logger(__name__)
file_ext = representation["ext"]
# check if `file_ext` in lower case is in CachedData.allowed_exts
if file_ext.lstrip(".").lower() not in CachedData.allowed_exts:
log.debug(
"Extension '{}' is not in allowed extensions.".format(file_ext)
)
return
# get colorspace settings
config_data, file_rules = get_colorspace_settings_from_publish_context(
context_data)
# in case host color management is not enabled
if not config_data:
log.warning("Host's colorspace management is disabled.")
return
log.debug("Config data is: `{}`".format(config_data))
project_name = context_data["projectName"]
host_name = context_data["hostName"]
project_settings = context_data["project_settings"]
# get one filename
filename = representation["files"]
if isinstance(filename, list):
filename = filename[0]
# get matching colorspace from rules
colorspace = colorspace or get_imageio_colorspace_from_filepath(
filename, host_name, project_name,
config_data=config_data,
file_rules=file_rules,
project_settings=project_settings
)
# infuse data to representation
if colorspace:
colorspace_data = {
"colorspace": colorspace,
"config": config_data
}
# update data key
representation["colorspaceData"] = colorspace_data

View file

@ -1,6 +1,5 @@
import inspect
from abc import ABCMeta
from pprint import pformat
import pyblish.api
from pyblish.plugin import MetaPlugin, ExplicitMetaPlugin
from openpype.lib.transcoding import VIDEO_EXTENSIONS, IMAGE_EXTENSIONS
@ -14,9 +13,8 @@ from .lib import (
)
from openpype.pipeline.colorspace import (
get_imageio_colorspace_from_filepath,
get_imageio_config,
get_imageio_file_rules
get_colorspace_settings_from_publish_context,
set_colorspace_data_to_representation
)
@ -306,12 +304,8 @@ class ColormanagedPyblishPluginMixin(object):
matching colorspace from rules. Finally, it infuses this
data into the representation.
"""
allowed_ext = set(
ext.lstrip(".") for ext in IMAGE_EXTENSIONS.union(VIDEO_EXTENSIONS)
)
@staticmethod
def get_colorspace_settings(context):
def get_colorspace_settings(self, context):
"""Returns solved settings for the host context.
Args:
@ -320,50 +314,18 @@ class ColormanagedPyblishPluginMixin(object):
Returns:
tuple | bool: config, file rules or None
"""
if "imageioSettings" in context.data:
return context.data["imageioSettings"]
project_name = context.data["projectName"]
host_name = context.data["hostName"]
anatomy_data = context.data["anatomyData"]
project_settings_ = context.data["project_settings"]
config_data = get_imageio_config(
project_name, host_name,
project_settings=project_settings_,
anatomy_data=anatomy_data
)
# in case host color management is not enabled
if not config_data:
return None
file_rules = get_imageio_file_rules(
project_name, host_name,
project_settings=project_settings_
)
# caching settings for future instance processing
context.data["imageioSettings"] = (config_data, file_rules)
return config_data, file_rules
return get_colorspace_settings_from_publish_context(context.data)
def set_representation_colorspace(
self, representation, context,
colorspace=None,
colorspace_settings=None
):
"""Sets colorspace data to representation.
Args:
representation (dict): publishing representation
context (publish.Context): publishing context
config_data (dict): host resolved config data
file_rules (dict): host resolved file rules data
colorspace (str, optional): colorspace name. Defaults to None.
colorspace_settings (tuple[dict, dict], optional):
Settings for config_data and file_rules.
Defaults to None.
Example:
```
@ -380,64 +342,10 @@ class ColormanagedPyblishPluginMixin(object):
```
"""
ext = representation["ext"]
# check extension
self.log.debug("__ ext: `{}`".format(ext))
# check if ext in lower case is in self.allowed_ext
if ext.lstrip(".").lower() not in self.allowed_ext:
self.log.debug(
"Extension '{}' is not in allowed extensions.".format(ext)
)
return
if colorspace_settings is None:
colorspace_settings = self.get_colorspace_settings(context)
# in case host color management is not enabled
if not colorspace_settings:
self.log.warning("Host's colorspace management is disabled.")
return
# unpack colorspace settings
config_data, file_rules = colorspace_settings
if not config_data:
# warn in case no colorspace path was defined
self.log.warning("No colorspace management was defined")
return
self.log.debug("Config data is: `{}`".format(config_data))
project_name = context.data["projectName"]
host_name = context.data["hostName"]
project_settings = context.data["project_settings"]
# get one filename
filename = representation["files"]
if isinstance(filename, list):
filename = filename[0]
self.log.debug("__ filename: `{}`".format(filename))
# get matching colorspace from rules
colorspace = colorspace or get_imageio_colorspace_from_filepath(
filename, host_name, project_name,
config_data=config_data,
file_rules=file_rules,
project_settings=project_settings
# using cached settings if available
set_colorspace_data_to_representation(
representation, context.data,
colorspace,
log=self.log
)
self.log.debug("__ colorspace: `{}`".format(colorspace))
# infuse data to representation
if colorspace:
colorspace_data = {
"colorspace": colorspace,
"config": config_data
}
# update data key
representation["colorspaceData"] = colorspace_data
self.log.debug("__ colorspace_data: `{}`".format(
pformat(colorspace_data)))

View file

@ -28,10 +28,9 @@ class TestPipelineColorspace(TestPipeline):
cd to OpenPype repo root dir
poetry run python ./start.py runtests ../tests/unit/openpype/pipeline
"""
TEST_FILES = [
(
"1Lf-mFxev7xiwZCWfImlRcw7Fj8XgNQMh",
"1csqimz8bbNcNgxtEXklLz6GRv91D3KgA",
"test_pipeline_colorspace.zip",
""
)