From 331ec6bf9d0eea58c12d7f1cfbca7cf67a1796a8 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Thu, 12 Jan 2023 11:01:53 +0100 Subject: [PATCH 01/15] OP-4617 - added new plugin to expose field for frames to fix Collector should get triggered for render family and offer field to input frames that should be re-rendered and replaced ones in latest version --- .../plugins/publish/collect_frames_fix.py | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 openpype/plugins/publish/collect_frames_fix.py diff --git a/openpype/plugins/publish/collect_frames_fix.py b/openpype/plugins/publish/collect_frames_fix.py new file mode 100644 index 0000000000..1e73f2caaa --- /dev/null +++ b/openpype/plugins/publish/collect_frames_fix.py @@ -0,0 +1,29 @@ +import pyblish.api +from openpype.lib.attribute_definitions import TextDef +from openpype.pipeline.publish import OpenPypePyblishPluginMixin + + +class CollectFramesFixDef( + pyblish.api.ContextPlugin, + OpenPypePyblishPluginMixin +): + label = "Collect frames to fix" + targets = ["local"] + # Disable plugin by default + families = ["render"] + enabled = True + + def process(self, instance): + attribute_values = self.get_attr_values_from_data(instance.data) + frames_to_fix = attribute_values.get("frames_to_fix") + if frames_to_fix: + instance.data["frames_to_fix"] = frames_to_fix + + @classmethod + def get_attribute_defs(cls): + return [ + TextDef("frames_to_fix", label="Frames to fix", + placeholder="5,10-15", + regex="[0-9,-]+") + ] + From 0b65779698d7f820ef8dea25be2c9ba9f65e0e85 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Thu, 12 Jan 2023 11:04:14 +0100 Subject: [PATCH 02/15] OP-4617 - added possibility to rerender frames locally in Nuke WIP --- .../plugins/publish/extract_render_local.py | 87 ++++++++++++------- 1 file changed, 57 insertions(+), 30 deletions(-) diff --git a/openpype/hosts/nuke/plugins/publish/extract_render_local.py b/openpype/hosts/nuke/plugins/publish/extract_render_local.py index 811b2d4ffb..7271c8b45b 100644 --- a/openpype/hosts/nuke/plugins/publish/extract_render_local.py +++ b/openpype/hosts/nuke/plugins/publish/extract_render_local.py @@ -5,6 +5,11 @@ import clique import nuke from openpype.pipeline import publish +from openpype.client import ( + get_version_by_id, + get_last_version_by_subset_id, +) + class NukeRenderLocal(publish.Extractor): @@ -35,42 +40,64 @@ class NukeRenderLocal(publish.Extractor): self.log.debug("instance collected: {}".format(instance.data)) - first_frame = instance.data.get("frameStartHandle", None) - - last_frame = instance.data.get("frameEndHandle", None) node_subset_name = instance.data.get("name", None) + frames_to_fix = instance.data.get("frames_to_fix") + frames_to_render = [] + if not frames_to_fix: + first_frame = instance.data.get("frameStartHandle", None) + last_frame = instance.data.get("frameEndHandle", None) + frames_to_render.append((first_frame, last_frame)) + else: + for frame_range in frames_to_fix.split(","): + if isinstance(frame_range, int): + first_frame = frame_range + last_frame = frame_range + elif '-' in frame_range: + frames = frame_range.split('-') + first_frame = int(frames[0]) + last_frame = int(frames[1]) + else: + raise ValueError("Wrong format of frames to fix {}" + .format(frames_to_fix)) + frames_to_render.append((first_frame, last_frame)) - self.log.info("Starting render") - self.log.info("Start frame: {}".format(first_frame)) - self.log.info("End frame: {}".format(last_frame)) + filenames = [] + for first_frame, last_frame in frames_to_render: - node_file = node["file"] - # Collecte expected filepaths for each frame - # - for cases that output is still image is first created set of - # paths which is then sorted and converted to list - expected_paths = list(sorted({ - node_file.evaluate(frame) - for frame in range(first_frame, last_frame + 1) - })) - # Extract only filenames for representation - filenames = [ - os.path.basename(filepath) - for filepath in expected_paths - ] + self.log.info("Starting render") + self.log.info("Start frame: {}".format(first_frame)) + self.log.info("End frame: {}".format(last_frame)) - # Ensure output directory exists. - out_dir = os.path.dirname(expected_paths[0]) - if not os.path.exists(out_dir): - os.makedirs(out_dir) + node_file = node["file"] + # Collecte expected filepaths for each frame + # - for cases that output is still image is first created set of + # paths which is then sorted and converted to list + expected_paths = list(sorted({ + node_file.evaluate(frame) + for frame in range(first_frame, last_frame + 1) + })) + # Extract only filenames for representation + filenames.extend([ + os.path.basename(filepath) + for filepath in expected_paths + ]) - # Render frames - nuke.execute( - node_subset_name, - int(first_frame), - int(last_frame) - ) + # Ensure output directory exists. + out_dir = os.path.dirname(expected_paths[0]) + if not os.path.exists(out_dir): + os.makedirs(out_dir) - ext = node["file_type"].value() + # Render frames + nuke.execute( + node_subset_name, + int(first_frame), + int(last_frame) + ) + + ext = node["file_type"].value() + + if frames_to_fix: + pass if "representations" not in instance.data: instance.data["representations"] = [] From 161e09bcdb681bb5593fe062939917f40efdb7d6 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Tue, 17 Jan 2023 12:30:59 +0100 Subject: [PATCH 03/15] OP-4615 - AE - fix missing list_instances --- .../hosts/aftereffects/plugins/publish/pre_collect_render.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/aftereffects/plugins/publish/pre_collect_render.py b/openpype/hosts/aftereffects/plugins/publish/pre_collect_render.py index 03ec184524..85a42830a4 100644 --- a/openpype/hosts/aftereffects/plugins/publish/pre_collect_render.py +++ b/openpype/hosts/aftereffects/plugins/publish/pre_collect_render.py @@ -1,6 +1,6 @@ import json import pyblish.api -from openpype.hosts.aftereffects.api import list_instances +from openpype.hosts.aftereffects.api import AfterEffectsHost class PreCollectRender(pyblish.api.ContextPlugin): @@ -25,7 +25,7 @@ class PreCollectRender(pyblish.api.ContextPlugin): self.log.debug("Not applicable for New Publisher, skip") return - for inst in list_instances(): + for inst in AfterEffectsHost().list_instances(): if inst.get("creator_attributes"): raise ValueError("Instance created in New publisher, " "cannot be published in Pyblish.\n" From 81ca789c8b62272283cb74136033fbef61db7e16 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Tue, 24 Jan 2023 13:13:16 +0100 Subject: [PATCH 04/15] OP-4617 - collect last published files --- .../plugins/publish/collect_frames_fix.py | 43 +++++++++++++++++-- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/openpype/plugins/publish/collect_frames_fix.py b/openpype/plugins/publish/collect_frames_fix.py index 1e73f2caaa..2640c08ae1 100644 --- a/openpype/plugins/publish/collect_frames_fix.py +++ b/openpype/plugins/publish/collect_frames_fix.py @@ -1,14 +1,24 @@ import pyblish.api from openpype.lib.attribute_definitions import TextDef from openpype.pipeline.publish import OpenPypePyblishPluginMixin +from openpype.client.entities import ( + get_last_version_by_subset_name, + get_representations +) class CollectFramesFixDef( - pyblish.api.ContextPlugin, + pyblish.api.InstancePlugin, OpenPypePyblishPluginMixin ): - label = "Collect frames to fix" - targets = ["local"] + """Provides text field to insert frame(s) to be rerendered. + + Published files of last version of an instance subset are collected into + instance.data["last_version_published_files"]. All these but frames + mentioned in text field will be reused for new version. + """ + order = pyblish.api.CollectorOrder + 0.495 + label = "Collect Frames to Fix" # Disable plugin by default families = ["render"] enabled = True @@ -19,6 +29,32 @@ class CollectFramesFixDef( if frames_to_fix: instance.data["frames_to_fix"] = frames_to_fix + subset_name = instance.data["subset"] + asset_name = instance.data["asset"] + + project_entity = instance.data["projectEntity"] + project_name = project_entity["name"] + + version = get_last_version_by_subset_name(project_name, + subset_name, + asset_name=asset_name) + if not version: + return + + representations = get_representations(project_name, + version_ids=[version["_id"]]) + published_files = [] + for repre in representations: + if repre["context"]["family"] not in self.families: + continue + + for file_info in repre.get("files"): + published_files.append(file_info["path"]) + + instance.data["last_version_published_files"] = published_files + self.log.debug("last_version_published_files::{}".format( + instance.data["last_version_published_files"])) + @classmethod def get_attribute_defs(cls): return [ @@ -26,4 +62,3 @@ class CollectFramesFixDef( placeholder="5,10-15", regex="[0-9,-]+") ] - From 27df249a1c61a33ef754c205735505925e98caed Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Tue, 24 Jan 2023 13:16:22 +0100 Subject: [PATCH 05/15] OP-4617 - reuse last published and rerender specific If frames_to_fix is filled, use this to render only these frames, use 'last_version_published_files' for other --- .../plugins/publish/extract_render_local.py | 156 ++++++++++++------ 1 file changed, 102 insertions(+), 54 deletions(-) diff --git a/openpype/hosts/nuke/plugins/publish/extract_render_local.py b/openpype/hosts/nuke/plugins/publish/extract_render_local.py index 842a62ab4a..5a857de509 100644 --- a/openpype/hosts/nuke/plugins/publish/extract_render_local.py +++ b/openpype/hosts/nuke/plugins/publish/extract_render_local.py @@ -1,15 +1,12 @@ import os +import shutil import pyblish.api import clique import nuke from openpype.pipeline import publish -from openpype.client import ( - get_version_by_id, - get_last_version_by_subset_id, -) - +from openpype.lib import collect_frames class NukeRenderLocal(publish.ExtractorColormanaged): @@ -18,6 +15,8 @@ class NukeRenderLocal(publish.ExtractorColormanaged): Extract the result of savers by starting a comp render This will run the local render of Fusion. + Allows to use last published frames and overwrite only specific ones + (set in instance.data.get("frames_to_fix")) """ order = pyblish.api.ExtractorOrder @@ -26,7 +25,6 @@ class NukeRenderLocal(publish.ExtractorColormanaged): families = ["render.local", "prerender.local", "still.local"] def process(self, instance): - families = instance.data["families"] child_nodes = ( instance.data.get("transientData", {}).get("childNodes") or instance @@ -40,64 +38,54 @@ class NukeRenderLocal(publish.ExtractorColormanaged): self.log.debug("instance collected: {}".format(instance.data)) node_subset_name = instance.data.get("name", None) + + first_frame = instance.data.get("frameStartHandle", None) + last_frame = instance.data.get("frameEndHandle", None) + frames_to_fix = instance.data.get("frames_to_fix") - frames_to_render = [] - if not frames_to_fix: - first_frame = instance.data.get("frameStartHandle", None) - last_frame = instance.data.get("frameEndHandle", None) - frames_to_render.append((first_frame, last_frame)) - else: - for frame_range in frames_to_fix.split(","): - if isinstance(frame_range, int): - first_frame = frame_range - last_frame = frame_range - elif '-' in frame_range: - frames = frame_range.split('-') - first_frame = int(frames[0]) - last_frame = int(frames[1]) - else: - raise ValueError("Wrong format of frames to fix {}" - .format(frames_to_fix)) - frames_to_render.append((first_frame, last_frame)) + frames_to_render = self._get_frames_to_render(frames_to_fix, + first_frame, + last_frame) filenames = [] - for first_frame, last_frame in frames_to_render: + node_file = node["file"] + # Collect expected filepaths for each frame + # - for cases that output is still image is first created set of + # paths which is then sorted and converted to list + expected_paths = list(sorted({ + node_file.evaluate(frame) + for frame in range(first_frame, last_frame + 1) + })) + # Extract only filenames for representation + filenames.extend([ + os.path.basename(filepath) + for filepath in expected_paths + ]) + + # Ensure output directory exists. + out_dir = os.path.dirname(expected_paths[0]) + if not os.path.exists(out_dir): + os.makedirs(out_dir) + + if instance.data.get("last_version_published_files"): + anatomy = instance.context.data["anatomy"] + self._copy_last_published(anatomy, instance, out_dir, filenames) + + for render_first_frame, render_last_frame in frames_to_render: self.log.info("Starting render") - self.log.info("Start frame: {}".format(first_frame)) - self.log.info("End frame: {}".format(last_frame)) - - node_file = node["file"] - # Collecte expected filepaths for each frame - # - for cases that output is still image is first created set of - # paths which is then sorted and converted to list - expected_paths = list(sorted({ - node_file.evaluate(frame) - for frame in range(first_frame, last_frame + 1) - })) - # Extract only filenames for representation - filenames.extend([ - os.path.basename(filepath) - for filepath in expected_paths - ]) - - # Ensure output directory exists. - out_dir = os.path.dirname(expected_paths[0]) - if not os.path.exists(out_dir): - os.makedirs(out_dir) + self.log.info("Start frame: {}".format(render_first_frame)) + self.log.info("End frame: {}".format(render_last_frame)) # Render frames nuke.execute( - node_subset_name, - int(first_frame), - int(last_frame) + str(node_subset_name), + int(render_first_frame), + int(render_last_frame) ) - ext = node["file_type"].value() - colorspace = node["colorspace"].value() - - if frames_to_fix: - pass + ext = node["file_type"].value() + colorspace = node["colorspace"].value() if "representations" not in instance.data: instance.data["representations"] = [] @@ -135,6 +123,7 @@ class NukeRenderLocal(publish.ExtractorColormanaged): out_dir )) + families = instance.data["families"] # redefinition of families if "render.local" in families: instance.data['family'] = 'render' @@ -162,3 +151,62 @@ class NukeRenderLocal(publish.ExtractorColormanaged): self.log.info('Finished render') self.log.debug("_ instance.data: {}".format(instance.data)) + + def _copy_last_published(self, anatomy, instance, out_dir, + expected_filenames): + """Copies last published files to temporary out_dir. + + These are base of files which will be extended/fixed for specific + frames. + Renames published file to expected file name based on frame, eg. + test_project_test_asset_subset_v005.1001.exr > new_render.1001.exr + """ + last_published = instance.data["last_version_published_files"] + last_published_and_frames = collect_frames(last_published) + + expected_and_frames = collect_frames(expected_filenames) + frames_and_expected = {v: k for k, v in expected_and_frames.items()} + for file_path, frame in last_published_and_frames.items(): + file_path = anatomy.fill_root(file_path) + if not os.path.exists(file_path): + continue + target_file_name = frames_and_expected.get(frame) + if not target_file_name: + continue + + out_path = os.path.join(out_dir, target_file_name) + self.log.debug("Copying '{}' -> '{}'".format(file_path, out_path)) + shutil.copy(file_path, out_path) + + # TODO shouldn't this be uncommented + # instance.context.data["cleanupFullPaths"].append(out_path) + + def _get_frames_to_render(self, frames_to_fix, first_frame, last_frame): + """Return list of frame range tuples to render + + Args: + frames_to_fix (str): specific or range of frames to be rerendered + (1005, 1009-1010) + first_frame (int): original first frame + last_frame (int) + Returns: + (list): [(1005, 1005), (1009-1010)] + """ + frames_to_render = [] + if not frames_to_fix: + frames_to_render.append((first_frame, last_frame)) + else: + for frame_range in frames_to_fix.split(","): + if isinstance(frame_range, int) or frame_range.isdigit(): + render_first_frame = frame_range + render_last_frame = frame_range + elif '-' in frame_range: + frames = frame_range.split('-') + render_first_frame = int(frames[0]) + render_last_frame = int(frames[1]) + else: + raise ValueError("Wrong format of frames to fix {}" + .format(frames_to_fix)) + frames_to_render.append((render_first_frame, + render_last_frame)) + return frames_to_render From 9d8ad09fa1f2636011f9bc625a00cbea2ace1110 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Tue, 24 Jan 2023 13:19:48 +0100 Subject: [PATCH 06/15] OP-4617 - implemented currently only in Nuke New host implementation should be added to hosts filter --- openpype/plugins/publish/collect_frames_fix.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/plugins/publish/collect_frames_fix.py b/openpype/plugins/publish/collect_frames_fix.py index 2640c08ae1..560b8fa41c 100644 --- a/openpype/plugins/publish/collect_frames_fix.py +++ b/openpype/plugins/publish/collect_frames_fix.py @@ -19,7 +19,7 @@ class CollectFramesFixDef( """ order = pyblish.api.CollectorOrder + 0.495 label = "Collect Frames to Fix" - # Disable plugin by default + hosts = ["nuke"] families = ["render"] enabled = True From ec248c6ab761561293108a9c312f7b6234bae55f Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Tue, 24 Jan 2023 13:52:01 +0100 Subject: [PATCH 07/15] OP-4617 - better handle if no last version --- .../plugins/publish/extract_render_local.py | 46 +++++++++---------- 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/openpype/hosts/nuke/plugins/publish/extract_render_local.py b/openpype/hosts/nuke/plugins/publish/extract_render_local.py index 5a857de509..a48db60179 100644 --- a/openpype/hosts/nuke/plugins/publish/extract_render_local.py +++ b/openpype/hosts/nuke/plugins/publish/extract_render_local.py @@ -42,11 +42,6 @@ class NukeRenderLocal(publish.ExtractorColormanaged): first_frame = instance.data.get("frameStartHandle", None) last_frame = instance.data.get("frameEndHandle", None) - frames_to_fix = instance.data.get("frames_to_fix") - frames_to_render = self._get_frames_to_render(frames_to_fix, - first_frame, - last_frame) - filenames = [] node_file = node["file"] # Collect expected filepaths for each frame @@ -67,9 +62,14 @@ class NukeRenderLocal(publish.ExtractorColormanaged): if not os.path.exists(out_dir): os.makedirs(out_dir) - if instance.data.get("last_version_published_files"): + frames_to_render = [(first_frame, last_frame)] + + frames_to_fix = instance.data.get("frames_to_fix") + if instance.data.get("last_version_published_files") and frames_to_fix: + frames_to_render = self._get_frames_to_render(frames_to_fix) anatomy = instance.context.data["anatomy"] - self._copy_last_published(anatomy, instance, out_dir, filenames) + self._copy_last_published(anatomy, instance, out_dir, + filenames) for render_first_frame, render_last_frame in frames_to_render: @@ -181,7 +181,7 @@ class NukeRenderLocal(publish.ExtractorColormanaged): # TODO shouldn't this be uncommented # instance.context.data["cleanupFullPaths"].append(out_path) - def _get_frames_to_render(self, frames_to_fix, first_frame, last_frame): + def _get_frames_to_render(self, frames_to_fix): """Return list of frame range tuples to render Args: @@ -193,20 +193,18 @@ class NukeRenderLocal(publish.ExtractorColormanaged): (list): [(1005, 1005), (1009-1010)] """ frames_to_render = [] - if not frames_to_fix: - frames_to_render.append((first_frame, last_frame)) - else: - for frame_range in frames_to_fix.split(","): - if isinstance(frame_range, int) or frame_range.isdigit(): - render_first_frame = frame_range - render_last_frame = frame_range - elif '-' in frame_range: - frames = frame_range.split('-') - render_first_frame = int(frames[0]) - render_last_frame = int(frames[1]) - else: - raise ValueError("Wrong format of frames to fix {}" - .format(frames_to_fix)) - frames_to_render.append((render_first_frame, - render_last_frame)) + + for frame_range in frames_to_fix.split(","): + if isinstance(frame_range, int) or frame_range.isdigit(): + render_first_frame = frame_range + render_last_frame = frame_range + elif '-' in frame_range: + frames = frame_range.split('-') + render_first_frame = int(frames[0]) + render_last_frame = int(frames[1]) + else: + raise ValueError("Wrong format of frames to fix {}" + .format(frames_to_fix)) + frames_to_render.append((render_first_frame, + render_last_frame)) return frames_to_render From 98170356b37e17543404db2b428ad9df6e649070 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Tue, 24 Jan 2023 14:01:52 +0100 Subject: [PATCH 08/15] OP-4617 - added logging if no last version --- openpype/plugins/publish/collect_frames_fix.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openpype/plugins/publish/collect_frames_fix.py b/openpype/plugins/publish/collect_frames_fix.py index 560b8fa41c..4ada8120e0 100644 --- a/openpype/plugins/publish/collect_frames_fix.py +++ b/openpype/plugins/publish/collect_frames_fix.py @@ -39,6 +39,8 @@ class CollectFramesFixDef( subset_name, asset_name=asset_name) if not version: + self.log.warning("No last version found, " + "re-render not possible") return representations = get_representations(project_name, From 9208b76f103699a30d827fd05f30ac904ac7219a Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Tue, 24 Jan 2023 14:28:12 +0100 Subject: [PATCH 09/15] OP-4617 - added prerender family --- openpype/plugins/publish/collect_frames_fix.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/plugins/publish/collect_frames_fix.py b/openpype/plugins/publish/collect_frames_fix.py index 4ada8120e0..413cbfe978 100644 --- a/openpype/plugins/publish/collect_frames_fix.py +++ b/openpype/plugins/publish/collect_frames_fix.py @@ -20,7 +20,7 @@ class CollectFramesFixDef( order = pyblish.api.CollectorOrder + 0.495 label = "Collect Frames to Fix" hosts = ["nuke"] - families = ["render"] + families = ["render", "prerender"] enabled = True def process(self, instance): From ff80b73de875a26d4d787d06e55825dc0879ad72 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Tue, 24 Jan 2023 14:29:00 +0100 Subject: [PATCH 10/15] OP-4617 - added local targets This plugin should run only on local (eg not no farm - no one to fill valu in UI). --- openpype/plugins/publish/collect_frames_fix.py | 1 + 1 file changed, 1 insertion(+) diff --git a/openpype/plugins/publish/collect_frames_fix.py b/openpype/plugins/publish/collect_frames_fix.py index 413cbfe978..fdaa810897 100644 --- a/openpype/plugins/publish/collect_frames_fix.py +++ b/openpype/plugins/publish/collect_frames_fix.py @@ -19,6 +19,7 @@ class CollectFramesFixDef( """ order = pyblish.api.CollectorOrder + 0.495 label = "Collect Frames to Fix" + targets = ["local"] hosts = ["nuke"] families = ["render", "prerender"] enabled = True From a03ce5d6fea965761d960ca3eb54a5c7c816fffc Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Tue, 24 Jan 2023 17:05:19 +0100 Subject: [PATCH 11/15] OP-4617 - fix - os.path.samefile not present on Python2 --- openpype/lib/file_transaction.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/lib/file_transaction.py b/openpype/lib/file_transaction.py index cba361a8d4..fe70b37cb1 100644 --- a/openpype/lib/file_transaction.py +++ b/openpype/lib/file_transaction.py @@ -189,6 +189,6 @@ class FileTransaction(object): def _same_paths(self, src, dst): # handles same paths but with C:/project vs c:/project if os.path.exists(src) and os.path.exists(dst): - return os.path.samefile(src, dst) + return os.stat(src) == os.stat(dst) return src == dst From 30b00705f4b74c163111534acfd154706143c703 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Tue, 24 Jan 2023 17:06:54 +0100 Subject: [PATCH 12/15] OP-4617 - fix - allow overwriting of old version in integrate.py Without it it will always use version from anatomy, even if it logs that it uses old version. --- openpype/plugins/publish/integrate.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openpype/plugins/publish/integrate.py b/openpype/plugins/publish/integrate.py index a97ab2acca..7521f91cbd 100644 --- a/openpype/plugins/publish/integrate.py +++ b/openpype/plugins/publish/integrate.py @@ -534,6 +534,9 @@ class IntegrateAsset(pyblish.api.InstancePlugin): template_data["representation"] = repre["name"] template_data["ext"] = repre["ext"] + # allow overwriting existing version + template_data["version"] = version["name"] + # add template data for colorspaceData if repre.get("colorspaceData"): colorspace = repre["colorspaceData"]["colorspace"] From eed6ec6bf56bf0d776eeec55e5bceeb99e324503 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Tue, 24 Jan 2023 17:08:02 +0100 Subject: [PATCH 13/15] OP-4617 - added rewrite_version toggle Allows to rewrite latest version, eg. not duplicating files. --- openpype/plugins/publish/collect_frames_fix.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/openpype/plugins/publish/collect_frames_fix.py b/openpype/plugins/publish/collect_frames_fix.py index fdaa810897..bdd49585a5 100644 --- a/openpype/plugins/publish/collect_frames_fix.py +++ b/openpype/plugins/publish/collect_frames_fix.py @@ -1,5 +1,9 @@ import pyblish.api -from openpype.lib.attribute_definitions import TextDef +from openpype.lib.attribute_definitions import ( + TextDef, + BoolDef +) + from openpype.pipeline.publish import OpenPypePyblishPluginMixin from openpype.client.entities import ( get_last_version_by_subset_name, @@ -27,6 +31,8 @@ class CollectFramesFixDef( def process(self, instance): attribute_values = self.get_attr_values_from_data(instance.data) frames_to_fix = attribute_values.get("frames_to_fix") + rewrite_version = attribute_values.get("rewrite_version") + if frames_to_fix: instance.data["frames_to_fix"] = frames_to_fix @@ -58,10 +64,17 @@ class CollectFramesFixDef( self.log.debug("last_version_published_files::{}".format( instance.data["last_version_published_files"])) + if rewrite_version: + instance.data["version"] = version["name"] + # limits triggering version validator + instance.data.pop("latestVersion") + @classmethod def get_attribute_defs(cls): return [ TextDef("frames_to_fix", label="Frames to fix", placeholder="5,10-15", - regex="[0-9,-]+") + regex="[0-9,-]+"), + BoolDef("rewrite_version", label="Rewrite latest version", + default=False), ] From 6842dc8eba9875fb6951e0ef3cc0f5a78d91d828 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Fri, 27 Jan 2023 13:29:04 +0100 Subject: [PATCH 14/15] OP-4617 - reworked condition Co-authored-by: Roy Nieterau --- openpype/hosts/nuke/plugins/publish/extract_render_local.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/nuke/plugins/publish/extract_render_local.py b/openpype/hosts/nuke/plugins/publish/extract_render_local.py index a48db60179..4fee6350f0 100644 --- a/openpype/hosts/nuke/plugins/publish/extract_render_local.py +++ b/openpype/hosts/nuke/plugins/publish/extract_render_local.py @@ -195,7 +195,7 @@ class NukeRenderLocal(publish.ExtractorColormanaged): frames_to_render = [] for frame_range in frames_to_fix.split(","): - if isinstance(frame_range, int) or frame_range.isdigit(): + if frame_range.isdigit(): render_first_frame = frame_range render_last_frame = frame_range elif '-' in frame_range: From a015a1a27a71013821ebe667805fd4363fb73950 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Fri, 27 Jan 2023 13:29:32 +0100 Subject: [PATCH 15/15] OP-4617 - removed arguments from docstring Co-authored-by: Roy Nieterau --- openpype/hosts/nuke/plugins/publish/extract_render_local.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/openpype/hosts/nuke/plugins/publish/extract_render_local.py b/openpype/hosts/nuke/plugins/publish/extract_render_local.py index 4fee6350f0..b99a7a9548 100644 --- a/openpype/hosts/nuke/plugins/publish/extract_render_local.py +++ b/openpype/hosts/nuke/plugins/publish/extract_render_local.py @@ -187,8 +187,6 @@ class NukeRenderLocal(publish.ExtractorColormanaged): Args: frames_to_fix (str): specific or range of frames to be rerendered (1005, 1009-1010) - first_frame (int): original first frame - last_frame (int) Returns: (list): [(1005, 1005), (1009-1010)] """