You are on page 1of 9

import fx

#
# Helper function which returns a function that calls
# a specified method of an object, passing in the argument list.
# Used to replace 'lambda', which is being phased out
#
def callMethod(func, *args, **kwargs):
def _return_func():
return func(*args, **kwargs)
return _return_func
# toggle for recursive subdivision preference
subdivide = fx.prefs["shape.subdivide"]
def toggleSubdivide():
global subdivide
subdivide = not subdivide
fx.prefs["shape.subdivide"] = subdivide
if subdivide:
fx.status("Subdivide: ON")
else:
fx.status("Subdivide: OFF")
# force an update of the node
node = fx.activeNode()
if node:
children = node.property("children")
children.invalidate()
node.invalidate()
fx.bind("Shift+Alt+r", toggleSubdivide)
def toggleRotateEdit():
if not fx.viewer.rotate:
fx.viewer.rotate = True
fx.viewer.hand = not fx.viewer.hand
fx.bind("Shift+r", toggleRotateEdit)
fx.viewer.setControlBind("rotate", "Shift+Ctrl+r")
fx.viewer.setToolTip("hand", "Shift+r")
#
# tool binds
#
# roto tools
fx.viewer.setToolBind("Transform", "t")
fx.viewer.setToolBind("Reshape", "r")
fx.viewer.setToolBind("IK", "y")
fx.viewer.setToolBind("B-Spline", "b")
fx.viewer.setToolBind("X-Spline", "s")

fx.viewer.setToolBind("Bezier", "Shift+b")
fx.viewer.setToolBind("Circle", "Shift+c")
fx.viewer.setToolBind("Square", "Shift+s")
fx.viewer.setToolBind("Feather", "Shift+f")
fx.viewer.setToolBind("Track", "Shift+t")
fx.viewer.setToolBind("MultiFrame", "m")
fx.viewer.setToolBind("Correspondence", "c")
# paint tools
fx.viewer.setToolBind("BW", "b")
fx.viewer.setToolBind("Blemish", "Shift+b")
fx.viewer.setToolBind("Blur", "Ctrl+b")
fx.viewer.setToolBind("Clone", "c")
fx.viewer.setToolBind("Color", "Shift+c")
fx.viewer.setToolBind("ColorCorrect", "Alt+c")
fx.viewer.setToolBind("Drag", "Shift+d")
fx.viewer.setToolBind("Eraser", "Shift+e")
fx.viewer.setToolBind("Grain", "g")
fx.viewer.setToolBind("Mosaic", "m")
fx.viewer.setToolBind("Repair", "r")
fx.viewer.setToolBind("Scatter", "s")
current_view = None
current_channels = None
def toggleOutputView():
global current_view
global current_channels
if current_view == None:
current_view = fx.viewer.viewNode
current_channels = fx.viewer.channelMask
fx.viewer.setViewNode("OutputNode")
if current_view == "RotoNode":
fx.viewer.setChannelMask(fx.Color(0, 0, 0, 1))
else:
fx.viewer.setViewNode(current_view)
fx.viewer.setChannelMask(current_channels)
current_view = None
fx.bind("Alt+o", toggleOutputView)
def cycleUpdateMode():
# cycle through the update modes
mode = fx.viewer.updateMode + 1
if mode >= len(fx.viewer.updateModes):
mode = 0
fx.viewer.setUpdateMode(mode)
current_mask = None
def cycleAlpha():
from fx import Color
global current_mask
if current_mask == None:
current_mask = Color(1, 1, 1, 0)

# cycle through the channel masks (RGBA, A, RGB)


mask = fx.viewer.channelMask
if mask.a == 0:
current_mask = fx.viewer.channelMask
mask.a = 1
fx.viewer.setChannelMask(mask)
elif mask == Color(0, 0, 0, 1):
fx.viewer.setChannelMask(current_mask)
else:
fx.viewer.setChannelMask(Color(0, 0, 0, 1))
fx.bind("1",
fx.bind("2",
fx.bind("3",
fx.bind("4",
fx.bind("5",
fx.bind("6",
fx.bind("7",

callMethod(fx.viewer.setViewMode,
callMethod(fx.viewer.setViewMode,
callMethod(fx.viewer.setViewMode,
callMethod(fx.viewer.setViewMode,
callMethod(fx.viewer.setViewMode,
callMethod(fx.viewer.setViewMode,
callMethod(fx.viewer.setViewMode,

fx.bind("~", cycleUpdateMode)
(Manual, Release, Drag)
fx.bind("a", cycleAlpha)
settings (RGBA, A, RGB)

0))
1))
2))
3))
4))
5))
6))

