Merge pull request #1653 from pypeclub/feature/1651-nuke-publish-simplification

This commit is contained in:
Jakub Ježek 2021-06-08 16:51:49 +02:00 committed by GitHub
commit a68e23ff46
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 51 additions and 138 deletions

View file

@ -298,18 +298,21 @@ def create_write_node(name, data, input=None, prenodes=None, review=True):
review (bool): adding review knob
Example:
prenodes = [(
"NameNode", # string
"NodeClass", # string
( # OrderDict: knob and values pairs
("knobName", "knobValue"),
("knobName", "knobValue")
),
( # list outputs
"firstPostNodeName",
"secondPostNodeName"
)
)
prenodes = [
{
"nodeName": {
"class": "" # string
"knobs": [
("knobName": value),
...
],
"dependent": [
following_node_01,
...
]
}
},
...
]
Return:
@ -385,35 +388,42 @@ def create_write_node(name, data, input=None, prenodes=None, review=True):
prev_node.hideControlPanel()
# creating pre-write nodes `prenodes`
if prenodes:
for name, klass, properties, set_output_to in prenodes:
for node in prenodes:
# get attributes
name = node["name"]
klass = node["class"]
knobs = node["knobs"]
dependent = node["dependent"]
# create node
now_node = nuke.createNode(klass, "name {}".format(name))
now_node.hideControlPanel()
# add data to knob
for k, v in properties:
for _knob in knobs:
knob, value = _knob
try:
now_node[k].value()
now_node[knob].value()
except NameError:
log.warning(
"knob `{}` does not exist on node `{}`".format(
k, now_node["name"].value()
knob, now_node["name"].value()
))
continue
if k and v:
now_node[k].setValue(str(v))
if knob and value:
now_node[knob].setValue(value)
# connect to previous node
if set_output_to:
if isinstance(set_output_to, (tuple or list)):
for i, node_name in enumerate(set_output_to):
if dependent:
if isinstance(dependent, (tuple or list)):
for i, node_name in enumerate(dependent):
input_node = nuke.createNode(
"Input", "name {}".format(node_name))
input_node.hideControlPanel()
now_node.setInput(1, input_node)
elif isinstance(set_output_to, str):
elif isinstance(dependent, str):
input_node = nuke.createNode(
"Input", "name {}".format(node_name))
input_node.hideControlPanel()

View file

@ -99,10 +99,28 @@ class CreateWriteRender(plugin.PypeCreator):
"fpath_template": ("{work}/renders/nuke/{subset}"
"/{subset}.{frame}.{ext}")})
# add crop node to cut off all outside of format bounding box
_prenodes = [
{
"name": "Crop01",
"class": "Crop",
"knobs": [
("box", [
0.0,
0.0,
selected_node.width(),
selected_node.height()
])
],
"dependent": None
}
]
write_node = lib.create_write_node(
self.data["subset"],
write_data,
input=selected_node)
input=selected_node,
prenodes=_prenodes)
# relinking to collected connections
for i, input in enumerate(inputs):

View file

@ -1,106 +0,0 @@
import nuke
import pyblish.api
class RepairNukeBoundingBoxAction(pyblish.api.Action):
label = "Repair"
icon = "wrench"
on = "failed"
def process(self, context, plugin):
# Get the errored instances
failed = []
for result in context.data["results"]:
if (result["error"] is not None and result["instance"] is not None
and result["instance"] not in failed):
failed.append(result["instance"])
# Apply pyblish.logic to get the instances for the plug-in
instances = pyblish.api.instances_by_plugin(failed, plugin)
for instance in instances:
crop = instance[0].dependencies()[0]
if crop.Class() != "Crop":
crop = nuke.nodes.Crop(inputs=[instance[0].input(0)])
xpos = instance[0].xpos()
ypos = instance[0].ypos() - 26
dependent_ypos = instance[0].dependencies()[0].ypos()
if (instance[0].ypos() - dependent_ypos) <= 51:
xpos += 110
crop.setXYpos(xpos, ypos)
instance[0].setInput(0, crop)
crop["box"].setValue(
(
0.0,
0.0,
instance[0].input(0).width(),
instance[0].input(0).height()
)
)
class ValidateNukeWriteBoundingBox(pyblish.api.InstancePlugin):
"""Validates write bounding box.
Ffmpeg does not support bounding boxes outside of the image
resolution a crop is needed. This needs to validate all frames, as each
rendered exr can break the ffmpeg transcode.
"""
order = pyblish.api.ValidatorOrder
optional = True
families = ["render", "render.local", "render.farm"]
label = "Write Bounding Box"
hosts = ["nuke"]
actions = [RepairNukeBoundingBoxAction]
def process(self, instance):
# Skip bounding box check if a crop node exists.
if instance[0].dependencies()[0].Class() == "Crop":
return
msg = "Bounding box is outside the format."
assert self.check_bounding_box(instance), msg
def check_bounding_box(self, instance):
node = instance[0]
first_frame = instance.data["frameStart"]
last_frame = instance.data["frameEnd"]
format_width = node.format().width()
format_height = node.format().height()
# The trick is that we need to execute() some node every time we go to
# a next frame, to update the context.
# So we create a CurveTool that we can execute() on every frame.
temporary_node = nuke.nodes.CurveTool()
bbox_check = True
for frame in range(first_frame, last_frame + 1):
# Workaround to update the tree
nuke.execute(temporary_node, frame, frame)
x = node.bbox().x()
y = node.bbox().y()
w = node.bbox().w()
h = node.bbox().h()
if x < 0 or (x + w) > format_width:
bbox_check = False
break
if y < 0 or (y + h) > format_height:
bbox_check = False
break
nuke.delete(temporary_node)
return bbox_check

View file

@ -43,11 +43,6 @@
"optional": true,
"active": true
},
"ValidateNukeWriteBoundingBox": {
"enabled": true,
"optional": true,
"active": true
},
"ExtractThumbnail": {
"enabled": true,
"nodes": {

View file

@ -64,10 +64,6 @@
{
"key": "ValidateScript",
"label": "Validate script settings"
},
{
"key": "ValidateNukeWriteBoundingBox",
"label": "Validate and Write Bounding Box"
}
]
},