diff --git a/pype/plugins/global/publish/extract_scanline_exr.py b/pype/plugins/global/publish/extract_scanline_exr.py new file mode 100644 index 00000000000..ca62476ab2d --- /dev/null +++ b/pype/plugins/global/publish/extract_scanline_exr.py @@ -0,0 +1,89 @@ +# -*- coding: utf-8 -*- +"""Convert exrs in representation to tiled exrs usin oiio tools.""" +import os +import shutil + +import pyblish.api +import pype.api +import pype.lib + + +class ExtractScanlineExr(pyblish.api.InstancePlugin): + """Convert tiled EXRs to scanline using OIIO tool.""" + + label = "Extract Scanline EXR" + hosts = ["shell"] + order = pyblish.api.ExtractorOrder + families = ["imagesequence", "render", "render2d", "source"] + + def process(self, instance): + """Plugin entry point.""" + # get representation and loop them + representations = instance.data["representations"] + + representations_new = [] + + for repre in representations: + self.log.info( + "Processing representation {}".format(repre.get("name"))) + tags = repre.get("tags", []) + if "toScanline" not in tags: + self.log.info(" - missing toScanline tag") + continue + + # run only on exrs + if repre.get("ext") != "exr": + self.log.info("- not EXR files") + continue + + if not isinstance(repre['files'], (list, tuple)): + input_files = [repre['files']] + self.log.info("We have a single frame") + else: + input_files = repre['files'] + self.log.info("We have a sequence") + + stagingdir = os.path.normpath(repre.get("stagingDir")) + + oiio_tool_path = os.getenv("PYPE_OIIO_PATH", "") + + for file in input_files: + + original_name = os.path.join(stagingdir, file) + temp_name = os.path.join(stagingdir, "__{}".format(file)) + # move original render to temp location + shutil.move(original_name, temp_name) + oiio_cmd = [] + oiio_cmd.append(oiio_tool_path) + oiio_cmd.append( + os.path.join(stagingdir, temp_name) + ) + oiio_cmd.append("--scanline") + oiio_cmd.append("-o") + oiio_cmd.append(os.path.join(stagingdir, original_name)) + + subprocess_exr = " ".join(oiio_cmd) + self.log.info(f"running: {subprocess_exr}") + pype.api.subprocess(subprocess_exr) + + # raise error if there is no ouptput + if not os.path.exists(os.path.join(stagingdir, original_name)): + self.log.error( + ("File {} was not converted " + "by oiio tool!").format(original_name)) + raise AssertionError("OIIO tool conversion failed") + else: + try: + os.remove(temp_name) + except OSError as e: + self.log.warning("Unable to delete temp file") + self.log.warning(e) + + repre['name'] = 'exr' + try: + repre['tags'].remove('toScanline') + except ValueError: + # no `toScanline` tag present + pass + + instance.data["representations"] += representations_new diff --git a/pype/plugins/global/publish/submit_publish_job.py b/pype/plugins/global/publish/submit_publish_job.py index 99f0ae7cb65..630a75e7df6 100644 --- a/pype/plugins/global/publish/submit_publish_job.py +++ b/pype/plugins/global/publish/submit_publish_job.py @@ -193,7 +193,8 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin): "slate": ["slateFrame"], "review": ["lutPath"], "render2d": ["bakeScriptPath", "bakeRenderPath", - "bakeWriteNodeName", "version"] + "bakeWriteNodeName", "version"], + "renderlayer": ["convertToScanline"] } # list of family names to transfer to new family if present @@ -491,6 +492,11 @@ def _create_instances_for_aov(self, instance_data, exp_files): "tags": ["review"] if preview else [] } + # support conversion from tiled to scanline + if instance_data.get("convertToScanline"): + self.log.info("Adding scanline conversion.") + rep["tags"].append("toScanline") + # poor man exclusion if ext in self.skip_integration_repre_list: rep["tags"].append("delete") @@ -581,6 +587,11 @@ def _get_representations(self, instance, exp_files): if instance.get("multipartExr", False): rep["tags"].append("multipartExr") + # support conversion from tiled to scanline + if instance.get("convertToScanline"): + self.log.info("Adding scanline conversion.") + rep["tags"].append("toScanline") + representations.append(rep) self._solve_families(instance, preview) diff --git a/pype/plugins/maya/create/create_render.py b/pype/plugins/maya/create/create_render.py index 6826d33c580..fa0e2691260 100644 --- a/pype/plugins/maya/create/create_render.py +++ b/pype/plugins/maya/create/create_render.py @@ -188,6 +188,7 @@ def _create_render_settings(self): self.data["tileRendering"] = False self.data["tilesX"] = 2 self.data["tilesY"] = 2 + self.data["convertToScanline"] = False # Disable for now as this feature is not working yet # self.data["assScene"] = False diff --git a/pype/plugins/maya/publish/collect_render.py b/pype/plugins/maya/publish/collect_render.py index 91230fcc462..093827809c1 100644 --- a/pype/plugins/maya/publish/collect_render.py +++ b/pype/plugins/maya/publish/collect_render.py @@ -246,7 +246,8 @@ def process(self, context): "tileRendering": render_instance.data.get("tileRendering") or False, # noqa: E501 "tilesX": render_instance.data.get("tilesX") or 2, "tilesY": render_instance.data.get("tilesY") or 2, - "priority": render_instance.data.get("priority") + "priority": render_instance.data.get("priority"), + "convertToScanline": render_instance.data.get("convertToScanline") or False # noqa: E501 } # Apply each user defined attribute as data