nukeprocess v1.0


 
This location is for Registered Users Only.
Perhaps you need to login or register.
Contributor: Francois Lord
Python module to control Nuke from the exterior. Useful for pipeline automation.
Requirements:
5.1, 5.2, 6.0, 6.1 or later
18 Nov 2010
147

One thing I liked about Shake and miss in Nuke was its ability to process images easily from the command line. When working on automation tools for a pipeline, this was a very useful feature and a easy one to learn. After realizing that Nuke wasn’t built from a command line software and that such a feature surely won’t come anytime soon, I decided to spend some time writing my own tool to use Nuke from the exterior. It’s not a command line API, but it’s an API that can be used by any Python script anywhere in the pipeline.

Oblique, my employer, has allowed me to release it publicly. So here it is…
Save this inside your custom python library or inside your Python’s site-packages directory. Since this is a tool for controlling an application via programming, I assume you know where to save a python file to use it. You will have to modify some parts to make sure it points to the right Nuke installation and to your own Python library.

It creates a Python script that can be run inside Nuke. It then starts Nuke and pipe the script to the STDIN, executes the script and exits Nuke. At the time of this writing, it works with Nuke 5.1v4.

If you find any bugs or have any comments about this tool, don’t hesitate to tell me. I’ve been using it in production for a few years now and it's been stable,  the Oblique pipeline relies on it. Also, feel free to modify it to your own needs. I would appreciate if you told me what you did. In the Oblique internal version, I added a method to process on the render farm, but since our render manager API is custom made, I felt it was unnecessary for a public release.

Its usage is simple. You first create an instance of the NukeProcess class by giving it the name of the sequence you want to work with as well as its first frame, last frame and step. You then add nodes with the createNode() method by setting all the knob values with arguments. And execute the whole thing with the executeVerbose() method. The knob names you pass as args must be the scripting name. You can find them by hovering the mouse over any knob in Nuke, the tooltip is the script name.

Usage examples

#
# To resize a sequence of images, color correct it, and save to jpeg:
#
from nukeprocess import NukeProcess
np = NukeProcess("/someplace/someImageSequence.%04d.exr", 1, 100, 1)
np.createNode("Reformat", type='to box', box_width=1920, box_height=1080,
box_fixed=True, resize='fit', black_outside=True)
np.createNode('Grade', black=.00537, white=.83)
np.createNode("Write", file="/someplace/someImageSequence_HD.%04d.jpg",
file_type='jpeg', _jpeg_quality=1)
np.executeVerbose()
#
# To resize a sequence, offset it to frame 1 and put gray bars:
#
from nukeprocess import NukeProcess

# When declaring a empty string, it creates a Constant node instead of a Read.
np = nukeprocess.NukeProcess("", 1, sequence.getEnd()-sequence.getStart()+1,
color="{from_byte(64)}")

# Use the addCode() method when you need to do something special.
np.addCode("f = nuke.addFormat('512 288 PreviewMovie')")
np.addCode("n.knob('format').setValue(f)")

# We save the node in a variable to use it later in the connectInput() method
np.saveNodeInVariable('constant')

# sequence.getStart() and sequence.getEnd() come from another API,
# in this case a custom file browser.
np.createNode("Read", file="/somePlace/sequence.%04d.exr",
 first=sequence.getStart(), last=sequence.getEnd(),
frame="frame+%d" % (sequence.getStart()+1))
np.createNode('Shuffle', alpha=6)
np.createNode("Reformat", type="to box", box_width=512, box_height=288,
resize='fit', black_outside=True, box_fixed=True)

# The connectInput() method works on the previously added node.
np.createNode("Merge")
np.connectInput('constant')
np.createNode("Write", file="/somePlace/sequence_fit.%04d.exr",
file_type="exr", compression='ZIP')

