My Nuke defaults - part 1

posted: May 7, 2020, 6:06 p.m.

So you rock up in a new facility (I mean you probably "rocking up" via vpn) and let's say they are open to letting you set up your own preferences using your menu.py - what stuff do you do there?

Don't know what this is about? Check here:

Well I posted my personal faves on my github a while back but thought I would run through them here.

labels

I like things labelled, on the other hand labelling things is boring. So automatic labels are great.

nuke.knobDefault('TimeClip.label', '[value first] to [value last]')
nuke.knobDefault('OCIOColorSpace.label', '<i>[value in_colorspace]</i> <b>to</b> <i>[value out_colorspace]')
nuke.knobDefault('Tracker.label', '[value transform] [value reference_frame]')

You can actually run these straight in the Script Editor to try them out before adding them to a menu.py - the defaults will persist until you close Nuke.

Basically the idea is that every TimeClip node will be labelled with it's framerange. TimeClips by the way are super handy when you have a long shot with no VFX and then something happens on like frame 3798-4000

Trackers I like to know what they are doing, same for OCIOColorSpace nodes.

Then there are just defaults e.g.:

nuke.knobDefault('Exposure.mode', 'Stops')

defaults

The default for Exposure nodes is Densities - this was a telecine setting. Ever used a Telecine? NO well neither have I. But I have used a camera and so have most clients, directors and supervisors. "Stops" is a sensible real-world setting that most people have experience with.

Anyway these are one liners.

Custom Functions

Next up something a bit more interesting:

##custom functions

def bbob_to_x():
    [ n['bbox'].setValue('B') for n in nuke.selectedNodes() if 'bbox' in n.knobs()]

def serve_raw():
    [ n['raw'].setValue(True) for n in nuke.selectedNodes() if 'raw' in n.knobs()]

def label_dots_and_stamps():
    dotsNStamps=[]
    n=nuke.selectedNode()
    classes=['Dot', 'PostageStamp']
    while n.Class() in classes:
        dotsNStamps.append(n)
        n= n.input(0)
    colour= int(n['tile_color'].getValue()) 
    for d in dotsNStamps:
        d['label'].setValue( n['name'].getValue() )
        d['tile_color'].setValue(colour)

def toggle_hide():
    nh=nuke.selectedNode()['hide_input']
    toggle={True: False, False: True}
    nh.setValue(toggle[nh.getValue()] )

So these are functions. The first one means I can select a bunch of nodes, and if they have a "bbox" setting (such as with a Merge or Keymix) I can set them to 'B'. This stops the bounding box getting silly. Notice the function is callled bbox_to_b That's a basic principal, name things in a way that is obvious to anyone reading your code (even you, to quote another comper Steven Bray - "The life you save may be your own")

Next we have serve_raw -sometimes facilities have default luts which are great for footage but a pain for elements. This just lets me set them all to raw so I can manage the colours how I want.

Next up something a little more interesting, label_dots_and_stamps. This is further to the idea of nicely labelled scripts - select a dot or postage stamp node, run the function and this will run through all the dots and PostageStamp nodes, until it finds the first node which is neither a stamp nor a dot. Then it grabs than name and labels all the dots and stamps with that name. This can be compined with a habit I see a lot of Houdini users have - make a NoOp node (Null in Houdini parlance) at the end of each action (so at the end of you key, or at the end of your transforms etc...) give it a nice colour and use that as the output of that section. This will label and colour all the dots and PostageStamps connected to that node the same so it's easy to see where they come from.

The last one toggles whether a node's input is hidden.

Adding hotkeys

All very well but no one will ever use these if they aren't accessible. Now we are going to add a menu and more importantly for regular usage, hotkeys.

##custom menu

danTools=nuke.menu("Nuke")
d=danTools.addMenu("&Danny")
d.addCommand("python/&bbox2B", "bbox_to_b()", "Shift+B")
d.addCommand("python/&Serve Raw", "serve_raw()", "Shift+R")
d.addCommand("python/&Label Dots and Stamps", "label_dots_and_stamps()", ",", shortcutContext=2)
d.addCommand("python/&Toggle Hide", "toggle_hide()", "shift+h")

So first we create a menu and assign it to a variable. Then we add all our custom functions to that menu. The syntax of the menu item is ("[menu]/[submenu]/[function lable]", "[hotkey]")

There is also an optional argument to give the hotkey a context, when I first shared my label function this function with another artist they pointed out that the ' hotkey in the Viewer is useful for changing exposure. By setting a Hotkey context we can have our custom hotkey only assigned where we need it (in this case in the DAG).

d.addCommand("python/&Label Dots and Stamps", "label_dots_and_stamps()", ",", shortcutContext=2)

This means that the ' hot key will still lower exposure in the Viewer, but will do it's new custom function in the DAG. You can click for a full explanation from the Foundry

Hope this is helpful!

Check out part 2 for some more customization fun.

modified May 17, 2020, 10:15 a.m.

Leave a comment:

Comments:

On July 18, 2020  Manooj Manoharan wrote:

Very much informative!