From 3f6af490d6fab1e27aeeb7c9d2ceed37deb56bb6 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Mon, 29 Jul 2019 20:47:01 +0200 Subject: [PATCH] feat(nuke): make publishable write node as group node with imprinted data and linked properties on panel --- pype/nuke/lib.py | 127 +++++++++++++++++++++-- pype/plugins/nuke/create/create_write | 17 --- pype/plugins/nuke/create/create_write.py | 81 ++++++--------- 3 files changed, 145 insertions(+), 80 deletions(-) delete mode 100644 pype/plugins/nuke/create/create_write diff --git a/pype/nuke/lib.py b/pype/nuke/lib.py index f6f6767163..87cff9bc72 100644 --- a/pype/nuke/lib.py +++ b/pype/nuke/lib.py @@ -18,6 +18,7 @@ log = Logger().get_logger(__name__, "nuke") self = sys.modules[__name__] self._project = None + def onScriptLoad(): if nuke.env['LINUX']: nuke.tcl('load ffmpegReader') @@ -102,6 +103,9 @@ def writes_version_sync(): node_new_file = node_file.replace(node_version, new_version) each['file'].setValue(node_new_file) + if not os.path.isdir(os.path.dirname(node_new_file)): + log.info("path does not exist") + os.makedirs(os.path.dirname(node_new_file), 0o766) except Exception as e: log.debug( "Write node: `{}` has no version in path: {}".format(each.name(), e)) @@ -172,7 +176,32 @@ def script_name(): return nuke.root().knob('name').value() -def create_write_node(name, data): +def create_write_node(name, data, prenodes=None): + '''Creating write node which is group node + + Arguments: + name (str): name of node + data (dict): data to be imprinted + prenodes (list, optional): list of lists, definitions for nodes + to be created before write + + Example: + prenodes = [( + "NameNode", # string + "NodeClass", # string + ( # OrderDict: knob and values pairs + ("knobName", "knobValue"), + ("knobName", "knobValue") + ), + ( # list inputs + "firstPrevNodeName", + "secondPrevNodeName" + ) + ) + ] + + ''' + nuke_dataflow_writes = get_node_dataflow_preset(**data) nuke_colorspace_writes = get_node_colorspace_preset(**data) application = lib.get_application(os.environ["AVALON_APP_NAME"]) @@ -191,7 +220,7 @@ def create_write_node(name, data): # build file path to workfiles fpath = str(anatomy_filled["work"]["folder"]).replace("\\", "/") - fpath = '{work}/renders/v{version}/{subset}.{frame}.{ext}'.format( + fpath = data["fpath_template"].format( work=fpath, version=data["version"], subset=data["subset"], frame=data["frame"], ext=data["nuke_dataflow_writes"]["file_type"]) @@ -219,14 +248,89 @@ def create_write_node(name, data): log.debug(_data) _data["frame_range"] = data.get("frame_range", None) - log.info("__ _data3: {}".format(_data)) - instance = avalon.nuke.lib.add_write_node( - name, - **_data - ) - instance = avalon.nuke.lib.imprint(instance, data["avalon"]) - add_rendering_knobs(instance) - return instance + + # todo: hange this to new way + GN = nuke.createNode("Group", "name {}".format(name)) + + prev_node = None + with GN: + # creating pre-write nodes `prenodes` + if prenodes: + for name, klass, properties, set_input_to in prenodes: + # create node + now_node = nuke.createNode(klass, "name {}".format(name)) + + # add data to knob + for k, v in properties: + if k and v: + now_node[k].serValue(str(v)) + + # connect to previous node + if set_input_to: + if isinstance(set_input_to, (tuple or list)): + for i, node_name in enumerate(set_input_to): + input_node = nuke.toNode(node_name) + now_node.setInput(1, input_node) + elif isinstance(set_input_to, str): + input_node = nuke.toNode(set_input_to) + now_node.setInput(0, input_node) + else: + now_node.setInput(0, prev_node) + + # swith actual node to previous + prev_node = now_node + else: + prev_node = nuke.createNode("Input", "name rgba") + + + # creating write node + now_node = avalon.nuke.lib.add_write_node("inside_{}".format(name), + **_data + ) + write_node = now_node + # connect to previous node + now_node.setInput(0, prev_node) + + # swith actual node to previous + prev_node = now_node + + now_node = nuke.createNode("Output", "name write") + + # connect to previous node + now_node.setInput(0, prev_node) + + # imprinting group node + GN = avalon.nuke.imprint(GN, data["avalon"]) + + divider = nuke.Text_Knob('') + GN.addKnob(divider) + + add_rendering_knobs(GN) + + divider = nuke.Text_Knob('') + GN.addKnob(divider) + + # set tile color + tile_color = _data.get("tile_color", "0xff0000ff") + GN["tile_color"].setValue(tile_color) + + + # add render button + lnk = nuke.Link_Knob("Render") + lnk.makeLink(write_node.name(), "Render") + lnk.setName("Render") + GN.addKnob(lnk) + + # linking knobs to group property panel + linking_knobs = ["first", "last", "use_limit"] + for k in linking_knobs: + lnk = nuke.Link_Knob(k) + lnk.makeLink(write_node.name(), k) + lnk.setName(k.replace('_', ' ').capitalize()) + lnk.clearFlag(nuke.STARTLINE) + GN.addKnob(lnk) + + return GN def add_rendering_knobs(node): @@ -431,7 +535,8 @@ def reset_resolution(): log.info("pixel_aspect: {}".format(pixel_aspect)) if any(not x for x in [width, height, pixel_aspect]): - log.error("Missing set shot attributes in DB. \nContact your supervisor!. \n\nWidth: `{0}` \nHeight: `{1}` \nPixel Asspect: `{2}`".format(width, height, pixel_aspect)) + log.error("Missing set shot attributes in DB. \nContact your supervisor!. \n\nWidth: `{0}` \nHeight: `{1}` \nPixel Asspect: `{2}`".format( + width, height, pixel_aspect)) return bbox = asset.get('data', {}).get('crop') diff --git a/pype/plugins/nuke/create/create_write b/pype/plugins/nuke/create/create_write deleted file mode 100644 index dcb132875a..0000000000 --- a/pype/plugins/nuke/create/create_write +++ /dev/null @@ -1,17 +0,0 @@ -# type: render -# if no render type node in script then first is having in name [master] for definition of main script renderer -# colorspace setting from templates -# dataflow setting from templates - -# type: mask_render -# created with shuffle gizmo for RGB separation into davinci matte -# colorspace setting from templates -# dataflow setting from templates - -# type: prerender -# backdrop with write and read -# colorspace setting from templates -# dataflow setting from templates - -# type: geo -# dataflow setting from templates diff --git a/pype/plugins/nuke/create/create_write.py b/pype/plugins/nuke/create/create_write.py index ff1fde6638..6d325ab259 100644 --- a/pype/plugins/nuke/create/create_write.py +++ b/pype/plugins/nuke/create/create_write.py @@ -5,7 +5,7 @@ from pype.nuke import ( create_write_node ) from pype import api as pype -# from pypeapp import Logger +from pypeapp import config import nuke @@ -33,6 +33,11 @@ class CreateWriteRender(avalon.nuke.Creator): def __init__(self, *args, **kwargs): super(CreateWriteRender, self).__init__(*args, **kwargs) + self.presets = config.get_presets()['plugins']["nuke"]["create"].get( + self.__class__.__name__, {} + ) + + self.name = self.data["subset"] data = OrderedDict() @@ -44,7 +49,6 @@ class CreateWriteRender(avalon.nuke.Creator): self.data = data def process(self): - self.name = self.data["subset"] family = self.family node = 'write' @@ -58,6 +62,16 @@ class CreateWriteRender(avalon.nuke.Creator): "avalon": self.data } + if self.presets.get('fpath_template'): + self.log.info("Adding template path from preset") + write_data.update( + {"fpath_template": self.presets["fpath_template"]} + ) + else: + self.log.info("Adding template path from plugin") + write_data.update({ + "fpath_template": "{work}/renders/v{version}/{subset}.{frame}.{ext}"}) + create_write_node(self.data["subset"], write_data) return @@ -77,6 +91,9 @@ class CreateWritePrerender(avalon.nuke.Creator): def __init__(self, *args, **kwargs): super(CreateWritePrerender, self).__init__(*args, **kwargs) + self.presets = config.get_presets()['plugins']["nuke"]["create"].get( + self.__class__.__name__, {} + ) data = OrderedDict() @@ -100,56 +117,16 @@ class CreateWritePrerender(avalon.nuke.Creator): "avalon": self.data } + if self.presets.get('fpath_template'): + self.log.info("Adding template path from preset") + write_data.update( + {"fpath_template": self.presets["fpath_template"]} + ) + else: + self.log.info("Adding template path from plugin") + write_data.update({ + "fpath_template": "{work}/prerenders/{subset}/{subset}.{frame}.{ext}"}) + create_write_node(self.data["subset"], write_data) return - - -""" -class CrateWriteStill(avalon.nuke.Creator): - # change this to template preset - preset = "still" - - name = "WriteStill" - label = "Create Write Still" - hosts = ["nuke"] - family = "{}_write".format(preset) - families = preset - icon = "image" - - def __init__(self, *args, **kwargs): - super(CrateWriteStill, self).__init__(*args, **kwargs) - - data = OrderedDict() - - data["family"] = self.family.split("_")[-1] - data["families"] = self.families - - {data.update({k: v}) for k, v in self.data.items() - if k not in data.keys()} - self.data = data - - def process(self): - self.name = self.data["subset"] - - node_name = self.data["subset"].replace( - "_", "_f{}_".format(nuke.frame())) - instance = nuke.toNode(self.data["subset"]) - self.data["subset"] = node_name - - family = self.family - node = 'write' - - if not instance: - write_data = { - "frame_range": [nuke.frame(), nuke.frame()], - "class": node, - "preset": self.preset, - "avalon": self.data - } - - nuke.createNode("FrameHold", "first_frame {}".format(nuke.frame())) - create_write_node(node_name, write_data) - - return -"""