mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-24 21:04:40 +01:00
Merge branch 'develop' of https://github.com/ynput/ayon-core into enhancement/AY-5073_Baking-animation-to-joins-during-the-publishing
This commit is contained in:
commit
f050aaed5f
23 changed files with 733 additions and 350 deletions
|
|
@ -1,7 +1,7 @@
|
|||
from ayon_applications import PreLaunchHook
|
||||
|
||||
from ayon_core.pipeline.colorspace import get_imageio_config
|
||||
from ayon_core.pipeline.template_data import get_template_data_with_names
|
||||
from ayon_core.pipeline.colorspace import get_imageio_config_preset
|
||||
from ayon_core.pipeline.template_data import get_template_data
|
||||
|
||||
|
||||
class OCIOEnvHook(PreLaunchHook):
|
||||
|
|
@ -26,32 +26,38 @@ class OCIOEnvHook(PreLaunchHook):
|
|||
def execute(self):
|
||||
"""Hook entry method."""
|
||||
|
||||
template_data = get_template_data_with_names(
|
||||
project_name=self.data["project_name"],
|
||||
folder_path=self.data["folder_path"],
|
||||
task_name=self.data["task_name"],
|
||||
folder_entity = self.data["folder_entity"]
|
||||
|
||||
template_data = get_template_data(
|
||||
self.data["project_entity"],
|
||||
folder_entity=folder_entity,
|
||||
task_entity=self.data["task_entity"],
|
||||
host_name=self.host_name,
|
||||
settings=self.data["project_settings"]
|
||||
settings=self.data["project_settings"],
|
||||
)
|
||||
|
||||
config_data = get_imageio_config(
|
||||
project_name=self.data["project_name"],
|
||||
host_name=self.host_name,
|
||||
project_settings=self.data["project_settings"],
|
||||
anatomy_data=template_data,
|
||||
config_data = get_imageio_config_preset(
|
||||
self.data["project_name"],
|
||||
self.data["folder_path"],
|
||||
self.data["task_name"],
|
||||
self.host_name,
|
||||
anatomy=self.data["anatomy"],
|
||||
project_settings=self.data["project_settings"],
|
||||
template_data=template_data,
|
||||
env=self.launch_context.env,
|
||||
folder_id=folder_entity["id"],
|
||||
)
|
||||
|
||||
if config_data:
|
||||
ocio_path = config_data["path"]
|
||||
|
||||
if self.host_name in ["nuke", "hiero"]:
|
||||
ocio_path = ocio_path.replace("\\", "/")
|
||||
|
||||
self.log.info(
|
||||
f"Setting OCIO environment to config path: {ocio_path}")
|
||||
|
||||
self.launch_context.env["OCIO"] = ocio_path
|
||||
else:
|
||||
if not config_data:
|
||||
self.log.debug("OCIO not set or enabled")
|
||||
return
|
||||
|
||||
ocio_path = config_data["path"]
|
||||
|
||||
if self.host_name in ["nuke", "hiero"]:
|
||||
ocio_path = ocio_path.replace("\\", "/")
|
||||
|
||||
self.log.info(
|
||||
f"Setting OCIO environment to config path: {ocio_path}")
|
||||
|
||||
self.launch_context.env["OCIO"] = ocio_path
|
||||
|
|
|
|||
|
|
@ -1110,10 +1110,7 @@ def apply_colorspace_project():
|
|||
'''
|
||||
# backward compatibility layer
|
||||
# TODO: remove this after some time
|
||||
config_data = get_imageio_config(
|
||||
project_name=get_current_project_name(),
|
||||
host_name="hiero"
|
||||
)
|
||||
config_data = get_current_context_imageio_config_preset()
|
||||
|
||||
if config_data:
|
||||
presets.update({
|
||||
|
|
|
|||
29
client/ayon_core/hosts/houdini/startup/OPmenu.xml
Normal file
29
client/ayon_core/hosts/houdini/startup/OPmenu.xml
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- OPMenu Stencil.
|
||||
It's used to extend the OPMenu.
|
||||
-->
|
||||
|
||||
<menuDocument>
|
||||
<menu>
|
||||
<!-- Operator type and asset options. -->
|
||||
<subMenu id="opmenu.vhda_options_create">
|
||||
<insertBefore>opmenu.unsynchronize</insertBefore>
|
||||
<scriptItem id="opmenu.vhda_create_ayon">
|
||||
<insertAfter>opmenu.vhda_create</insertAfter>
|
||||
<label>Create New (AYON)...</label>
|
||||
<context>
|
||||
</context>
|
||||
<scriptCode>
|
||||
<![CDATA[
|
||||
from ayon_core.hosts.houdini.api.creator_node_shelves import create_interactive
|
||||
|
||||
node = kwargs["node"]
|
||||
if node not in hou.selectedNodes():
|
||||
node.setSelected(True)
|
||||
create_interactive("io.openpype.creators.houdini.hda", **kwargs)
|
||||
]]>
|
||||
</scriptCode>
|
||||
</scriptItem>
|
||||
</subMenu>
|
||||
</menu>
|
||||
</menuDocument>
|
||||
|
|
@ -369,12 +369,8 @@ def reset_colorspace():
|
|||
"""
|
||||
if int(get_max_version()) < 2024:
|
||||
return
|
||||
project_name = get_current_project_name()
|
||||
colorspace_mgr = rt.ColorPipelineMgr
|
||||
project_settings = get_project_settings(project_name)
|
||||
|
||||
max_config_data = colorspace.get_imageio_config(
|
||||
project_name, "max", project_settings)
|
||||
max_config_data = colorspace.get_current_context_imageio_config_preset()
|
||||
if max_config_data:
|
||||
ocio_config_path = max_config_data["path"]
|
||||
colorspace_mgr = rt.ColorPipelineMgr
|
||||
|
|
@ -389,10 +385,7 @@ def check_colorspace():
|
|||
"because Max main window can't be found.")
|
||||
if int(get_max_version()) >= 2024:
|
||||
color_mgr = rt.ColorPipelineMgr
|
||||
project_name = get_current_project_name()
|
||||
project_settings = get_project_settings(project_name)
|
||||
max_config_data = colorspace.get_imageio_config(
|
||||
project_name, "max", project_settings)
|
||||
max_config_data = colorspace.get_current_context_imageio_config_preset()
|
||||
if max_config_data and color_mgr.Mode != rt.Name("OCIO_Custom"):
|
||||
if not is_headless():
|
||||
from ayon_core.tools.utils import SimplePopup
|
||||
|
|
|
|||
|
|
@ -52,11 +52,7 @@ class MaxHost(HostBase, IWorkfileHost, ILoadHost, IPublishHost):
|
|||
|
||||
self._has_been_setup = True
|
||||
|
||||
def context_setting():
|
||||
return lib.set_context_setting()
|
||||
|
||||
rt.callbacks.addScript(rt.Name('systemPostNew'),
|
||||
context_setting)
|
||||
rt.callbacks.addScript(rt.Name('systemPostNew'), on_new)
|
||||
|
||||
rt.callbacks.addScript(rt.Name('filePostOpen'),
|
||||
lib.check_colorspace)
|
||||
|
|
@ -163,6 +159,14 @@ def ls() -> list:
|
|||
yield lib.read(container)
|
||||
|
||||
|
||||
def on_new():
|
||||
lib.set_context_setting()
|
||||
if rt.checkForSave():
|
||||
rt.resetMaxFile(rt.Name("noPrompt"))
|
||||
rt.clearUndoBuffer()
|
||||
rt.redrawViews()
|
||||
|
||||
|
||||
def containerise(name: str, nodes: list, context,
|
||||
namespace=None, loader=None, suffix="_CON"):
|
||||
data = {
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ from ayon_core.pipeline import (
|
|||
from ayon_core.pipeline.load.utils import get_representation_path_from_context
|
||||
from ayon_core.pipeline.colorspace import (
|
||||
get_imageio_file_rules_colorspace_from_filepath,
|
||||
get_imageio_config,
|
||||
get_current_context_imageio_config_preset,
|
||||
get_imageio_file_rules
|
||||
)
|
||||
from ayon_core.settings import get_project_settings
|
||||
|
|
@ -270,8 +270,7 @@ class FileNodeLoader(load.LoaderPlugin):
|
|||
host_name = get_current_host_name()
|
||||
project_settings = get_project_settings(project_name)
|
||||
|
||||
config_data = get_imageio_config(
|
||||
project_name, host_name,
|
||||
config_data = get_current_context_imageio_config_preset(
|
||||
project_settings=project_settings
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -43,7 +43,9 @@ from ayon_core.pipeline import (
|
|||
from ayon_core.pipeline.context_tools import (
|
||||
get_current_context_custom_workfile_template
|
||||
)
|
||||
from ayon_core.pipeline.colorspace import get_imageio_config
|
||||
from ayon_core.pipeline.colorspace import (
|
||||
get_current_context_imageio_config_preset
|
||||
)
|
||||
from ayon_core.pipeline.workfile import BuildWorkfile
|
||||
from . import gizmo_menu
|
||||
from .constants import ASSIST
|
||||
|
|
@ -1552,10 +1554,7 @@ class WorkfileSettings(object):
|
|||
imageio_host (dict): host colorspace configurations
|
||||
|
||||
'''
|
||||
config_data = get_imageio_config(
|
||||
project_name=get_current_project_name(),
|
||||
host_name="nuke"
|
||||
)
|
||||
config_data = get_current_context_imageio_config_preset()
|
||||
|
||||
workfile_settings = imageio_host["workfile"]
|
||||
color_management = workfile_settings["color_management"]
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ class LoadBackdropNodes(load.LoaderPlugin):
|
|||
}
|
||||
|
||||
# add attributes from the version to imprint to metadata knob
|
||||
for k in ["source", "author", "fps"]:
|
||||
for k in ["source", "fps"]:
|
||||
data_imprint[k] = version_attributes[k]
|
||||
|
||||
# getting file path
|
||||
|
|
@ -206,7 +206,7 @@ class LoadBackdropNodes(load.LoaderPlugin):
|
|||
"colorspaceInput": colorspace,
|
||||
}
|
||||
|
||||
for k in ["source", "author", "fps"]:
|
||||
for k in ["source", "fps"]:
|
||||
data_imprint[k] = version_attributes[k]
|
||||
|
||||
# adding nodes to node graph
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ class AlembicCameraLoader(load.LoaderPlugin):
|
|||
"frameEnd": last,
|
||||
"version": version_entity["version"],
|
||||
}
|
||||
for k in ["source", "author", "fps"]:
|
||||
for k in ["source", "fps"]:
|
||||
data_imprint[k] = version_attributes[k]
|
||||
|
||||
# getting file path
|
||||
|
|
@ -123,7 +123,7 @@ class AlembicCameraLoader(load.LoaderPlugin):
|
|||
}
|
||||
|
||||
# add attributes from the version to imprint to metadata knob
|
||||
for k in ["source", "author", "fps"]:
|
||||
for k in ["source", "fps"]:
|
||||
data_imprint[k] = version_attributes[k]
|
||||
|
||||
# getting file path
|
||||
|
|
|
|||
|
|
@ -9,7 +9,8 @@ from ayon_core.pipeline import (
|
|||
get_representation_path,
|
||||
)
|
||||
from ayon_core.pipeline.colorspace import (
|
||||
get_imageio_file_rules_colorspace_from_filepath
|
||||
get_imageio_file_rules_colorspace_from_filepath,
|
||||
get_current_context_imageio_config_preset,
|
||||
)
|
||||
from ayon_core.hosts.nuke.api.lib import (
|
||||
get_imageio_input_colorspace,
|
||||
|
|
@ -197,7 +198,6 @@ class LoadClip(plugin.NukeLoader):
|
|||
"frameStart",
|
||||
"frameEnd",
|
||||
"source",
|
||||
"author",
|
||||
"fps",
|
||||
"handleStart",
|
||||
"handleEnd",
|
||||
|
|
@ -347,8 +347,7 @@ class LoadClip(plugin.NukeLoader):
|
|||
"source": version_attributes.get("source"),
|
||||
"handleStart": str(self.handle_start),
|
||||
"handleEnd": str(self.handle_end),
|
||||
"fps": str(version_attributes.get("fps")),
|
||||
"author": version_attributes.get("author")
|
||||
"fps": str(version_attributes.get("fps"))
|
||||
}
|
||||
|
||||
last_version_entity = ayon_api.get_last_version_by_product_id(
|
||||
|
|
@ -547,9 +546,10 @@ class LoadClip(plugin.NukeLoader):
|
|||
f"Colorspace from representation colorspaceData: {colorspace}"
|
||||
)
|
||||
|
||||
config_data = get_current_context_imageio_config_preset()
|
||||
# check if any filerules are not applicable
|
||||
new_parsed_colorspace = get_imageio_file_rules_colorspace_from_filepath( # noqa
|
||||
filepath, "nuke", project_name
|
||||
filepath, "nuke", project_name, config_data=config_data
|
||||
)
|
||||
self.log.debug(f"Colorspace new filerules: {new_parsed_colorspace}")
|
||||
|
||||
|
|
|
|||
|
|
@ -69,7 +69,6 @@ class LoadEffects(load.LoaderPlugin):
|
|||
"handleStart",
|
||||
"handleEnd",
|
||||
"source",
|
||||
"author",
|
||||
"fps"
|
||||
]:
|
||||
data_imprint[k] = version_attributes[k]
|
||||
|
|
@ -189,7 +188,6 @@ class LoadEffects(load.LoaderPlugin):
|
|||
"handleStart",
|
||||
"handleEnd",
|
||||
"source",
|
||||
"author",
|
||||
"fps",
|
||||
]:
|
||||
data_imprint[k] = version_attributes[k]
|
||||
|
|
|
|||
|
|
@ -69,7 +69,6 @@ class LoadEffectsInputProcess(load.LoaderPlugin):
|
|||
"handleStart",
|
||||
"handleEnd",
|
||||
"source",
|
||||
"author",
|
||||
"fps"
|
||||
]:
|
||||
data_imprint[k] = version_attributes[k]
|
||||
|
|
@ -192,7 +191,6 @@ class LoadEffectsInputProcess(load.LoaderPlugin):
|
|||
"handleStart",
|
||||
"handleEnd",
|
||||
"source",
|
||||
"author",
|
||||
"fps"
|
||||
]:
|
||||
data_imprint[k] = version_attributes[k]
|
||||
|
|
|
|||
|
|
@ -71,7 +71,6 @@ class LoadGizmo(load.LoaderPlugin):
|
|||
"handleStart",
|
||||
"handleEnd",
|
||||
"source",
|
||||
"author",
|
||||
"fps"
|
||||
]:
|
||||
data_imprint[k] = version_attributes[k]
|
||||
|
|
@ -139,7 +138,6 @@ class LoadGizmo(load.LoaderPlugin):
|
|||
"handleStart",
|
||||
"handleEnd",
|
||||
"source",
|
||||
"author",
|
||||
"fps"
|
||||
]:
|
||||
data_imprint[k] = version_attributes[k]
|
||||
|
|
|
|||
|
|
@ -73,7 +73,6 @@ class LoadGizmoInputProcess(load.LoaderPlugin):
|
|||
"handleStart",
|
||||
"handleEnd",
|
||||
"source",
|
||||
"author",
|
||||
"fps"
|
||||
]:
|
||||
data_imprint[k] = version_attributes[k]
|
||||
|
|
@ -145,7 +144,6 @@ class LoadGizmoInputProcess(load.LoaderPlugin):
|
|||
"handleStart",
|
||||
"handleEnd",
|
||||
"source",
|
||||
"author",
|
||||
"fps"
|
||||
]:
|
||||
data_imprint[k] = version_attributes[k]
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ class LoadImage(load.LoaderPlugin):
|
|||
"version": version_entity["version"],
|
||||
"colorspace": colorspace,
|
||||
}
|
||||
for k in ["source", "author", "fps"]:
|
||||
for k in ["source", "fps"]:
|
||||
data_imprint[k] = version_attributes.get(k, str(None))
|
||||
|
||||
r["tile_color"].setValue(int("0x4ecd25ff", 16))
|
||||
|
|
@ -207,7 +207,6 @@ class LoadImage(load.LoaderPlugin):
|
|||
"colorspace": version_attributes.get("colorSpace"),
|
||||
"source": version_attributes.get("source"),
|
||||
"fps": str(version_attributes.get("fps")),
|
||||
"author": version_attributes.get("author")
|
||||
}
|
||||
|
||||
# change color of node
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ class AlembicModelLoader(load.LoaderPlugin):
|
|||
"version": version_entity["version"]
|
||||
}
|
||||
# add attributes from the version to imprint to metadata knob
|
||||
for k in ["source", "author", "fps"]:
|
||||
for k in ["source", "fps"]:
|
||||
data_imprint[k] = version_attributes[k]
|
||||
|
||||
# getting file path
|
||||
|
|
@ -130,7 +130,7 @@ class AlembicModelLoader(load.LoaderPlugin):
|
|||
}
|
||||
|
||||
# add additional metadata from the version to imprint to Avalon knob
|
||||
for k in ["source", "author", "fps"]:
|
||||
for k in ["source", "fps"]:
|
||||
data_imprint[k] = version_attributes[k]
|
||||
|
||||
# getting file path
|
||||
|
|
|
|||
|
|
@ -55,7 +55,6 @@ class LinkAsGroup(load.LoaderPlugin):
|
|||
"handleStart",
|
||||
"handleEnd",
|
||||
"source",
|
||||
"author",
|
||||
"fps"
|
||||
]:
|
||||
data_imprint[k] = version_attributes[k]
|
||||
|
|
@ -131,7 +130,6 @@ class LinkAsGroup(load.LoaderPlugin):
|
|||
"colorspace": version_attributes.get("colorSpace"),
|
||||
"source": version_attributes.get("source"),
|
||||
"fps": version_attributes.get("fps"),
|
||||
"author": version_attributes.get("author")
|
||||
}
|
||||
|
||||
# Update the imprinted representation
|
||||
|
|
|
|||
|
|
@ -156,14 +156,9 @@ This creator publishes color space look file (LUT).
|
|||
]
|
||||
|
||||
def apply_settings(self, project_settings):
|
||||
host = self.create_context.host
|
||||
host_name = host.name
|
||||
project_name = host.get_current_project_name()
|
||||
config_data = colorspace.get_imageio_config(
|
||||
project_name, host_name,
|
||||
config_data = colorspace.get_current_context_imageio_config_preset(
|
||||
project_settings=project_settings
|
||||
)
|
||||
|
||||
if not config_data:
|
||||
self.enabled = False
|
||||
return
|
||||
|
|
|
|||
|
|
@ -1,10 +1,7 @@
|
|||
import pyblish.api
|
||||
from ayon_core.pipeline import (
|
||||
publish,
|
||||
registered_host
|
||||
)
|
||||
from ayon_core.lib import EnumDef
|
||||
from ayon_core.pipeline import colorspace
|
||||
from ayon_core.pipeline import publish
|
||||
from ayon_core.pipeline.publish import KnownPublishError
|
||||
|
||||
|
||||
|
|
@ -19,9 +16,10 @@ class CollectColorspace(pyblish.api.InstancePlugin,
|
|||
families = ["render", "plate", "reference", "image", "online"]
|
||||
enabled = False
|
||||
|
||||
colorspace_items = [
|
||||
default_colorspace_items = [
|
||||
(None, "Don't override")
|
||||
]
|
||||
colorspace_items = list(default_colorspace_items)
|
||||
colorspace_attr_show = False
|
||||
config_items = None
|
||||
|
||||
|
|
@ -69,14 +67,13 @@ class CollectColorspace(pyblish.api.InstancePlugin,
|
|||
|
||||
@classmethod
|
||||
def apply_settings(cls, project_settings):
|
||||
host = registered_host()
|
||||
host_name = host.name
|
||||
project_name = host.get_current_project_name()
|
||||
config_data = colorspace.get_imageio_config(
|
||||
project_name, host_name,
|
||||
config_data = colorspace.get_current_context_imageio_config_preset(
|
||||
project_settings=project_settings
|
||||
)
|
||||
|
||||
enabled = False
|
||||
colorspace_items = list(cls.default_colorspace_items)
|
||||
config_items = None
|
||||
if config_data:
|
||||
filepath = config_data["path"]
|
||||
config_items = colorspace.get_ocio_config_colorspaces(filepath)
|
||||
|
|
@ -85,9 +82,11 @@ class CollectColorspace(pyblish.api.InstancePlugin,
|
|||
include_aliases=True,
|
||||
include_roles=True
|
||||
)
|
||||
cls.config_items = config_items
|
||||
cls.colorspace_items.extend(labeled_colorspaces)
|
||||
cls.enabled = True
|
||||
colorspace_items.extend(labeled_colorspaces)
|
||||
|
||||
cls.config_items = config_items
|
||||
cls.colorspace_items = colorspace_items
|
||||
cls.enabled = enabled
|
||||
|
||||
@classmethod
|
||||
def get_attribute_defs(cls):
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ from ayon_core.lib import Logger, run_subprocess, AYONSettingsRegistry
|
|||
from ayon_core.lib.vendor_bin_utils import find_tool_in_custom_paths
|
||||
|
||||
from .rr_job import SubmitFile
|
||||
from .rr_job import RRjob, SubmitterParameter # noqa F401
|
||||
from .rr_job import RRJob, SubmitterParameter # noqa F401
|
||||
|
||||
|
||||
class Api:
|
||||
|
|
|
|||
|
|
@ -8,14 +8,19 @@ import tempfile
|
|||
import warnings
|
||||
from copy import deepcopy
|
||||
|
||||
import ayon_api
|
||||
|
||||
from ayon_core import AYON_CORE_ROOT
|
||||
from ayon_core.settings import get_project_settings
|
||||
from ayon_core.lib import (
|
||||
filter_profiles,
|
||||
StringTemplate,
|
||||
run_ayon_launcher_process,
|
||||
Logger
|
||||
Logger,
|
||||
)
|
||||
from ayon_core.pipeline import Anatomy
|
||||
from ayon_core.pipeline.template_data import get_template_data
|
||||
from ayon_core.pipeline.load import get_representation_path_with_anatomy
|
||||
from ayon_core.lib.transcoding import VIDEO_EXTENSIONS, IMAGE_EXTENSIONS
|
||||
|
||||
|
||||
|
|
@ -81,28 +86,25 @@ def deprecated(new_destination):
|
|||
def _make_temp_json_file():
|
||||
"""Wrapping function for json temp file
|
||||
"""
|
||||
temporary_json_file = None
|
||||
try:
|
||||
# Store dumped json to temporary file
|
||||
temporary_json_file = tempfile.NamedTemporaryFile(
|
||||
with tempfile.NamedTemporaryFile(
|
||||
mode="w", suffix=".json", delete=False
|
||||
)
|
||||
temporary_json_file.close()
|
||||
temporary_json_filepath = temporary_json_file.name.replace(
|
||||
"\\", "/"
|
||||
)
|
||||
) as tmpfile:
|
||||
temporary_json_filepath = tmpfile.name.replace("\\", "/")
|
||||
|
||||
yield temporary_json_filepath
|
||||
|
||||
except IOError as _error:
|
||||
except IOError as exc:
|
||||
raise IOError(
|
||||
"Unable to create temp json file: {}".format(
|
||||
_error
|
||||
)
|
||||
"Unable to create temp json file: {}".format(exc)
|
||||
)
|
||||
|
||||
finally:
|
||||
# Remove the temporary json
|
||||
os.remove(temporary_json_filepath)
|
||||
if temporary_json_file is not None:
|
||||
os.remove(temporary_json_filepath)
|
||||
|
||||
|
||||
def get_ocio_config_script_path():
|
||||
|
|
@ -110,53 +112,58 @@ def get_ocio_config_script_path():
|
|||
|
||||
Returns:
|
||||
str: path string
|
||||
|
||||
"""
|
||||
return os.path.normpath(
|
||||
os.path.join(
|
||||
AYON_CORE_ROOT,
|
||||
"scripts",
|
||||
"ocio_wrapper.py"
|
||||
)
|
||||
return os.path.join(
|
||||
os.path.normpath(AYON_CORE_ROOT),
|
||||
"scripts",
|
||||
"ocio_wrapper.py"
|
||||
)
|
||||
|
||||
|
||||
def get_colorspace_name_from_filepath(
|
||||
filepath, host_name, project_name,
|
||||
config_data=None, file_rules=None,
|
||||
filepath,
|
||||
host_name,
|
||||
project_name,
|
||||
config_data,
|
||||
file_rules=None,
|
||||
project_settings=None,
|
||||
validate=True
|
||||
):
|
||||
"""Get colorspace name from filepath
|
||||
|
||||
Args:
|
||||
filepath (str): path string, file rule pattern is tested on it
|
||||
host_name (str): host name
|
||||
project_name (str): project name
|
||||
config_data (Optional[dict]): config path and template in dict.
|
||||
Defaults to None.
|
||||
file_rules (Optional[dict]): file rule data from settings.
|
||||
Defaults to None.
|
||||
project_settings (Optional[dict]): project settings. Defaults to None.
|
||||
filepath (str): Path string, file rule pattern is tested on it.
|
||||
host_name (str): Host name.
|
||||
project_name (str): Project name.
|
||||
config_data (dict): Config path and template in dict.
|
||||
file_rules (Optional[dict]): File rule data from settings.
|
||||
project_settings (Optional[dict]): Project settings.
|
||||
validate (Optional[bool]): should resulting colorspace be validated
|
||||
with config file? Defaults to True.
|
||||
with config file? Defaults to True.
|
||||
|
||||
Returns:
|
||||
str: name of colorspace
|
||||
"""
|
||||
project_settings, config_data, file_rules = _get_context_settings(
|
||||
host_name, project_name,
|
||||
config_data=config_data, file_rules=file_rules,
|
||||
project_settings=project_settings
|
||||
)
|
||||
Union[str, None]: name of colorspace
|
||||
|
||||
"""
|
||||
if not config_data:
|
||||
# in case global or host color management is not enabled
|
||||
return None
|
||||
|
||||
if file_rules is None:
|
||||
if project_settings is None:
|
||||
project_settings = get_project_settings(project_name)
|
||||
file_rules = get_imageio_file_rules(
|
||||
project_name, host_name, project_settings
|
||||
)
|
||||
|
||||
# use ImageIO file rules
|
||||
colorspace_name = get_imageio_file_rules_colorspace_from_filepath(
|
||||
filepath, host_name, project_name,
|
||||
config_data=config_data, file_rules=file_rules,
|
||||
filepath,
|
||||
host_name,
|
||||
project_name,
|
||||
config_data=config_data,
|
||||
file_rules=file_rules,
|
||||
project_settings=project_settings
|
||||
)
|
||||
|
||||
|
|
@ -182,7 +189,8 @@ def get_colorspace_name_from_filepath(
|
|||
# validate matching colorspace with config
|
||||
if validate:
|
||||
validate_imageio_colorspace_in_config(
|
||||
config_data["path"], colorspace_name)
|
||||
config_data["path"], colorspace_name
|
||||
)
|
||||
|
||||
return colorspace_name
|
||||
|
||||
|
|
@ -198,31 +206,12 @@ def get_colorspace_from_filepath(*args, **kwargs):
|
|||
return get_imageio_file_rules_colorspace_from_filepath(*args, **kwargs)
|
||||
|
||||
|
||||
def _get_context_settings(
|
||||
host_name, project_name,
|
||||
config_data=None, file_rules=None,
|
||||
project_settings=None
|
||||
):
|
||||
project_settings = project_settings or get_project_settings(
|
||||
project_name
|
||||
)
|
||||
|
||||
config_data = config_data or get_imageio_config(
|
||||
project_name, host_name, project_settings)
|
||||
|
||||
# in case host color management is not enabled
|
||||
if not config_data:
|
||||
return (None, None, None)
|
||||
|
||||
file_rules = file_rules or get_imageio_file_rules(
|
||||
project_name, host_name, project_settings)
|
||||
|
||||
return project_settings, config_data, file_rules
|
||||
|
||||
|
||||
def get_imageio_file_rules_colorspace_from_filepath(
|
||||
filepath, host_name, project_name,
|
||||
config_data=None, file_rules=None,
|
||||
filepath,
|
||||
host_name,
|
||||
project_name,
|
||||
config_data,
|
||||
file_rules=None,
|
||||
project_settings=None
|
||||
):
|
||||
"""Get colorspace name from filepath
|
||||
|
|
@ -230,28 +219,28 @@ def get_imageio_file_rules_colorspace_from_filepath(
|
|||
ImageIO Settings file rules are tested for matching rule.
|
||||
|
||||
Args:
|
||||
filepath (str): path string, file rule pattern is tested on it
|
||||
host_name (str): host name
|
||||
project_name (str): project name
|
||||
config_data (Optional[dict]): config path and template in dict.
|
||||
Defaults to None.
|
||||
file_rules (Optional[dict]): file rule data from settings.
|
||||
Defaults to None.
|
||||
project_settings (Optional[dict]): project settings. Defaults to None.
|
||||
filepath (str): Path string, file rule pattern is tested on it.
|
||||
host_name (str): Host name.
|
||||
project_name (str): Project name.
|
||||
config_data (dict): Config path and template in dict.
|
||||
file_rules (Optional[dict]): File rule data from settings.
|
||||
project_settings (Optional[dict]): Project settings.
|
||||
|
||||
Returns:
|
||||
str: name of colorspace
|
||||
"""
|
||||
project_settings, config_data, file_rules = _get_context_settings(
|
||||
host_name, project_name,
|
||||
config_data=config_data, file_rules=file_rules,
|
||||
project_settings=project_settings
|
||||
)
|
||||
Union[str, None]: Name of colorspace.
|
||||
|
||||
"""
|
||||
if not config_data:
|
||||
# in case global or host color management is not enabled
|
||||
return None
|
||||
|
||||
if file_rules is None:
|
||||
if project_settings is None:
|
||||
project_settings = get_project_settings(project_name)
|
||||
file_rules = get_imageio_file_rules(
|
||||
project_name, host_name, project_settings
|
||||
)
|
||||
|
||||
# match file rule from path
|
||||
colorspace_name = None
|
||||
for file_rule in file_rules:
|
||||
|
|
@ -344,10 +333,10 @@ def parse_colorspace_from_filepath(
|
|||
pattern = "|".join(
|
||||
# Allow to match spaces also as underscores because the
|
||||
# integrator replaces spaces with underscores in filenames
|
||||
re.escape(colorspace) for colorspace in
|
||||
re.escape(colorspace)
|
||||
# Sort by longest first so the regex matches longer matches
|
||||
# over smaller matches, e.g. matching 'Output - sRGB' over 'sRGB'
|
||||
sorted(colorspaces, key=len, reverse=True)
|
||||
for colorspace in sorted(colorspaces, key=len, reverse=True)
|
||||
)
|
||||
return re.compile(pattern)
|
||||
|
||||
|
|
@ -519,16 +508,15 @@ def get_ocio_config_colorspaces(config_path):
|
|||
if not compatibility_check():
|
||||
# python environment is not compatible with PyOpenColorIO
|
||||
# needs to be run in subprocess
|
||||
CachedData.ocio_config_colorspaces[config_path] = \
|
||||
_get_wrapped_with_subprocess(
|
||||
"config", "get_colorspace", in_path=config_path
|
||||
config_colorspaces = _get_wrapped_with_subprocess(
|
||||
"config", "get_colorspace", in_path=config_path
|
||||
)
|
||||
else:
|
||||
# TODO: refactor this so it is not imported but part of this file
|
||||
from ayon_core.scripts.ocio_wrapper import _get_colorspace_data
|
||||
|
||||
CachedData.ocio_config_colorspaces[config_path] = \
|
||||
_get_colorspace_data(config_path)
|
||||
config_colorspaces = _get_colorspace_data(config_path)
|
||||
CachedData.ocio_config_colorspaces[config_path] = config_colorspaces
|
||||
|
||||
return CachedData.ocio_config_colorspaces[config_path]
|
||||
|
||||
|
|
@ -540,11 +528,12 @@ def convert_colorspace_enumerator_item(
|
|||
"""Convert colorspace enumerator item to dictionary
|
||||
|
||||
Args:
|
||||
colorspace_item (str): colorspace and family in couple
|
||||
config_items (dict[str,dict]): colorspace data
|
||||
colorspace_enum_item (str): Colorspace and family in couple.
|
||||
config_items (dict[str,dict]): Colorspace data.
|
||||
|
||||
Returns:
|
||||
dict: colorspace data
|
||||
|
||||
"""
|
||||
if "::" not in colorspace_enum_item:
|
||||
return None
|
||||
|
|
@ -745,6 +734,7 @@ def get_views_data_subprocess(config_path):
|
|||
)
|
||||
|
||||
|
||||
@deprecated("get_imageio_config_preset")
|
||||
def get_imageio_config(
|
||||
project_name,
|
||||
host_name,
|
||||
|
|
@ -758,6 +748,9 @@ def get_imageio_config(
|
|||
Config path is formatted in `path` key
|
||||
and original settings input is saved into `template` key.
|
||||
|
||||
Deprecated:
|
||||
Deprecated since '0.3.1' . Use `get_imageio_config_preset` instead.
|
||||
|
||||
Args:
|
||||
project_name (str): project name
|
||||
host_name (str): host name
|
||||
|
|
@ -768,157 +761,355 @@ def get_imageio_config(
|
|||
|
||||
Returns:
|
||||
dict: config path data or empty dict
|
||||
"""
|
||||
project_settings = project_settings or get_project_settings(project_name)
|
||||
anatomy = anatomy or Anatomy(project_name)
|
||||
|
||||
"""
|
||||
if not anatomy_data:
|
||||
from ayon_core.pipeline.context_tools import (
|
||||
get_current_context_template_data)
|
||||
from .context_tools import get_current_context_template_data
|
||||
anatomy_data = get_current_context_template_data()
|
||||
|
||||
formatting_data = deepcopy(anatomy_data)
|
||||
task_name = anatomy_data.get("task", {}).get("name")
|
||||
folder_path = anatomy_data.get("folder", {}).get("path")
|
||||
return get_imageio_config_preset(
|
||||
project_name,
|
||||
folder_path,
|
||||
task_name,
|
||||
host_name,
|
||||
anatomy=anatomy,
|
||||
project_settings=project_settings,
|
||||
template_data=anatomy_data,
|
||||
env=env,
|
||||
)
|
||||
|
||||
# Add project roots to anatomy data
|
||||
formatting_data["root"] = anatomy.roots
|
||||
formatting_data["platform"] = platform.system().lower()
|
||||
|
||||
def _get_global_config_data(
|
||||
project_name,
|
||||
host_name,
|
||||
anatomy,
|
||||
template_data,
|
||||
imageio_global,
|
||||
folder_id,
|
||||
log,
|
||||
):
|
||||
"""Get global config data.
|
||||
|
||||
Global config from core settings is using profiles that are based on
|
||||
host name, task name and task type. The filtered profile can define 3
|
||||
types of config sources:
|
||||
1. AYON ocio addon configs.
|
||||
2. Custom path to ocio config.
|
||||
3. Path to 'ocioconfig' representation on product. Name of product can be
|
||||
defined in settings. Product name can be regex but exact match is
|
||||
always preferred.
|
||||
|
||||
None is returned when no profile is found, when path
|
||||
|
||||
Args:
|
||||
project_name (str): Project name.
|
||||
host_name (str): Host name.
|
||||
anatomy (Anatomy): Project anatomy object.
|
||||
template_data (dict[str, Any]): Template data.
|
||||
imageio_global (dict[str, Any]): Core imagio settings.
|
||||
folder_id (Union[dict[str, Any], None]): Folder id.
|
||||
log (logging.Logger): Logger object.
|
||||
|
||||
Returns:
|
||||
Union[dict[str, str], None]: Config data with path and template
|
||||
or None.
|
||||
|
||||
"""
|
||||
task_name = task_type = None
|
||||
task_data = template_data.get("task")
|
||||
if task_data:
|
||||
task_name = task_data["name"]
|
||||
task_type = task_data["type"]
|
||||
|
||||
filter_values = {
|
||||
"task_names": task_name,
|
||||
"task_types": task_type,
|
||||
"host_names": host_name,
|
||||
}
|
||||
profile = filter_profiles(
|
||||
imageio_global["ocio_config_profiles"], filter_values
|
||||
)
|
||||
if profile is None:
|
||||
log.info(f"No config profile matched filters {str(filter_values)}")
|
||||
return None
|
||||
|
||||
profile_type = profile["type"]
|
||||
if profile_type in ("builtin_path", "custom_path"):
|
||||
template = profile[profile_type]
|
||||
result = StringTemplate.format_strict_template(
|
||||
template, template_data
|
||||
)
|
||||
normalized_path = str(result.normalized())
|
||||
if not os.path.exists(normalized_path):
|
||||
log.warning(f"Path was not found '{normalized_path}'.")
|
||||
return None
|
||||
|
||||
return {
|
||||
"path": normalized_path,
|
||||
"template": template
|
||||
}
|
||||
|
||||
# TODO decide if this is the right name for representation
|
||||
repre_name = "ocioconfig"
|
||||
|
||||
folder_info = template_data.get("folder")
|
||||
if not folder_info:
|
||||
log.warning("Folder info is missing.")
|
||||
return None
|
||||
folder_path = folder_info["path"]
|
||||
|
||||
product_name = profile["product_name"]
|
||||
if folder_id is None:
|
||||
folder_entity = ayon_api.get_folder_by_path(
|
||||
project_name, folder_path, fields={"id"}
|
||||
)
|
||||
if not folder_entity:
|
||||
log.warning(f"Folder entity '{folder_path}' was not found..")
|
||||
return None
|
||||
folder_id = folder_entity["id"]
|
||||
|
||||
product_entities_by_name = {
|
||||
product_entity["name"]: product_entity
|
||||
for product_entity in ayon_api.get_products(
|
||||
project_name,
|
||||
folder_ids={folder_id},
|
||||
product_name_regex=product_name,
|
||||
fields={"id", "name"}
|
||||
)
|
||||
}
|
||||
if not product_entities_by_name:
|
||||
log.debug(
|
||||
f"No product entities were found for folder '{folder_path}' with"
|
||||
f" product name filter '{product_name}'."
|
||||
)
|
||||
return None
|
||||
|
||||
# Try to use exact match first, otherwise use first available product
|
||||
product_entity = product_entities_by_name.get(product_name)
|
||||
if product_entity is None:
|
||||
product_entity = next(iter(product_entities_by_name.values()))
|
||||
|
||||
product_name = product_entity["name"]
|
||||
# Find last product version
|
||||
version_entity = ayon_api.get_last_version_by_product_id(
|
||||
project_name,
|
||||
product_id=product_entity["id"],
|
||||
fields={"id"}
|
||||
)
|
||||
if not version_entity:
|
||||
log.info(
|
||||
f"Product '{product_name}' does not have available any versions."
|
||||
)
|
||||
return None
|
||||
|
||||
# Find 'ocioconfig' representation entity
|
||||
repre_entity = ayon_api.get_representation_by_name(
|
||||
project_name,
|
||||
representation_name=repre_name,
|
||||
version_id=version_entity["id"],
|
||||
)
|
||||
if not repre_entity:
|
||||
log.debug(
|
||||
f"Representation '{repre_name}'"
|
||||
f" not found on product '{product_name}'."
|
||||
)
|
||||
return None
|
||||
|
||||
path = get_representation_path_with_anatomy(repre_entity, anatomy)
|
||||
template = repre_entity["attrib"]["template"]
|
||||
return {
|
||||
"path": path,
|
||||
"template": template,
|
||||
}
|
||||
|
||||
|
||||
def get_imageio_config_preset(
|
||||
project_name,
|
||||
folder_path,
|
||||
task_name,
|
||||
host_name,
|
||||
anatomy=None,
|
||||
project_settings=None,
|
||||
template_data=None,
|
||||
env=None,
|
||||
folder_id=None,
|
||||
):
|
||||
"""Returns config data from settings
|
||||
|
||||
Output contains 'path' key and 'template' key holds its template.
|
||||
|
||||
Template data can be prepared with 'get_template_data'.
|
||||
|
||||
Args:
|
||||
project_name (str): Project name.
|
||||
folder_path (str): Folder path.
|
||||
task_name (str): Task name.
|
||||
host_name (str): Host name.
|
||||
anatomy (Optional[Anatomy]): Project anatomy object.
|
||||
project_settings (Optional[dict]): Project settings.
|
||||
template_data (Optional[dict]): Template data used for
|
||||
template formatting.
|
||||
env (Optional[dict]): Environment variables. Environments are used
|
||||
for template formatting too. Values from 'os.environ' are used
|
||||
when not provided.
|
||||
folder_id (Optional[str]): Folder id. Is used only when config path
|
||||
is received from published representation. Is autofilled when
|
||||
not provided.
|
||||
|
||||
Returns:
|
||||
dict: config path data or empty dict
|
||||
|
||||
"""
|
||||
if not project_settings:
|
||||
project_settings = get_project_settings(project_name)
|
||||
|
||||
# Get colorspace settings
|
||||
imageio_global, imageio_host = _get_imageio_settings(
|
||||
project_settings, host_name)
|
||||
project_settings, host_name
|
||||
)
|
||||
# Global color management must be enabled to be able to use host settings
|
||||
if not imageio_global["activate_global_color_management"]:
|
||||
log.info("Colorspace management is disabled globally.")
|
||||
return {}
|
||||
|
||||
# Host 'ocio_config' is optional
|
||||
host_ocio_config = imageio_host.get("ocio_config") or {}
|
||||
|
||||
# Global color management must be enabled to be able to use host settings
|
||||
activate_color_management = imageio_global.get(
|
||||
"activate_global_color_management")
|
||||
# TODO: remove this in future - backward compatibility
|
||||
# For already saved overrides from previous version look for 'enabled'
|
||||
# on host settings.
|
||||
if activate_color_management is None:
|
||||
activate_color_management = host_ocio_config.get("enabled", False)
|
||||
|
||||
if not activate_color_management:
|
||||
# if global settings are disabled return empty dict because
|
||||
# it is expected that no colorspace management is needed
|
||||
log.info("Colorspace management is disabled globally.")
|
||||
return {}
|
||||
# TODO remove
|
||||
# - backward compatibility when host settings had only 'enabled' flag
|
||||
# the flag was split into 'activate_global_color_management'
|
||||
# and 'override_global_config'
|
||||
host_ocio_config_enabled = host_ocio_config.get("enabled", False)
|
||||
|
||||
# Check if host settings group is having 'activate_host_color_management'
|
||||
# - if it does not have activation key then default it to True so it uses
|
||||
# global settings
|
||||
# This is for backward compatibility.
|
||||
# TODO: in future rewrite this to be more explicit
|
||||
activate_host_color_management = imageio_host.get(
|
||||
"activate_host_color_management")
|
||||
|
||||
# TODO: remove this in future - backward compatibility
|
||||
"activate_host_color_management"
|
||||
)
|
||||
if activate_host_color_management is None:
|
||||
activate_host_color_management = host_ocio_config.get("enabled", False)
|
||||
activate_host_color_management = host_ocio_config_enabled
|
||||
|
||||
if not activate_host_color_management:
|
||||
# if host settings are disabled return False because
|
||||
# it is expected that no colorspace management is needed
|
||||
log.info(
|
||||
"Colorspace management for host '{}' is disabled.".format(
|
||||
host_name)
|
||||
f"Colorspace management for host '{host_name}' is disabled."
|
||||
)
|
||||
return {}
|
||||
|
||||
# get config path from either global or host settings
|
||||
# depending on override flag
|
||||
project_entity = None
|
||||
if anatomy is None:
|
||||
project_entity = ayon_api.get_project(project_name)
|
||||
anatomy = Anatomy(project_name, project_entity)
|
||||
|
||||
if env is None:
|
||||
env = dict(os.environ.items())
|
||||
|
||||
if template_data:
|
||||
template_data = deepcopy(template_data)
|
||||
else:
|
||||
if not project_entity:
|
||||
project_entity = ayon_api.get_project(project_name)
|
||||
|
||||
folder_entity = task_entity = folder_id = None
|
||||
if folder_path:
|
||||
folder_entity = ayon_api.get_folder_by_path(
|
||||
project_name, folder_path
|
||||
)
|
||||
folder_id = folder_entity["id"]
|
||||
|
||||
if folder_id and task_name:
|
||||
task_entity = ayon_api.get_task_by_name(
|
||||
project_name, folder_id, task_name
|
||||
)
|
||||
template_data = get_template_data(
|
||||
project_entity,
|
||||
folder_entity,
|
||||
task_entity,
|
||||
host_name,
|
||||
project_settings,
|
||||
)
|
||||
|
||||
# Add project roots to anatomy data
|
||||
template_data["root"] = anatomy.roots
|
||||
template_data["platform"] = platform.system().lower()
|
||||
|
||||
# Add environment variables to template data
|
||||
template_data.update(env)
|
||||
|
||||
# Get config path from core or host settings
|
||||
# - based on override flag in host settings
|
||||
# TODO: in future rewrite this to be more explicit
|
||||
override_global_config = host_ocio_config.get("override_global_config")
|
||||
if override_global_config is None:
|
||||
# for already saved overrides from previous version
|
||||
# TODO: remove this in future - backward compatibility
|
||||
override_global_config = host_ocio_config.get("enabled")
|
||||
override_global_config = host_ocio_config_enabled
|
||||
|
||||
if override_global_config:
|
||||
config_data = _get_config_data(
|
||||
host_ocio_config["filepath"], formatting_data, env
|
||||
if not override_global_config:
|
||||
config_data = _get_global_config_data(
|
||||
project_name,
|
||||
host_name,
|
||||
anatomy,
|
||||
template_data,
|
||||
imageio_global,
|
||||
folder_id,
|
||||
log,
|
||||
)
|
||||
else:
|
||||
# get config path from global
|
||||
config_global = imageio_global["ocio_config"]
|
||||
config_data = _get_config_data(
|
||||
config_global["filepath"], formatting_data, env
|
||||
config_data = _get_host_config_data(
|
||||
host_ocio_config["filepath"], template_data
|
||||
)
|
||||
|
||||
if not config_data:
|
||||
raise FileExistsError(
|
||||
"No OCIO config found in settings. It is "
|
||||
"either missing or there is typo in path inputs"
|
||||
"No OCIO config found in settings. It is"
|
||||
" either missing or there is typo in path inputs"
|
||||
)
|
||||
|
||||
return config_data
|
||||
|
||||
|
||||
def _get_config_data(path_list, anatomy_data, env=None):
|
||||
def _get_host_config_data(templates, template_data):
|
||||
"""Return first existing path in path list.
|
||||
|
||||
If template is used in path inputs,
|
||||
then it is formatted by anatomy data
|
||||
and environment variables
|
||||
Use template data to fill possible formatting in paths.
|
||||
|
||||
Args:
|
||||
path_list (list[str]): list of abs paths
|
||||
anatomy_data (dict): formatting data
|
||||
env (Optional[dict]): Environment variables.
|
||||
templates (list[str]): List of templates to config paths.
|
||||
template_data (dict): Template data used to format templates.
|
||||
|
||||
Returns:
|
||||
dict: config data
|
||||
Union[dict, None]: Config data or 'None' if templates are empty
|
||||
or any path exists.
|
||||
|
||||
"""
|
||||
formatting_data = deepcopy(anatomy_data)
|
||||
|
||||
environment_vars = env or dict(**os.environ)
|
||||
|
||||
# format the path for potential env vars
|
||||
formatting_data.update(environment_vars)
|
||||
|
||||
# first try host config paths
|
||||
for path_ in path_list:
|
||||
formatted_path = _format_path(path_, formatting_data)
|
||||
|
||||
if not os.path.exists(formatted_path):
|
||||
for template in templates:
|
||||
formatted_path = StringTemplate.format_template(
|
||||
template, template_data
|
||||
)
|
||||
if not formatted_path.solved:
|
||||
continue
|
||||
|
||||
return {
|
||||
"path": os.path.normpath(formatted_path),
|
||||
"template": path_
|
||||
}
|
||||
|
||||
|
||||
def _format_path(template_path, formatting_data):
|
||||
"""Single template path formatting.
|
||||
|
||||
Args:
|
||||
template_path (str): template string
|
||||
formatting_data (dict): data to be used for
|
||||
template formatting
|
||||
|
||||
Returns:
|
||||
str: absolute formatted path
|
||||
"""
|
||||
# format path for anatomy keys
|
||||
formatted_path = StringTemplate(template_path).format(
|
||||
formatting_data)
|
||||
|
||||
return os.path.abspath(formatted_path)
|
||||
path = os.path.abspath(formatted_path)
|
||||
if os.path.exists(path):
|
||||
return {
|
||||
"path": os.path.normpath(path),
|
||||
"template": template
|
||||
}
|
||||
|
||||
|
||||
def get_imageio_file_rules(project_name, host_name, project_settings=None):
|
||||
"""Get ImageIO File rules from project settings
|
||||
|
||||
Args:
|
||||
project_name (str): project name
|
||||
host_name (str): host name
|
||||
project_settings (dict, optional): project settings.
|
||||
Defaults to None.
|
||||
project_name (str): Project name.
|
||||
host_name (str): Host name.
|
||||
project_settings (Optional[dict]): Project settings.
|
||||
|
||||
Returns:
|
||||
list[dict[str, Any]]: file rules data
|
||||
|
||||
"""
|
||||
project_settings = project_settings or get_project_settings(project_name)
|
||||
|
||||
|
|
@ -960,7 +1151,7 @@ def get_remapped_colorspace_to_native(
|
|||
"""Return native colorspace name.
|
||||
|
||||
Args:
|
||||
ocio_colorspace_name (str | None): ocio colorspace name
|
||||
ocio_colorspace_name (str | None): OCIO colorspace name.
|
||||
host_name (str): Host name.
|
||||
imageio_host_settings (dict[str, Any]): ImageIO host settings.
|
||||
|
||||
|
|
@ -968,16 +1159,15 @@ def get_remapped_colorspace_to_native(
|
|||
Union[str, None]: native colorspace name defined in remapping or None
|
||||
"""
|
||||
|
||||
CachedData.remapping.setdefault(host_name, {})
|
||||
if CachedData.remapping[host_name].get("to_native") is None:
|
||||
host_mapping = CachedData.remapping.setdefault(host_name, {})
|
||||
if "to_native" not in host_mapping:
|
||||
remapping_rules = imageio_host_settings["remapping"]["rules"]
|
||||
CachedData.remapping[host_name]["to_native"] = {
|
||||
host_mapping["to_native"] = {
|
||||
rule["ocio_name"]: rule["host_native_name"]
|
||||
for rule in remapping_rules
|
||||
}
|
||||
|
||||
return CachedData.remapping[host_name]["to_native"].get(
|
||||
ocio_colorspace_name)
|
||||
return host_mapping["to_native"].get(ocio_colorspace_name)
|
||||
|
||||
|
||||
def get_remapped_colorspace_from_native(
|
||||
|
|
@ -992,30 +1182,29 @@ def get_remapped_colorspace_from_native(
|
|||
|
||||
Returns:
|
||||
Union[str, None]: Ocio colorspace name defined in remapping or None.
|
||||
"""
|
||||
|
||||
CachedData.remapping.setdefault(host_name, {})
|
||||
if CachedData.remapping[host_name].get("from_native") is None:
|
||||
"""
|
||||
host_mapping = CachedData.remapping.setdefault(host_name, {})
|
||||
if "from_native" not in host_mapping:
|
||||
remapping_rules = imageio_host_settings["remapping"]["rules"]
|
||||
CachedData.remapping[host_name]["from_native"] = {
|
||||
host_mapping["from_native"] = {
|
||||
rule["host_native_name"]: rule["ocio_name"]
|
||||
for rule in remapping_rules
|
||||
}
|
||||
|
||||
return CachedData.remapping[host_name]["from_native"].get(
|
||||
host_native_colorspace_name)
|
||||
return host_mapping["from_native"].get(host_native_colorspace_name)
|
||||
|
||||
|
||||
def _get_imageio_settings(project_settings, host_name):
|
||||
"""Get ImageIO settings for global and host
|
||||
|
||||
Args:
|
||||
project_settings (dict): project settings.
|
||||
Defaults to None.
|
||||
host_name (str): host name
|
||||
project_settings (dict[str, Any]): Project settings.
|
||||
host_name (str): Host name.
|
||||
|
||||
Returns:
|
||||
tuple[dict, dict]: image io settings for global and host
|
||||
tuple[dict, dict]: Image io settings for global and host.
|
||||
|
||||
"""
|
||||
# get image io from global and host_name
|
||||
imageio_global = project_settings["core"]["imageio"]
|
||||
|
|
@ -1033,27 +1222,41 @@ def get_colorspace_settings_from_publish_context(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"]
|
||||
folder_path = context_data["folderPath"]
|
||||
task_name = context_data["task"]
|
||||
host_name = context_data["hostName"]
|
||||
anatomy_data = context_data["anatomyData"]
|
||||
project_settings_ = context_data["project_settings"]
|
||||
anatomy = context_data["anatomy"]
|
||||
template_data = context_data["anatomyData"]
|
||||
project_settings = context_data["project_settings"]
|
||||
folder_id = None
|
||||
folder_entity = context_data.get("folderEntity")
|
||||
if folder_entity:
|
||||
folder_id = folder_entity["id"]
|
||||
|
||||
config_data = get_imageio_config(
|
||||
project_name, host_name,
|
||||
project_settings=project_settings_,
|
||||
anatomy_data=anatomy_data
|
||||
config_data = get_imageio_config_preset(
|
||||
project_name,
|
||||
folder_path,
|
||||
task_name,
|
||||
host_name,
|
||||
anatomy=anatomy,
|
||||
project_settings=project_settings,
|
||||
template_data=template_data,
|
||||
folder_id=folder_id,
|
||||
)
|
||||
|
||||
# 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_
|
||||
project_name,
|
||||
host_name,
|
||||
project_settings=project_settings
|
||||
)
|
||||
|
||||
# caching settings for future instance processing
|
||||
|
|
@ -1063,18 +1266,13 @@ def get_colorspace_settings_from_publish_context(context_data):
|
|||
|
||||
|
||||
def set_colorspace_data_to_representation(
|
||||
representation, context_data,
|
||||
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:
|
||||
```
|
||||
{
|
||||
|
|
@ -1089,6 +1287,12 @@ def set_colorspace_data_to_representation(
|
|||
}
|
||||
```
|
||||
|
||||
Args:
|
||||
representation (dict): publishing representation
|
||||
context_data (publish.Context.data): publishing context data
|
||||
colorspace (Optional[str]): Colorspace name.
|
||||
log (Optional[logging.Logger]): logger instance.
|
||||
|
||||
"""
|
||||
log = log or Logger.get_logger(__name__)
|
||||
|
||||
|
|
@ -1122,12 +1326,15 @@ def set_colorspace_data_to_representation(
|
|||
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
|
||||
)
|
||||
if colorspace is None:
|
||||
colorspace = get_imageio_file_rules_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:
|
||||
|
|
@ -1149,21 +1356,22 @@ def get_display_view_colorspace_name(config_path, display, view):
|
|||
view (str): view name e.g. "sRGB"
|
||||
|
||||
Returns:
|
||||
view color space name (str) e.g. "Output - sRGB"
|
||||
"""
|
||||
str: View color space name. e.g. "Output - sRGB"
|
||||
|
||||
"""
|
||||
if not compatibility_check():
|
||||
# python environment is not compatible with PyOpenColorIO
|
||||
# needs to be run in subprocess
|
||||
return get_display_view_colorspace_subprocess(config_path,
|
||||
display, view)
|
||||
return _get_display_view_colorspace_subprocess(
|
||||
config_path, display, view
|
||||
)
|
||||
|
||||
from ayon_core.scripts.ocio_wrapper import _get_display_view_colorspace_name # noqa
|
||||
|
||||
return _get_display_view_colorspace_name(config_path, display, view)
|
||||
|
||||
|
||||
def get_display_view_colorspace_subprocess(config_path, display, view):
|
||||
def _get_display_view_colorspace_subprocess(config_path, display, view):
|
||||
"""Returns the colorspace attribute of the (display, view) pair
|
||||
via subprocess.
|
||||
|
||||
|
|
@ -1174,8 +1382,8 @@ def get_display_view_colorspace_subprocess(config_path, display, view):
|
|||
|
||||
Returns:
|
||||
view color space name (str) e.g. "Output - sRGB"
|
||||
"""
|
||||
|
||||
"""
|
||||
with _make_temp_json_file() as tmp_json_path:
|
||||
# Prepare subprocess arguments
|
||||
args = [
|
||||
|
|
@ -1193,3 +1401,39 @@ def get_display_view_colorspace_subprocess(config_path, display, view):
|
|||
# return default view colorspace name
|
||||
with open(tmp_json_path, "r") as f:
|
||||
return json.load(f)
|
||||
|
||||
|
||||
# --- Current context functions ---
|
||||
def get_current_context_imageio_config_preset(
|
||||
anatomy=None,
|
||||
project_settings=None,
|
||||
template_data=None,
|
||||
env=None,
|
||||
):
|
||||
"""Get ImageIO config preset for current context.
|
||||
|
||||
Args:
|
||||
anatomy (Optional[Anatomy]): Current project anatomy.
|
||||
project_settings (Optional[dict[str, Any]]): Current project settings.
|
||||
template_data (Optional[dict[str, Any]]): Prepared template data
|
||||
for current context.
|
||||
env (Optional[dict[str, str]]): Custom environment variable values.
|
||||
|
||||
Returns:
|
||||
dict: ImageIO config preset.
|
||||
|
||||
"""
|
||||
from .context_tools import get_current_context, get_current_host_name
|
||||
|
||||
context = get_current_context()
|
||||
host_name = get_current_host_name()
|
||||
return get_imageio_config_preset(
|
||||
context["project_name"],
|
||||
context["folder_path"],
|
||||
context["task_name"],
|
||||
host_name,
|
||||
anatomy=anatomy,
|
||||
project_settings=project_settings,
|
||||
template_data=template_data,
|
||||
env=env,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
from typing import Any
|
||||
|
||||
from ayon_server.addons import BaseServerAddon
|
||||
|
||||
from .settings import CoreSettings, DEFAULT_VALUES
|
||||
|
|
@ -9,3 +11,53 @@ class CoreAddon(BaseServerAddon):
|
|||
async def get_default_settings(self):
|
||||
settings_model_cls = self.get_settings_model()
|
||||
return settings_model_cls(**DEFAULT_VALUES)
|
||||
|
||||
async def convert_settings_overrides(
|
||||
self,
|
||||
source_version: str,
|
||||
overrides: dict[str, Any],
|
||||
) -> dict[str, Any]:
|
||||
self._convert_imagio_configs_0_3_1(overrides)
|
||||
# Use super conversion
|
||||
return await super().convert_settings_overrides(
|
||||
source_version, overrides
|
||||
)
|
||||
|
||||
def _convert_imagio_configs_0_3_1(self, overrides):
|
||||
"""Imageio config settings did change to profiles since 0.3.1. ."""
|
||||
imageio_overrides = overrides.get("imageio") or {}
|
||||
if (
|
||||
"ocio_config" not in imageio_overrides
|
||||
or "filepath" not in imageio_overrides["ocio_config"]
|
||||
):
|
||||
return
|
||||
|
||||
ocio_config = imageio_overrides.pop("ocio_config")
|
||||
|
||||
filepath = ocio_config["filepath"]
|
||||
if not filepath:
|
||||
return
|
||||
first_filepath = filepath[0]
|
||||
ocio_config_profiles = imageio_overrides.setdefault(
|
||||
"ocio_config_profiles", []
|
||||
)
|
||||
base_value = {
|
||||
"type": "builtin_path",
|
||||
"product_name": "",
|
||||
"host_names": [],
|
||||
"task_names": [],
|
||||
"task_types": [],
|
||||
"custom_path": "",
|
||||
"builtin_path": "{BUILTIN_OCIO_ROOT}/aces_1.2/config.ocio"
|
||||
}
|
||||
if first_filepath in (
|
||||
"{BUILTIN_OCIO_ROOT}/aces_1.2/config.ocio",
|
||||
"{BUILTIN_OCIO_ROOT}/nuke-default/config.ocio",
|
||||
):
|
||||
base_value["type"] = "builtin_path"
|
||||
base_value["builtin_path"] = first_filepath
|
||||
else:
|
||||
base_value["type"] = "custom_path"
|
||||
base_value["custom_path"] = first_filepath
|
||||
|
||||
ocio_config_profiles.append(base_value)
|
||||
|
|
|
|||
|
|
@ -54,9 +54,67 @@ class CoreImageIOFileRulesModel(BaseSettingsModel):
|
|||
return value
|
||||
|
||||
|
||||
class CoreImageIOConfigModel(BaseSettingsModel):
|
||||
filepath: list[str] = SettingsField(
|
||||
default_factory=list, title="Config path"
|
||||
def _ocio_config_profile_types():
|
||||
return [
|
||||
{"value": "builtin_path", "label": "AYON built-in OCIO config"},
|
||||
{"value": "custom_path", "label": "Path to OCIO config"},
|
||||
{"value": "product_name", "label": "Published product"},
|
||||
]
|
||||
|
||||
|
||||
def _ocio_built_in_paths():
|
||||
return [
|
||||
{
|
||||
"value": "{BUILTIN_OCIO_ROOT}/aces_1.2/config.ocio",
|
||||
"label": "ACES 1.2",
|
||||
"description": "Aces 1.2 OCIO config file."
|
||||
},
|
||||
{
|
||||
"value": "{BUILTIN_OCIO_ROOT}/nuke-default/config.ocio",
|
||||
"label": "Nuke default",
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
class CoreImageIOConfigProfilesModel(BaseSettingsModel):
|
||||
_layout = "expanded"
|
||||
host_names: list[str] = SettingsField(
|
||||
default_factory=list,
|
||||
title="Host names"
|
||||
)
|
||||
task_types: list[str] = SettingsField(
|
||||
default_factory=list,
|
||||
title="Task types",
|
||||
enum_resolver=task_types_enum
|
||||
)
|
||||
task_names: list[str] = SettingsField(
|
||||
default_factory=list,
|
||||
title="Task names"
|
||||
)
|
||||
type: str = SettingsField(
|
||||
title="Profile type",
|
||||
enum_resolver=_ocio_config_profile_types,
|
||||
conditionalEnum=True,
|
||||
default="builtin_path",
|
||||
section="---",
|
||||
)
|
||||
builtin_path: str = SettingsField(
|
||||
"ACES 1.2",
|
||||
title="Built-in OCIO config",
|
||||
enum_resolver=_ocio_built_in_paths,
|
||||
)
|
||||
custom_path: str = SettingsField(
|
||||
"",
|
||||
title="OCIO config path",
|
||||
description="Path to OCIO config. Anatomy formatting is supported.",
|
||||
)
|
||||
product_name: str = SettingsField(
|
||||
"",
|
||||
title="Product name",
|
||||
description=(
|
||||
"Published product name to get OCIO config from. "
|
||||
"Partial match is supported."
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -65,9 +123,8 @@ class CoreImageIOBaseModel(BaseSettingsModel):
|
|||
False,
|
||||
title="Enable Color Management"
|
||||
)
|
||||
ocio_config: CoreImageIOConfigModel = SettingsField(
|
||||
default_factory=CoreImageIOConfigModel,
|
||||
title="OCIO config"
|
||||
ocio_config_profiles: list[CoreImageIOConfigProfilesModel] = SettingsField(
|
||||
default_factory=list, title="OCIO config profiles"
|
||||
)
|
||||
file_rules: CoreImageIOFileRulesModel = SettingsField(
|
||||
default_factory=CoreImageIOFileRulesModel,
|
||||
|
|
@ -186,12 +243,17 @@ class CoreSettings(BaseSettingsModel):
|
|||
DEFAULT_VALUES = {
|
||||
"imageio": {
|
||||
"activate_global_color_management": False,
|
||||
"ocio_config": {
|
||||
"filepath": [
|
||||
"{BUILTIN_OCIO_ROOT}/aces_1.2/config.ocio",
|
||||
"{BUILTIN_OCIO_ROOT}/nuke-default/config.ocio"
|
||||
]
|
||||
},
|
||||
"ocio_config_profiles": [
|
||||
{
|
||||
"host_names": [],
|
||||
"task_types": [],
|
||||
"task_names": [],
|
||||
"type": "builtin_path",
|
||||
"builtin_path": "{BUILTIN_OCIO_ROOT}/aces_1.2/config.ocio",
|
||||
"custom_path": "",
|
||||
"product_name": "",
|
||||
}
|
||||
],
|
||||
"file_rules": {
|
||||
"activate_global_file_rules": False,
|
||||
"rules": [
|
||||
|
|
@ -199,42 +261,57 @@ DEFAULT_VALUES = {
|
|||
"name": "example",
|
||||
"pattern": ".*(beauty).*",
|
||||
"colorspace": "ACES - ACEScg",
|
||||
"ext": "exr"
|
||||
"ext": "exr",
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
},
|
||||
},
|
||||
"studio_name": "",
|
||||
"studio_code": "",
|
||||
"environments": "{\n\"STUDIO_SW\": {\n \"darwin\": \"/mnt/REPO_SW\",\n \"linux\": \"/mnt/REPO_SW\",\n \"windows\": \"P:/REPO_SW\"\n }\n}",
|
||||
"environments": json.dumps(
|
||||
{
|
||||
"STUDIO_SW": {
|
||||
"darwin": "/mnt/REPO_SW",
|
||||
"linux": "/mnt/REPO_SW",
|
||||
"windows": "P:/REPO_SW"
|
||||
}
|
||||
},
|
||||
indent=4
|
||||
),
|
||||
"tools": DEFAULT_TOOLS_VALUES,
|
||||
"version_start_category": {
|
||||
"profiles": []
|
||||
},
|
||||
"publish": DEFAULT_PUBLISH_VALUES,
|
||||
"project_folder_structure": json.dumps({
|
||||
"__project_root__": {
|
||||
"prod": {},
|
||||
"resources": {
|
||||
"footage": {
|
||||
"plates": {},
|
||||
"offline": {}
|
||||
"project_folder_structure": json.dumps(
|
||||
{
|
||||
"__project_root__": {
|
||||
"prod": {},
|
||||
"resources": {
|
||||
"footage": {
|
||||
"plates": {},
|
||||
"offline": {}
|
||||
},
|
||||
"audio": {},
|
||||
"art_dept": {}
|
||||
},
|
||||
"audio": {},
|
||||
"art_dept": {}
|
||||
},
|
||||
"editorial": {},
|
||||
"assets": {
|
||||
"characters": {},
|
||||
"locations": {}
|
||||
},
|
||||
"shots": {}
|
||||
}
|
||||
}, indent=4),
|
||||
"editorial": {},
|
||||
"assets": {
|
||||
"characters": {},
|
||||
"locations": {}
|
||||
},
|
||||
"shots": {}
|
||||
}
|
||||
},
|
||||
indent=4
|
||||
),
|
||||
"project_plugins": {
|
||||
"windows": [],
|
||||
"darwin": [],
|
||||
"linux": []
|
||||
},
|
||||
"project_environments": "{}"
|
||||
"project_environments": json.dumps(
|
||||
{},
|
||||
indent=4
|
||||
)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue