Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhancing ocio config embedding of looks #25

Merged
merged 19 commits into from
Sep 14, 2024
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
334c6c7
Update dependencies in pyproject.toml and remove specific Poetry vers…
jakubjezek001 Jul 26, 2024
c6e0c47
WIP on enhancement/renderer-basic
jakubjezek001 Jul 30, 2024
c58aa3c
Refactor test for AYONOCIOLookFileProcessor parameters
jakubjezek001 Jul 30, 2024
ba9dd3a
Update OCIO search paths and add attributes to AYONOCIOLookFileProces…
jakubjezek001 Jul 30, 2024
af0b7db
Refactor OCIO configuration and typing in files
jakubjezek001 Jul 30, 2024
705692c
Add logging and update test results directory handling
jakubjezek001 Jul 30, 2024
d75554b
Update test configuration to not keep test results.
jakubjezek001 Jul 30, 2024
b98f4f7
Refactor debug logs and variable names, update assertions for process…
jakubjezek001 Jul 30, 2024
3033d50
WIP testing for AYONHieroEffectsFileProcessor.
jakubjezek001 Jul 30, 2024
ce8525c
WIP refactor ayon hiero effect file module
jakubjezek001 Jul 30, 2024
5ef5267
AYONHieroEffectsFileProcessor.
jakubjezek001 Jul 30, 2024
4091f17
Add target view space handling and refactor code for better readability.
jakubjezek001 Aug 8, 2024
86c05e8
Added a docstring to clarify the behavior of the load method.
jakubjezek001 Aug 8, 2024
32aac90
Refactor search paths handling in OCIOConfigFileGenerator
jakubjezek001 Aug 8, 2024
0d91f37
Remove unused _ocio_transforms list and replace it with _operators th…
jakubjezek001 Aug 8, 2024
07b7e59
Add PyOpenColorIO import, test OCIOConfigFileGenerator
jakubjezek001 Aug 8, 2024
fd64571
Solving the search path and environment adding inconsistency
jakubjezek001 Aug 9, 2024
42fe3b9
cccid has to be set to 0 if none is set
jakubjezek001 Aug 14, 2024
5bd6f14
sets search paths and environment using native methods
tweak-wtf Sep 14, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
138 changes: 99 additions & 39 deletions lablib/generators/ocio_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,16 @@ class OCIOConfigFileGenerator:
objects.
working_space (Optional[str]): The working space of the OCIO Config
file.
target_view_space (Optional[str]): The target view space of the OCIO
Config file. For views to be using specific color spaces
different from working space.
views (Optional[List[str]]): A list of views.
description (Optional[str]): The description of the OCIO Config file.
staging_dir (Optional[str]): The staging directory of the OCIO Config
file.
environment_variables (Optional[Dict]): A dictionary of environment
variables.
search_paths (Optional[List[str]]): A list of search paths.

Example:
>>> from lablib.operators import LUT
Expand All @@ -54,17 +58,17 @@ class OCIOConfigFileGenerator:
FileNotFoundError: If the OCIO Config file is not found.

"""
log: logging.Logger = log

_description: str
_vars: Dict[str, str] = {}
_views: List[str] = []
_config_path: Path # OCIO Config file
_ocio_config: OCIO.Config # OCIO Config object
_ocio_transforms: List = []
_ocio_search_paths: List[str]
_ocio_config: OCIO.Config # OCIO Config object
_ocio_search_paths: List[str] = []
_ocio_config_name: str = "config.ocio"
_dest_path: str
_operators: List[OCIO.Transform]
_dest_path: str = ""
_operators: List[OCIO.Transform] = []

def __init__(
self,
Expand All @@ -73,11 +77,15 @@ def __init__(
operators: Optional[List[OCIO.Transform]] = None,
config_path: Optional[str] = None,
working_space: Optional[str] = None,
target_view_space: Optional[str] = None,
views: Optional[List[str]] = None,
description: Optional[str] = None,
staging_dir: Optional[str] = None,
environment_variables: Optional[Dict] = None,
search_paths: Optional[List[str]] = None,
logger: logging.Logger = None,
):

# Context is required
self.context = context

Expand All @@ -89,13 +97,21 @@ def __init__(
else:
self.working_space = working_space

# Default target view space
if target_view_space is None:
self.target_view_space = self.working_space
else:
self.target_view_space = target_view_space

# Default views
if views:
self.set_views(views)

# Default operators
if operators:
self.set_operators(operators)
else:
self.clear_operators()

# Set OCIO config path and with validation
if config_path is None:
Expand Down Expand Up @@ -130,6 +146,15 @@ def __init__(
if environment_variables:
self.set_vars(**environment_variables)

# first clear all search paths
self._ocio_search_paths = []
if search_paths:
# add additional search paths
self.set_search_paths(search_paths)

if logger:
self.log = logger

def set_ocio_config_name(self, name: str) -> None:
"""Set the name of the OCIO Config file.

Expand All @@ -150,6 +175,9 @@ def set_views(self, *args: Union[str, List[str]]) -> None:
self.clear_views()
self.append_views(*args)

def set_search_paths(self, *args: Union[str, List[str]]) -> None:
self.append_search_paths(*args)

def set_operators(self, *args) -> None:
"""Set operators.

Expand Down Expand Up @@ -186,6 +214,18 @@ def clear_vars(self):
"""Clear the environment variables."""
self._vars = {}

def append_search_paths(self, *args) -> None:
"""Append search paths.

Arguments:
*args: A list of search paths.
"""
for arg in args:
if isinstance(arg, list):
self.append_search_paths(*arg)
else:
self._ocio_search_paths.append(self._swap_variables(arg))

def append_operators(self, *args) -> None:
"""Append operators.

Expand Down Expand Up @@ -261,19 +301,17 @@ def _sanitize_search_paths(self, paths: List[str]) -> None:
computed_path = computed_path.resolve()
real_paths.append(computed_path.as_posix())

real_paths = list(set(real_paths))
var_paths = [self._swap_variables(path) for path in real_paths]
self._search_paths = var_paths
self.append_search_paths(list(set(real_paths)))

def _get_absolute_search_paths(self) -> None:
"""Get the absolute search paths from the OCIO Config file."""
paths = self._get_search_paths_from_config()
for ocio_transform in self._ocio_transforms:
for ocio_transform in self._operators:
if not hasattr(ocio_transform, "getSrc"):
continue
search_path = Path(ocio_transform.getSrc())
if not search_path.exists():
log.warning(f"Path not found: {search_path}")
self.log.warning(f"Path not found: {search_path}")

paths.append(ocio_transform.getSrc())

Expand All @@ -284,27 +322,21 @@ def _change_src_paths_to_names(self) -> None:

This will also replace any variables found in the path.
"""
for ocio_transform in self._ocio_transforms:
for ocio_transform in self._operators:
if not hasattr(ocio_transform, "getSrc"):
continue

# TODO: this should be probably somewhere else
if (
hasattr(ocio_transform, "getCCCId")
and ocio_transform.getCCCId()
):
ocio_transform.setCCCId(
self._swap_variables(ocio_transform.getCCCId())
)
if hasattr(ocio_transform, "getCCCId") and ocio_transform.getCCCId():
ocio_transform.setCCCId(self._swap_variables(ocio_transform.getCCCId()))

search_path = Path(ocio_transform.getSrc())
if not search_path.exists():
log.warning(f"Path not found: {search_path}")
self.log.warning(f"Path not found: {search_path}")

# Change the src path to the name of the search path
# and replace any found variables
ocio_transform.setSrc(
self._swap_variables(search_path.name))
ocio_transform.setSrc(self._swap_variables(search_path.name))

def _swap_variables(self, text: str) -> str:
"""Replace variables in a string with their values.
Expand All @@ -317,7 +349,13 @@ def _swap_variables(self, text: str) -> str:
"""
new_text = text
for k, v in self._vars.items():
new_text = text.replace(v, f"${k}")
v = v.replace("\\", "/")
text = text.replace("\\", "/")
if v in text:
new_text = text.replace(v, f"${k}")
# and stop the loop since it had already found a match
break

return new_text

def load_config_from_file(self, filepath: str) -> None:
Expand All @@ -335,11 +373,8 @@ def process_config(self) -> None:
color space transform, color space, look, display view, active views,
and validate the OCIO Config object.
"""
for k, v in self._vars.items():
self._ocio_config.addEnvironmentVar(k, v)

