0

I've got a python script for (Foundry) Nuke that listens to commands and for every command received executes a Write node. I've noticed that if I don't do nuke.scriptOpen(my_renderScript) before nuke.execute(writeNode,1,1) and then after do nuke.scriptClose(my_renderScript), then the write command seems to execute but nothing is written to file, despite me changing knob values before I call execute again.

The reason I want to not use scriptOpen and scriptClose every time I execute -the same node- is for performance. I'm new to nuke, so correct me if I'm wrong, but it's inefficient to unload and reload a script every time you want to run a node inside it, right?

[EDIT] Here's a simple test script. Waits for command line input and runs the function, then repeats. If I move the script open and script close outside the looping / recursive function, then it will only write to file once, the first time. On subsequent commands it will "run", and nuke will output "Total render time: " in the console (render time will be 10x faster since it's not writing / doing anything) and pretend it succeeded.

# Nuke12.2.exe -nukex -i -t my_nukePython.py render.nk
# Then it asks for user input. The input should be:
# "0,1,0,1", "1024x1024", "C:/0000.exr", "C:/Output/", "myOutput####.png", 1, 1
# then just keep spamming it and see.

import nuke
import os
import sys
import colorsys

renderScript = sys.argv[1]
nuke.scriptOpen(renderScript)

readNode = nuke.toNode("Read1")
gradeNode = nuke.toNode("CustomGroup1")
writeNode = nuke.toNode("Write1")


def runRenderCommand():
    cmdArgs = input("enter render command: ")
    
    print cmdArgs
    
    if len(cmdArgs) != 7:
        print "Computer says no. Try again."
        runRenderCommand()
    
    nuke.scriptOpen(renderScript)
    
    colorArr = cmdArgs[0].split(",")

    imageProcessingRGB = [float(colorArr[0]), float(colorArr[1]), float(colorArr[2]), float(colorArr[3])]
    previewImageSize = cmdArgs[1]
    inputFileLocation = cmdArgs[2]
    outputFileLocation = cmdArgs[3]
    outputFileName = cmdArgs[4]
    startFrameToExecute = cmdArgs[5]
    endFrameToExecute = cmdArgs[6]

    readNode.knob("file").setValue(inputFileLocation)
        
    writeNode.knob("file").setValue(outputFileLocation+outputFileName)

    gradeNode.knob("white").setValue(imageProcessingRGB)
    print gradeNode.knob("white").getValue()

    nuke.execute(writeNode.name(),20,20,1)
    runRenderCommand()
    
    nuke.scriptClose(renderScript)
    
runRenderCommand()
Spectraljump
  • 4,189
  • 10
  • 40
  • 55
  • i'm not sure i follow, can i see more of the code? you may try passing continueOnError=False to the execute() function - by default, nuke will fail silently on errors. – tk421storm Oct 15 '20 at 20:48
  • Uploaded some code. It should work in my example, and it should not work if you take nuke.scriptClose and nuke.scriptOpen and move them outside the looping function. – Spectraljump Oct 15 '20 at 21:20

1 Answers1

0

The problem was between the chair and the screen. Turns out my example works. My actual code that I didn't include for the example, was a bit more complex and involved websockets.

But anyway, it turns out I don't know how python scoping sintax works ^__^ I was making exactly this error in understanding how the global keyword should be used: referenced before assignment error in python

So now it indeed works without opening and closing the nuke file every time. Funny how local scope declaration in python in this case in my code made it look like there's no errors at all... This is why nothing's sacred in scripting languages :)

Is there a way to delete this question on grounds that the problem turns out was completely unrelated to the question?

Well that took an unexpected turn. So yes I had the global problem. BUT ALSO I WAS RIGHT in my original question! Turns out depending on the nodes you're running, nuke can think that nothing has changed (probably the internal hash doesn't change) and therefore it doesn't need to execute the write command. In my case I was giving it new parameters, but the parameters were the same (telling it to render the same frame again)

If I add this global counter to the write node frame count (even though the source image only has 1 frame), then it works.

nuke.execute(m_writeNode.name(),startFrameToExecute+m_count,endFrameToExecute+m_count, continueOnError = False)
m_count+=1

So I gotta figure out how to make it render the write node without changing frames, as later on I might want to use actual frames not just bogus count increments.

Spectraljump
  • 4,189
  • 10
  • 40
  • 55
  • I think there's something else going on here - the nuke write node definitely shouldn't make any calculation about when something has changed; it should always write. Unless it's a really pernicious undocumented bug, I bet something else is happening. Any results with continueOnError=false? – tk421storm Oct 16 '20 at 15:17
  • You mean like this? `nuke.execute(m_writeNode.name(),startFrameToExecute+m_count,endFrameToExecute+m_count, continueOnError = False)`? It doesn't report any errors. The node I'm plugging into the write node is one of those baked nodes that are an aggregation of multiple things. Maybe there's smth wrong in there, I'll talk to the artist. – Spectraljump Oct 18 '20 at 15:49
  • 1
    ooo that definitely could be it - if it's a group, to do the render correctly you'll have to walk to the actual "Write" node in the group, and execute it - ie. GroupNode.node('Write1').execute() – tk421storm Oct 19 '20 at 16:56
  • Good point, but actually the file looks like this: `Group ... end_group Write { file C:/jobs/post/render.png raw true file_type png checkHashOnRead false version 1 name OUT xpos 180 ypos -21 }` So the out node, is just a regular write node as far as I know. The group is the one before the write node. So could there be something in the group or do you see smth wrong in the wite node, like maybe `checkHashOnRead` should be true? – Spectraljump Oct 19 '20 at 17:54
  • 1
    The write node DOES write every time, except the node group doesn't get refreshed somehow. If every call, I tell the write node to execute either frame 0 or frame 1, alternating between them each call, then it works. If I tell the write node to always render the same frame, the node group doesn't produce a change. So def something the artist did only works in the editor and not in python. – Spectraljump Oct 20 '20 at 10:08