From b4ae58634d3697c7ccf72ba58fd93d5afa3af24e Mon Sep 17 00:00:00 2001 From: Fabia Serra Arrizabalaga Date: Mon, 26 Jun 2023 10:19:02 -0500 Subject: [PATCH] Nuke: Add support to submit existing frames to the farm --- openpype/hosts/nuke/api/plugin.py | 3 ++- .../nuke/plugins/publish/collect_writes.py | 21 ++++++++++++++++++- .../plugins/publish/submit_nuke_deadline.py | 2 +- .../plugins/publish/submit_publish_job.py | 16 +++++++++----- .../validate_expected_and_rendered_files.py | 4 ++++ 5 files changed, 38 insertions(+), 8 deletions(-) diff --git a/openpype/hosts/nuke/api/plugin.py b/openpype/hosts/nuke/api/plugin.py index 7035da2bb5..b82ed0a1e3 100644 --- a/openpype/hosts/nuke/api/plugin.py +++ b/openpype/hosts/nuke/api/plugin.py @@ -311,6 +311,7 @@ class NukeWriteCreator(NukeCreator): } if ("farm_rendering" in self.instance_attributes): rendering_targets["farm"] = "Farm rendering" + rendering_targets["farm_frames"] = "Existing frames farm rendering" return EnumDef( "render_target", @@ -669,7 +670,7 @@ class ExporterReviewLut(ExporterReview): self.ext = ext or "cube" self.cube_size = cube_size or 32 self.lut_size = lut_size or 1024 - self.lut_style = lut_style or "linear" + self.lut_style = lut_style or "scene_linear" # set frame start / end and file name to self self.get_file_info() diff --git a/openpype/hosts/nuke/plugins/publish/collect_writes.py b/openpype/hosts/nuke/plugins/publish/collect_writes.py index 2d1caacdc3..0b6fe392d8 100644 --- a/openpype/hosts/nuke/plugins/publish/collect_writes.py +++ b/openpype/hosts/nuke/plugins/publish/collect_writes.py @@ -29,6 +29,9 @@ class CollectNukeWrites(pyblish.api.InstancePlugin, instance.data["families"].append( "{}.{}".format(family, render_target) ) + self.log.debug("Appending render target to families: {}.{}".format( + family, render_target) + ) if instance.data.get("review"): instance.data["families"].append("review") @@ -73,7 +76,7 @@ class CollectNukeWrites(pyblish.api.InstancePlugin, self.log.debug('output dir: {}'.format(output_dir)) - if render_target == "frames": + if render_target in ["frames", "farm_frames"]: representation = { 'name': ext, 'ext': ext, @@ -142,6 +145,22 @@ class CollectNukeWrites(pyblish.api.InstancePlugin, instance.data["representations"].append(representation) self.log.info("Publishing rendered frames ...") + if render_target == "farm_frames": + # Farm rendering + instance.data["toBeRenderedOn"] = "deadline" + instance.data["transfer"] = False + instance.data["farm"] = True # to skip integrate + self.log.info("Farm rendering ON ...") + + self.log.info( + "Adding collected files %s to expectedFiles instance.data", + collected_frames + ) + if "expectedFiles" not in instance.data: + instance.data["expectedFiles"] = list() + for source_file in collected_frames: + instance.data["expectedFiles"].append(os.path.join(output_dir, source_file)) + elif render_target == "farm": farm_keys = ["farm_chunk", "farm_priority", "farm_concurrency"] for key in farm_keys: diff --git a/openpype/modules/deadline/plugins/publish/submit_nuke_deadline.py b/openpype/modules/deadline/plugins/publish/submit_nuke_deadline.py index 4900231783..34e335e442 100644 --- a/openpype/modules/deadline/plugins/publish/submit_nuke_deadline.py +++ b/openpype/modules/deadline/plugins/publish/submit_nuke_deadline.py @@ -32,7 +32,7 @@ class NukeSubmitDeadline(pyblish.api.InstancePlugin, label = "Submit Nuke to Deadline" order = pyblish.api.IntegratorOrder + 0.1 hosts = ["nuke"] - families = ["render", "prerender"] + families = ["render.farm", "prerender.farm"] optional = True targets = ["local"] diff --git a/openpype/modules/deadline/plugins/publish/submit_publish_job.py b/openpype/modules/deadline/plugins/publish/submit_publish_job.py index 69e9fb6449..677d322a19 100644 --- a/openpype/modules/deadline/plugins/publish/submit_publish_job.py +++ b/openpype/modules/deadline/plugins/publish/submit_publish_job.py @@ -17,6 +17,7 @@ from openpype.client import ( from openpype.pipeline import ( get_representation_path, legacy_io, + publish, ) from openpype.tests.lib import is_in_tests from openpype.pipeline.farm.patterning import match_aov_pattern @@ -123,7 +124,8 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin, hosts = ["fusion", "max", "maya", "nuke", "houdini", "celaction", "aftereffects", "harmony"] - families = ["render.farm", "prerender.farm", + families = ["render.farm", "render.farm_frames", + "prerender.farm", "prerender.farm_frames", "renderlayer", "imagesequence", "vrayscene", "maxrender", "arnold_rop", "mantra_rop", @@ -334,7 +336,7 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin, for assembly_id in instance.data["bakingSubmissionJobs"]: payload["JobInfo"]["JobDependency{}".format(job_index)] = assembly_id # noqa: E501 job_index += 1 - else: + elif job.get("_id"): payload["JobInfo"]["JobDependency0"] = job["_id"] if instance.data.get("suspend_publish"): @@ -870,6 +872,7 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin, "multipartExr": data.get("multipartExr", False), "jobBatchName": data.get("jobBatchName", ""), "useSequenceForReview": data.get("useSequenceForReview", True), + "colorspace": data.get("colorspace"), # map inputVersions `ObjectId` -> `str` so json supports it "inputVersions": list(map(str, data.get("inputVersions", []))), "colorspace": instance.data.get("colorspace") @@ -883,6 +886,7 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin, # transfer specific families from original instance to new render for item in self.families_transfer: if item in instance.data.get("families", []): + self.log.debug("Transfering '%s' family to instance.", item) instance_skeleton_data["families"] += [item] # transfer specific properties from original instance based on @@ -890,6 +894,7 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin, for key, values in self.instance_transfer.items(): if key in instance.data.get("families", []): for v in values: + self.log.debug("Transfering '%s' property to instance.", v) instance_skeleton_data[v] = instance.data.get(v) # look into instance data if representations are not having any @@ -912,7 +917,7 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin, repre["stagingDir"] = staging_dir if "publish_on_farm" in repre.get("tags"): - # create representations attribute of not there + # create representations attribute if not there if "representations" not in instance_skeleton_data.keys(): instance_skeleton_data["representations"] = [] @@ -1095,6 +1100,7 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin, "FTRACK_SERVER": os.environ.get("FTRACK_SERVER"), } + deadline_publish_job_id = None if submission_type == "deadline": # get default deadline webservice url from deadline module self.deadline_url = instance.context.data["defaultDeadline"] @@ -1118,7 +1124,7 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin, "fps": context.data.get("fps", None), "source": source, "user": context.data["user"], - "version": context.data["version"], # this is workfile version + "version": context.data.get("version"), # this is workfile version "intent": context.data.get("intent"), "comment": context.data.get("comment"), "job": render_job or None, @@ -1151,7 +1157,7 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin, json.dump(publish_job, f, indent=4, sort_keys=True) def _extend_frames(self, asset, subset, start, end): - """Get latest version of asset nad update frame range. + """Get latest version of asset and update frame range. Based on minimum and maximuma values. diff --git a/openpype/modules/deadline/plugins/publish/validate_expected_and_rendered_files.py b/openpype/modules/deadline/plugins/publish/validate_expected_and_rendered_files.py index ff4be677e7..6fbaa0d7b5 100644 --- a/openpype/modules/deadline/plugins/publish/validate_expected_and_rendered_files.py +++ b/openpype/modules/deadline/plugins/publish/validate_expected_and_rendered_files.py @@ -21,6 +21,10 @@ class ValidateExpectedFiles(pyblish.api.InstancePlugin): def process(self, instance): self.instance = instance + # TODO: Find a better way to check whether a job has been submitted with + # existing frames + if not instance.data["render_job_id"]: + return frame_list = self._get_frame_list(instance.data["render_job_id"]) for repre in instance.data["representations"]: