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

Nuke: Center Transform Button

As I continue to use Nuke in ways in which it was never intended to be used (read: motion graphics), I keep finding small bits of friction that I just can't help but remove with app customizations.

My latest annoyance stems from an animated project that involved more traditional motion-graphics-style animation than the typical interface design and animation I usually create. I built all the graphic assets I would need for the video ahead of time, then assembled and animated them into a sequence, entirely in Nuke.

Again and again, I would merge a new graphic asset onto my shot, and I would have to do some math to figure out how to transform it into the center of the frame. Since the origin (0,0) of a Nuke frame is the bottom left corner, by default, images show up in the lower left of the frame rather than the center. Which is not what I want.

So, I'd add a Transform to the asset and move it to the center of the 1920 x 1080 frame. Since I care about precision, I didn't just eyeball the transform. I want it to be exact.

As long as I add a Transform to a graphic element with the upstream node selected, the Transform will detect the width and height of the asset and place the transform jack in the center of the object. As a Nuke user, you already knew that.

Then, I place my cursor in the x translate parameter box and type 1920/2 - whatever value was in the x center position, as determined by the upstream node. I repeat this process for the y translate parameter, using 1080/2 to match the frame's height.

And lo, we have discovered another simple, math-based operation, prone to human error, ripe for automation. The formula is simple:

  • The x translate parameter should be defined as half the frame width minus half the asset width.
  • The y translate parameter should be defined as half the frame height minus half the asset height.
  • If we have added the Translate node directly to the asset — which is to say we have not added it to our script unconnected — the x center and y center parameters will be automatically filled with the half-width and half-height values of our asset.

In Nuke Python, this formula would be expressed as:

n = nuke.thisNode()

# Get the x and y values of the Transform's center point
xVal = n['center'].value(0)
yVal = n['center'].value(1)

# Get the width and height of the frame format
rVal = nuke.Root()
xfVal = rVal.width()
yfVal = rVal.height()

# Define the variables to set the translate values
txVal = n['translate'].value(0)
tyVal = n['translate'].value(1)

# Find difference between center of frame and center of transform
cxVal = xfVal/2-xVal
cyVal = yfVal/2-yVal

# Translate to center of frame format
n['translate'].setValue(cxVal, 0)
n['translate'].setValue(cyVal, 1)

Next, we take that nicely formatted Python script and shove it into an addOnUserCreate function within our Menu.py file thusly:

def OnTransformCreate():
  nTR = nuke.thisNode()
  if nTR != None:
    script="n = nuke.thisNode(); xVal = n['center'].value(0); yVal = n['center'].value(1); rVal = nuke.Root(); xfVal = rVal.width(); yfVal = rVal.height(); txVal = n['translate'].value(0); tyVal = n['translate'].value(1); cxVal = xfVal/2-xVal; cyVal = yfVal/2-yVal; n['translate'].setValue(cxVal, 0); n['translate'].setValue(cyVal, 1);"
    k = nuke.PyScript_Knob('center_trans', 'Center Transform')

nuke.addOnUserCreate(OnTransformCreate, nodeClass="Transform")

Now, every Transform node created will have a nice big "Center Transform" button added to it automatically.

So, when I bring in a 584 x 1024 graphic asset like, say, this:

And I merge it over a 1920 x 1080 background...

...add a Transform node — which will find the center point to be (292,512)

All I have to do to center my graphic asset is click this button...

...and boom. Automated.