Merge branch 'master' of bitbucket.org:pypeclub/pype

This commit is contained in:
Milan Kolar 2019-11-11 11:49:45 +01:00
commit b37586b6b1
6 changed files with 228 additions and 136 deletions

View file

@ -80,17 +80,21 @@ def reload_config():
for module in ( for module in (
"{}.api".format(AVALON_CONFIG), "{}.api".format(AVALON_CONFIG),
"{}.nuke.actions".format(AVALON_CONFIG), "{}.nuke.actions".format(AVALON_CONFIG),
"{}.nuke.templates".format(AVALON_CONFIG), "{}.nuke.presets".format(AVALON_CONFIG),
"{}.nuke.menu".format(AVALON_CONFIG), "{}.nuke.menu".format(AVALON_CONFIG),
"{}.nuke.plugin".format(AVALON_CONFIG),
"{}.nuke.lib".format(AVALON_CONFIG), "{}.nuke.lib".format(AVALON_CONFIG),
): ):
log.info("Reloading module: {}...".format(module)) log.info("Reloading module: {}...".format(module))
module = importlib.import_module(module)
try: try:
module = importlib.import_module(module)
reload(module)
except Exception as e:
log.warning("Cannot reload module: {}".format(e))
importlib.reload(module) importlib.reload(module)
except AttributeError as e:
log.warning("Cannot reload module: {}".format(e))
reload(module)
def install(): def install():

View file

@ -16,7 +16,7 @@ from .presets import (
get_node_colorspace_preset get_node_colorspace_preset
) )
from .templates import ( from .presets import (
get_anatomy get_anatomy
) )
# TODO: remove get_anatomy and import directly Anatomy() here # TODO: remove get_anatomy and import directly Anatomy() here
@ -174,8 +174,13 @@ def format_anatomy(data):
anatomy = get_anatomy() anatomy = get_anatomy()
log.debug("__ anatomy.templates: {}".format(anatomy.templates)) log.debug("__ anatomy.templates: {}".format(anatomy.templates))
# TODO: perhaps should be in try! try:
padding = int(anatomy.templates['render']['padding']) padding = int(anatomy.templates['render']['padding'])
except KeyError as e:
log.error("`padding` key is not in `render` "
"Anatomy template. Please, add it there and restart "
"the pipeline (padding: \"4\"): `{}`".format(e))
version = data.get("version", None) version = data.get("version", None)
if not version: if not version:
file = script_name() file = script_name()
@ -212,12 +217,13 @@ def add_button_write_to_read(node):
node.addKnob(k) node.addKnob(k)
def create_write_node(name, data, prenodes=None): def create_write_node(name, data, input=None, prenodes=None):
''' Creating write node which is group node ''' Creating write node which is group node
Arguments: Arguments:
name (str): name of node name (str): name of node
data (dict): data to be imprinted data (dict): data to be imprinted
input (node): selected node to connect to
prenodes (list, optional): list of lists, definitions for nodes prenodes (list, optional): list of lists, definitions for nodes
to be created before write to be created before write
@ -229,9 +235,9 @@ def create_write_node(name, data, prenodes=None):
("knobName", "knobValue"), ("knobName", "knobValue"),
("knobName", "knobValue") ("knobName", "knobValue")
), ),
( # list inputs ( # list outputs
"firstPrevNodeName", "firstPostNodeName",
"secondPrevNodeName" "secondPostNodeName"
) )
) )
] ]
@ -273,28 +279,44 @@ def create_write_node(name, data, prenodes=None):
}) })
# adding dataflow template # adding dataflow template
log.debug("nuke_dataflow_writes: `{}`".format(nuke_dataflow_writes))
{_data.update({k: v}) {_data.update({k: v})
for k, v in nuke_dataflow_writes.items() for k, v in nuke_dataflow_writes.items()
if k not in ["_id", "_previous"]} if k not in ["_id", "_previous"]}
# adding dataflow template # adding colorspace template
log.debug("nuke_colorspace_writes: `{}`".format(nuke_colorspace_writes))
{_data.update({k: v}) {_data.update({k: v})
for k, v in nuke_colorspace_writes.items()} for k, v in nuke_colorspace_writes.items()}
_data = avalon.nuke.lib.fix_data_for_node_create(_data) _data = avalon.nuke.lib.fix_data_for_node_create(_data)
log.debug(_data) log.debug("_data: `{}`".format(_data))
_data["frame_range"] = data.get("frame_range", None) if "frame_range" in data.keys():
_data["frame_range"] = data.get("frame_range", None)
log.debug("_data[frame_range]: `{}`".format(_data["frame_range"]))
# todo: hange this to new way
GN = nuke.createNode("Group", "name {}".format(name)) GN = nuke.createNode("Group", "name {}".format(name))
prev_node = None prev_node = None
with GN: with GN:
connections = list()
if input:
# if connected input node was defined
connections.append({
"node": input,
"inputName": input.name()})
prev_node = nuke.createNode(
"Input", "name {}".format(input.name()))
else:
# generic input node connected to nothing
prev_node = nuke.createNode(
"Input", "name {}".format("rgba"))
# creating pre-write nodes `prenodes` # creating pre-write nodes `prenodes`
if prenodes: if prenodes:
for name, klass, properties, set_input_to in prenodes: for name, klass, properties, set_output_to in prenodes:
# create node # create node
now_node = nuke.createNode(klass, "name {}".format(name)) now_node = nuke.createNode(klass, "name {}".format(name))
@ -304,34 +326,41 @@ def create_write_node(name, data, prenodes=None):
now_node[k].serValue(str(v)) now_node[k].serValue(str(v))
# connect to previous node # connect to previous node
if set_input_to: if set_output_to:
if isinstance(set_input_to, (tuple or list)): if isinstance(set_output_to, (tuple or list)):
for i, node_name in enumerate(set_input_to): for i, node_name in enumerate(set_output_to):
input_node = nuke.toNode(node_name) input_node = nuke.createNode(
"Input", "name {}".format(node_name))
connections.append({
"node": nuke.toNode(node_name),
"inputName": node_name})
now_node.setInput(1, input_node) now_node.setInput(1, input_node)
elif isinstance(set_input_to, str): elif isinstance(set_output_to, str):
input_node = nuke.toNode(set_input_to) input_node = nuke.createNode(
"Input", "name {}".format(node_name))
connections.append({
"node": nuke.toNode(set_output_to),
"inputName": set_output_to})
now_node.setInput(0, input_node) now_node.setInput(0, input_node)
else: else:
now_node.setInput(0, prev_node) now_node.setInput(0, prev_node)
# swith actual node to previous # swith actual node to previous
prev_node = now_node prev_node = now_node
else:
prev_node = nuke.createNode("Input", "name rgba")
# creating write node # creating write node
now_node = avalon.nuke.lib.add_write_node("inside_{}".format(name), write_node = now_node = avalon.nuke.lib.add_write_node(
**_data "inside_{}".format(name),
) **_data
write_node = now_node )
# connect to previous node # connect to previous node
now_node.setInput(0, prev_node) now_node.setInput(0, prev_node)
# swith actual node to previous # swith actual node to previous
prev_node = now_node prev_node = now_node
now_node = nuke.createNode("Output", "name write") now_node = nuke.createNode("Output", "name Output1")
# connect to previous node # connect to previous node
now_node.setInput(0, prev_node) now_node.setInput(0, prev_node)

14
pype/nuke/plugin.py Normal file
View file

@ -0,0 +1,14 @@
import re
import avalon.api
import avalon.nuke
from pype import api as pype
from pypeapp import config
class PypeCreator(avalon.nuke.pipeline.Creator):
"""Pype Nuke Creator class wrapper
"""
def __init__(self, *args, **kwargs):
super(PypeCreator, self).__init__(*args, **kwargs)
self.presets = config.get_presets()['plugins']["nuke"]["create"].get(
self.__class__.__name__, {}
)

View file

@ -39,8 +39,9 @@ def get_node_dataflow_preset(**kwarg):
nuke_dataflow_node = nuke_dataflow_node.get(str(preset), None) nuke_dataflow_node = nuke_dataflow_node.get(str(preset), None)
# omit < 2.0.0v # omit < 2.0.0v
for family in families: if families:
nuke_dataflow_node = nuke_dataflow_node.get(str(family), None) for family in families:
nuke_dataflow_node = nuke_dataflow_node.get(str(family), None)
log.info("Dataflow: {}".format(nuke_dataflow_node)) log.info("Dataflow: {}".format(nuke_dataflow_node))
return nuke_dataflow_node return nuke_dataflow_node
@ -52,14 +53,22 @@ def get_node_colorspace_preset(**kwarg):
log.info(kwarg) log.info(kwarg)
host = kwarg.get("host", "nuke") host = kwarg.get("host", "nuke")
cls = kwarg.get("class", None) cls = kwarg.get("class", None)
preset = kwarg.get("preset", None) families = kwarg.get("families", [])
preset = kwarg.get("preset", None) # omit < 2.0.0v
assert any([host, cls]), log.error( assert any([host, cls]), log.error(
"`{}`: Missing mandatory kwargs `host`, `cls`".format(__file__)) "`{}`: Missing mandatory kwargs `host`, `cls`".format(__file__))
nuke_colorspace = get_colorspace_preset().get(str(host), None) nuke_colorspace = get_colorspace_preset().get(str(host), None)
nuke_colorspace_node = nuke_colorspace.get(str(cls), None) nuke_colorspace_node = nuke_colorspace.get(str(cls), None)
if preset:
if preset: # omit < 2.0.0v
nuke_colorspace_node = nuke_colorspace_node.get(str(preset), None) nuke_colorspace_node = nuke_colorspace_node.get(str(preset), None)
# omit < 2.0.0v
if families:
for family in families:
nuke_colorspace_node = nuke_colorspace_node.get(str(family), None)
log.info("Colorspace: {}".format(nuke_colorspace_node)) log.info("Colorspace: {}".format(nuke_colorspace_node))
return nuke_colorspace_node return nuke_colorspace_node

