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

Nuke: LoadClip colorspace override - OP-6591 #89

Merged
merged 10 commits into from
Mar 11, 2024
34 changes: 19 additions & 15 deletions client/ayon_core/hosts/nuke/api/utils.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import os
import re

import nuke

from ayon_core import resources
Expand Down Expand Up @@ -103,9 +105,8 @@ def colorspace_exists_on_node(node, colorspace_name):
except ValueError:
# knob is not available on input node
return False
all_clrs = get_colorspace_list(colorspace_knob)

return colorspace_name in all_clrs
return colorspace_name in get_colorspace_list(colorspace_knob)


def get_colorspace_list(colorspace_knob):
Expand All @@ -117,19 +118,22 @@ def get_colorspace_list(colorspace_knob):
Returns:
list: list of strings names of profiles
"""

all_clrs = list(colorspace_knob.values())
reduced_clrs = []

if not colorspace_knob.getFlag(nuke.STRIP_CASCADE_PREFIX):
return all_clrs

# strip colorspace with nested path
for clrs in all_clrs:
clrs = clrs.split('/')[-1]
reduced_clrs.append(clrs)

return reduced_clrs
results = []

# This pattern is to match with roles which uses an indentation and
# parentheses with original colorspace. The value returned from the
# colorspace is the string before the indentation, so we'll need to
# convert the values to match with value returned from the knob,
# ei. knob.value().
pattern = r".*\t.* \(.*\)"
for colorspace in nuke.getColorspaceList(colorspace_knob):
match = re.search(pattern, colorspace)
if match:
results.append(colorspace.split("\t")[0])
tokejepsen marked this conversation as resolved.
Show resolved Hide resolved
else:
results.append(colorspace)

return results


def is_headless():
Expand Down
106 changes: 76 additions & 30 deletions client/ayon_core/hosts/nuke/plugins/load/load_clip.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,6 @@ def load(self, context, name, namespace, options):

filepath = self.filepath_from_context(context)
filepath = filepath.replace("\\", "/")
self.log.debug("_ filepath: {}".format(filepath))

start_at_workfile = options.get(
"start_at_workfile", self.options_defaults["start_at_workfile"])
Expand Down Expand Up @@ -154,8 +153,8 @@ def load(self, context, name, namespace, options):
with viewer_update_and_undo_stop():
read_node["file"].setValue(filepath)

used_colorspace = self._set_colorspace(
read_node, version_data, representation["data"], filepath)
self.set_colorspace_to_node(
read_node, filepath, version, representation)

self._set_range_to_node(read_node, first, last, start_at_workfile)

Expand All @@ -180,8 +179,6 @@ def load(self, context, name, namespace, options):
colorspace = representation["data"].get(key)
colorspace = colorspace or version_data.get(key)
data_imprint["db_colorspace"] = colorspace
if used_colorspace:
data_imprint["used_colorspace"] = used_colorspace
else:
value_ = context["version"]['data'].get(
key, str(None))
Expand Down Expand Up @@ -304,8 +301,9 @@ def update(self, container, context):
# to avoid multiple undo steps for rest of process
# we will switch off undo-ing
with viewer_update_and_undo_stop():
used_colorspace = self._set_colorspace(
read_node, version_data, repre_doc["data"], filepath)
self.set_colorspace_to_node(
read_node, filepath, version_doc, repre_doc
)

self._set_range_to_node(read_node, first, last, start_at_workfile)

Expand All @@ -322,10 +320,6 @@ def update(self, container, context):
"author": version_data.get("author")
}

# add used colorspace if found any
if used_colorspace:
updated_dict["used_colorspace"] = used_colorspace

last_version_doc = get_last_version_by_subset_id(
project_name, version_doc["parent"], fields=["_id"]
)
Expand All @@ -352,6 +346,36 @@ def update(self, container, context):

self.set_as_member(read_node)

def set_colorspace_to_node(
self,
read_node,
filepath,
version_doc,
representation_doc,
):
"""Set colorspace to read node.

Sets colorspace with available names validation.

Args:
read_node (nuke.Node): The nuke's read node
filepath (str): file path
version_doc (dict): version document
representation_doc (dict): representation document

"""
used_colorspace = self._get_colorspace_data(
version_doc, representation_doc, filepath)

if (
used_colorspace
and colorspace_exists_on_node(read_node, used_colorspace)
):
self.log.info(f"Used colorspace: {used_colorspace}")
read_node["colorspace"].setValue(used_colorspace)
else:
self.log.info("Colorspace not set...")

def remove(self, container):
read_node = container["node"]
assert read_node.Class() == "Read", "Must be Read"
Expand Down Expand Up @@ -452,25 +476,47 @@ def _get_node_name(self, representation):

return self.node_name_template.format(**name_data)

def _set_colorspace(self, node, version_data, repre_data, path):
output_color = None
path = path.replace("\\", "/")
# get colorspace
colorspace = repre_data.get("colorspace")
colorspace = colorspace or version_data.get("colorspace")
def _get_colorspace_data(self, version_doc, representation_doc, filepath):
"""Get colorspace data from version and representation documents

# colorspace from `project_settings/nuke/imageio/regex_inputs`
iio_colorspace = get_imageio_input_colorspace(path)
Args:
version_doc (dict): version document
representation_doc (dict): representation document
filepath (str): file path

# Set colorspace defined in version data
if (
colorspace is not None
and colorspace_exists_on_node(node, str(colorspace))
):
node["colorspace"].setValue(str(colorspace))
output_color = str(colorspace)
elif iio_colorspace is not None:
node["colorspace"].setValue(iio_colorspace)
output_color = iio_colorspace
Returns:
Any[str,None]: colorspace name or None
"""
# Get backward compatible colorspace key.
colorspace = representation_doc["data"].get("colorspace")
self.log.debug(
f"Colorspace from representation colorspace: {colorspace}"
)

# Get backward compatible version data key if colorspace is not found.
colorspace = colorspace or version_doc["data"].get("colorspace")
self.log.debug(f"Colorspace from version colorspace: {colorspace}")

return output_color
# Get colorspace from representation colorspaceData if colorspace is
# not found.
colorspace_data = representation_doc["data"].get("colorspaceData", {})
colorspace = colorspace or colorspace_data.get("colorspace")
self.log.debug(
f"Colorspace from representation colorspaceData: {colorspace}"
)

# check if any filerules are not applicable
new_parsed_colorspace = get_imageio_file_rules_colorspace_from_filepath( # noqa
filepath, "nuke", get_current_project_name()
)
self.log.debug(f"Colorspace new filerules: {new_parsed_colorspace}")

# colorspace from `project_settings/nuke/imageio/regexInputs`
old_parsed_colorspace = get_imageio_input_colorspace(filepath)
self.log.debug(f"Colorspace old filerules: {old_parsed_colorspace}")

return (
new_parsed_colorspace
or old_parsed_colorspace
or colorspace
)