A quick script here to convert Gizmos in Nuke into Groups. Gizmos are nice in theory in that they provide reusable groups of nodes for users to interact with, but they’re often more trouble than they’re worth, especially if you need to send your Nuke scripts to someone else. Here’s a script that just converts all the Gizmos in your scene into groups seamlessly:

import nuke

def isGizmo(node):
    return 'gizmo_file' in node.knobs()
    
def getGizmos():
    allNodes = nuke.allNodes()
    if allNodes:
        gizmos = [f for f in allNodes if isGizmo(f)]
        if gizmos:
            return gizmos
    return False

def deselectAll():
    # deselect all nodes.
    for i in nuke.allNodes():
        i.knob('selected').setValue(False)
        
def convertGizmoToGroup(gizmo):
    # convert a gizmo to an identical group.
    # delete the original, reconnect the group in the chain.
    # rename the group to match the original.
    inputs = []
    for x in range(0, gizmo.maximumInputs()):
        if gizmo.input(x):
            # print 'input: %s' % (gizmo.input(x).knob('name').value())
            inputs.append(gizmo.input(x))
        else:
            inputs.append(False)
    origName = gizmo.knob('name').value()
    origPosX = gizmo.xpos()
    origPosY = gizmo.ypos()
    deselectAll()
    # select knob, then run gizmo.makeGroup()
    gizmo.knob('selected').setValue(True)
    newGroup = gizmo.makeGroup()
    deselectAll()
    # delete original
    nuke.delete(gizmo)
    newGroup.knob('name').setValue(origName)
    newGroup['xpos'].setValue(origPosX)
    newGroup['ypos'].setValue(origPosY)
    # disconnect old inputs
    # reconnect inputs
    for x in range(0, newGroup.maximumInputs()):
        newGroup.setInput(x,None) 
        if inputs[x]:
            newGroup.connectInput(x, inputs[x])
        # print 'connecting output: %s to input: %s' % (inputs[x].knob('name').value(), newGroup.input(x).name())
    return newGroup
    
def convertGizmosToGroups():
    gizmos = getGizmos()
    if gizmos:
        for i in gizmos:
            convertGizmoToGroup(i)

There’s four methods here: first, a method to determine whether or not a node is a gizmo (by looking for a “gizmo_file” knob). Second, a method to find all gizmos by running isGizmo on every node in nuke.allNodes(). Third, the big function that does most of the heavy lifting. There’s a built-in API call that can run on gizmos called makeGroup() but by itself it’s not incredibly useful; it just wedges a converted copy of your Gizmo into the flow without doing anything to the original node, and it doesn’t name the group or anything. So this script is just adding onto that API call.

The first few lines of convertGizmoToGroup are creating an array of inputs so that we know what nodes are connected to the inputs of the gizmo. We’re just grabbing references to each input and stuffing it into the array. Next we record the name and position in the node graph of the original gizmo. We deselect everything and then set the “selected” knob of the gizmo to “True” (why we don’t have a real selection API call in Nuke, I’ll never know). Then we run the magic gizmo.makeGroup() command, which converts the gizmo into a group, but potentially leaves inputs disconnected, doesn’t delete the original gizmo, and doesn’t rename the new group. We do that in the next few lines; first deleting the original, then renaming our newGroup to match the original name, then setting the node graph position of the new group to match the original’s so it doesn’t mess up your organization. Finally, we loop through our array of inputs and connect them (in order) to the new group node. Pretty simple!

The last function is just a loop that converts every gizmo in the scene. You could import this module using menu.py and turn it into a button on a toolbar to quickly convert the whole scene from gizmos to groups by calling convertGizmosToGroups.

Hope it’s useful!

Categories: Python