From a18125803a94dece8a163fcd342542c40115cf2d Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Sat, 1 Dec 2018 01:39:19 +0100 Subject: [PATCH] update publishing render locally --- pype/nuke/__init__.py | 31 ++++----- .../plugins/nuke/publish/collect_instances.py | 17 +++-- .../nuke/{ => publish}/collect_writes.py | 68 +++++++++++-------- .../nuke/publish/validate_collection.py | 39 +++++++++++ 4 files changed, 101 insertions(+), 54 deletions(-) rename pype/plugins/nuke/{ => publish}/collect_writes.py (51%) create mode 100644 pype/plugins/nuke/publish/validate_collection.py diff --git a/pype/nuke/__init__.py b/pype/nuke/__init__.py index ba76b0b1e3..371fe2a786 100644 --- a/pype/nuke/__init__.py +++ b/pype/nuke/__init__.py @@ -144,29 +144,24 @@ def uninstall(): pype.reset_data_from_templates() -def on_pyblish_instance_toggled(instance, new_value, old_value): - """Toggle saver tool passthrough states on instance toggles.""" +def on_pyblish_instance_toggled(instance, old_value, new_value): + """Toggle node passthrough states on instance toggles.""" + self.log.info("instance toggle: {}, old_value: {}, new_value:{} ".format( + instance, old_value, new_value)) from avalon.nuke import ( viewer_update_and_undo_stop, add_publish_knob ) - writes = [n for n in instance if - n.Class() is "Write"] - if not writes: - return - # Whether instances should be passthrough based on new value - passthrough = not new_value - with viewer_update_and_undo_stop(): - for n in writes: - try: - n["publish"].value() - except ValueError: - n = add_publish_knob(n) - log.info(" `Publish` knob was added to write node..") - current = n["publish"].value() - if current != passthrough: - n["publish"].setValue(passthrough) + with viewer_update_and_undo_stop(): + n = instance[0] + try: + n["publish"].value() + except ValueError: + n = add_publish_knob(n) + log.info(" `Publish` knob was added to write node..") + + n["publish"].setValue(new_value) diff --git a/pype/plugins/nuke/publish/collect_instances.py b/pype/plugins/nuke/publish/collect_instances.py index 387716dbca..f1fa1276c2 100644 --- a/pype/plugins/nuke/publish/collect_instances.py +++ b/pype/plugins/nuke/publish/collect_instances.py @@ -7,18 +7,21 @@ from pype.nuke.lib import get_avalon_knob_data @pyblish.api.log class CollectNukeInstances(pyblish.api.ContextPlugin): - """Collect all write nodes.""" + """Collect all nodes with Avalon knob.""" order = pyblish.api.CollectorOrder label = "Collect Instances" hosts = ["nuke", "nukeassist"] def process(self, context): - + instances = [] # creating instances per write node for node in nuke.allNodes(): - if node["disable"].value(): + try: + if node["disable"].value(): + continue + except Exception: continue # get data from avalon knob @@ -41,12 +44,14 @@ class CollectNukeInstances(pyblish.api.ContextPlugin): "publish": node.knob("publish").value() }) self.log.info("collected instance: {}".format(instance.data)) + instances.append(instance) + + context.data["instances"] = instances + # Sort/grouped by family (preserving local index) context[:] = sorted(context, key=self.sort_by_family) - self.log.info("context: {}".format(context)) - - return context + self.log.debug("context: {}".format(context)) def sort_by_family(self, instance): """Sort by family""" diff --git a/pype/plugins/nuke/collect_writes.py b/pype/plugins/nuke/publish/collect_writes.py similarity index 51% rename from pype/plugins/nuke/collect_writes.py rename to pype/plugins/nuke/publish/collect_writes.py index 1d46d889dd..e83402ba48 100644 --- a/pype/plugins/nuke/collect_writes.py +++ b/pype/plugins/nuke/publish/collect_writes.py @@ -3,24 +3,25 @@ import os import nuke import pyblish.api import clique +import logging +log = logging.getLogger(__name__) @pyblish.api.log -class CollectNukeInstances(pyblish.api.ContextPlugin): +class CollectNukeWrites(pyblish.api.ContextPlugin): """Collect all write nodes.""" - order = pyblish.api.CollectorOrder - label = "Collect Instances" + order = pyblish.api.CollectorOrder + 0.1 + label = "Collect Writes" hosts = ["nuke", "nukeassist"] def process(self, context): + for instance in context.data["instances"]: + self.log.debug("checking instance: {}".format(instance)) + node = instance[0] - # creating instances per write node - for node in nuke.allNodes(): if node.Class() != "Write": continue - if node["disable"].value(): - continue # Determine defined file type ext = node["file_type"].value() @@ -41,49 +42,56 @@ class CollectNukeInstances(pyblish.api.ContextPlugin): # Add collection collection = None path = nuke.filename(node) + + if "#" in path: + path_split = path.split("#") + length = len(path_split)-1 + path = "{}%0{}d{}".format(path_split[0], length, path_split[-1]) + path += " [{0}-{1}]".format( str(first_frame), str(last_frame) ) - collection = clique.parse(path) + self.log.info("collection: {}".format(path)) + + try: + collection = clique.parse(path) + + except Exception as e: + self.log.warning(e) + collection = None # Include start and end render frame in label - label = "{subset} ({start}-{end})".format(subset=subset, - start=int(first_frame), - end=int(last_frame)) + name = node.name() - # Create instance - instance = context.create_instance(subset) - instance.add(node) - - # Adding/Checking publish and render target attribute - if "render_local" not in node.knobs(): - knob = nuke.Boolean_Knob("render_local", "Local rendering") - knob.setValue(False) - node.addKnob(knob) + label = "{0} ({1}-{2})".format( + name, + int(first_frame), + int(last_frame) + ) + self.log.debug("checking for error: {}".format(label)) + # # Adding/Checking publish and render target attribute + # if "render_local" not in node.knobs(): + # knob = nuke.Boolean_Knob("render_local", "Local rendering") + # knob.setValue(False) + # node.addKnob(knob) + self.log.debug("checking for error: {}".format(label)) instance.data.update({ - "asset": os.environ["AVALON_ASSET"], "path": nuke.filename(node), "outputDir": os.path.dirname(nuke.filename(node)), "ext": ext, # todo: should be redundant "label": label, - "families": ["render.local"], + "families": ["{}.local".format(instance.data["families"][0])], "collection": collection, "first_frame": first_frame, "last_frame": last_frame, "output_type": output_type }) - def instanceToggled(instance, value): - instance[0]["publish"].setValue(value) + self.log.debug("instance.data: {}".format(instance.data)) - instance.data["instanceToggled"] = instanceToggled - - # Sort/grouped by family (preserving local index) - context[:] = sorted(context, key=self.sort_by_family) - - return context + self.log.debug("context: {}".format(context)) def sort_by_family(self, instance): """Sort by family""" diff --git a/pype/plugins/nuke/publish/validate_collection.py b/pype/plugins/nuke/publish/validate_collection.py new file mode 100644 index 0000000000..4f15b1e495 --- /dev/null +++ b/pype/plugins/nuke/publish/validate_collection.py @@ -0,0 +1,39 @@ +import os +import pyblish.api + + +@pyblish.api.log +class RepairCollectionAction(pyblish.api.Action): + label = "Repair" + on = "failed" + icon = "wrench" + + def process(self, instance, plugin): + self.log.info("this is going to be repaired") + + +class ValidateCollection(pyblish.api.InstancePlugin): + """ Validates file output. """ + + order = pyblish.api.ValidatorOrder + optional = True + families = ["write"] + label = "Check Full Img Sequence" + hosts = ["nuke"] + actions = [RepairCollectionAction] + + def process(self, instance): + + missing_files = [] + for f in instance.data["collection"]: + # print f + if not os.path.exists(f): + missing_files.append(f) + + for f in missing_files: + instance.data["collection"].remove(f) + + frame_length = instance.data["last_frame"] - instance.data["first_frame"] + + assert len(list(instance.data["collection"])) is frame_length, self.log.info( + "{} missing frames. Use repair to render all frames".format(__name__))