0% found this document useful (0 votes)
52 views

Key Binds

This document defines keyboard shortcuts and custom functions for navigating, manipulating objects, and using tools in a 3D modeling or animation software. It sets bindings for common commands like zooming and playback controls. It also defines functions for toggling features like subdivision, switching views, and cycling through tool modes. Customizations are provided for tools like cloning, painting, and selecting channels.

Uploaded by

Goce Stavreski
Copyright
© © All Rights Reserved
Available Formats
Download as RTF, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
52 views

Key Binds

This document defines keyboard shortcuts and custom functions for navigating, manipulating objects, and using tools in a 3D modeling or animation software. It sets bindings for common commands like zooming and playback controls. It also defines functions for toggling features like subdivision, switching views, and cycling through tool modes. Customizations are provided for tools like cloning, painting, and selecting channels.

Uploaded by

Goce Stavreski
Copyright
© © All Rights Reserved
Available Formats
Download as RTF, PDF, TXT or read online on Scribd
You are on page 1/ 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