From d42a67e814fc7503afe70887f54b6b7176daedf8 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Tue, 21 Nov 2023 15:14:18 +0100 Subject: [PATCH 01/24] nuke: adding `need_thumnail` to intermediate representations --- openpype/hosts/nuke/api/plugin.py | 35 ++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/nuke/api/plugin.py b/openpype/hosts/nuke/api/plugin.py index 301b9533a9..15d7bfc4b9 100644 --- a/openpype/hosts/nuke/api/plugin.py +++ b/openpype/hosts/nuke/api/plugin.py @@ -21,6 +21,11 @@ from openpype.pipeline import ( CreatedInstance, get_current_task_name ) +from openpype.pipeline.colorspace import ( + get_display_view_colorspace_name, + get_colorspace_settings_from_publish_context, + set_colorspace_data_to_representation +) from openpype.lib.transcoding import ( VIDEO_EXTENSIONS ) @@ -612,7 +617,7 @@ class ExporterReview(object): def get_representation_data( self, tags=None, range=False, - custom_tags=None + custom_tags=None, colorspace=None ): """ Add representation data to self.data @@ -652,6 +657,14 @@ class ExporterReview(object): if self.publish_on_farm: repre["tags"].append("publish_on_farm") + # add colorspace data to representation + if colorspace: + set_colorspace_data_to_representation( + repre, + self.instance.context.data, + colorspace=colorspace, + log=self.log + ) self.data["representations"].append(repre) def get_imageio_baking_profile(self): @@ -866,6 +879,13 @@ class ExporterReviewMov(ExporterReview): return path def generate_mov(self, farm=False, **kwargs): + # colorspace data + colorspace = None + # get colorspace settings + # get colorspace data from context + config_data, _ = get_colorspace_settings_from_publish_context( + self.instance.context.data) + add_tags = [] self.publish_on_farm = farm read_raw = kwargs["read_raw"] @@ -951,6 +971,14 @@ class ExporterReviewMov(ExporterReview): # assign viewer dag_node["view"].setValue(viewer) + if config_data: + # convert display and view to colorspace + colorspace = get_display_view_colorspace_name( + config_path=config_data["path"], + display=display, + view=viewer + ) + self._connect_to_above_nodes(dag_node, subset, "OCIODisplay... `{}`") # Write node write_node = nuke.createNode("Write") @@ -996,9 +1024,10 @@ class ExporterReviewMov(ExporterReview): # ---------- generate representation data self.get_representation_data( - tags=["review", "delete"] + add_tags, + tags=["review", "need_thumbnail", "delete"] + add_tags, custom_tags=add_custom_tags, - range=True + range=True, + colorspace=colorspace ) self.log.debug("Representation... `{}`".format(self.data)) From 5432c2fa699ed0c1ebae49c64e8b4e08ca4dfadd Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Tue, 21 Nov 2023 15:25:22 +0100 Subject: [PATCH 02/24] Global: adding `need_thumbnail` tag worklfow extract review and extract review slate --- openpype/plugins/publish/extract_review.py | 29 +++++++++++++++---- .../plugins/publish/extract_review_slate.py | 10 +++++-- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/openpype/plugins/publish/extract_review.py b/openpype/plugins/publish/extract_review.py index cd0f78530a..8448c45e70 100644 --- a/openpype/plugins/publish/extract_review.py +++ b/openpype/plugins/publish/extract_review.py @@ -89,8 +89,18 @@ class ExtractReview(pyblish.api.InstancePlugin): # Make sure cleanup happens and pop representations with "delete" tag. for repre in tuple(instance.data["representations"]): tags = repre.get("tags") or [] - if "delete" in tags and "thumbnail" not in tags: - instance.data["representations"].remove(repre) + # Representation is not marked to be deleted + if "delete" not in tags: + continue + + # The representation can be used as thumbnail source + if "thumbnail" in tags or "need_thumbnail" in tags: + continue + + self.log.debug( + "Removing representation: {}".format(repre) + ) + instance.data["representations"].remove(repre) def _get_outputs_for_instance(self, instance): host_name = instance.context.data["hostName"] @@ -321,19 +331,26 @@ class ExtractReview(pyblish.api.InstancePlugin): # Create copy of representation new_repre = copy.deepcopy(repre) + new_tags = new_repre.get("tags") or [] # Make sure new representation has origin staging dir # - this is because source representation may change # it's staging dir because of ffmpeg conversion new_repre["stagingDir"] = src_repre_staging_dir # Remove "delete" tag from new repre if there is - if "delete" in new_repre["tags"]: - new_repre["tags"].remove("delete") + if "delete" in new_tags: + new_tags.remove("delete") + + if "need_thumbnail" in new_tags: + new_tags.remove("need_thumbnail") # Add additional tags from output definition to representation for tag in output_def["tags"]: - if tag not in new_repre["tags"]: - new_repre["tags"].append(tag) + if tag not in new_tags: + new_tags.append(tag) + + # Return tags to new representation + new_repre["tags"] = new_tags # Add burnin link from output definition to representation for burnin in output_def["burnins"]: diff --git a/openpype/plugins/publish/extract_review_slate.py b/openpype/plugins/publish/extract_review_slate.py index d89fbb90c4..4e3406d3f9 100644 --- a/openpype/plugins/publish/extract_review_slate.py +++ b/openpype/plugins/publish/extract_review_slate.py @@ -376,9 +376,13 @@ class ExtractReviewSlate(publish.Extractor): # Remove any representations tagged for deletion. for repre in inst_data.get("representations", []): - if "delete" in repre.get("tags", []): - self.log.debug("Removing representation: {}".format(repre)) - inst_data["representations"].remove(repre) + tags = repre.get("tags", []) + if "delete" not in tags: + continue + if "need_thumbnail" in tags: + continue + self.log.debug("Removing representation: {}".format(repre)) + inst_data["representations"].remove(repre) self.log.debug(inst_data["representations"]) From 7aacc4f0ec37ca3f2b673a470216376a4360d01a Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Tue, 21 Nov 2023 15:40:14 +0100 Subject: [PATCH 03/24] global: extract review with `need_thumbnail` tag explicit source --- openpype/plugins/publish/extract_thumbnail.py | 86 +++++++++++++++++-- 1 file changed, 78 insertions(+), 8 deletions(-) diff --git a/openpype/plugins/publish/extract_thumbnail.py b/openpype/plugins/publish/extract_thumbnail.py index 0ddbb3f40b..839a0f70f2 100644 --- a/openpype/plugins/publish/extract_thumbnail.py +++ b/openpype/plugins/publish/extract_thumbnail.py @@ -29,6 +29,26 @@ class ExtractThumbnail(pyblish.api.InstancePlugin): ffmpeg_args = None def process(self, instance): + # run main process + self._main_process(instance) + + # Make sure cleanup happens to representations which are having both + # tags `delete` and `need_thumbnail` + for repre in tuple(instance.data["representations"]): + tags = repre.get("tags") or [] + # skip representations which are going to be published on farm + if "publish_on_farm" in tags: + continue + if ( + "delete" in tags + and "need_thumbnail" in tags + ): + self.log.debug( + "Removing representation: {}".format(repre) + ) + instance.data["representations"].remove(repre) + + def _main_process(self, instance): subset_name = instance.data["subset"] instance_repres = instance.data.get("representations") if not instance_repres: @@ -61,7 +81,13 @@ class ExtractThumbnail(pyblish.api.InstancePlugin): self.log.debug("Skipping crypto passes.") return - filtered_repres = self._get_filtered_repres(instance) + # first check for any explicitly marked representations for thumbnail + explicit_repres = self._get_explicit_repres_for_thumbnail(instance) + if explicit_repres: + filtered_repres = explicit_repres + else: + filtered_repres = self._get_filtered_repres(instance) + if not filtered_repres: self.log.info( "Instance doesn't have representations that can be used " @@ -120,8 +146,21 @@ class ExtractThumbnail(pyblish.api.InstancePlugin): if not thumbnail_created: continue + if len(explicit_repres) > 1: + repre_name = "thumbnail_{}".format(repre["outputName"]) + else: + repre_name = "thumbnail" + + # add thumbnail path to instance data for integrator + instance_thumb_path = instance.data.get("thumbnailPath") + if ( + not instance_thumb_path + or not os.path.isfile(instance_thumb_path) + ): + instance.data["thumbnailPath"] = full_output_path + new_repre = { - "name": "thumbnail", + "name": repre_name, "ext": "jpg", "files": jpeg_file, "stagingDir": dst_staging, @@ -130,15 +169,23 @@ class ExtractThumbnail(pyblish.api.InstancePlugin): } # adding representation - self.log.debug( - "Adding thumbnail representation: {}".format(new_repre) - ) instance.data["representations"].append(new_repre) - # There is no need to create more then one thumbnail - break + + if explicit_repres: + # this key will then align assetVersion ftrack thumbnail sync + new_repre["outputName"] = repre["outputName"] + self.log.debug( + "Adding explicit thumbnail representation: {}".format( + new_repre)) + else: + self.log.debug( + "Adding thumbnail representation: {}".format(new_repre) + ) + # There is no need to create more then one thumbnail + break if not thumbnail_created: - self.log.warning("Thumbanil has not been created.") + self.log.warning("Thumbnail has not been created.") def _is_review_instance(self, instance): # TODO: We should probably handle "not creating" of thumbnail @@ -154,6 +201,29 @@ class ExtractThumbnail(pyblish.api.InstancePlugin): return True return False + def _get_explicit_repres_for_thumbnail(self, instance): + src_repres = instance.data.get("representations") or [] + # This is mainly for Nuke where we have multiple representations for + # one instance. We want to use only one representation for thumbnail + # first check if any of the representations have + # `need-thumbnail` in tags and add them to filtered_repres + need_thumb_repres = [ + repre for repre in src_repres + if "need_thumbnail" in repre.get("tags", []) + if "publish_on_farm" not in repre.get("tags", []) + ] + if not need_thumb_repres: + return [] + + self.log.info( + "Instance has representation with tag `need_thumbnail`. " + "Using only this representations for thumbnail creation. " + ) + self.log.debug( + "Representations: {}".format(pformat(need_thumb_repres)) + ) + return need_thumb_repres + def _get_filtered_repres(self, instance): filtered_repres = [] src_repres = instance.data.get("representations") or [] From f4354080188c6949463a3c76181e88efc3e6cbef Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Tue, 21 Nov 2023 15:41:21 +0100 Subject: [PATCH 04/24] typo --- openpype/plugins/publish/extract_thumbnail.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/plugins/publish/extract_thumbnail.py b/openpype/plugins/publish/extract_thumbnail.py index 839a0f70f2..4ace429cf4 100644 --- a/openpype/plugins/publish/extract_thumbnail.py +++ b/openpype/plugins/publish/extract_thumbnail.py @@ -206,7 +206,7 @@ class ExtractThumbnail(pyblish.api.InstancePlugin): # This is mainly for Nuke where we have multiple representations for # one instance. We want to use only one representation for thumbnail # first check if any of the representations have - # `need-thumbnail` in tags and add them to filtered_repres + # `need_thumbnail` in tags and add them to filtered_repres need_thumb_repres = [ repre for repre in src_repres if "need_thumbnail" in repre.get("tags", []) From 9d2c600c8be3dcb75408665249ed7a4f3c130f53 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Tue, 21 Nov 2023 17:23:14 +0100 Subject: [PATCH 05/24] nuke: typo and wrong log in slate extractor --- openpype/hosts/nuke/plugins/publish/extract_slate_frame.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/nuke/plugins/publish/extract_slate_frame.py b/openpype/hosts/nuke/plugins/publish/extract_slate_frame.py index 7befb7b7f3..5816434f2b 100644 --- a/openpype/hosts/nuke/plugins/publish/extract_slate_frame.py +++ b/openpype/hosts/nuke/plugins/publish/extract_slate_frame.py @@ -276,7 +276,7 @@ class ExtractSlateFrame(publish.Extractor): if not matching_repre: self.log.info( - "Matching reresentation was not found." + "Matching representation was not found." " Representation files were not filled with slate." ) return @@ -294,7 +294,7 @@ class ExtractSlateFrame(publish.Extractor): self.log.debug( "__ matching_repre: {}".format(pformat(matching_repre))) - self.log.warning("Added slate frame to representation files") + self.log.info("Added slate frame to representation files") def add_comment_slate_node(self, instance, node): From 51992419e731e2a0bf51607ab640ea5158d61be5 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Tue, 21 Nov 2023 17:25:20 +0100 Subject: [PATCH 06/24] nuke: removing thumbnail extractor --- .../nuke/plugins/publish/extract_thumbnail.py | 216 ------------------ .../defaults/project_settings/nuke.json | 62 ----- .../schemas/schema_nuke_publish.json | 75 ------ 3 files changed, 353 deletions(-) delete mode 100644 openpype/hosts/nuke/plugins/publish/extract_thumbnail.py diff --git a/openpype/hosts/nuke/plugins/publish/extract_thumbnail.py b/openpype/hosts/nuke/plugins/publish/extract_thumbnail.py deleted file mode 100644 index de7567c1b1..0000000000 --- a/openpype/hosts/nuke/plugins/publish/extract_thumbnail.py +++ /dev/null @@ -1,216 +0,0 @@ -import sys -import os -import nuke -import pyblish.api - -from openpype.pipeline import publish -from openpype.hosts.nuke import api as napi -from openpype.hosts.nuke.api.lib import set_node_knobs_from_settings - - -# Python 2/3 compatibility -if sys.version_info[0] >= 3: - unicode = str - - -class ExtractThumbnail(publish.Extractor): - """Extracts movie and thumbnail with baked in luts - - must be run after extract_render_local.py - - """ - - order = pyblish.api.ExtractorOrder + 0.011 - label = "Extract Thumbnail" - - families = ["review"] - hosts = ["nuke"] - - # settings - use_rendered = False - bake_viewer_process = True - bake_viewer_input_process = True - nodes = {} - reposition_nodes = None - - def process(self, instance): - if instance.data.get("farm"): - return - - with napi.maintained_selection(): - self.log.debug("instance: {}".format(instance)) - self.log.debug("instance.data[families]: {}".format( - instance.data["families"])) - - if instance.data.get("bakePresets"): - for o_name, o_data in instance.data["bakePresets"].items(): - self.render_thumbnail(instance, o_name, **o_data) - else: - viewer_process_switches = { - "bake_viewer_process": True, - "bake_viewer_input_process": True - } - self.render_thumbnail( - instance, None, **viewer_process_switches) - - def render_thumbnail(self, instance, output_name=None, **kwargs): - first_frame = instance.data["frameStartHandle"] - last_frame = instance.data["frameEndHandle"] - colorspace = instance.data["colorspace"] - - # find frame range and define middle thumb frame - mid_frame = int((last_frame - first_frame) / 2) - - # solve output name if any is set - output_name = output_name or "" - - bake_viewer_process = kwargs["bake_viewer_process"] - bake_viewer_input_process_node = kwargs[ - "bake_viewer_input_process"] - - node = instance.data["transientData"]["node"] # group node - self.log.debug("Creating staging dir...") - - if "representations" not in instance.data: - instance.data["representations"] = [] - - staging_dir = os.path.normpath( - os.path.dirname(instance.data['path'])) - - instance.data["stagingDir"] = staging_dir - - self.log.debug( - "StagingDir `{0}`...".format(instance.data["stagingDir"])) - - temporary_nodes = [] - - # try to connect already rendered images - previous_node = node - collection = instance.data.get("collection", None) - self.log.debug("__ collection: `{}`".format(collection)) - - if collection: - # get path - fhead = collection.format("{head}") - - thumb_fname = list(collection)[mid_frame] - else: - fname = thumb_fname = os.path.basename( - instance.data.get("path", None)) - fhead = os.path.splitext(fname)[0] + "." - - self.log.debug("__ fhead: `{}`".format(fhead)) - - if "#" in fhead: - fhead = fhead.replace("#", "")[:-1] - - path_render = os.path.join( - staging_dir, thumb_fname).replace("\\", "/") - self.log.debug("__ path_render: `{}`".format(path_render)) - - if self.use_rendered and os.path.isfile(path_render): - # check if file exist otherwise connect to write node - rnode = nuke.createNode("Read") - rnode["file"].setValue(path_render) - rnode["colorspace"].setValue(colorspace) - - # turn it raw if none of baking is ON - if all([ - not self.bake_viewer_input_process, - not self.bake_viewer_process - ]): - rnode["raw"].setValue(True) - - temporary_nodes.append(rnode) - previous_node = rnode - - if self.reposition_nodes is None: - # [deprecated] create reformat node old way - reformat_node = nuke.createNode("Reformat") - ref_node = self.nodes.get("Reformat", None) - if ref_node: - for k, v in ref_node: - self.log.debug("k, v: {0}:{1}".format(k, v)) - if isinstance(v, unicode): - v = str(v) - reformat_node[k].setValue(v) - - reformat_node.setInput(0, previous_node) - previous_node = reformat_node - temporary_nodes.append(reformat_node) - else: - # create reformat node new way - for repo_node in self.reposition_nodes: - node_class = repo_node["node_class"] - knobs = repo_node["knobs"] - node = nuke.createNode(node_class) - set_node_knobs_from_settings(node, knobs) - - # connect in order - node.setInput(0, previous_node) - previous_node = node - temporary_nodes.append(node) - - # only create colorspace baking if toggled on - if bake_viewer_process: - if bake_viewer_input_process_node: - # get input process and connect it to baking - ipn = napi.get_view_process_node() - if ipn is not None: - ipn.setInput(0, previous_node) - previous_node = ipn - temporary_nodes.append(ipn) - - dag_node = nuke.createNode("OCIODisplay") - dag_node.setInput(0, previous_node) - previous_node = dag_node - temporary_nodes.append(dag_node) - - thumb_name = "thumbnail" - # only add output name and - # if there are more than one bake preset - if ( - output_name - and len(instance.data.get("bakePresets", {}).keys()) > 1 - ): - thumb_name = "{}_{}".format(output_name, thumb_name) - - # create write node - write_node = nuke.createNode("Write") - file = fhead[:-1] + thumb_name + ".jpg" - thumb_path = os.path.join(staging_dir, file).replace("\\", "/") - - # add thumbnail to cleanup - instance.context.data["cleanupFullPaths"].append(thumb_path) - - # make sure only one thumbnail path is set - # and it is existing file - instance_thumb_path = instance.data.get("thumbnailPath") - if not instance_thumb_path or not os.path.isfile(instance_thumb_path): - instance.data["thumbnailPath"] = thumb_path - - write_node["file"].setValue(thumb_path) - write_node["file_type"].setValue("jpg") - write_node["raw"].setValue(1) - write_node.setInput(0, previous_node) - temporary_nodes.append(write_node) - - repre = { - 'name': thumb_name, - 'ext': "jpg", - "outputName": thumb_name, - 'files': file, - "stagingDir": staging_dir, - "tags": ["thumbnail", "publish_on_farm", "delete"] - } - instance.data["representations"].append(repre) - - # Render frames - nuke.execute(write_node.name(), mid_frame, mid_frame) - - self.log.debug( - "representations: {}".format(instance.data["representations"])) - - # Clean up - for node in temporary_nodes: - nuke.delete(node) diff --git a/openpype/settings/defaults/project_settings/nuke.json b/openpype/settings/defaults/project_settings/nuke.json index 20df0ad5c2..17932c793d 100644 --- a/openpype/settings/defaults/project_settings/nuke.json +++ b/openpype/settings/defaults/project_settings/nuke.json @@ -379,68 +379,6 @@ "optional": true, "active": true }, - "ExtractThumbnail": { - "enabled": true, - "use_rendered": true, - "bake_viewer_process": true, - "bake_viewer_input_process": true, - "nodes": { - "Reformat": [ - [ - "type", - "to format" - ], - [ - "format", - "HD_1080" - ], - [ - "filter", - "Lanczos6" - ], - [ - "black_outside", - true - ], - [ - "pbb", - false - ] - ] - }, - "reposition_nodes": [ - { - "node_class": "Reformat", - "knobs": [ - { - "type": "text", - "name": "type", - "value": "to format" - }, - { - "type": "text", - "name": "format", - "value": "HD_1080" - }, - { - "type": "text", - "name": "filter", - "value": "Lanczos6" - }, - { - "type": "bool", - "name": "black_outside", - "value": true - }, - { - "type": "bool", - "name": "pbb", - "value": false - } - ] - } - ] - }, "ExtractReviewData": { "enabled": false }, diff --git a/openpype/settings/entities/schemas/projects_schema/schemas/schema_nuke_publish.json b/openpype/settings/entities/schemas/projects_schema/schemas/schema_nuke_publish.json index e0cd086119..09b67e7d1a 100644 --- a/openpype/settings/entities/schemas/projects_schema/schemas/schema_nuke_publish.json +++ b/openpype/settings/entities/schemas/projects_schema/schemas/schema_nuke_publish.json @@ -125,81 +125,6 @@ "type": "label", "label": "Extractors" }, - { - "type": "dict", - "collapsible": true, - "checkbox_key": "enabled", - "key": "ExtractThumbnail", - "label": "ExtractThumbnail", - "is_group": true, - "children": [ - { - "type": "boolean", - "key": "enabled", - "label": "Enabled" - }, - { - "type": "boolean", - "key": "use_rendered", - "label": "Use rendered images" - }, - { - "type": "boolean", - "key": "bake_viewer_process", - "label": "Bake viewer process" - }, - { - "type": "boolean", - "key": "bake_viewer_input_process", - "label": "Bake viewer input process" - }, - { - "type": "collapsible-wrap", - "label": "Nodes", - "collapsible": true, - "children": [ - { - "type": "label", - "label": "Nodes attribute will be deprecated in future releases. Use reposition_nodes instead." - }, - { - "type": "raw-json", - "key": "nodes", - "label": "Nodes [depricated]" - }, - { - "type": "label", - "label": "Reposition knobs supported only. You can add multiple reformat nodes
and set their knobs. Order of reformat nodes is important. First reformat node
will be applied first and last reformat node will be applied last." - }, - { - "key": "reposition_nodes", - "type": "list", - "label": "Reposition nodes", - "object_type": { - "type": "dict", - "children": [ - { - "key": "node_class", - "label": "Node class", - "type": "text" - }, - { - "type": "schema_template", - "name": "template_nuke_knob_inputs", - "template_data": [ - { - "label": "Node knobs", - "key": "knobs" - } - ] - } - ] - } - } - ] - } - ] - }, { "type": "dict", "collapsible": true, From 0f6cecb29a74fecb4d8ff22504de619466ceeb0d Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Tue, 21 Nov 2023 17:26:58 +0100 Subject: [PATCH 07/24] nuke: deadline not adding explicit farm representation to expected files --- .../plugins/publish/submit_nuke_deadline.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/openpype/modules/deadline/plugins/publish/submit_nuke_deadline.py b/openpype/modules/deadline/plugins/publish/submit_nuke_deadline.py index fb3ab2710d..182afe546d 100644 --- a/openpype/modules/deadline/plugins/publish/submit_nuke_deadline.py +++ b/openpype/modules/deadline/plugins/publish/submit_nuke_deadline.py @@ -470,6 +470,22 @@ class NukeSubmitDeadline(pyblish.api.InstancePlugin, dirname = os.path.dirname(path) file = os.path.basename(path) + # since some files might be already tagged as publish_on_farm + # we need to avoid adding them to expected files since those would be + # duplicated into metadata.json file + representations = instance.data.get("representations", []) + if representations: + # check if file is not in representations with publish_on_farm tag + for repre in representations: + # is file in representations files? + if file not in repre.get("files", []): + continue + # is publish_on_farm tag set to False? + if "publish_on_farm" in repre.get("tags", []): + self.log.debug( + "Skipping expected file: {}".format(path)) + return + if "#" in file: pparts = file.split("#") padding = "%0{}d".format(len(pparts) - 1) From e0b4cef87e9f44edec0e5faf689ba5af0f3a9ffe Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Tue, 21 Nov 2023 17:28:25 +0100 Subject: [PATCH 08/24] nuke: deadline removing redundant code --- .../modules/deadline/plugins/publish/submit_nuke_deadline.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/openpype/modules/deadline/plugins/publish/submit_nuke_deadline.py b/openpype/modules/deadline/plugins/publish/submit_nuke_deadline.py index 182afe546d..7b5a8c9b2d 100644 --- a/openpype/modules/deadline/plugins/publish/submit_nuke_deadline.py +++ b/openpype/modules/deadline/plugins/publish/submit_nuke_deadline.py @@ -370,10 +370,6 @@ class NukeSubmitDeadline(pyblish.api.InstancePlugin, environment = dict({key: os.environ[key] for key in keys if key in os.environ}, **legacy_io.Session) - for _path in os.environ: - if _path.lower().startswith('openpype_'): - environment[_path] = os.environ[_path] - # to recognize render jobs if AYON_SERVER_ENABLED: environment["AYON_BUNDLE_NAME"] = os.environ["AYON_BUNDLE_NAME"] From e0776c8548990691edeb6775cc2c8103dfef9ac0 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Tue, 21 Nov 2023 17:32:37 +0100 Subject: [PATCH 09/24] farm: remove `publish_on_farm` from representations to metadata.json --- openpype/pipeline/farm/pyblish_functions.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openpype/pipeline/farm/pyblish_functions.py b/openpype/pipeline/farm/pyblish_functions.py index 7ef3439dbd..380ada234e 100644 --- a/openpype/pipeline/farm/pyblish_functions.py +++ b/openpype/pipeline/farm/pyblish_functions.py @@ -145,6 +145,9 @@ def get_transferable_representations(instance): trans_rep = representation.copy() + # remove publish_on_farm from representations tags + trans_rep["tags"].remove("publish_on_farm") + staging_dir = trans_rep.get("stagingDir") if staging_dir: From 2f78943791a928ef9571a1148de5d744d928dcf0 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Tue, 21 Nov 2023 17:33:55 +0100 Subject: [PATCH 10/24] improving code coment --- openpype/plugins/publish/extract_burnin.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/plugins/publish/extract_burnin.py b/openpype/plugins/publish/extract_burnin.py index 9a978ed286..56d45e477b 100644 --- a/openpype/plugins/publish/extract_burnin.py +++ b/openpype/plugins/publish/extract_burnin.py @@ -89,8 +89,8 @@ class ExtractBurnin(publish.Extractor): self.main_process(instance) - # Remove any representations tagged for deletion. - # QUESTION Is possible to have representation with "delete" tag? + # Remove only representation tagged with both + # tags `delete` and `burnin` for repre in tuple(instance.data["representations"]): if all(x in repre.get("tags", []) for x in ['delete', 'burnin']): self.log.debug("Removing representation: {}".format(repre)) From 619b4ccafc565fc9da0f7741fc768778604084c0 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Tue, 21 Nov 2023 17:38:43 +0100 Subject: [PATCH 11/24] ayon-nuke: removing extract thumbnail from settings --- .../nuke/server/settings/publish_plugins.py | 104 ------------------ server_addon/nuke/server/version.py | 2 +- 2 files changed, 1 insertion(+), 105 deletions(-) diff --git a/server_addon/nuke/server/settings/publish_plugins.py b/server_addon/nuke/server/settings/publish_plugins.py index 81663fa5aa..d76e95a638 100644 --- a/server_addon/nuke/server/settings/publish_plugins.py +++ b/server_addon/nuke/server/settings/publish_plugins.py @@ -51,17 +51,6 @@ class NodeModel(BaseSettingsModel): return value -class ThumbnailRepositionNodeModel(BaseSettingsModel): - node_class: str = Field(title="Node class") - knobs: list[KnobModel] = Field(title="Knobs", default_factory=list) - - @validator("knobs") - def ensure_unique_names(cls, value): - """Ensure name fields within the lists have unique names.""" - ensure_unique_names(value) - return value - - class CollectInstanceDataModel(BaseSettingsModel): sync_workfile_version_on_product_types: list[str] = Field( default_factory=list, @@ -89,22 +78,6 @@ class ValidateKnobsModel(BaseSettingsModel): return validate_json_dict(value) -class ExtractThumbnailModel(BaseSettingsModel): - enabled: bool = Field(title="Enabled") - use_rendered: bool = Field(title="Use rendered images") - bake_viewer_process: bool = Field(title="Bake view process") - bake_viewer_input_process: bool = Field(title="Bake viewer input process") - - nodes: list[NodeModel] = Field( - default_factory=list, - title="Nodes (deprecated)" - ) - reposition_nodes: list[ThumbnailRepositionNodeModel] = Field( - title="Reposition nodes", - default_factory=list - ) - - class ExtractReviewDataModel(BaseSettingsModel): enabled: bool = Field(title="Enabled") @@ -267,11 +240,6 @@ class PublishPuginsModel(BaseSettingsModel): title="Validate workfile attributes", default_factory=OptionalPluginModel ) - ExtractThumbnail: ExtractThumbnailModel = Field( - title="Extract Thumbnail", - default_factory=ExtractThumbnailModel, - section="Extractors" - ) ExtractReviewData: ExtractReviewDataModel = Field( title="Extract Review Data", default_factory=ExtractReviewDataModel @@ -350,78 +318,6 @@ DEFAULT_PUBLISH_PLUGIN_SETTINGS = { "optional": True, "active": True }, - "ExtractThumbnail": { - "enabled": True, - "use_rendered": True, - "bake_viewer_process": True, - "bake_viewer_input_process": True, - "nodes": [ - { - "name": "Reformat01", - "nodeclass": "Reformat", - "dependency": "", - "knobs": [ - { - "type": "text", - "name": "type", - "text": "to format" - }, - { - "type": "text", - "name": "format", - "text": "HD_1080" - }, - { - "type": "text", - "name": "filter", - "text": "Lanczos6" - }, - { - "type": "boolean", - "name": "black_outside", - "boolean": True - }, - { - "type": "boolean", - "name": "pbb", - "boolean": False - } - ] - } - ], - "reposition_nodes": [ - { - "node_class": "Reformat", - "knobs": [ - { - "type": "text", - "name": "type", - "text": "to format" - }, - { - "type": "text", - "name": "format", - "text": "HD_1080" - }, - { - "type": "text", - "name": "filter", - "text": "Lanczos6" - }, - { - "type": "boolean", - "name": "black_outside", - "boolean": True - }, - { - "type": "boolean", - "name": "pbb", - "boolean": False - } - ] - } - ] - }, "ExtractReviewData": { "enabled": False }, diff --git a/server_addon/nuke/server/version.py b/server_addon/nuke/server/version.py index 1276d0254f..0a8da88258 100644 --- a/server_addon/nuke/server/version.py +++ b/server_addon/nuke/server/version.py @@ -1 +1 @@ -__version__ = "0.1.5" +__version__ = "0.1.6" From 93b5a3941d23cf9f8a0567a9f0808fc7f0fdba5b Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Tue, 21 Nov 2023 21:43:16 +0100 Subject: [PATCH 12/24] adding nuke host into extract thumbnail plugin --- openpype/plugins/publish/extract_thumbnail.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/openpype/plugins/publish/extract_thumbnail.py b/openpype/plugins/publish/extract_thumbnail.py index 4ace429cf4..1c970affcd 100644 --- a/openpype/plugins/publish/extract_thumbnail.py +++ b/openpype/plugins/publish/extract_thumbnail.py @@ -22,10 +22,17 @@ class ExtractThumbnail(pyblish.api.InstancePlugin): "imagesequence", "render", "render2d", "prerender", "source", "clip", "take", "online", "image" ] - hosts = ["shell", "fusion", "resolve", "traypublisher", "substancepainter"] + hosts = [ + "shell", + "fusion", + "resolve", + "traypublisher", + "substancepainter", + "nuke", + ] enabled = False - # presetable attribute + # presentable attribute ffmpeg_args = None def process(self, instance): @@ -220,7 +227,7 @@ class ExtractThumbnail(pyblish.api.InstancePlugin): "Using only this representations for thumbnail creation. " ) self.log.debug( - "Representations: {}".format(pformat(need_thumb_repres)) + "Representations: {}".format(need_thumb_repres) ) return need_thumb_repres From 178f044869b4527e417129a7c8200b27a1c4f912 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Tue, 21 Nov 2023 21:49:17 +0100 Subject: [PATCH 13/24] ftrack: ignore representations with `publish_on_farm` tag --- .../ftrack/plugins/publish/integrate_ftrack_instances.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openpype/modules/ftrack/plugins/publish/integrate_ftrack_instances.py b/openpype/modules/ftrack/plugins/publish/integrate_ftrack_instances.py index 75f43cb22f..fc97b2c516 100644 --- a/openpype/modules/ftrack/plugins/publish/integrate_ftrack_instances.py +++ b/openpype/modules/ftrack/plugins/publish/integrate_ftrack_instances.py @@ -126,6 +126,8 @@ class IntegrateFtrackInstance(pyblish.api.InstancePlugin): other_representations = [] has_movie_review = False for repre in instance_repres: + if "publish_on_farm" in repre.get("tags", []): + continue self.log.debug("Representation {}".format(repre)) repre_tags = repre.get("tags") or [] if repre.get("thumbnail") or "thumbnail" in repre_tags: From b8838d70cf55b0888dbda0adf63a5dbf52d1ae9f Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Tue, 21 Nov 2023 21:55:48 +0100 Subject: [PATCH 14/24] ignoring `publish_on_farm` representations it was creating thumbnails in Ftrack even the version had to be created in future --- openpype/plugins/publish/extract_thumbnail.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/openpype/plugins/publish/extract_thumbnail.py b/openpype/plugins/publish/extract_thumbnail.py index 1c970affcd..a46c3acf12 100644 --- a/openpype/plugins/publish/extract_thumbnail.py +++ b/openpype/plugins/publish/extract_thumbnail.py @@ -234,9 +234,16 @@ class ExtractThumbnail(pyblish.api.InstancePlugin): def _get_filtered_repres(self, instance): filtered_repres = [] src_repres = instance.data.get("representations") or [] + for repre in src_repres: self.log.debug(repre) tags = repre.get("tags") or [] + + if "publish_on_farm" in tags: + # only process representations with are going + # to be published locally + continue + valid = "review" in tags or "thumb-nuke" in tags if not valid: continue From ec47c7466fc4e133c0c776aea66b046576eef69f Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Tue, 21 Nov 2023 22:12:41 +0100 Subject: [PATCH 15/24] enhancing code --- .../plugins/publish/integrate_ftrack_instances.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/openpype/modules/ftrack/plugins/publish/integrate_ftrack_instances.py b/openpype/modules/ftrack/plugins/publish/integrate_ftrack_instances.py index fc97b2c516..5f70f5340b 100644 --- a/openpype/modules/ftrack/plugins/publish/integrate_ftrack_instances.py +++ b/openpype/modules/ftrack/plugins/publish/integrate_ftrack_instances.py @@ -126,19 +126,25 @@ class IntegrateFtrackInstance(pyblish.api.InstancePlugin): other_representations = [] has_movie_review = False for repre in instance_repres: - if "publish_on_farm" in repre.get("tags", []): - continue - self.log.debug("Representation {}".format(repre)) repre_tags = repre.get("tags") or [] + # exclude representations with are going to be published on farm + if "publish_on_farm" in repre_tags: + continue + + self.log.debug("Representation {}".format(repre)) + + # include only thumbnail representations if repre.get("thumbnail") or "thumbnail" in repre_tags: thumbnail_representations.append(repre) + # include only review representations elif "ftrackreview" in repre_tags: review_representations.append(repre) if self._is_repre_video(repre): has_movie_review = True else: + # include all other representations other_representations.append(repre) # Prepare ftrack locations From 9b1d24acb87428aa8c74e6aaf5cdae6b7cfb3551 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Tue, 21 Nov 2023 22:18:43 +0100 Subject: [PATCH 16/24] improving code in nuke deadline submitter --- .../plugins/publish/submit_nuke_deadline.py | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/openpype/modules/deadline/plugins/publish/submit_nuke_deadline.py b/openpype/modules/deadline/plugins/publish/submit_nuke_deadline.py index 7b5a8c9b2d..8cb4e9eea4 100644 --- a/openpype/modules/deadline/plugins/publish/submit_nuke_deadline.py +++ b/openpype/modules/deadline/plugins/publish/submit_nuke_deadline.py @@ -470,17 +470,16 @@ class NukeSubmitDeadline(pyblish.api.InstancePlugin, # we need to avoid adding them to expected files since those would be # duplicated into metadata.json file representations = instance.data.get("representations", []) - if representations: - # check if file is not in representations with publish_on_farm tag - for repre in representations: - # is file in representations files? - if file not in repre.get("files", []): - continue - # is publish_on_farm tag set to False? - if "publish_on_farm" in repre.get("tags", []): - self.log.debug( - "Skipping expected file: {}".format(path)) - return + # check if file is not in representations with publish_on_farm tag + for repre in representations: + # Skip if 'publish_on_farm' not available + if "publish_on_farm" not in repre.get("tags", []): + continue + # is file in representations files? + if file in repre.get("files", []): + self.log.debug( + "Skipping expected file: {}".format(path)) + return if "#" in file: pparts = file.split("#") From 2aea1cd8fc9a5c43e937ab70255454a1cc31a3bd Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Wed, 22 Nov 2023 14:52:11 +0100 Subject: [PATCH 17/24] avoid situation where missing `outputName` this might happen if only one Intermediate reviewable file stream is used. --- openpype/plugins/publish/extract_thumbnail.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openpype/plugins/publish/extract_thumbnail.py b/openpype/plugins/publish/extract_thumbnail.py index a46c3acf12..2948f80ce5 100644 --- a/openpype/plugins/publish/extract_thumbnail.py +++ b/openpype/plugins/publish/extract_thumbnail.py @@ -180,7 +180,8 @@ class ExtractThumbnail(pyblish.api.InstancePlugin): if explicit_repres: # this key will then align assetVersion ftrack thumbnail sync - new_repre["outputName"] = repre["outputName"] + new_repre["outputName"] = ( + repre.get("outputName") or repre["name"]) self.log.debug( "Adding explicit thumbnail representation: {}".format( new_repre)) From ddfb95467e301d0d609c84244750348408027b0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Je=C5=BEek?= Date: Mon, 27 Nov 2023 16:39:34 +0100 Subject: [PATCH 18/24] Update openpype/plugins/publish/extract_thumbnail.py Co-authored-by: Roy Nieterau --- openpype/plugins/publish/extract_thumbnail.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/plugins/publish/extract_thumbnail.py b/openpype/plugins/publish/extract_thumbnail.py index 2948f80ce5..202b8647c8 100644 --- a/openpype/plugins/publish/extract_thumbnail.py +++ b/openpype/plugins/publish/extract_thumbnail.py @@ -32,7 +32,7 @@ class ExtractThumbnail(pyblish.api.InstancePlugin): ] enabled = False - # presentable attribute + # attribute presets from settings ffmpeg_args = None def process(self, instance): From fafb34ffc0ca7184db14d2376d00fc7c554ef0c7 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 7 Dec 2023 11:06:30 +0100 Subject: [PATCH 19/24] Update Ayon settings and Nuke server version - Updated Ayon settings to remove the 'ExtractThumbnail' schema in v3 - Updated Nuke server version from 0.1.6 to 0.1.7 --- openpype/settings/ayon_settings.py | 22 ---------------------- server_addon/nuke/server/version.py | 2 +- 2 files changed, 1 insertion(+), 23 deletions(-) diff --git a/openpype/settings/ayon_settings.py b/openpype/settings/ayon_settings.py index 5171517232..992e91dfe4 100644 --- a/openpype/settings/ayon_settings.py +++ b/openpype/settings/ayon_settings.py @@ -821,28 +821,6 @@ def _convert_nuke_project_settings(ayon_settings, output): collect_instance_data.pop( "sync_workfile_version_on_product_types")) - # TODO 'ExtractThumbnail' does not have ideal schema in v3 - ayon_extract_thumbnail = ayon_publish["ExtractThumbnail"] - new_thumbnail_nodes = {} - for item in ayon_extract_thumbnail["nodes"]: - name = item["nodeclass"] - value = [] - for knob in _convert_nuke_knobs(item["knobs"]): - knob_name = knob["name"] - # This may crash - if knob["type"] == "expression": - knob_value = knob["expression"] - else: - knob_value = knob["value"] - value.append([knob_name, knob_value]) - new_thumbnail_nodes[name] = value - - ayon_extract_thumbnail["nodes"] = new_thumbnail_nodes - - if "reposition_nodes" in ayon_extract_thumbnail: - for item in ayon_extract_thumbnail["reposition_nodes"]: - item["knobs"] = _convert_nuke_knobs(item["knobs"]) - # --- ImageIO --- # NOTE 'monitorOutLut' is maybe not yet in v3 (ut should be) _convert_host_imageio(ayon_nuke) diff --git a/server_addon/nuke/server/version.py b/server_addon/nuke/server/version.py index 0a8da88258..f1380eede2 100644 --- a/server_addon/nuke/server/version.py +++ b/server_addon/nuke/server/version.py @@ -1 +1 @@ -__version__ = "0.1.6" +__version__ = "0.1.7" From cdbf764a85178962771f888f4ae1a26e60ad8526 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 7 Dec 2023 11:13:22 +0100 Subject: [PATCH 20/24] improving comments --- openpype/plugins/publish/extract_thumbnail.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/plugins/publish/extract_thumbnail.py b/openpype/plugins/publish/extract_thumbnail.py index 202b8647c8..b05415a9e0 100644 --- a/openpype/plugins/publish/extract_thumbnail.py +++ b/openpype/plugins/publish/extract_thumbnail.py @@ -212,8 +212,8 @@ class ExtractThumbnail(pyblish.api.InstancePlugin): def _get_explicit_repres_for_thumbnail(self, instance): src_repres = instance.data.get("representations") or [] # This is mainly for Nuke where we have multiple representations for - # one instance. We want to use only one representation for thumbnail - # first check if any of the representations have + # one instance and representations are tagged for thumbnail. + # First check if any of the representations have # `need_thumbnail` in tags and add them to filtered_repres need_thumb_repres = [ repre for repre in src_repres From 99674b8f0e34f231a21b02594bdf5bc8cfed5c3b Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 7 Dec 2023 11:57:44 +0100 Subject: [PATCH 21/24] Fix expected files path handling in NukeSubmitDeadline plugin The commit fixes a typo in the code where "expectied" was changed to "expected". It also improves the handling of expected file paths by correctly adding them to the instance data. Additionally, it adds support for hashed sequence expressions and shifts the start frame by 1 if a slate is present. --- .../plugins/publish/submit_nuke_deadline.py | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/openpype/modules/deadline/plugins/publish/submit_nuke_deadline.py b/openpype/modules/deadline/plugins/publish/submit_nuke_deadline.py index 8cb4e9eea4..d03416ca00 100644 --- a/openpype/modules/deadline/plugins/publish/submit_nuke_deadline.py +++ b/openpype/modules/deadline/plugins/publish/submit_nuke_deadline.py @@ -398,7 +398,7 @@ class NukeSubmitDeadline(pyblish.api.InstancePlugin, self.log.debug("Submitting..") self.log.debug(json.dumps(payload, indent=4, sort_keys=True)) - # adding expectied files to instance.data + # adding expected files to instance.data self.expected_files( instance, render_path, @@ -454,7 +454,7 @@ class NukeSubmitDeadline(pyblish.api.InstancePlugin, def expected_files( self, instance, - path, + filepath, start_frame, end_frame ): @@ -463,8 +463,8 @@ class NukeSubmitDeadline(pyblish.api.InstancePlugin, if not instance.data.get("expectedFiles"): instance.data["expectedFiles"] = [] - dirname = os.path.dirname(path) - file = os.path.basename(path) + dirname = os.path.dirname(filepath) + file = os.path.basename(filepath) # since some files might be already tagged as publish_on_farm # we need to avoid adding them to expected files since those would be @@ -475,24 +475,32 @@ class NukeSubmitDeadline(pyblish.api.InstancePlugin, # Skip if 'publish_on_farm' not available if "publish_on_farm" not in repre.get("tags", []): continue - # is file in representations files? + + # in case where single file (video, image) is already in + # representation file. Will be added to expected files via + # submit_publish_job.py if file in repre.get("files", []): self.log.debug( - "Skipping expected file: {}".format(path)) + "Skipping expected file: {}".format(filepath)) return + # in case path is hashed sequence expression + # (e.g. /path/to/file.####.png) if "#" in file: pparts = file.split("#") padding = "%0{}d".format(len(pparts) - 1) file = pparts[0] + padding + pparts[-1] + # in case input path was single file (video or image) if "%" not in file: - instance.data["expectedFiles"].append(path) + instance.data["expectedFiles"].append(filepath) return + # shift start frame by 1 if slate is present if instance.data.get("slate"): start_frame -= 1 + # add sequence files to expected files for i in range(start_frame, (end_frame + 1)): instance.data["expectedFiles"].append( os.path.join(dirname, (file % i)).replace("\\", "/")) From 7449f27855b5a56deea6e24a182324a1222bf6bf Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 7 Dec 2023 14:26:53 +0100 Subject: [PATCH 22/24] Update IntermediateOutputModel in publish_plugins.py - Set read_raw switch to False - Set viewer_process_override to an empty string - Set bake_viewer_process to True - Set bake_viewer_input_process to True - Set extension to `mov` by default --- .../nuke/server/settings/publish_plugins.py | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/server_addon/nuke/server/settings/publish_plugins.py b/server_addon/nuke/server/settings/publish_plugins.py index d76e95a638..84457d2484 100644 --- a/server_addon/nuke/server/settings/publish_plugins.py +++ b/server_addon/nuke/server/settings/publish_plugins.py @@ -126,16 +126,29 @@ class IntermediateOutputModel(BaseSettingsModel): name: str = Field(title="Output name") filter: BakingStreamFilterModel = Field( title="Filter", default_factory=BakingStreamFilterModel) - read_raw: bool = Field(title="Read raw switch") - viewer_process_override: str = Field(title="Viewer process override") - bake_viewer_process: bool = Field(title="Bake viewer process") + read_raw: bool = Field( + False, + title="Read raw switch" + ) + viewer_process_override: str = Field( + "", + title="Viewer process override" + ) + bake_viewer_process: bool = Field( + True, + title="Bake viewer process" + ) bake_viewer_input_process: bool = Field( + True, title="Bake viewer input process node (LUT)" ) reformat_nodes_config: ReformatNodesConfigModel = Field( default_factory=ReformatNodesConfigModel, title="Reformat Nodes") - extension: str = Field(title="File extension") + extension: str = Field( + "mov", + title="File extension" + ) add_custom_tags: list[str] = Field( title="Custom tags", default_factory=list) From 30800c1c2ca5cd910772632a62ac269f0a9e2f40 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 7 Dec 2023 15:06:20 +0100 Subject: [PATCH 23/24] Refactor transcoding and thumbnail extraction code - Removed the unused `additional_input_args` parameter from the `convert_colorspace` function in `transcoding.py` - Renamed the `additional_input_args` parameter to `additional_command_args` in the `ExtractThumbnail` class in `extract_thumbnail.py` These changes improve code clarity and remove unnecessary parameters. --- openpype/lib/transcoding.py | 5 ----- openpype/plugins/publish/extract_thumbnail.py | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/openpype/lib/transcoding.py b/openpype/lib/transcoding.py index 37709f45e0..316dedbd3d 100644 --- a/openpype/lib/transcoding.py +++ b/openpype/lib/transcoding.py @@ -1103,7 +1103,6 @@ def convert_colorspace( target_colorspace=None, view=None, display=None, - additional_input_args=None, additional_command_args=None, logger=None, ): @@ -1125,7 +1124,6 @@ def convert_colorspace( both 'view' and 'display' must be filled (if 'target_colorspace') display (str): name for display-referred reference space (ocio valid) both 'view' and 'display' must be filled (if 'target_colorspace') - additional_input_args (list): arguments for input file additional_command_args (list): arguments for oiiotool (like binary depth for .dpx) logger (logging.Logger): Logger used for logging. @@ -1140,9 +1138,6 @@ def convert_colorspace( # Collect channels to export input_arg, channels_arg = get_oiio_input_and_channel_args(input_info) - if additional_input_args: - input_arg = "{} {}".format(input_arg, " ".join(additional_input_args)) - # Prepare subprocess arguments oiio_cmd = get_oiio_tool_args( "oiiotool", diff --git a/openpype/plugins/publish/extract_thumbnail.py b/openpype/plugins/publish/extract_thumbnail.py index c782bda73e..206ad76707 100644 --- a/openpype/plugins/publish/extract_thumbnail.py +++ b/openpype/plugins/publish/extract_thumbnail.py @@ -371,7 +371,7 @@ class ExtractThumbnail(pyblish.api.InstancePlugin): display=repre_display or oiio_default_display, view=repre_view or oiio_default_view, target_colorspace=oiio_default_colorspace, - additional_input_args=resolution_arg, + additional_command_args=resolution_arg, logger=self.log, ) except Exception: From 3ec7f9149f726854b74430083d3cbb3807f3d707 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 7 Dec 2023 15:28:07 +0100 Subject: [PATCH 24/24] Add thumbnail path to instance data and integrate thumbnails in Ayon plugin. - Added code to add the thumbnail path to the instance data. - Modified code to retrieve the thumbnail path from the instance data in Ayon plugin. - Updated code to handle cases where the thumbnail source is not available or specified. - Improved logic for finding the thumbnail representation in published representations. --- openpype/plugins/publish/extract_thumbnail.py | 5 +++++ .../plugins/publish/integrate_thumbnail_ayon.py | 13 ++++++++----- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/openpype/plugins/publish/extract_thumbnail.py b/openpype/plugins/publish/extract_thumbnail.py index 206ad76707..2b4a61845d 100644 --- a/openpype/plugins/publish/extract_thumbnail.py +++ b/openpype/plugins/publish/extract_thumbnail.py @@ -212,6 +212,11 @@ class ExtractThumbnail(pyblish.api.InstancePlugin): not instance_thumb_path or not os.path.isfile(instance_thumb_path) ): + self.log.debug( + "Adding thumbnail path to instance data: {}".format( + full_output_path + ) + ) instance.data["thumbnailPath"] = full_output_path new_repre_tags = ["thumbnail"] diff --git a/openpype/plugins/publish/integrate_thumbnail_ayon.py b/openpype/plugins/publish/integrate_thumbnail_ayon.py index 2c8fb5b692..1947c9dd4c 100644 --- a/openpype/plugins/publish/integrate_thumbnail_ayon.py +++ b/openpype/plugins/publish/integrate_thumbnail_ayon.py @@ -72,7 +72,7 @@ class IntegrateThumbnailsAYON(pyblish.api.ContextPlugin): ) def _prepare_instances(self, context): - context_thumbnail_path = context.get("thumbnailPath") + context_thumbnail_path = context.data.get("thumbnailPath") valid_context_thumbnail = bool( context_thumbnail_path and os.path.exists(context_thumbnail_path) @@ -93,9 +93,12 @@ class IntegrateThumbnailsAYON(pyblish.api.ContextPlugin): # Find thumbnail path on instance thumbnail_source = instance.data.get("thumbnailSource") - thumbnail_path = (thumbnail_source or - self._get_instance_thumbnail_path( - published_repres)) + thumbnail_path = instance.data.get("thumbnailPath") + thumbnail_path = ( + thumbnail_source + or thumbnail_path + or self._get_instance_thumbnail_path(published_repres) + ) if thumbnail_path: self.log.debug(( "Found thumbnail path for instance \"{}\"." @@ -133,7 +136,7 @@ class IntegrateThumbnailsAYON(pyblish.api.ContextPlugin): thumb_repre_doc = None for repre_info in published_representations.values(): repre_doc = repre_info["representation"] - if repre_doc["name"].lower() == "thumbnail": + if "thumbnail" in repre_doc["name"].lower(): thumb_repre_doc = repre_doc break