Ben, how do I use $gui when rendering locally?

Categories Python, Quick Tip

In Nuke, you’re able to dynamically change any knob’s value depending on if you’re looking through a Viewer in Nuke’s GUI, or rendering your Nuke script on a render farm. This can be useful to keep your Nuke scripts light & efficient while working, while automatically switching to more processor-intensive tasks at render time — for example, increasing motion blur render samples.

Compositors often use the $gui expression to handle this. For example:

  • $gui returns 1 when viewing through Nuke’s Viewer, or 0 in any other context where no GUI is present.
  • $gui?2:10 is similar, where the first value 2 is what will show in the GUI, otherwise 10 will be the value used.

However, $gui has one big drawback — Nuke still uses the GUI when rendering locally, and so our $gui expression would return the wrong value. So how do we get around this?

There is a python function built into the nuke module called nuke.executing(). Nuke’s documentation states that this function, “Returns whether an Executable Node is currently active or not”. An example of an executable node is the CurveTool, which has the “Go!” button, or a Write node with its “Render” button.

Like with TCL’s $gui, you can use this Python function in any knob by right-clicking the knob, and choosing “edit expression”. Next, click the “py” button to indicate we’re using Python instead of TCL, and type nuke.executing(). The returned value will be “True” when rendering, so it will return a value of 1 to this knob. Otherwise, it will return 0 when looking through the Viewer.

If you wanted to invert this, for example having a value of 1 in the Viewer, and 0 at render time, you can use 1-nuke.executing() as 1 minus 0 = 1. When rendering, 1 minus 1 = 0.

Lastly, 10 if nuke.executing() else 2 will return a value of 10 when rendering, or 2 otherwise. You can read this as, “set the value to 10 if Nuke is executing, otherwise set the value to 2”. It is a better alternative to $gui for setting dynamic values that update when working vs. rendering.

As always, it’s good practice to label any nodes which have these expressions in them, so that other artists can easily find them when opening your Nuke script.

As a shortcut, perhaps you can create a right-click menu item to quickly add this function to a knob? See description for details…

# Add this code to your

def toggle_nuke_executing():

    # Add the Python expression to the knob.
    nuke.thisKnob().setExpression('[python {nuke.executing()}]')

    # It is courteous to label nodes with dynamically-changing knobs, for other Compositors
    # who might have to open up, and work with your Nuke script...
    font = nuke.thisNode().knob('note_font').value()
    nuke.thisNode().knob('note_font').setValue(font+' Bold')
    nuke.thisNode().knob('label').setValue("nuke.executing() on this node")

# Add a menu item to any knob's right-click menu.'Animation').addCommand('Add nuke.executing() to knob', 'toggle_nuke_executing()')