Forum Posts

errors on nuke.delete(ReadNode)

in Nuke ForumsNukeNuke Python
Yeah, it's still annoying though because you have to iterate over all the knobs, and if any user knobs are found, you have to recreate them somehow.

The nuke.createNode("Read", source.writeKnobs(nuke.WRITE_USER_KNOB_DEFS | nuke.WRITE_NON_DEFAULT_ONLY | nuke.TO_SCRIPT), inpanel=False) method handles all that for you.

errors on nuke.delete(ReadNode)

in Nuke ForumsNukeNuke Python
So, I'm still randomly plagued by Nuke's annoying "ValueError: A PythonObject is not attached to a node" error, but in this case, I'm not able to stifle it with a try/except VaueError.

This time, I'm creating a temporary node and deleting it shorlty thereafter, but I get an error when it's a Read node (exr) because of nuke's built in readviewscheck callback.

Simple repro:

# First, load some footage with a Read node named "Read1"
source = nuke.toNode("Read1")

# Now, let's duplicate it
new_read = nuke.createNode("Read", source.writeKnobs(nuke.WRITE_USER_KNOB_DEFS | nuke.WRITE_NON_DEFAULT_ONLY | nuke.TO_SCRIPT), inpanel=False)

# Do stuff
print new_read.name(), new_read['file'].value()

# Now just delete the node
nuke.delete(new_read)



# Result: Traceback (most recent call last):
File "/mnt/tools/binlinux/apps/D2Software/Nuke10.0v6/plugins/nukescripts/readviewscheck.py", line 98, in <lambda>
QTimer.singleShot(0, lambda: checkReadNodeViews(read))
File "/mnt/tools/binlinux/apps/D2Software/Nuke10.0v6/plugins/nukescripts/readviewscheck.py", line 68, in checkReadNodeViews
views = getViews(read)
File "/mnt/tools/binlinux/apps/D2Software/Nuke10.0v6/plugins/nukescripts/readviewscheck.py", line 36, in getViews
if read['disable'].value():
ValueError: A PythonObject is not attached to a node



How can I suppress the error?! (Happens in Nuke 11.1v3 as well.)

number of tracks in selected tracker node

in Nuke ForumsNukeNuke Python
I ran into this problem and even though this thread is old, since there aren't any solutions posed, I thought I would add mine for the next person looking for this answer.

Also, since the name column only returns "0.0", that is included to.


# Select track node first
tracker = nuke.selectedNode()
tracks = tracker['tracks'].toScript().split('\n {')[1:]
track_count = len(tracks)
for idx in range(track_count):
track_name = tracks[idx].split('"')[1]
print track_name

Is there a smaller keyer range control?

in Nuke ForumsNukeNuke Python
Why is the keyer's range control widget so huge? Whenever I add it to a custom gizmo's control panel, it hogs up a lot of the property bin's real estate. Is there any way to shrink it down or build a custom one with PySide QT?

The example here would do if there was a widget similar to range that could set the A B C D trapezoid values on the keyer.

http://tylerart.com/sketchbook/22/12/2015/pyside-widgets-inside-a-nuke-gizmo

Redirecting stdout and stderr to file

in Nuke ForumsNukeNuke Python
I've been looking into logging nuke's errors to a file, but so far am unsuccessful.

I've tried a method based on:
http://kwblog.two3dmonkeys.com/?p=193

which basically reuses the built in functions nuke.stderr_redirector(out) and nuke.output_redirector(out), but I get an error when I launch nuke

ERROR:root:Traceback (most recent call last):
Child returned 1

I've also tried simply overriding sys.stdout and sys.stderr to point to a file as explained in one of these answers:
https://stackoverflow.com/questions/4675728/redirect-stdout-to-a-file-in-python

No error is thrown this time, but nothing is written to the file that gets created either.


Has anyone gotten this to work? Anyone know why the Foundry doesn't provide a mechanism for this natively? Seems like a developer friendly tool like Nuke should have this out of the box, ideally driven by an environment variable.

NukeStudio Export burnin not working

in Nuke ForumsNukeNuke Users
I have a timeline that I would like to export showing each clip's shot name and frame # using the burnin gizmo.

In version 9 I was able to use an expression to pull the shot name from a tag and the frame # from the metadata, but this is not working in NukeStudio 10.0v4.

When I view the metadata, the shot_name tag/key (>) is under some nested folders (+):

+ User
+ Tags
+ clip naming
+ shot_name
> shot_name


The expected syntax for getting the shot_name value isn't working in the burnin gizmo or softeffect:
/User/Tags/clip\\ naming/shot_name/shot_name

Furthermore, we would like our lower right corner to show the frames number with "x" prefix ("x ####"). using "input/frame" gets the correct value, but I can't add the "x" in front of it.

Unified selection callback

in Nuke ForumsNukeNuke Python
Ok, so since the goal of having the node selection was to relatively lock the position of the input0 to the node I went with this which does the trick.


c="""
k = nuke.thisKnob()
if k.name() in ['xpos', 'ypos']:
n = nuke.thisNode()
d = n.input(0)
d.setSelected(True)
"""

s = nuke.createNode('Dot')
m = nuke.createNode('NoOp')
m.setInput(0, s)
m['knobChanged'].setValue(c)




Then I thought, well, what about relatively locking the position of any node? I should be able to do something like this:


c="""
k = nuke.thisKnob()
if k.name() in ['xpos', 'ypos']:
n = nuke.thisNode()
d_name = n.input(0).name()
d = nuke.toNode(d_name)

d.setSelected(True)
"""

s = nuke.createNode('Dot')
m = nuke.createNode('NoOp')
m.setInput(0, s)
m['knobChanged'].setValue(c)


Notice, the only difference here is that I'm getting the name of input0 specifically and returning the node with nuke.toNode(). This could be a function that returns any node though so we could link adjacent nodes that aren't connected for example.

The weird thing is, now there's an expression link that shouldn't be there. We would rather not have this expression link show up because it's distracting and falsely leads the artist to believe there's an expression when there isn't.

Any ideas why this might be happening? Any ways around it?


Unified selection callback

in Nuke ForumsNukeNuke Python
Unfortunately, Michael's solution has similar quirkiness. Selecting the first time seems to work, but reclicking the node deselects the input.


from PySide import QtCore

def setSelected(n, k):
n.input(0)['selected'].setValue(k.value())


c="""
k = nuke.thisKnob()
if k.name() == 'selected':
n = nuke.thisNode()
print n.name(), n.input(0).name(), k.value()
QtCore.QTimer.singleShot(0, lambda :setSelected(n,k))

"""

s = nuke.createNode('Dot')
m = nuke.createNode('NoOp')
m.setInput(0, s)
m['knobChanged'].setValue(c)

Unified selection callback

in Nuke ForumsNukeNuke Python
So, let's say we want to select a slave node whenever a master node is selected. For simplicity we will make the slave the input(0) of the master node. The following knobChange callback on the "selected" knob should work:


c="""
k = nuke.thisKnob()
if k.name() == 'selected':
n = nuke.thisNode()
print n.name(), n.input(0).name(), k.value()
n.input(0)['selected'].setValue(k.value())
"""

s = nuke.createNode('Dot')
m = nuke.createNode('NoOp')
m.setInput(0, s)
m['knobChanged'].setValue(c)


Of course it's not as simple as that, so let's try with a redundant thread calling back into the main thread


import thread
c="""
k = nuke.thisKnob()
if k.name() == 'selected':
n = nuke.thisNode()
print n.name(), n.input(0).name(), k.value()
thread.start_new_thread(nuke.executeInMainThread, (n.input(0)['selected'].setValue, (k.value())))
"""

s = nuke.createNode('Dot')
m = nuke.createNode('NoOp')
m.setInput(0, s)
m['knobChanged'].setValue(c)


Closer, but it only really registers when the mouse click is down or if the node's position is changed.

I've also tried an UpdateUI callback, but get the same result.


What's going on here? Why won't the slaved node keep it's select value?

best way to check if a write node has been rendered?

in Nuke ForumsNukeNuke Python
For other people's benefit, I'm commenting on this old thread to confirm Wouter is right to avoid the external pyseq module.

I had been using pyseq to check for missing frames but it's pretty slow, taking about 1.5 seconds to check a single sequence. This adds up quick if you're checking several sequences as I was.

Also, I wanted to allow my function to be usable outside nuke, so I'm using a similar "glob" method as mentioned by Dimitri rather than the "evaluate(frame)" method Wouter mentioned. Now it takes less than .3 seconds to check the same sequence.

Why can't I center my input dot?!

in Nuke ForumsNukeNuke Python
Hello!

Simple task: We want to distinguish PostageStamps from Reads by building them with an input Dot automatically. I wrote a custom build_postage_stamp function to do this, but have a problem centering the incoming dot above the PostageStamp? The code I have will not get the proper values for the node screenWidth().

Other posts mention calling the xpos() function on the nodes to gets it closer, but the dot's screenWidth still seems to not update.

Sorry for the large amount of code for such a simple task, but I've made reusable functions for common tasks and want my repro to be accurate to my case.

def last_clicked_position():
"""
returns the x and y coordinates of the last position clicked by the user
"""
selection = nuke.selectedNodes()
[n.setSelected(False) for n in selection]
temp = nuke.createNode("Dot")
xy = [0, 0]
try:
xy = [temp.xpos(), temp.ypos()]
except:
pass
finally:
nuke.delete(temp)
[n.setSelected(True) for n in selection]
return xy

def place_in_y(node, reference_node, spacing=150, centered=True):
"""
Move node's position to be next to reference_node vertically, offset by the spacing amount
"""
# Refresh dag properties
node.xpos()
reference_node.xpos()

spacing = int(spacing)
if centered:
node.setXpos(int((reference_node.xpos() + (reference_node.screenWidth() / 2)) - (node.screenWidth() / 2)))

if spacing == 0:
node.setYpos(reference_node.ypos())
else:
node.setYpos(int(reference_node.ypos() + ((reference_node.screenHeight() + spacing) if spacing > 0 else spacing)))

def build_dot(name="", label="", xy_pos=None, input_node=None):
dot_node = nuke.nodes.Dot()
if name:
dot_node.setName(name)
if label:
dot_node['label'].setValue(label)
if input_node:
dot_node.setInput(0, input_node)
if not xy_pos:
xy_pos = last_clicked_position()
dot_node.setXYpos(xy_pos[0], xy_pos[1])
return dot_node


def build_postage_stamp(input_node=None, hide_input=False, lock_input=False):
"""
This builds a postage stamp with an incoming dot to help distinguish it from a standard Read node.
"""

if not input_node:
input_node = nuke.selectedNode() if nuke.selectedNodes() else None

nukescripts.clear_selection_recursive()
ps = nuke.nodes.PostageStamp()
ps['postage_stamp'].setValue(True)
dot_label = ''
xy_pos = last_clicked_position()
if input_node:
input_name = input_node.name()
dot_label = input_name
dy = xy_pos[1]-input_node.ypos()
if (abs(dy)+17) < 20:
dy = -50 if dy < 0 else 50
xy_pos[1] += dy

ps.setXYpos(*xy_pos)
dot_name = 'Dot_{}'.format(ps.name())
dot = build_dot(dot_name, dot_label, input_node=input_node)
dot.setSelected(False)
ps.setInput(0, dot)
dot['hide_input'].setValue(hide_input)
ps.xpos()
dot.xpos()
place_in_y(dot, ps, -25, True)
lock_input_relative_position(ps)
if lock_input:
lock_inputs(dot)
return dot, ps

# This is not working?
build_postage_stamp()

# Then why does this work?
ps = nuke.nodes.PostageStamp()
dot = nuke.nodes.Dot()
ps.setInput(0, dot)
place_in_y(dot, ps, -25, True)

orient to curve?

in Nuke ForumsNukeNuke Users
Thanks Wouter!

It was finding the derivative that I was missing. I reduced the expression on the rotation knob to this:

(translate.x.derivative>=0 )?(translate.x.derivative==0 && translate.y.derivative==0)?rotate(t-1):degrees(atan(translate.y.derivative/translate.x.derivative)):180 + degrees(atan(translate.y.derivative/translate.x.derivative))

This orients the rotation based on the nodes translation. Spot on.

best way to check if a write node has been rendered?

in Nuke ForumsNukeNuke Python
Hey Dimitre, that is pretty good and definitely fast, but since it depends on the play-head's frame, it's unreliable. What if the rendered frame is 1001, but the play-head is on 1100?

I found the pyseq module calls pretty quick and easy to use, so here's what I ended up coming up with:


import pyseq
import os.path

def get_rendered_frames(write):
# Return the list of file rendered image paths of the given write node
filepath = write['file'].toScript()
filename = os.path.basename(filepath)
render_dir = os.path.dirname(filepath) + os.sep
seqs = pyseq.get_sequences(render_dir)

for seq in seqs:
head, padding, tail = seq.head(), seq.format("%p"), seq.tail()
if not (filename.startswith(head) and filename.endswith(tail)):
# This is not the sequence you're looking for
continue
return ["{folder}{head}{frame}{tail}".format(folder=render_dir, head=head, frame=padding%f, tail=tail) for f in seq.frames()]
return []

def get_missing_frames(write, start=None, end=None):
# Return the list of file rendered image paths of the given write node
filepath = write['file'].toScript()
filename = os.path.basename(filepath)
render_dir = os.path.dirname(filepath) + os.sep
seqs = pyseq.get_sequences(render_dir)

for seq in seqs:
head, padding, tail = seq.head(), seq.format("%p"), seq.tail()
if not (filename.startswith(head) and filename.endswith(tail)):
# This is not the sequence you're looking for
continue

if start and end:
missing = []
for f in range(start, end+1):
framepath = "{folder}{head}{frame}{tail}".format(folder=render_dir, head=head, frame=padding%f, tail=tail)

if not os.path.exists(framepath):
missing.append(framepath)
else:
missing = seq.missing()

if missing:
return missing
return []

best way to check if a write node has been rendered?

in Nuke ForumsNukeNuke Python
Hey Nuke Gurus... (Nukurus?) riddle me this (what should be simple) question:

Write nodes understand frame padding, but AFAIK there's no built in way to check if a write node has been rendered and has files existing.
Some os.path.exists equivalent for nuke would be lovely like:
nuke.path.exists(write_node)

So, there are a bunch of ways I could approach this, but I'm curious how others have done it and what's most efficient?
pyseq?
os.listdir?
glob?
iterate over frame range?


I don't even really care if all the files are present as there may be cases when a still frame is rendered from a write node set to render a frame range, but I would want to know that that frame exists.

What's your favorite way to verify a render?