# to debug the script, you can print it and paste it in an interactive Nuke.
print np.getScript()
np.executeVerbose()
#
# To monitor the process:
#
from nukeprocess import NukeProcess
np = NukeProcess("/someplace/someImageSequence.%04d.exr", 1, 100, 1)
np.createNode("Write", file="/someplace/someImageSequence_HD.%04d.jpg",
file_type='jpeg', _jpeg_quality=1)
oProcess = np.execute(1, 100, 1)
sOutLine = "."
while sOutLine != "":
sOutLine = oProcess.stdout.readline()
# Update process progress
# Writing /someplace/someImageSequence_HD.0001.jpg took 1.08 seconds
if sOutLine.startswith('Writing'):
# Extract frame number from sOutLine
try:
iFrame = int(sOutLine.split()[1].rsplit('.')[-2])
except:
pass
else:
print("Processing frame: %d" % iFrame)

oProcess.wait()
result = oProcess.returncode

Documentation:

NukeProcess methods:

  • __init__(InputSequence, StartFrame, EndFrame, [Step], **kwargs)
    When instancing the NukeProcess, a createNode(“Read”) is done and
    **kwargs are passed.
  • createNode(NodeName, **kwargs)
    Adds a node in the script. Knobs values can be set via
    keyword arguments.
    example:
    np = createNode(‘Write’, file=’C:/patate.####.exr’, premultiplied=True)

    Internally, createNode() returns n, and uses n.knob().setValue() to
    set the parameters. If you need to create some branches, you might want
    to use saveNodeInVariable([variable]) to keep the last added node in a safe variable
    since n will always be overwritten on the next createNode(). You can then later use
    connectInput([variable]) to connect the second input of a merge node for example.

  • addCode(Code)
    Adds a line of code to the script.
  • saveNodeInVariable(Variable)
    Saves the previously added node in a variable to be used by connectInput().
  • connectInput(Variable)
    Allows branching by connecting the secondary input of the previously added node
    to be connected to the node inside Variable.
    equivalent to: addCode(“n.connectInput(0, %s)” % sVariable)
  • execute([StartFrame], [EndFrame], [Step])
    Launches the render and returns a subprocess.Popen instance.
    stdios are piped so you can use oProcess.stdin.readline().
    Optional args:
    iStartFrame, iEndFrame, iStep
    If args are not present, start and end frames are taken from the input sequence.
  • executeVerbose([StartFrame], [EndFrame], [Step])
    Launches the render and prints the output of the process.
    Optional args:
    iStartFrame, iEndFrame, iStep
    If args are not present, start and end frames are taken from the input sequence.
  • getScript()
    Returns the script in its ready-to-use form,
    with the right indentation.
  • Please login in order to download these files.

    Comments   

     
    0 # Denis Tassenoy 2011-06-21 04:46
    hello.
    I tried the first example but I've that message:
    from nukeprocess import NukeProcess
    np = NukeProcess("c: /_____test/curr ent_dpx/5900_01 60.d.dpx", 101, 119, 1)
    np.createNode("Reformat", type='to box', box_width=1920, box_height=1080 , box_fixed=True, resize='fit', black_outside=True)
    np.createNode("Write", file="c:/_____t est/current_cmp /5900_0160.d.j pg", file_type='jpeg ', _jpeg_quality=1)
    np.executeVerbose()
    # Result: Traceback (most recent call last):
    File "", line 5, in
    File "Z:Shared/Python
    ukeprocess.py", line 129, in executeVerbose
    oProcess = self.execute(iS tartFrame, iEndFrame, iStep)
    File "Z:Shared/Python
    ukeprocess.py", line 119, in execute
    stdout = subprocess.PIPE , stderr = subprocess.STDO UT, shell=True, universal_newli nes=True)
    File "C:Program FilesNuke6.0v7l ibsubprocess.py ", line 615, in __init__
    self.stdout = os.fdopen(c2pre ad, 'rU', bufsize)
    OSError: [Errno 22] Invalid argument

    Any ideas?
     

    You have no rights to post comments

    We have 3399 guests and 57 members online