self._ocio_config.setDescription(self._description)
group_transform = OCIO.GroupTransform(self._ocio_transforms)
group_transform = OCIO.GroupTransform(self._operators)
look_transform = OCIO.ColorSpaceTransform(
src=self.working_space, dst=self.context
)
Expand All @@ -360,7 +395,7 @@ def process_config(self) -> None:
self._ocio_config.addDisplayView(
self._ocio_config.getActiveDisplays().split(",")[0],
self.context,
self.working_space,
self.target_view_space,
looks=self.context,
)

Expand All @@ -369,9 +404,7 @@ def process_config(self) -> None:
else:
views_value = ",".join(self._views)

self._ocio_config.setActiveViews(
f"{self.context},{views_value}"
)
self._ocio_config.setActiveViews(f"{self.context},{views_value}")
self._ocio_config.validate()

def write_config(self, dest: str = None) -> str:
Expand All @@ -380,14 +413,24 @@ def write_config(self, dest: str = None) -> str:
Arguments:
dest (str): The destination path to write the OCIO Config file.
"""
search_paths = [f" - {path}" for path in self._search_paths]

search_path_lines = self._get_search_paths_lines()
environment_lines = self._get_environment_variables_lines()

config_lines = []
for line in self._ocio_config.serialize().splitlines():
if "search_path" not in line:
config_lines.append(line)
continue
config_lines.extend(["", "search_path:"] + search_paths + [""])

# Add search paths and environment variables
# TODO: figure out how to do it properly since this is a hacky way
if environment_lines:
config_lines.extend(
["", "environment:"] + environment_lines + [""])
if search_path_lines:
config_lines.extend(
["", "search_path:"] + search_path_lines + [""])

final_config = "\n".join(config_lines)
dest = Path(dest).resolve()
Expand All @@ -396,6 +439,29 @@ def write_config(self, dest: str = None) -> str:
f.write(final_config)
return final_config

def _get_search_paths_lines(self) -> List[str]:
"""Add search paths to the OCIO Config file.

INFO: This is temporary hacky way to add search paths to the
OCIO since OCIO is ignoring official api methods `addSearchPath()`.

Arguments:
paths (List[str]): A list of search paths.
"""
return [f" - {path}" for path in self._ocio_search_paths]

def _get_environment_variables_lines(self) -> List[str]:
"""Add environment variables to the OCIO Config file.

INFO: This is temporary hacky way to add environment variables to the
OCIO since OCIO is ignoring official api
methods `addEnvironmentVar()`.

Returns:
List[str]: A list of environment variables.
"""
return [f" {k}: {v}" for k, v in self._vars.items()]

def create_config(self, dest: str = None) -> str:
"""Create an OCIO Config file.

Expand All @@ -410,9 +476,6 @@ def create_config(self, dest: str = None) -> str:
dest = Path(dest).resolve().as_posix()
self.load_config_from_file(self._config_path.resolve().as_posix())

for op in self._operators:
self._ocio_transforms.append(op)

self._get_absolute_search_paths()
self._change_src_paths_to_names()
self.process_config()
Expand All @@ -429,9 +492,6 @@ def get_oiiotool_cmd(self) -> List:
return [
"--colorconfig",
self._dest_path,
(
f"--ociolook:from=\"{self.working_space}\""
f":to=\"{self.working_space}\""
),
(f'--ociolook:from="{self.working_space}"' f':to="{self.working_space}"'),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
(f'--ociolook:from="{self.working_space}"' f':to="{self.working_space}"'),
f'--ociolook:from="{self.working_space}":to="{self.working_space}"',

self.context,
]
2 changes: 1 addition & 1 deletion lablib/operators/color.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ def to_ocio_obj(self) -> List[Union[OCIO.FileTransform, OCIO.CDLTransform]]: #
effects.append(
OCIO.FileTransform(
src=lut_file.as_posix(),
cccId=self.cccid,
cccId=(self.cccid or "0"),
interpolation=interpolation,
direction=direction,
)
Expand Down
Loading
Loading