# cycle through update modes


# cycle through alpha

fx.viewer.setControlBind("updateMode", "~")
# this just sets
the tooltip
fx.viewer.setControlBind("channels", "a")
# this just sets the
tooltip
fx.viewer.setControlBind("overlay", "0")
fx.viewer.setControlBind("leftView", "Shift+1")
fx.viewer.setControlBind("rightView", "Shift+2")
fx.viewer.setControlBind("leftRightView", "Shift+3")
fx.viewer.setControlBind("stereoAlign", "Shift+4")
fx.viewer.setControlBind("stereoPreview", "Shift+5")
fx.viewer.setControlBind("stereoViewer", "Shift+6")
# example of how to manipulate the viewer streamMode
prev_view_mode = None
def cycleDepth():
global prev_view_mode
# make sure the current mask supports depth
if fx.viewer.streamMask & fx.StreamMask_Depth:
if prev_view_mode == None:
prev_view_mode = fx.viewer.streamMode
fx.viewer.streamMode = fx.StreamMask_Depth
else:
# restore the old mask
fx.viewer.streamMode = prev_view_mode
prev_view_mode = None
fx.bind("d", cycleDepth)
def zoomToFit():
fx.viewer.setZoom(-1.0)
def zoomHome():
fx.viewer.setZoom(1.0)

def centerSelection():
fx.viewer.centerSelection()
fx.bind("h", zoomHome)
fx.bind("f", zoomToFit)
fx.bind("Ctrl+f", centerSelection)
def toggleFadeOutline():
id = "shape.fadeOutline"
fx.prefs[id] = not fx.prefs[id]
fx.bind("v", toggleFadeOutline)
def zoomIn():
zf = fx.viewer.zoomFactor
fx.viewer.setZoom(fx.viewer.zoom * zf)
def zoomOut():
zf = fx.viewer.zoomFactor
fx.viewer.setZoom(fx.viewer.zoom / zf)
fx.bind("i", zoomIn)
fx.bind("o", zoomOut)
#
# player binds
#
fx.bind('Page Up', lambda : fx.player.stepBackward())
fx.bind('Page Down', lambda : fx.player.stepForward())
fx.bind('k', lambda : fx.player.stop())
fx.player.setControlBind("prev_key", "Shift+z")
fx.player.setControlBind("next_key", "Shift+x")
fx.player.setControlBind("home", "Home")
fx.player.setControlBind("step_backward", "z")
fx.player.setControlBind("play_backward", "j")
fx.player.setControlBind("play_forward", "l")
fx.player.setControlBind("step_forward", "x")
fx.player.setControlBind("end", "End")
# step forward/backward 5 frames
def stepFrames(count):
session = fx.activeSession()
if session:
range = session.workRange
start = session.startFrame
range = (range[0] - start, range[1] - start)
time = fx.player.frame + count
if time < range[0]:
time = range[0]
if time > range[1]:
time = range[1]
fx.player.setFrame(time)

fx.bind('Shift+Page Up', callMethod(stepFrames, -5))


fx.bind('Shift+Page Down', callMethod(stepFrames, 5))
# RGBA mode
rgba_mode = False
rgba_prev_view = 0
rgba_prev_channels = None
def rgba():
global rgba_mode
global rgba_prev_view
global rgba_prev_channels
rgba_mode = not rgba_mode
if rgba_mode:
rgba_prev_view = fx.viewer.viewMode
rgba_prev_channels = fx.viewer.channelMask
fx.viewer.setOverlay(False)
channels = fx.viewer.channelMask
channels.a = 1.0
fx.viewer.setChannelMask(channels)
fx.viewer.setViewMode(0)
else:
fx.viewer.setOverlay(True)
fx.viewer.setChannelMask(rgba_prev_channels)
fx.viewer.setViewMode(rgba_prev_view)
fx.bind('Shift+a', rgba)
prev_solo_mask = None
new_solo_mask = None
def soloChannel(mask):
global prev_solo_mask
global new_solo_mask
if prev_solo_mask == None:
prev_solo_mask = fx.viewer.channelMask
new_solo_mask = mask
fx.viewer.setChannelMask(mask)
elif mask != new_solo_mask:
fx.viewer.setChannelMask(mask)
new_solo_mask = mask
else:
fx.viewer.setChannelMask(prev_solo_mask)
prev_solo_mask = None
new_solo_mask = None
fx.bind('Alt+r',
fx.bind('Alt+g',
fx.bind('Alt+b',
fx.bind('Alt+a',

callMethod(soloChannel,
callMethod(soloChannel,
callMethod(soloChannel,
callMethod(soloChannel,

curr_channels = None

fx.Color(1,
fx.Color(0,
fx.Color(0,
fx.Color(0,

0,
1,
0,
0,

0,
0,
1,
0,

0)))
0)))
0)))
1)))

# template mode
template_mode = False
fx.prefs["shape.templateColor"] = fx.Color(0, 1, 0, 0.8)
def toggleTemplateMode():
global template_mode
template_mode = not template_mode
if template_mode:
fx.prefs["viewer.templateMode"] = True
fx.status("Template mode: ENABLED")
else:
fx.prefs["viewer.templateMode"] = False
fx.status("Template mode: DISABLED")
fx.bind("Shift+w", toggleTemplateMode)
#
# Edit Tool anchor point
#
def toggleAnchor():
if fx.viewer.toolName == "Transform":
fx.viewer.toolCommand("toggleAnchor")
elif fx.viewer.toolName == "Color":
fx.viewer.toolCommand("pickColor")
def resetAnchor():
if fx.viewer.toolName == "Transform":
fx.viewer.toolCommand("setAnchor")
fx.bind('.', toggleAnchor)
fx.bind('Shift+.', resetAnchor)
#
# Quick Mode toggles
#
def quickMode(mode):
tool = fx.viewer.toolName
if tool == "Transform" or tool == "Clone":
state = fx.viewer.queryTool(mode) == "1"
fx.viewer.toolCommand(mode, not state)
if tool == "Clone":
fx.paint.setOnionSkin(not state)
fx.bind("q", callMethod(quickMode, "translate"))
fx.bind("w", callMethod(quickMode, "rotate"))
fx.bind("e", callMethod(quickMode, "scale"))
fx.bind("Ctrl+w", callMethod(quickMode, "rotate_no_anchor"))
fx.bind("Ctrl+e", callMethod(quickMode, "scale_no_anchor"))
#

# Paint
#
fx.paint.brushEditModifier = fx.ControlModifier
fx.paint.cloneOffsetModifier = fx.ShiftModifier
def beginCloneOffset():
tool = fx.viewer.toolName
if tool == "Clone":
fx.viewer.toolCommand("beginOffset")
fx.bind(",", beginCloneOffset)
fx.bind("Ctrl+1",
fx.bind("Ctrl+2",
fx.bind("Ctrl+3",
fx.bind("Ctrl+4",

callMethod(quickMode,
callMethod(quickMode,
callMethod(quickMode,
callMethod(quickMode,

"cp_tl"))
"cp_tr"))
"cp_br"))
"cp_bl"))

def resetClone():
if fx.viewer.toolName == "Clone":
fx.paint.cloneOffset = fx.Point3D(0, 0)
def invertCloneOffset():
if fx.viewer.toolName == "Clone":
fx.paint.cloneOffset = -fx.paint.cloneOffset
fx.bind("Shift+q", invertCloneOffset);
fx.bind("Alt+q", resetClone);
def setCloneSetup(index):
if fx.viewer.toolName == "Clone":
fx.paint.setState("Clone.preset", index)
def toggleDualClone():
if fx.viewer.toolName == "Clone":
mode = fx.paint.getState("Clone.dualMode")
mode = not mode
fx.paint.setState("Clone.dualMode", mode)
fx.bind("Shift+Alt+1", callMethod(setCloneSetup, 0))
fx.bind("Shift+Alt+2", callMethod(setCloneSetup, 1))
fx.bind("Shift+Ctrl+1", toggleDualClone)
def setCloneSourceView(index):
if fx.viewer.toolName == "Clone":
fx.paint.setCloneSourceView(index)
def setPaintPreset(index):
fx.paint.preset = index
fx.bind("Alt+1",
fx.bind("Alt+2",
fx.bind("Alt+3",
fx.bind("Alt+4",
fx.bind("Alt+5",
fx.bind("Alt+6",
fx.bind("Alt+7",

callMethod(setPaintPreset,
callMethod(setPaintPreset,
callMethod(setPaintPreset,
callMethod(setPaintPreset,
callMethod(setPaintPreset,
callMethod(setPaintPreset,
callMethod(setPaintPreset,

0))
1))
2))
3))
4))
5))
6))

fx.bind("Alt+8", callMethod(setPaintPreset, 7))


fx.bind("Alt+9", callMethod(setPaintPreset, 8))
fx.bind("Alt+0", callMethod(setPaintPreset, 9))
def replayStroke():
if fx.activeNode().type == "PaintNode":
fx.paint.replay()
fx.bind("Ctrl+k", replayStroke)
def toggleView(view):
visible = fx.viewVisible(view)
fx.showView(view, not visible)
# desired default clone view mode
clone_view_mode = fx.paint.View_Onion
def toggleOnionSkin():
global clone_view_mode
current_mode = fx.paint.cloneViewMode
if current_mode == fx.paint.View_Normal:
current_mode = clone_view_mode
else:
# save the current state for later
clone_view_mode = current_mode
current_mode = fx.paint.View_Normal
fx.paint.cloneViewMode = current_mode
# disable quick mode when doing this
if fx.viewer.toolName == "Clone":
cmds = ["translate", "rotate", "scale"]
for c in cmds:
if fx.viewer.queryTool(c) == "1":
fx.viewer.toolCommand(c, False)
fx.bind("CapsLock", toggleOnionSkin)
def decreaseBrushSize():
if fx.activeNode().type == "PaintNode":
fx.paint.brushSize = fx.paint.brushSize * 0.9
def increaseBrushSize():
if fx.activeNode().type == "PaintNode":
fx.paint.brushSize = fx.paint.brushSize * 1.1
fx.bind("[", decreaseBrushSize)
fx.bind("]", increaseBrushSize)
#
# Shape Editing
#
def selectAllPoints():
if fx.viewer.toolName == "Reshape":
fx.viewer.toolCommand("selectAllPoints");
if fx.viewer.toolName == "Clone":
fx.paint.setAlign(not fx.paint.align)

def deselectAllPoints():
if fx.viewer.toolName == "Reshape":
fx.viewer.toolCommand("deselectAllPoints");
def invertPoints():
if fx.viewer.toolName == "Reshape":
fx.viewer.toolCommand("invertPoints");
def copyPoints():
if fx.viewer.toolName == "Reshape":
session = fx.activeSession()
start = session.startFrame
frame = int(start + fx.player.frame)
fx.status("Copy points reference frame = %d" % (frame))
fx.viewer.toolCommand("copyPoints");
def pastePoints():
if fx.viewer.toolName == "Reshape":
fx.viewer.toolCommand("pastePoints");
session = fx.activeSession()
start = session.startFrame
frame = int(start + fx.player.frame)
fx.status("Selected points copied from frame %d." % (frame))
fx.bind("Shift+Alt+a", selectAllPoints)
fx.bind("Ctrl+Alt+a", deselectAllPoints)
fx.bind("Ctrl+Alt+i", invertPoints)
fx.bind("Ctrl+Alt+c", copyPoints)
fx.bind("Ctrl+Alt+v", pastePoints)
def modifyPoints(mode):
if fx.viewer.toolName == "Reshape":
fx.viewer.toolCommand(mode)
fx.bind("Ctrl+Alt+1", callMethod(modifyPoints, "cornerPoints"))
fx.bind("Ctrl+Alt+2", callMethod(modifyPoints, "cardinalPoints"))
fx.bind("Ctrl+Alt+3", callMethod(modifyPoints, "bsplinePoints"))
def toggleMotionBlur():
fx.beginUndo("Toggle Motion Blur")
for shape in fx.selection():
if isinstance(shape, fx.Shape):
mb = shape.property("motionBlur")
mb.setValue(not mb.getValue(0))
fx.endUndo()
fx.bind("Ctrl+m", toggleMotionBlur)

You might also like