View file

@ -1,8 +1,8 @@
from collections import OrderedDict from collections import OrderedDict
import avalon.api import avalon.api
import avalon.nuke import avalon.nuke
from pype.nuke.lib import create_write_node
from pype import api as pype from pype import api as pype
from pype.nuke import plugin
from pypeapp import config from pypeapp import config
import nuke import nuke
@ -11,135 +11,167 @@ import nuke
log = pype.Logger().get_logger(__name__, "nuke") log = pype.Logger().get_logger(__name__, "nuke")
def subset_to_families(subset, family, families): class CreateWriteRender(plugin.PypeCreator):
subset_sufx = str(subset).replace(family, "")
new_subset = families + subset_sufx
return "{}.{}".format(family, new_subset)
class CreateWriteRender(avalon.nuke.Creator):
# change this to template preset # change this to template preset
preset = "render"
name = "WriteRender" name = "WriteRender"
label = "Create Write Render" label = "Create Write Render"
hosts = ["nuke"] hosts = ["nuke"]
family = "{}_write".format(preset) nClass = "write"
families = preset family = "render"
icon = "sign-out" icon = "sign-out"
defaults = ["Main", "Mask"] defaults = ["Main", "Mask"]
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(CreateWriteRender, self).__init__(*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"] self.name = self.data["subset"]
data = OrderedDict() data = OrderedDict()
data["family"] = self.family.split("_")[-1] data["family"] = self.nClass
data["families"] = self.families data["families"] = self.family
for k, v in self.data.items():
if k not in data.keys():
data.update({k: v})
{data.update({k: v}) for k, v in self.data.items()
if k not in data.keys()}
self.data = data self.data = data
self.log.info("self.data: '{}'".format(self.data))
def process(self): def process(self):
from pype.nuke import lib as pnlib
reload(pnlib)
family = self.family inputs = []
node = 'write' outputs = []
instance = nuke.toNode(self.data["subset"]) instance = nuke.toNode(self.data["subset"])
selected_node = None
if not instance: # use selection
write_data = { if (self.options or {}).get("useSelection"):
"class": node, nodes = nuke.selectedNodes()
"preset": self.preset,
"avalon": self.data
}
if self.presets.get('fpath_template'): assert len(nodes) == 1, self.log.error("Select only one node. The node you want to connect to, or tick off `Use selection`")
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/nuke/{subset}/{subset}.{frame}.{ext}"})
return create_write_node(self.data["subset"], write_data) selected_node = nodes[0]
inputs = [selected_node]
outputs = selected_node.dependent()
if instance:
if (instance.name() in selected_node.name()):
selected_node = instance.dependencies()[0]
class CreateWritePrerender(avalon.nuke.Creator): # if node already exist
# change this to template preset if instance:
preset = "prerender" # collect input / outputs
inputs = instance.dependencies()
outputs = instance.dependent()
selected_node = inputs[0]
# remove old one
nuke.delete(instance)
name = "WritePrerender" # recreate new
label = "Create Write Prerender" write_data = {
hosts = ["nuke"] "class": self.nClass,
family = "{}_write".format(preset) "families": [self.family],
families = preset "avalon": self.data
icon = "sign-out" }
defaults = ["Main", "Mask"]
def __init__(self, *args, **kwargs): if self.presets.get('fpath_template'):
super(CreateWritePrerender, self).__init__(*args, **kwargs) self.log.info("Adding template path from preset")
self.presets = config.get_presets()['plugins']["nuke"]["create"].get( write_data.update(
self.__class__.__name__, {} {"fpath_template": self.presets["fpath_template"]}
) )
else:
self.log.info("Adding template path from plugin")
write_data.update({
"fpath_template": "{work}/renders/nuke/{subset}/{subset}.{frame}.{ext}"})
data = OrderedDict() write_node = pnlib.create_write_node(
self.data["subset"],
write_data,
input=selected_node)
data["family"] = self.family.split("_")[1] # relinking to collected connections
data["families"] = self.families for i, input in enumerate(inputs):
write_node.setInput(i, input)
{data.update({k: v}) for k, v in self.data.items() write_node.autoplace()
if k not in data.keys()}
self.data = data
def process(self): for output in outputs:
self.name = self.data["subset"] output.setInput(0, write_node)
instance = nuke.toNode(self.data["subset"]) return True
node = 'write'
if not instance: #
write_data = { # class CreateWritePrerender(avalon.nuke.Creator):
"class": node, # # change this to template preset
"preset": self.preset, # preset = "prerender"
"avalon": self.data #
} # name = "WritePrerender"
# label = "Create Write Prerender"
if self.presets.get('fpath_template'): # hosts = ["nuke"]
self.log.info("Adding template path from preset") # family = "{}_write".format(preset)
write_data.update( # families = preset
{"fpath_template": self.presets["fpath_template"]} # icon = "sign-out"
) # defaults = ["Main", "Mask"]
else: #
self.log.info("Adding template path from plugin") # def __init__(self, *args, **kwargs):
write_data.update({ # super(CreateWritePrerender, self).__init__(*args, **kwargs)
"fpath_template": "{work}/prerenders/{subset}/{subset}.{frame}.{ext}"}) # self.presets = config.get_presets()['plugins']["nuke"]["create"].get(
# self.__class__.__name__, {}
# get group node # )
group_node = create_write_node(self.data["subset"], write_data) #
# data = OrderedDict()
# open group node #
group_node.begin() # data["family"] = self.family.split("_")[1]
for n in nuke.allNodes(): # data["families"] = self.families
# get write node #
if n.Class() in "Write": # {data.update({k: v}) for k, v in self.data.items()
write_node = n # if k not in data.keys()}
group_node.end() # self.data = data
#
# linking knobs to group property panel # def process(self):
linking_knobs = ["first", "last", "use_limit"] # self.name = self.data["subset"]
for k in linking_knobs: #
lnk = nuke.Link_Knob(k) # instance = nuke.toNode(self.data["subset"])
lnk.makeLink(write_node.name(), k) # node = 'write'
lnk.setName(k.replace('_', ' ').capitalize()) #
lnk.clearFlag(nuke.STARTLINE) # if not instance:
group_node.addKnob(lnk) # write_data = {
# "class": node,
return # "preset": self.preset,
# "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}"})
#
# # get group node
# group_node = create_write_node(self.data["subset"], write_data)
#
# # open group node
# group_node.begin()
# for n in nuke.allNodes():
# # get write node
# if n.Class() in "Write":
# write_node = n
# group_node.end()
#
# # 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)
# group_node.addKnob(lnk)
#
# return

View file

@ -38,7 +38,7 @@ def evaluate_filepath_new(k_value, k_eval, project_dir, first_frame):
filepath = os.path.abspath(filepath) filepath = os.path.abspath(filepath)
except Exception as E: except Exception as E:
log.error("Cannot create Read node. Perhaps it needs to be rendered first :) Error: `{}`".format(E)) log.error("Cannot create Read node. Perhaps it needs to be rendered first :) Error: `{}`".format(E))
return return None
filepath = filepath.replace('\\', '/') filepath = filepath.replace('\\', '/')
current_frame = re.findall(r'\d+', filepath)[-1] current_frame = re.findall(r'\d+', filepath)[-1]
@ -114,12 +114,16 @@ def write_to_read(gn):
n = group_writes[0] n = group_writes[0]
if n.knob('file') is not None: if n.knob('file') is not None:
myfiletranslated, firstFrame, lastFrame = evaluate_filepath_new( file_path_new = evaluate_filepath_new(
n.knob('file').getValue(), n.knob('file').getValue(),
n.knob('file').evaluate(), n.knob('file').evaluate(),
project_dir, project_dir,
comp_start comp_start
) )
if not file_path_new:
return
myfiletranslated, firstFrame, lastFrame = file_path_new
# get node data # get node data
ndata = { ndata = {
'filepath': myfiletranslated, 'filepath': myfiletranslated,