diff --git a/openpype/hosts/nuke/api/plugin.py b/openpype/hosts/nuke/api/plugin.py index b753bc0965..7b8af96df0 100644 --- a/openpype/hosts/nuke/api/plugin.py +++ b/openpype/hosts/nuke/api/plugin.py @@ -117,8 +117,6 @@ class ExporterReview(object): self.log = klass.log self.instance = instance - self.bake_colorspace = instance.data["bakeColorspace"] - self.bake_viewer_input = instance.data["bakeViewerInput"] self.path_in = self.instance.data.get("path", None) self.staging_dir = self.instance.data["stagingDir"] self.collection = self.instance.data.get("collection", None) @@ -146,11 +144,10 @@ class ExporterReview(object): self.fhead = self.fhead.replace("#", "")[:-1] def get_representation_data(self, tags=None, range=False): - add_tags = [] - if tags: - add_tags = tags + add_tags = tags or [] repre = { + 'outputName': self.name, 'name': self.name, 'ext': self.ext, 'files': self.file, @@ -166,7 +163,7 @@ class ExporterReview(object): self.data["representations"].append(repre) - def get_view_process_node(self): + def get_view_input_process_node(self): """ Will get any active view process. @@ -197,6 +194,11 @@ class ExporterReview(object): return ipn + def get_imageio_baking_profile(self): + from . import lib as opnlib + nuke_imageio = opnlib.get_nuke_imageio_settings() + return nuke_imageio["baking"]["viewerProcess"] + class ExporterReviewLut(ExporterReview): """ @@ -249,6 +251,10 @@ class ExporterReviewLut(ExporterReview): self.log.info("Deleted nodes...") def generate_lut(self): + bake_viewer_process = kwargs["bake_viewer_process"] + bake_viewer_input_process_node = kwargs[ + "bake_viewer_input_process"] + # ---------- start nodes creation # CMSTestPattern @@ -259,10 +265,10 @@ class ExporterReviewLut(ExporterReview): self.previous_node = cms_node self.log.debug("CMSTestPattern... `{}`".format(self._temp_nodes)) - if self.bake_colorspace: + if bake_viewer_process: # Node View Process - if self.bake_viewer_input: - ipn = self.get_view_process_node() + if bake_viewer_input_process_node: + ipn = self.get_view_input_process_node() if ipn is not None: # connect ipn.setInput(0, self.previous_node) @@ -336,8 +342,6 @@ class ExporterReviewMov(ExporterReview): # deal with now lut defined in viewer lut self.viewer_lut_raw = klass.viewer_lut_raw - self.bake_colorspace_fallback = klass.bake_colorspace_fallback - self.bake_colorspace_main = klass.bake_colorspace_main self.write_colorspace = instance.data["colorspace"] self.name = name or "baked" @@ -380,7 +384,26 @@ class ExporterReviewMov(ExporterReview): self.log.info("Nodes exported...") return path - def generate_mov(self, farm=False): + def generate_mov(self, farm=False, **kwargs): + bake_viewer_process = kwargs["bake_viewer_process"] + bake_viewer_input_process_node = kwargs[ + "bake_viewer_input_process"] + viewer_process_override = kwargs[ + "viewer_process_override"] + + baking_view_profile = ( + viewer_process_override or self.get_imageio_baking_profile()) + + fps = self.instance.context.data["fps"] + + self.log.debug(">> baking_view_profile `{}`".format( + baking_view_profile)) + + add_tags = kwargs.get("add_tags", []) + + self.log.info( + "__ add_tags: `{0}`".format(add_tags)) + subset = self.instance.data["subset"] self._temp_nodes[subset] = [] # ---------- start nodes creation @@ -400,10 +423,10 @@ class ExporterReviewMov(ExporterReview): self.log.debug("Read... `{}`".format(self._temp_nodes[subset])) # only create colorspace baking if toggled on - if self.bake_colorspace: - if self.bake_viewer_input: + if bake_viewer_process: + if bake_viewer_input_process_node: # View Process node - ipn = self.get_view_process_node() + ipn = self.get_view_input_process_node() if ipn is not None: # connect ipn.setInput(0, self.previous_node) @@ -414,26 +437,9 @@ class ExporterReviewMov(ExporterReview): self._temp_nodes[subset])) if not self.viewer_lut_raw: - colorspaces = [ - self.bake_colorspace_main, self.bake_colorspace_fallback - ] - - if any(colorspaces): - # OCIOColorSpace with controled output - dag_node = nuke.createNode("OCIOColorSpace") - self._temp_nodes[subset].append(dag_node) - for c in colorspaces: - test = dag_node["out_colorspace"].setValue(str(c)) - if test: - self.log.info( - "Baking in colorspace... `{}`".format(c)) - break - - if not test: - dag_node = nuke.createNode("OCIODisplay") - else: - # OCIODisplay - dag_node = nuke.createNode("OCIODisplay") + # OCIODisplay + dag_node = nuke.createNode("OCIODisplay") + dag_node["view"].setValue(str(baking_view_profile)) # connect dag_node.setInput(0, self.previous_node) @@ -445,11 +451,11 @@ class ExporterReviewMov(ExporterReview): # Write node write_node = nuke.createNode("Write") self.log.debug("Path: {}".format(self.path)) - write_node["file"].setValue(self.path) - write_node["file_type"].setValue(self.ext) + write_node["file"].setValue(str(self.path)) + write_node["file_type"].setValue(str(self.ext)) # Knobs `meta_codec` and `mov64_codec` are not available on centos. - # TODO change this to use conditions, if possible. + # TODO should't this come from settings on outputs? try: write_node["meta_codec"].setValue("ap4h") except Exception: @@ -457,8 +463,10 @@ class ExporterReviewMov(ExporterReview): try: write_node["mov64_codec"].setValue("ap4h") + write_node["mov64_fps"].setValue(float(fps)) except Exception: self.log.info("`mov64_codec` knob was not found") + write_node["mov64_write_timecode"].setValue(1) write_node["raw"].setValue(1) # connect @@ -480,7 +488,7 @@ class ExporterReviewMov(ExporterReview): self.render(write_node.name()) # ---------- generate representation data self.get_representation_data( - tags=["review", "delete"], + tags=["review", "delete"] + add_tags, range=True ) diff --git a/openpype/hosts/nuke/plugins/publish/extract_review_data_mov.py b/openpype/hosts/nuke/plugins/publish/extract_review_data_mov.py index 83275f9716..f092700e3b 100644 --- a/openpype/hosts/nuke/plugins/publish/extract_review_data_mov.py +++ b/openpype/hosts/nuke/plugins/publish/extract_review_data_mov.py @@ -27,11 +27,11 @@ class ExtractReviewDataMov(openpype.api.Extractor): # presets viewer_lut_raw = None - bake_colorspace_fallback = None - bake_colorspace_main = None + outputs = {} def process(self, instance): families = instance.data["families"] + task_type = instance.context.data["taskType"] self.log.info("Creating staging dir...") if "representations" not in instance.data: @@ -45,28 +45,71 @@ class ExtractReviewDataMov(openpype.api.Extractor): self.log.info( "StagingDir `{0}`...".format(instance.data["stagingDir"])) + self.log.info(self.outputs) + # generate data with anlib.maintained_selection(): - exporter = plugin.ExporterReviewMov( - self, instance) + for o_name, o_data in self.outputs.items(): + f_families = o_data["filter"]["families"] + f_task_types = o_data["filter"]["task_types"] - if "render.farm" in families: - instance.data["families"].remove("review") - data = exporter.generate_mov(farm=True) + test_families = any([ + bool(set(families).intersection(f_families)), + bool(not f_families) + ]) + + test_task_types = any([ + bool(task_type in f_task_types), + bool(not f_task_types) + ]) + + test_all = all([ + test_families, + test_task_types + ]) + + if not test_all: + continue + + self.log.info( + "Baking output `{}` with settings: {}".format( + o_name, o_data)) + + # add additional families + add_families = o_data["add_families"] + for adf in add_families: + if adf in instance.data["families"]: + continue + instance.data["families"].append(adf) + + # create exporter instance + exporter = plugin.ExporterReviewMov( + self, instance, o_name, o_data["extension"]) + + if "render.farm" in families: + if "review" in instance.data["families"]: + instance.data["families"].remove("review") + + data = exporter.generate_mov(farm=True, **o_data) + + self.log.debug( + "_ data: {}".format(data)) + + if not instance.data.get("bakingNukeScripts"): + instance.data["bakingNukeScripts"] = [] + + instance.data["bakingNukeScripts"].append({ + "bakeRenderPath": data.get("bakeRenderPath"), + "bakeScriptPath": data.get("bakeScriptPath"), + "bakeWriteNodeName": data.get("bakeWriteNodeName") + }) + else: + data = exporter.generate_mov(**o_data) + + self.log.info(data["representations"]) + + # assign to representations + instance.data["representations"] += data["representations"] self.log.debug( - "_ data: {}".format(data)) - - instance.data.update({ - "bakeRenderPath": data.get("bakeRenderPath"), - "bakeScriptPath": data.get("bakeScriptPath"), - "bakeWriteNodeName": data.get("bakeWriteNodeName") - }) - else: - data = exporter.generate_mov() - - # assign to representations - instance.data["representations"] += data["representations"] - - self.log.debug( - "_ representations: {}".format(instance.data["representations"])) + "_ representations: {}".format(instance.data["representations"])) diff --git a/openpype/hosts/nuke/plugins/publish/precollect_instances.py b/openpype/hosts/nuke/plugins/publish/precollect_instances.py index c34e314a79..5c30df9a62 100644 --- a/openpype/hosts/nuke/plugins/publish/precollect_instances.py +++ b/openpype/hosts/nuke/plugins/publish/precollect_instances.py @@ -74,21 +74,6 @@ class PreCollectNukeInstances(pyblish.api.ContextPlugin): if review: families.append("review") - # deside if to bake or not to bake - baking = True - if "bake_colorspace" in node.knobs(): - baking = node["bake_colorspace"].value() - - if baking: - families.append("bake_viewer") - - viewer_input = True - if "bake_viewer_input" in node.knobs(): - viewer_input = node["bake_viewer_input"].value() - - if viewer_input: - families.append("bake_viewer_input") - # Add all nodes in group instances. if node.Class() == "Group": # only alter families for render family @@ -157,9 +142,7 @@ class PreCollectNukeInstances(pyblish.api.ContextPlugin): "resolutionWidth": resolution_width, "resolutionHeight": resolution_height, "pixelAspect": pixel_aspect, - "review": review, - "bakeColorspace": baking, - "bakeViewerInput": viewer_input + "review": review }) self.log.info("collected instance: {}".format(instance.data)) diff --git a/openpype/settings/defaults/project_settings/nuke.json b/openpype/settings/defaults/project_settings/nuke.json index 67446ca6b9..ed0db6a000 100644 --- a/openpype/settings/defaults/project_settings/nuke.json +++ b/openpype/settings/defaults/project_settings/nuke.json @@ -110,10 +110,12 @@ "task_types": [], "families": [] }, + "extension": "mov", "viewer_process_override": "", "bake_viewer_process": true, "bake_viewer_input_process": true, - "add_taggs": [] + "add_tags": [], + "add_families": [] } } }, 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 1bdd15c650..b1f640e951 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 @@ -198,6 +198,11 @@ { "type": "separator" }, + { + "type": "text", + "key": "extension", + "label": "File extension" + }, { "type": "text", "key": "viewer_process_override", @@ -214,8 +219,14 @@ "label": "Bake Viewer Input Process (LUTs)" }, { - "key": "add_taggs", - "label": "Add tags to representations", + "key": "add_families", + "label": "Add additional families to instance", + "type": "list", + "object_type": "text" + }, + { + "key": "add_tags", + "label": "Add additional tags to representations", "type": "list", "object_type": "text" }