Created
November 12, 2015 00:15
-
-
Save jedypod/1a4256194f6821224307 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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