Home

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

Automated Viewer Frame Handles in Nuke

When working on a VFX shot, more often than not, the plate's image sequence will include frame handles; an additional 8 or 12 frames at the start and end of the shot. The extra half or third of a second at the ends of the shot give us the flexibility to adjust in and out points later without having to come back to our compositing application and re-render the shot with a new frame range. Which is great.

But, when working on a shot in, say, Nuke, you'll often want to play back the shot without viewing the currently-extraneous frames. Lucky for us, Nuke has a these fun little red triangles on its timeline that you can drag around to set custom in and out points as you see fit. It's a great feature for focusing on a smaller range of frames for a specific task.

But, if you're trying to see eactly the frames that are currently in the edit, and only those frames, dragging around tiny red triangles isn't terribly precise. And the other option, typing in the first frame plus the handle, a hyphen, then the last frame minus the handle, is slow and requires math (yuck).

This being a well-defined, menial, and repetitive task, it's a perfect candidate for automation. With help, again, from my good friend Jake at The Foundry Support, I've added two new items to the bottom of my Viewer menu.

Now, all it takes is a single click (or keyboard shortcut, if you're so inclined) to quickly add 12 or 8 frame handles to my Viewer Timeline Range.

Here's the code to add to your Menu.py file in your .nuke folder:

def newViewerRange12():
  # Get the node that is the current viewer
  v = nuke.activeViewer().node()
  # Get the first and last frames from the project settings
  firstFrame = nuke.Root()['first_frame'].value()
  lastFrame = nuke.Root()['last_frame'].value()
  # get a string for the new range and set this on the viewer
  newRange = str(int(firstFrame)+12) + '-' + str(int(lastFrame) - 12)
  v['frame_range_lock'].setValue(True)
  v['frame_range'].setValue(newRange)


def newViewerRange8():
  # Get the node that is the current viewer
  v = nuke.activeViewer().node()
  # Get the first and last frames from the project settings
  firstFrame = nuke.Root()['first_frame'].value()
  lastFrame = nuke.Root()['last_frame'].value()
  # get a string for the new range and set this on the viewer
  newRange = str(int(firstFrame)+8) + '-' + str(int(lastFrame) - 8)
  v['frame_range_lock'].setValue(True)
  v['frame_range'].setValue(newRange)

# Add the commands to the Viewer Menu
nuke.menu('Nuke').addCommand('Viewer/Viewer Handles - 12f',
"newViewerRange12()")
nuke.menu('Nuke').addCommand('Viewer/Viewer Handles - 8f',
"newViewerRange8()")

Naturally, if you only ever deal with one duration for your frame handles, you can add just one of the functions, but I like having the flexibility of both options.

That Jake, he sure is good with the Python code, isn't he?

Update - 2014-10-25

The release of Nuke 9 is just around the corner and its revamped Viewer interface brings with it a small bug in my Viewer Frame Handles code (allegedly).

Design decisions in Nuke's new big brother, Nuke Studio, have made their way into the standalone app (reportedly) and now require the Frame Range Lock to be set before the new Frame Range is defined (or so I hear). Keen observers will notice that the last 2 lines of the newViewerRange functions above have been swapped to reflect this change.

According to a friend who's not me, the old code will still work in Nuke 9, but requires you to have existing In and Out points prior to running the command or run the command twice.

If you're planning on using this tool with Nuke 9 and Nuke Studio, you should update your Menu.py file now. The updated code will run properly in both Nuke 8 and Nuke 9 (so the story goes).