mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-24 21:04:40 +01:00
Merge pull request #494 from tokejepsen/2.x/feature/nuke_build_workfile
Revamp Build Workfile in Nuke.
This commit is contained in:
commit
297fcdc8da
2 changed files with 21 additions and 315 deletions
|
|
@ -1,7 +1,6 @@
|
|||
import os
|
||||
import re
|
||||
import sys
|
||||
import getpass
|
||||
from collections import OrderedDict
|
||||
|
||||
from avalon import api, io, lib
|
||||
|
|
@ -1060,310 +1059,6 @@ def get_write_node_template_attr(node):
|
|||
return avalon.nuke.lib.fix_data_for_node_create(correct_data)
|
||||
|
||||
|
||||
class BuildWorkfile(WorkfileSettings):
|
||||
"""
|
||||
Building first version of workfile.
|
||||
|
||||
Settings are taken from presets and db. It will add all subsets
|
||||
in last version for defined representaions
|
||||
|
||||
Arguments:
|
||||
variable (type): description
|
||||
|
||||
"""
|
||||
xpos = 0
|
||||
ypos = 0
|
||||
xpos_size = 80
|
||||
ypos_size = 90
|
||||
xpos_gap = 50
|
||||
ypos_gap = 50
|
||||
pos_layer = 10
|
||||
|
||||
def __init__(self,
|
||||
root_path=None,
|
||||
root_node=None,
|
||||
nodes=None,
|
||||
to_script=None,
|
||||
**kwargs):
|
||||
"""
|
||||
A short description.
|
||||
|
||||
A bit longer description.
|
||||
|
||||
Argumetns:
|
||||
root_path (str): description
|
||||
root_node (nuke.Node): description
|
||||
nodes (list): list of nuke.Node
|
||||
nodes_effects (dict): dictionary with subsets
|
||||
|
||||
Example:
|
||||
nodes_effects = {
|
||||
"plateMain": {
|
||||
"nodes": [
|
||||
[("Class", "Reformat"),
|
||||
("resize", "distort"),
|
||||
("flip", True)],
|
||||
|
||||
[("Class", "Grade"),
|
||||
("blackpoint", 0.5),
|
||||
("multiply", 0.4)]
|
||||
]
|
||||
},
|
||||
}
|
||||
|
||||
"""
|
||||
|
||||
WorkfileSettings.__init__(self,
|
||||
root_node=root_node,
|
||||
nodes=nodes,
|
||||
**kwargs)
|
||||
self.to_script = to_script
|
||||
# collect data for formating
|
||||
self.data_tmp = {
|
||||
"project": {"name": self._project["name"],
|
||||
"code": self._project["data"].get("code", "")},
|
||||
"asset": self._asset or os.environ["AVALON_ASSET"],
|
||||
"task": kwargs.get("task") or api.Session["AVALON_TASK"],
|
||||
"hierarchy": kwargs.get("hierarchy") or pype.get_hierarchy(),
|
||||
"version": kwargs.get("version", {}).get("name", 1),
|
||||
"user": getpass.getuser(),
|
||||
"comment": "firstBuild",
|
||||
"ext": "nk"
|
||||
}
|
||||
|
||||
# get presets from anatomy
|
||||
anatomy = get_anatomy()
|
||||
# format anatomy
|
||||
anatomy_filled = anatomy.format(self.data_tmp)
|
||||
|
||||
# get dir and file for workfile
|
||||
self.work_dir = anatomy_filled["work"]["folder"]
|
||||
self.work_file = anatomy_filled["work"]["file"]
|
||||
|
||||
def save_script_as(self, path=None):
|
||||
# first clear anything in open window
|
||||
nuke.scriptClear()
|
||||
|
||||
if not path:
|
||||
dir = self.work_dir
|
||||
path = os.path.join(
|
||||
self.work_dir,
|
||||
self.work_file).replace("\\", "/")
|
||||
else:
|
||||
dir = os.path.dirname(path)
|
||||
|
||||
# check if folder is created
|
||||
if not os.path.exists(dir):
|
||||
os.makedirs(dir)
|
||||
|
||||
# save script to path
|
||||
nuke.scriptSaveAs(path)
|
||||
|
||||
def process(self,
|
||||
regex_filter=None,
|
||||
version=None,
|
||||
representations=["exr", "dpx", "lutJson", "mov",
|
||||
"preview", "png", "jpeg", "jpg"]):
|
||||
"""
|
||||
A short description.
|
||||
|
||||
A bit longer description.
|
||||
|
||||
Args:
|
||||
regex_filter (raw string): regex pattern to filter out subsets
|
||||
version (int): define a particular version, None gets last
|
||||
representations (list):
|
||||
|
||||
Returns:
|
||||
type: description
|
||||
|
||||
Raises:
|
||||
Exception: description
|
||||
|
||||
"""
|
||||
|
||||
if not self.to_script:
|
||||
# save the script
|
||||
self.save_script_as()
|
||||
|
||||
# create viewer and reset frame range
|
||||
viewer = self.get_nodes(nodes_filter=["Viewer"])
|
||||
if not viewer:
|
||||
vn = nuke.createNode("Viewer")
|
||||
vn["xpos"].setValue(self.xpos)
|
||||
vn["ypos"].setValue(self.ypos)
|
||||
else:
|
||||
vn = viewer[-1]
|
||||
|
||||
# move position
|
||||
self.position_up()
|
||||
|
||||
wn = self.write_create()
|
||||
wn["xpos"].setValue(self.xpos)
|
||||
wn["ypos"].setValue(self.ypos)
|
||||
wn["render"].setValue(True)
|
||||
vn.setInput(0, wn)
|
||||
|
||||
# adding backdrop under write
|
||||
self.create_backdrop(label="Render write \n\n\n\nOUTPUT",
|
||||
color='0xcc1102ff', layer=-1,
|
||||
nodes=[wn])
|
||||
|
||||
# move position
|
||||
self.position_up(4)
|
||||
|
||||
# set frame range for new viewer
|
||||
self.reset_frame_range_handles()
|
||||
|
||||
# get all available representations
|
||||
subsets = pype.get_subsets(self._asset,
|
||||
regex_filter=regex_filter,
|
||||
version=version,
|
||||
representations=representations)
|
||||
|
||||
for name, subset in subsets.items():
|
||||
log.debug("___________________")
|
||||
log.debug(name)
|
||||
log.debug(subset["version"])
|
||||
|
||||
nodes_backdrop = list()
|
||||
for name, subset in subsets.items():
|
||||
if "lut" in name:
|
||||
continue
|
||||
log.info("Building Loader to: `{}`".format(name))
|
||||
version = subset["version"]
|
||||
log.info("Version to: `{}`".format(version["name"]))
|
||||
representations = subset["representaions"]
|
||||
for repr in representations:
|
||||
rn = self.read_loader(repr)
|
||||
rn["xpos"].setValue(self.xpos)
|
||||
rn["ypos"].setValue(self.ypos)
|
||||
wn.setInput(0, rn)
|
||||
|
||||
# get editional nodes
|
||||
lut_subset = [s for n, s in subsets.items()
|
||||
if "lut{}".format(name.lower()) in n.lower()]
|
||||
log.debug(">> lut_subset: `{}`".format(lut_subset))
|
||||
|
||||
if len(lut_subset) > 0:
|
||||
lsub = lut_subset[0]
|
||||
fxn = self.effect_loader(lsub["representaions"][-1])
|
||||
fxn_ypos = fxn["ypos"].value()
|
||||
fxn["ypos"].setValue(fxn_ypos - 100)
|
||||
nodes_backdrop.append(fxn)
|
||||
|
||||
nodes_backdrop.append(rn)
|
||||
# move position
|
||||
self.position_right()
|
||||
|
||||
# adding backdrop under all read nodes
|
||||
self.create_backdrop(label="Loaded Reads",
|
||||
color='0x2d7702ff', layer=-1,
|
||||
nodes=nodes_backdrop)
|
||||
|
||||
def read_loader(self, representation):
|
||||
"""
|
||||
Gets Loader plugin for image sequence or mov
|
||||
|
||||
Arguments:
|
||||
representation (dict): avalon db entity
|
||||
|
||||
"""
|
||||
context = representation["context"]
|
||||
|
||||
loader_name = "LoadSequence"
|
||||
if "mov" in context["representation"]:
|
||||
loader_name = "LoadMov"
|
||||
|
||||
loader_plugin = None
|
||||
for Loader in api.discover(api.Loader):
|
||||
if Loader.__name__ != loader_name:
|
||||
continue
|
||||
|
||||
loader_plugin = Loader
|
||||
|
||||
return api.load(Loader=loader_plugin,
|
||||
representation=representation["_id"])
|
||||
|
||||
def effect_loader(self, representation):
|
||||
"""
|
||||
Gets Loader plugin for effects
|
||||
|
||||
Arguments:
|
||||
representation (dict): avalon db entity
|
||||
|
||||
"""
|
||||
loader_name = "LoadLuts"
|
||||
|
||||
loader_plugin = None
|
||||
for Loader in api.discover(api.Loader):
|
||||
if Loader.__name__ != loader_name:
|
||||
continue
|
||||
|
||||
loader_plugin = Loader
|
||||
|
||||
return api.load(Loader=loader_plugin,
|
||||
representation=representation["_id"])
|
||||
|
||||
def write_create(self):
|
||||
"""
|
||||
Create render write
|
||||
|
||||
Arguments:
|
||||
representation (dict): avalon db entity
|
||||
|
||||
"""
|
||||
task = self.data_tmp["task"]
|
||||
sanitized_task = re.sub('[^0-9a-zA-Z]+', '', task)
|
||||
subset_name = "render{}Main".format(
|
||||
sanitized_task.capitalize())
|
||||
|
||||
Create_name = "CreateWriteRender"
|
||||
|
||||
creator_plugin = None
|
||||
for Creator in api.discover(api.Creator):
|
||||
if Creator.__name__ != Create_name:
|
||||
continue
|
||||
|
||||
creator_plugin = Creator
|
||||
|
||||
# return api.create()
|
||||
return creator_plugin(subset_name, self._asset).process()
|
||||
|
||||
def create_backdrop(self, label="", color=None, layer=0,
|
||||
nodes=None):
|
||||
"""
|
||||
Create Backdrop node
|
||||
|
||||
Arguments:
|
||||
color (str): nuke compatible string with color code
|
||||
layer (int): layer of node usually used (self.pos_layer - 1)
|
||||
label (str): the message
|
||||
nodes (list): list of nodes to be wrapped into backdrop
|
||||
|
||||
"""
|
||||
assert isinstance(nodes, list), "`nodes` should be a list of nodes"
|
||||
layer = self.pos_layer + layer
|
||||
|
||||
create_backdrop(label=label, color=color, layer=layer, nodes=nodes)
|
||||
|
||||
def position_reset(self, xpos=0, ypos=0):
|
||||
self.xpos = xpos
|
||||
self.ypos = ypos
|
||||
|
||||
def position_right(self, multiply=1):
|
||||
self.xpos += (self.xpos_size * multiply) + self.xpos_gap
|
||||
|
||||
def position_left(self, multiply=1):
|
||||
self.xpos -= (self.xpos_size * multiply) + self.xpos_gap
|
||||
|
||||
def position_down(self, multiply=1):
|
||||
self.ypos -= (self.ypos_size * multiply) + self.ypos_gap
|
||||
|
||||
def position_up(self, multiply=1):
|
||||
self.ypos -= (self.ypos_size * multiply) + self.ypos_gap
|
||||
|
||||
|
||||
class ExporterReview:
|
||||
"""
|
||||
Base class object for generating review data from Nuke
|
||||
|
|
|
|||
|
|
@ -2,10 +2,12 @@ import nuke
|
|||
from avalon.api import Session
|
||||
|
||||
from pype.hosts.nuke import lib
|
||||
from ...lib import BuildWorkfile
|
||||
from pype.api import Logger
|
||||
|
||||
log = Logger().get_logger(__name__, "nuke")
|
||||
|
||||
|
||||
def install():
|
||||
menubar = nuke.menu("Nuke")
|
||||
menu = menubar.findItem(Session["AVALON_LABEL"])
|
||||
|
|
@ -20,7 +22,11 @@ def install():
|
|||
log.debug("Changing Item: {}".format(rm_item))
|
||||
# rm_item[1].setEnabled(False)
|
||||
menu.removeItem(rm_item[1].name())
|
||||
menu.addCommand(new_name, lambda: workfile_settings().reset_resolution(), index=(rm_item[0]))
|
||||
menu.addCommand(
|
||||
new_name,
|
||||
lambda: workfile_settings().reset_resolution(),
|
||||
index=(rm_item[0])
|
||||
)
|
||||
|
||||
# replace reset frame range from avalon core to pype's
|
||||
name = "Reset Frame Range"
|
||||
|
|
@ -31,33 +37,38 @@ def install():
|
|||
log.debug("Changing Item: {}".format(rm_item))
|
||||
# rm_item[1].setEnabled(False)
|
||||
menu.removeItem(rm_item[1].name())
|
||||
menu.addCommand(new_name, lambda: workfile_settings().reset_frame_range_handles(), index=(rm_item[0]))
|
||||
menu.addCommand(
|
||||
new_name,
|
||||
lambda: workfile_settings().reset_frame_range_handles(),
|
||||
index=(rm_item[0])
|
||||
)
|
||||
|
||||
# add colorspace menu item
|
||||
name = "Set colorspace"
|
||||
name = "Set Colorspace"
|
||||
menu.addCommand(
|
||||
name, lambda: workfile_settings().set_colorspace(),
|
||||
index=(rm_item[0]+2)
|
||||
index=(rm_item[0] + 2)
|
||||
)
|
||||
log.debug("Adding menu item: {}".format(name))
|
||||
|
||||
# add workfile builder menu item
|
||||
name = "Build First Workfile.."
|
||||
name = "Build Workfile"
|
||||
menu.addCommand(
|
||||
name, lambda: lib.BuildWorkfile().process(),
|
||||
index=(rm_item[0]+7)
|
||||
name, lambda: BuildWorkfile().process(),
|
||||
index=(rm_item[0] + 7)
|
||||
)
|
||||
log.debug("Adding menu item: {}".format(name))
|
||||
|
||||
# add item that applies all setting above
|
||||
name = "Apply all settings"
|
||||
name = "Apply All Settings"
|
||||
menu.addCommand(
|
||||
name, lambda: workfile_settings().set_context_settings(), index=(rm_item[0]+3)
|
||||
name,
|
||||
lambda: workfile_settings().set_context_settings(),
|
||||
index=(rm_item[0] + 3)
|
||||
)
|
||||
log.debug("Adding menu item: {}".format(name))
|
||||
|
||||
|
||||
|
||||
def uninstall():
|
||||
|
||||
menubar = nuke.menu("Nuke")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue