Skip to content

Instantly share code, notes, and snippets.

@jedypod
Created November 12, 2015 00:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jedypod/1a4256194f6821224307 to your computer and use it in GitHub Desktop.
Save jedypod/1a4256194f6821224307 to your computer and use it in GitHub Desktop.
import nuke, operator
'''
## Add these lines to your menu.py after putting this file somewhere in your NUKE_PATH
# Manipulate nodes in the node graph
import node_handler
nuke.menu('Nuke').addCommand('Edit/Node/Move/Right', 'node_handler.move(1,0)', 'alt+meta+Right')
nuke.menu('Nuke').addCommand('Edit/Node/Move/Left', 'node_handler.move(-1,0)', 'alt+meta+Left')
nuke.menu('Nuke').addCommand('Edit/Node/Move/Up', 'node_handler.move(0,-1)', 'alt+meta+Up')
nuke.menu('Nuke').addCommand('Edit/Node/Move/Down', 'node_handler.move(0,1)', 'alt+meta+Down')
nuke.menu('Nuke').addCommand('Edit/Node/Move/Right Big', 'node_handler.move(4,0)', 'alt+meta+shift+Right')
nuke.menu('Nuke').addCommand('Edit/Node/Move/Left Big', 'node_handler.move(-4,0)', 'alt+meta+shift+Left')
nuke.menu('Nuke').addCommand('Edit/Node/Move/Up Big', 'node_handler.move(0,-8)', 'alt+meta+shift+Up')
nuke.menu('Nuke').addCommand('Edit/Node/Move/Down Big', 'node_handler.move(0,8)', 'alt+meta+shift+Down')
nuke.menu('Nuke').addCommand('Edit/Node/Move/Scale Up Vertical', 'node_handler.scale(1, 1.1)', 'ctrl+alt+meta+=')
nuke.menu('Nuke').addCommand('Edit/Node/Move/Scale Down Vertical', 'node_handler.scale(1, 0.9)', 'ctrl+alt+meta+-')
nuke.menu('Nuke').addCommand('Edit/Node/Move/Scale Up Horizontal', 'node_handler.scale(1.1, 1)')
nuke.menu('Nuke').addCommand('Edit/Node/Move/Scale Down Horizontal', 'node_handler.scale(0.9, 1)', 'alt+meta+-')
nuke.menu('Nuke').addCommand('Edit/Node/Move/Expand One Grid Unit', 'node_handler.expand()', 'alt+meta+=')
nuke.menu('Nuke').addCommand('Edit/Node/Move/Contract One Grid Unit', 'node_handler.expand(True)', )
nuke.menu("Nuke").addCommand('Edit/Node/Move/Mirror Horizontally', 'node_handler.mirror(direction="x")', 'ctrl+alt+shift+m')
nuke.menu("Nuke").addCommand('Edit/Node/Move/Mirror Vertically', 'node_handler.mirror(direction="y")', '')
nuke.menu("Nuke").addCommand('Edit/Node/Move/Align Horizontally', 'node_handler.align(direction="x")', 'alt+meta+shift+x')
nuke.menu("Nuke").addCommand('Edit/Node/Move/Align Vertically', 'node_handler.align(direction="y")', '')
'''
def move(xdir, ydir):
grid_x = int(nuke.toNode('preferences').knob('GridWidth').value())
grid_y = int(nuke.toNode('preferences').knob('GridHeight').value())
nodes = nuke.selectedNodes()
for node in nodes:
node.setXYpos(int(node.xpos() + grid_x * xdir), int(node.ypos() + grid_y * ydir))
def align(direction = 'x' ):
'''
Align nodes either horizontally or vertically.
'''
nodes = nuke.selectedNodes()
if len( nodes ) < 2:
return
if direction.lower() not in ('x', 'y'):
raise ValueError, 'direction argument must be x or y'
positions = [ float( n[ direction.lower()+'pos' ].value() ) for n in nodes]
avrg = sum( positions ) / len( positions )
for n in nodes:
if direction == 'x':
for n in nodes:
n.setXpos( int(avrg) )
else:
for n in nodes:
n.setYpos( int(avrg) )
return avrg
def mirror( direction = 'x' ):
'''
Mirror nodes either horizontally or vertically.
'''
nodes = nuke.selectedNodes()
if len( nodes ) < 2:
return
if direction.lower() not in ('x', 'y'):
raise ValueError, 'direction argument must be x or y'
# Find lowest value to use as a pivot
min_y = nodes[0].ypos()
min_x = nodes[0].xpos()
for n in nodes:
min_y = min(min_y, n.ypos())
min_x = min(min_x, n.xpos())
if direction.lower() == 'x':
#positions = [ float( n.xpos()+n.screenWidth()/2 ) for n in nodes ]
axis = min_x
else:
axis = min_y
#positions = [ float( n.ypos()+n.screenHeight()/2 ) for n in nodes ]
#axis = sum( positions ) / len( positions )
for n in nodes:
if direction.lower() == 'x':
n.setXpos( int( n.xpos() - 2*(n.xpos()+n.screenWidth()/2-axis) ) )
else:
n.setYpos( int( n.ypos() - 2*(n.ypos()+n.screenHeight()/2-axis) ) )
return axis
def expand(shrink=False):
# Expand nodes by adding 1 additional grid space between every x position
# TODO Currently doubles the current spacing instead of working one unit at a time
# TODO Currently shrinking is broken
grid_x = int(nuke.toNode('preferences').knob('GridWidth').value())
grid_y = int(nuke.toNode('preferences').knob('GridHeight').value())
nodes = nuke.selectedNodes()
node_positions = {node : node.xpos() for node in nuke.selectedNodes()}
sorted_node_positions = sorted(node_positions.items(), key=operator.itemgetter(1))
min_x_pos = sorted_node_positions[0][1]
max_x_pos = sorted_node_positions[-1][1]
sel_length = max_x_pos - min_x_pos
print min_x_pos, max_x_pos, sel_length
grid_spaces_occupied = (max_x_pos - min_x_pos) / grid_x
for item in sorted_node_positions:
pos = item[1]
node = item[0]
pos_perc = float(pos - min_x_pos)/float(sel_length)
offset = pos_perc * grid_spaces_occupied * grid_x
if not shrink:
new_pos = int(pos + offset)
else:
new_pos = int(pos - offset)
print "Grid position:", pos, ": Perc", pos_perc, ": Offset", offset, ": New Pos", new_pos
node.setXYpos(new_pos, node.ypos())
def scale( xScale, yScale=None ):
def getSideNodes( bd ):
''' Return a given backdrop node's "side nodes" (left, right, top andbottom most nodes)
as a dictionary including the nodes and the respective DAG coordinates
'''
origSel = nuke.selectedNodes()
[ n.setSelected( False ) for n in origSel ]
bd.selectNodes()
bdNodes = nuke.selectedNodes()
[ n.setSelected( False ) for n in bdNodes ] #DESELECT BACKDROP NODES
[ n.setSelected( True ) for n in origSel ] #RESTORE ORIGINAL SELECTION
if not bdNodes:
return []
leftNode = rightNode = bottomNode = topNode= bdNodes[0] # START WITH RANDOM NODE
for n in bdNodes:
if n.xpos() < leftNode.xpos():
leftNode = n
if n.xpos() > rightNode.xpos():
rightNode = n
if n.ypos() < topNode.ypos():
topNode = n
if n.ypos() > bottomNode.ypos():
bottomNode = n
return dict( left=[leftNode, nuke.math.Vector2( leftNode.xpos(), leftNode.ypos()) ], right=[rightNode, nuke.math.Vector2( rightNode.xpos(), rightNode.ypos()) ], top=[topNode, nuke.math.Vector2( topNode.xpos(), topNode.ypos()) ], bottom=[bottomNode, nuke.math.Vector2( bottomNode.xpos(), bottomNode.ypos()) ])
# MAKE THINGS BACKWARDS COMPATIBLE
yScale = yScale or xScale
# COLLECT SIDE NODES AND COORDINATES FOR BACKDROPS
backdrops = {}
bds = [ n for n in nuke.selectedNodes() if n.Class() == 'BackdropNode']
for bd in bds:
backdrops[bd] = getSideNodes( bd )
# MOVE NODES FROM CENTRE OUTWARD
nodes = [ n for n in nuke.selectedNodes() if n.Class() != 'BackdropNode' ]
if len(nodes) < 1:
return
min_y = nodes[0].ypos()
max_x = nodes[0].xpos()
for n in nodes:
min_y = min(min_y, n.ypos())
max_x = max(max_x, n.xpos())
for n in nodes:
n.setXpos( int( max_x + ( n.xpos() - max_x ) * xScale ) )
n.setYpos( int( min_y + ( n.ypos() - min_y ) * yScale ) )
#ADJUST BACKDROP NODES
for bd, bdSides in backdrops.iteritems():
leftDelta = bdSides['left'][0].xpos() - bdSides['left'][1].x
topDelta = bdSides['top'][0].ypos() - bdSides['top'][1].y
rightDelta = bdSides['right'][0].xpos() - bdSides['right'][1].x
bottomDelta = bdSides['bottom'][0].ypos() - bdSides['bottom'][1].y
bd.setXpos( int( bd.xpos() + leftDelta ) )
bd.setYpos( int( bd.ypos() + topDelta ) )
bd['bdwidth'].setValue( int( bd['bdwidth'].value() - leftDelta + rightDelta ) )
bd['bdheight'].setValue( int( bd['bdheight'].value() - topDelta + bottomDelta ) )
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment