You’re Doing That Wrong is a journal of various successes and failures by Dan Sturm.

Customizing Native Nuke Nodes with addOnCreate

As much as I enjoy building custom gizmos to make my work in Nuke more enjoyable, they're really no replacement for native nodes that (hopefully, eventually) include the tweaked feature that I want.

In fact, trying to use a custom gizmo as a replacement for a native node can add friction since I end up with two results in my tab+search window rather than one. When trying to use my beloved FrameHold gizmo, I end up adding the old, dumb, native FrameHold node about half of the time. It's partly because there are two FrameHold nodes in my results, and partly because my custom gizmo shows up lower in the search results than than the native node. Sure, I could rename my gizmo to something unique to avoid ambiguity in the search, but that would come at the cost of precious muscle memory.

framehold tab search.png

But, thanks to an email from reader Patrick, I've recently become aware of the addOnCreate command in Nuke's Python API. Essentially, addOnCreate allows you to define a function to be run whenever a given Class of node is added, opening the door to customizing the native Nuke nodes as they're added to your script.

As a quick test, I used addOnCreate to add some TCL code to the labels of my TimeOffset and Tracker nodes.

# Time Offset Label Modification

def OnTimeOffsetCreate():
  nTO = nuke.thisNode()
  if nTO != None:
    label = nTO['label'].value()
    nTO['label'].setValue('[value time_offset]')

# Tracker Label Modification

def OnTrackerCreate():
  nTR = nuke.thisNode()
  if nTR != None:
    label = nTR['label'].value()
    nTR['label'].setValue('[value transform]\n[value reference_frame]')

# Add the custom labels to newly created nodes

nuke.addOnCreate(OnTimeOffsetCreate, nodeClass="TimeOffset")
nuke.addOnCreate(OnTrackerCreate, nodeClass="Tracker4")

(code only)

I've long been a fan of using the label of my TimeOffset nodes to show me how many frames have been offset. Especially handy for my kind of work, where a single animated element can be reused dozens times, offset in time, and randomized to make large animations easier to create and manage. For Tracker nodes, it's important to keep track of both the Reference Frame used, as well as the type of Transform being applied. Now, every time I add a TimeOffset or Tracker node, the additional information is automatically added to my node label.

Nuke default nodes on top. With custom labels below.

Nuke default nodes on top. With custom labels below.

As expected, there are limits to what you can modify with the Python API but, henceforth, this method of interface customization is going to be my preference, resorting to creating gizmos as a fall-back when I run into a limitation. The thought of dropping a single Menu.py file into my local .nuke directory, and having all my Nuke customizations show up, is incredibly appealing to me.