From 723d7bbd7b87049f1be4c3fb87471aac09cbff9a Mon Sep 17 00:00:00 2001 From: Toke Stuart Jepsen Date: Mon, 19 Feb 2024 11:58:46 +0000 Subject: [PATCH 1/5] Porting from OpenPype --- client/ayon_core/hosts/nuke/api/utils.py | 33 ++++-- .../hosts/nuke/plugins/load/load_clip.py | 107 +++++++++++++----- 2 files changed, 98 insertions(+), 42 deletions(-) diff --git a/client/ayon_core/hosts/nuke/api/utils.py b/client/ayon_core/hosts/nuke/api/utils.py index d738ba5464..0a05077a68 100644 --- a/client/ayon_core/hosts/nuke/api/utils.py +++ b/client/ayon_core/hosts/nuke/api/utils.py @@ -103,33 +103,42 @@ 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): """Get available colorspace profile names + Because the values returned from colorspace_knob.values() do not correspond + to the value returned from colorspace_knob.value(), and the extracted + colorspace comes from using colorspace_knob.value(), we need to iterate + through all values to get the correct value. + + A code example of the above would be: + + for count, value in enumerate(colorspace_knob.values()): + colorspace_knob.setValue(count) + print(colorspace_knob.value() in colorspace_knob.values()) + Args: colorspace_knob (nuke.Knob): nuke knob object Returns: list: list of strings names of profiles """ + original_value = colorspace_knob.value() - all_clrs = list(colorspace_knob.values()) - reduced_clrs = [] + colorspaces = [] - 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) + try: + for count, _ in enumerate(colorspace_knob.values()): + colorspace_knob.setValue(count) + colorspaces.append(colorspace_knob.value()) + finally: + colorspace_knob.setValue(original_value) - return reduced_clrs + return colorspaces def is_headless(): diff --git a/client/ayon_core/hosts/nuke/plugins/load/load_clip.py b/client/ayon_core/hosts/nuke/plugins/load/load_clip.py index 8bce2eac6e..51cf5941ea 100644 --- a/client/ayon_core/hosts/nuke/plugins/load/load_clip.py +++ b/client/ayon_core/hosts/nuke/plugins/load/load_clip.py @@ -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"]) @@ -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) @@ -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)) @@ -302,8 +299,8 @@ def update(self, container, representation): # 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, representation["data"], filepath) + self.set_colorspace_to_node( + read_node, filepath, version_doc, representation) self._set_range_to_node(read_node, first, last, start_at_workfile) @@ -320,10 +317,6 @@ def update(self, container, representation): "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"] ) @@ -350,6 +343,36 @@ def update(self, container, representation): 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" @@ -450,25 +473,49 @@ 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/regexInputs` - 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}") + + # 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}" + ) + + print(f"Colorspace found: {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 output_color + return ( + new_parsed_colorspace + or old_parsed_colorspace + or colorspace + ) From 511e2047defb0bbd11bbb7d41dc13a047ba7c2e0 Mon Sep 17 00:00:00 2001 From: Toke Jepsen Date: Tue, 5 Mar 2024 16:03:50 +0000 Subject: [PATCH 2/5] Update client/ayon_core/hosts/nuke/plugins/load/load_clip.py --- client/ayon_core/hosts/nuke/plugins/load/load_clip.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/client/ayon_core/hosts/nuke/plugins/load/load_clip.py b/client/ayon_core/hosts/nuke/plugins/load/load_clip.py index 51cf5941ea..686cd6eac6 100644 --- a/client/ayon_core/hosts/nuke/plugins/load/load_clip.py +++ b/client/ayon_core/hosts/nuke/plugins/load/load_clip.py @@ -502,8 +502,6 @@ def _get_colorspace_data(self, version_doc, representation_doc, filepath): f"Colorspace from representation colorspaceData: {colorspace}" ) - print(f"Colorspace found: {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() From 091a706518e229fbb2c019351ef8dc73fa6b8f8b Mon Sep 17 00:00:00 2001 From: Toke Stuart Jepsen Date: Thu, 7 Mar 2024 11:49:20 +0000 Subject: [PATCH 3/5] Dont brute force colorspaces list --- client/ayon_core/hosts/nuke/api/utils.py | 41 +++++++++++------------- 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/client/ayon_core/hosts/nuke/api/utils.py b/client/ayon_core/hosts/nuke/api/utils.py index 0a05077a68..80d719664a 100644 --- a/client/ayon_core/hosts/nuke/api/utils.py +++ b/client/ayon_core/hosts/nuke/api/utils.py @@ -1,4 +1,6 @@ import os +import re + import nuke from ayon_core import resources @@ -110,35 +112,28 @@ def colorspace_exists_on_node(node, colorspace_name): def get_colorspace_list(colorspace_knob): """Get available colorspace profile names - Because the values returned from colorspace_knob.values() do not correspond - to the value returned from colorspace_knob.value(), and the extracted - colorspace comes from using colorspace_knob.value(), we need to iterate - through all values to get the correct value. - - A code example of the above would be: - - for count, value in enumerate(colorspace_knob.values()): - colorspace_knob.setValue(count) - print(colorspace_knob.value() in colorspace_knob.values()) - Args: colorspace_knob (nuke.Knob): nuke knob object Returns: list: list of strings names of profiles """ - original_value = colorspace_knob.value() - - colorspaces = [] - - try: - for count, _ in enumerate(colorspace_knob.values()): - colorspace_knob.setValue(count) - colorspaces.append(colorspace_knob.value()) - finally: - colorspace_knob.setValue(original_value) - - return colorspaces + 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]) + else: + results.append(colorspace) + + return results def is_headless(): From 5120df1157b0b865430f36ebd213d3887731edb0 Mon Sep 17 00:00:00 2001 From: Toke Jepsen Date: Thu, 7 Mar 2024 12:14:44 +0000 Subject: [PATCH 4/5] Update client/ayon_core/hosts/nuke/api/utils.py Co-authored-by: Roy Nieterau --- client/ayon_core/hosts/nuke/api/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/hosts/nuke/api/utils.py b/client/ayon_core/hosts/nuke/api/utils.py index 80d719664a..1bfc1919fa 100644 --- a/client/ayon_core/hosts/nuke/api/utils.py +++ b/client/ayon_core/hosts/nuke/api/utils.py @@ -129,7 +129,7 @@ def get_colorspace_list(colorspace_knob): for colorspace in nuke.getColorspaceList(colorspace_knob): match = re.search(pattern, colorspace) if match: - results.append(colorspace.split("\t")[0]) + results.append(colorspace.split("\t", 1)[0]) else: results.append(colorspace) From 2fe09689e8d317838ea218332ecd022f862f60d9 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 7 Mar 2024 21:57:24 +0100 Subject: [PATCH 5/5] missing import --- client/ayon_core/hosts/nuke/plugins/load/load_clip.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/client/ayon_core/hosts/nuke/plugins/load/load_clip.py b/client/ayon_core/hosts/nuke/plugins/load/load_clip.py index a75703b718..98c3303eb8 100644 --- a/client/ayon_core/hosts/nuke/plugins/load/load_clip.py +++ b/client/ayon_core/hosts/nuke/plugins/load/load_clip.py @@ -11,6 +11,9 @@ get_current_project_name, get_representation_path, ) +from ayon_core.pipeline.colorspace import ( + get_imageio_file_rules_colorspace_from_filepath +) from ayon_core.hosts.nuke.api.lib import ( get_imageio_input_colorspace, maintained_selection