Red9_AnimationUtils¶
Red9_AnimationUtils deals with all the key, attribute and time management within Red9. Anything from copying keys between processed hierarchies to Mirroring animation data.
Code examples:
ProcessNodes¶
All of the functions which have the ProcessNodes call share the same underlying functionality as described below. This is designed to process the given input nodes in a consistent manor across all the functions. Params: ‘nodes’ and ‘filterSettings’ are treated as special and build up a MatchedNode object that contains a tuple of matching pairs based on the given settings.
AnimFunctions example:¶
The main AnimFunctions class is designed to run with an r9Core.FilterNode object that is responsible for how we process hierarchies. If one isn’t passed as an arg then the code simply processes the ‘nodes’ args in zipped pairs. See the documentation on the r9Core.MatchedNodeInputs for more detail.
All the AnimFunctions such as copyKeys, copyAttrs etc use the same base setup
>>> import Red9_CoreUtils as r9Core >>> import maya.cmds as cmds >>> >>> #=========================== >>> # When Processing hierarchies: >>> #=========================== >>> # The Filter_Settings object required for hierarchy processing is now bound to >>> # the class directly so you no longer need to create a filterSettigns object directly! >>> # Lets set the filter to process nodes with a given attr 'myControl' who's type is 'nurbscurve' >>> animFunc=r9Anim.AnimFunctions() >>> animFunc.settings = r9Core.FilterNode_Settings() >>> animFunc.settings.nodeTypes ='nurbsCurve' >>> animFunc.settings.searchAttrs = 'myControl' >>> animFunc.settings.printSettings() >>> >>> # now run any of the AnimFunctions and pass in nodes which with the filter active >>> # as above would be the 2 root nodes of the hierarchies to filter >>> >>> animFunc.copyAttributes(cmds.ls(sl=True,l=True)) >>> >>> animFunc.snapTransform(nodes=cmds.ls(sl=True), time=r9Anim.timeLineRangeGet()) >>> >>> #============================== >>> # When processing simple objects: >>> #============================== >>> # If you simply ignore the filterSettings you can just process given nodes directly >>> # the nodes are zipped into selected pairs obj[0]>obj[1], obj[2]>obj[3] etc >>> anim = r9Anim.AnimFunctions() >>> anim.snapTransform(nodes=cmds.ls(sl=True), time=r9Anim.timeLineRangeGet())
Core Functions
getChannelBoxSelection () |
return a list of attributes selected in the ChannelBox |
getChannelBoxAttrs ([node, asDict, incLocked]) |
return the status of all attrs on the given node, either as a flat list or |
getSettableChannels ([node, incStatics]) |
return a list of settable attributes on a given node. |
getAnimLayersFromGivenNodes (nodes) |
return all animLayers associated with the given nodes |
timeLineRangeGet ([always]) |
Return the current PlaybackTimeline OR if a range is selected in the TimeLine, (Highlighted in Red) return that instead. |
timeLineRangeProcess (start, end, step[, incEnds]) |
Simple wrapper function to take a given framerange and return a list[] containing the actual keys required for processing. |
mergeAnimLayers (nodes[, deleteBaked]) |
from the given nodes find, merge and remove any animLayers found |
eulerSelected () |
cheap trick! for selected objects run a Euler Filter and then delete Static curves |
Core Classes
AnimationUI ([dockUI]) |
|
AnimFunctions ([filterSettings]) |
Most of the main Animation Functions take a settings object which is responsible for hierarchy processing. |
RandomizeKeys () |
This is a simple implementation of a Key Randomizer, designed to add noise to animations. |
FilterCurves () |
|
MirrorHierarchy ([nodes, filterSettings]) |
This class is designed to mirror pose and animation data on any given hierarchy. |
MirrorSetup () |
|
AnimationLayerContext (srcNodes[, ...]) |
Context Manager for merging animLayers down and restoring |
CameraTracker ([fixed]) |
-
RED_ANIMATION_UI_OPENCALLBACKS
= [<bound method Project.set_animtoolkit_UI of <r9project.Project object at 0x000000000BFFA860>>, <bound method Project.set_animtoolkit_UI of <r9project.Project object at 0x000000000BFFA860>>, <bound method Project.set_animtoolkit_UI of <r9project.Project object at 0x000000000BFFA860>>]¶ Callback globals so you can fire in commands prior to the UI opening, we use this internally to fire an asset sync call on our project pose library and to setup some additional paths.
- def myProjectCallback(cls)
- cls.poseHandlerPaths=[‘MyProjects/resources/poseHandlers’] cls.posePathProject =’My_projects/global/project/pose/lib’
r9Anim.RED_ANIMATION_UI_OPENCALLBACKS.append(myProjectCallback)
Note
the function calls bound to the callback are passed the current instance of the animUI class as an arg so you can modify as you need. Also when the PoseUI RMB popup menu is built, IF paths in the list cls.poseHandlerPaths are valid, then we bind into that popup all valid poseHandler.py files found the given path. This allow you to add custom handler types and expose them through the UI directly, they will show up in the RMB popup as such: Fingers_poseHandler.py will show as ‘Add Subfolder : FINGERS’
-
checkRunTimeCmds
()¶ Ensure the RedRuntime Command plugin is loaded.
-
getChannelBoxSelection
()¶ return a list of attributes selected in the ChannelBox
-
getNodeAttrStatus
(node=None, asDict=True, incLocked=True)¶ stub function/ wrapper of getChannelBoxAttrs as the name is a little misleading and not really what the function is doing in hindsight.
-
getChannelBoxAttrs
(node=None, asDict=True, incLocked=True)¶ return the status of all attrs on the given node, either as a flat list or a dict. As dict it contains all data which controls the lock, keyable, hidden states etc
statusDict={‘keyable’:attrs, ‘nonKeyable’:attrs, ‘locked’:attrs}
Parameters: - node – given node.
- asDict – True returns a dict with keys ‘keyable’,’locked’,’nonKeyable’ of attrs False returns a list (non ordered) of all attr states.
- incLocked – True by default - whether to include locked channels in the return (only valid if not asDict)
-
getSettableChannels
(node=None, incStatics=True)¶ return a list of settable attributes on a given node.
Parameters: - node – node to inspect.
- incStatics – whether to include non-keyable static channels (On by default).
FIXME: BUG some Compound attrs such as constraints return invalid data for some of the base functions using this as they can’t be simply set. Do we strip them here? ie: pointConstraint.target.targetWeight
-
getAnimLayersFromGivenNodes
(nodes)¶ return all animLayers associated with the given nodes
-
animLayersConfirmCheck
(nodes=None, deleteMerged=True)¶ return all animLayers associated with the given nodes
Parameters: - nodes – nodes to check membership of animLayers. If not pass the check will be at sceneLevel
- deleteMerged – modifies the warning message
-
mergeAnimLayers
(nodes, deleteBaked=True)¶ from the given nodes find, merge and remove any animLayers found
FOR THE LOVE OF GOD AUTODESK, fix animLayers and give us a decent api for them, oh, and stop building massive mel commands on the fly based on bloody optVars!!!!
-
pointOnPolyCmd
(nodes)¶ This is a BUG FIX for Maya’s command wrapping of the pointOnPolyCon which doesn’t support namespaces. This deals with that limitation
-
eulerSelected
()¶ cheap trick! for selected objects run a Euler Filter and then delete Static curves
-
animCurveDrawStyle
(style='simple', forceBuffer=True, showBufferCurves=False, displayTangents=False, displayActiveKeyTangents=True, *args)¶ Toggle the state of the graphEditor curve display, used in the Filter and Randomizer to simplify the display and the curve whilst processing. This allows you to also pass in the state directly, used by the UI close event to return the editor to the last cached state
-
animRangeFromNodes
(nodes, setTimeline=True)¶ return the extend of the animation range for the given objects :param nodes: nodes to examine for animation data :param setTimeLine: whether we should set the playback timeline to the extent of the found anim data
-
timeLineRangeGet
(always=True)¶ Return the current PlaybackTimeline OR if a range is selected in the TimeLine, (Highlighted in Red) return that instead.
Parameters: always – always return a timeline range, if none selected return the playbackRange. Return type: tuple Returns: (start,end)
-
timeLineRangeProcess
(start, end, step, incEnds=True)¶ Simple wrapper function to take a given framerange and return a list[] containing the actual keys required for processing. This manages whether the step is negative, if so it reverses the times. Basically just a wrapper to the python range function.
-
selectKeysByRange
(nodes=None, animLen=False)¶ select the keys from the selected or given nodes within the current timeRange or selectedTimerange
-
setTimeRangeToo
(nodes=None, setall=True)¶ set the playback timerange to be the animation range of the selected nodes. AnimRange is determined to be the extent of all found animation for a given node
-
class
AnimationLayerContext
(srcNodes, mergeLayers=True, restoreOnExit=True)¶ Bases:
object
Context Manager for merging animLayers down and restoring the data as is afterwards
-
class
AnimationUI
(dockUI=True)¶ Bases:
object
-
classmethod
show
()¶
-
setPoseSelected
(val=None, *args)¶ set the PoseSelected cache for the UI calls
-
getPoseSelected
()¶
-
buildPoseList
(sortBy='name')¶ Get a list of poses from the PoseRootDir, this allows us to filter much faster as it stops all the os calls, cached list instead
-
buildFilteredPoseList
(searchFilter)¶ build the list of poses to show in the poseUI TODO: hook up an order based by date in here as an option to tie into the UI
-
getPoseSubFolder
()¶ Return the given pose subFolder if set
-
getPoseDir
()¶ Return the poseDir including subPath
-
getPosePath
()¶ Return the full posePath for loading
-
getIconPath
()¶ Return the full posePath for loading
-
addPopupMenus_PoseHandlers
(parentPopup)¶ for a given list of folders containing poseHandler files add these as default ‘make subfolder’ types to the main poseUI popup menu
-
addPopupMenusFromFolderConfig
(parentPopup)¶ if the poseFolder has a poseHandler.py file see if it has the ‘posePopupAdditions’ func and if so, use that to extend the standard menu’s
-
classmethod
-
class
AnimFunctions
(filterSettings=None, **kws)¶ Bases:
object
Most of the main Animation Functions take a settings object which is responsible for hierarchy processing. See r9Core.FilterNode and r9Core.Filter_Settings for more details. These are then passed to the r9Core.MatchedNodeInputs class which is designed specifically to process two hierarchies and filter them for matching pairs. What this means is that all the anim functions deal with hierarchies in the same manor making it very simple to extend.
- Generic filters passed into r9Core.MatchedNodeInputs class:
- setting.nodeTypes: list[] - search for child nodes of type (wraps cmds.listRelatives types=)
- setting.searchAttrs: list[] - search for child nodes with Attrs of name
- setting.searchPattern: list[] - search for nodes with a given nodeName searchPattern
- setting.hierarchy: bool = lsHierarchy code to return all children from the given nodes
- setting.metaRig: bool = use the MetaRig wires to build the initial Object list up
Note
with all the search and hierarchy settings OFF the code performs a dumb copy, no matching and no Hierarchy filtering, copies using selected pairs obj[0]>obj[1], obj[2]>obj[3] etc
Note
filterSettings is also now bound to the class and if no filterSettings object is passed into any of the calls we use the classes instance instead. Makes coding a lot more simple as you can take an instance of AnimFunctions and just fill it directly before running the functions.
>>> # new functionality >>> animFunc=AnimFunctions() >>> animFunc.settings.nodeTypes=['nurbsCurve'] >>> animFunc.settings.searchPattern=['ctrl'] >>> animFunc.copyKeys([srcRootNode, destRootNode]) >>> >>> # old functionality >>> settings=r9Core.FilterSettings() >>> settings.nodeTypes=['nurbsCurve'] >>> settings.searchPattern=['ctrl'] >>> animFunc.copyKeys([srcRootNode, destRootNode], filterSettigns=settings)
-
copyKeys_ToMultiHierarchy
(nodes=None, time=(), pasteKey='replace', attributes=None, filterSettings=None, matchMethod=None, mergeLayers=True, **kws)¶ This isn’t the best way by far to do this, but as a quick wrapper it works well enough. Really we need to process the nodes more intelligently prior to sending data to the copyKeys calls
-
copyKeys
(nodes=None, time=(), pasteKey='replace', attributes=None, filterSettings=None, toMany=False, matchMethod=None, mergeLayers=False, timeOffset=0, **kws)¶ Copy Keys is a Hi-Level wrapper function to copy animation data between filtered nodes, either in hierarchies or just selected pairs.
Parameters: - nodes – List of Maya nodes to process. This combines the filterSettings object and the MatchedNodeInputs.processMatchedPairs() call, making it capable of powerful hierarchy filtering and node matching methods.
- filterSettings – Passed into the FilterNode code to setup the hierarchy filters see docs on the FilterNode_Settings class’ Note that this is also now bound to the class instance and if not passed in we use this classes instance of filterSettings cls.settings
- pasteKey – Uses the standard pasteKey option methods - merge,replace, insert etc. This is fed to the internal pasteKey method. Default=replace
- time – Copy over a given timerange - time=(start,end). Default is to use no timeRange. If time is passed in via the timeLineRange() function then it will consider the current timeLine PlaybackRange, OR if you have a highlighted range of time selected(in red) it’ll use this instead.
- attributes – Only copy the given attributes[]
- matchMethod – arg passed to the match code, sets matchMethod used to match 2 node names
- mergeLayers – this pre-processes animLayers so that we have a single, temporary merged animLayer to extract a compiled version of the animData from. This gets deleted afterwards.
TODO: this needs to support ‘skipAttrs’ param like the copyAttrs does - needed for the snapTransforms calls
-
copyAttrs_ToMultiHierarchy
(nodes=None, attributes=None, skipAttrs=None, filterSettings=None, matchMethod=None, **kws)¶ This isn’t the best way by far to do this, but as a quick wrapper it works well enough. Really we need to process the nodes more intelligently prior to sending data to the copyKeys calls
-
copyAttributes
(nodes=None, attributes=None, skipAttrs=None, filterSettings=None, toMany=False, matchMethod=None, **kws)¶ Copy Attributes is a Hi-Level wrapper function to copy Attribute data between filtered nodes, either in hierarchies or just selected pairs.
Parameters: - nodes – List of Maya nodes to process. This combines the filterSettings object and the MatchedNodeInputs.processMatchedPairs() call, making it capable of powerful hierarchy filtering and node matching methods.
- filterSettings – Passed into the FilterNode code to setup the hierarchy filters see docs on the FilterNode_Settings class’ Note that this is also now bound to the class instance and if not passed in we use this classes instance of filterSettings cls.settings
- attributes – Only copy the given attributes[]
- skipAttrs – Copy all Settable Attributes OTHER than the given, not used if an attributes list is passed
- matchMethod – arg passed to the match code, sets matchMethod used to match 2 node names
-
snapTransform
(nodes=None, time=(), step=1, preCopyKeys=1, preCopyAttrs=1, filterSettings=None, iterations=1, matchMethod=None, prioritySnapOnly=False, snapRotates=True, snapTranslates=True, **kws)¶ Snap objects over a timeRange. This wraps the default hierarchy filters so it’s capable of multiple hierarchy filtering and matching methods. The resulting node lists are snapped over time and keyed. :requires: SnapRuntime plugin to be available
Parameters: - nodes – List of Maya nodes to process. This combines the filterSettings object and the MatchedNodeInputs.processMatchedPairs() call, making it capable of powerful hierarchy filtering and node matching methods.
- filterSettings – Passed into the FilterNode code to setup the hierarchy filters see docs on the FilterNode_Settings class’ Note that this is also now bound to the class instance and if not passed in we use this classes instance of filterSettings cls.settings
- time – Copy over a given timerange - time=(start,end). Default is to use no timeRange. If time is passed in via the timeLineRange() function then it will consider the current timeLine PlaybackRange, OR if you have a highlighted range of time selected(in red) it’ll use this instead.
- step – Time Step between processing when using kws[‘time’] range this accepts negative values to run the time backwards if required
- preCopyKeys – Run a CopyKeys pass prior to snap - this means that all channels that are keyed have their data taken across
- preCopyAttrs – Run a CopyAttrs pass prior to snap - this means that all channel Values on all nodes will have their data taken across
- iterations – Number of times to process the frame.
- matchMethod – arg passed to the match code, sets matchMethod used to match 2 node names
- prioritySnapOnly – if True ONLY snap the nodes in the filterPriority list withing the filterSettings object = Super speed up!!
- snapTranslates – only snap the translate data
- snapRotates – only snap the rotate data
Note
you can also pass the CopyKey kws in to the preCopy call, see copyKeys above
Note
by default when using the preCopyKeys flag we run a temp merge of any animLayers and copy that merged animLayer data for consistency. The layers are restored afterwards
-
snapValidateResults
()¶ Run through the stored snap values to see if, once everything is processed, all the nodes still match. ie, you snap the Shoulders and strore the results, then at the end of the process you find that the Shoulders aren’t in the same position due to a driver controller shifting it because of hierarchy issues. TO IMPLEMENT
-
static
snap
(nodes=None, snapTranslates=True, snapRotates=True)¶ This takes 2 given transform nodes and snaps them together. It takes into account offsets in the pivots of the objects. Uses the API MFnTransform nodes to calculate the data via a command plugin. This is a stripped down version of the snapTransforms cmd
Parameters: - nodes – [src,dest]
- snapTranslates – snap the translate data
- snapRotates – snap the rotate data
-
static
stabilizer
(nodes=None, time=(), step=1, trans=True, rots=True)¶ This is designed with 2 specific functionalities: If you have a single node selected it will stabilize it regardless of it’s inputs or parent hierarchy animations If you pass in 2 objects then it will Track B to A (same order as constraints) This is primarily designed to aid in MoCap cleanup and character interactions. This now also allows for Component based track inputs, ie, track this nodes to this poly’s normal
Parameters: - nodes – either single (Stabilize) or twin to track
- time – [start,end] for a frameRange
- step – int value for frame advance between process runs
- trans – track translates
- rots – track rotates
-
bindNodes
(nodes=None, attributes=None, filterSettings=None, bindMethod='connect', matchMethod=None, **kws)¶ bindNodes is a Hi-Level wrapper function to bind animation data between filtered nodes, either in hierarchies or just selected pairs.
Parameters: - nodes – List of Maya nodes to process. This combines the filterSettings object and the MatchedNodeInputs.processMatchedPairs() call, making it capable of powerful hierarchy filtering and node matching methods.
- filterSettings – Passed into the FilterNode code to setup the hierarchy filters see docs on the FilterNode_Settings class’ Note that this is also now bound to the class instance and if not passed in we use this classes instance of filterSettings cls.settings
- attributes – Only copy the given attributes[]
- bindMethod – method of binding the data
- matchMethod – arg passed to the match code, sets matchMethod used to match 2 node names
TODO: expose this to the UI’s!!!!
-
static
inverseAnimChannels
(node, channels, time=None)¶ really basic method used in the Mirror calls
-
static
inverseAttributes
(node, channels)¶ really basic method used in the Mirror calls
-
class
curveModifierContext
(initialUndo=False, undoFuncCache=[], undoDepth=1)¶ Bases:
object
Simple Context Manager to allow modifications to animCurves in the graphEditor interactively by simply managing the undo stack and making sure that selections are maintained NOTE that this is optimized to run with a floatSlider and used in both interactive Randomizer and FilterCurves
Parameters: - initialUndo – on first process whether undo on entry to the context manager
- undoFuncCache – functions to catch in the undo stack
- undoDepth – depth of the undo stack to go to
-
undoCall
()¶
-
class
RandomizeKeys
¶ Bases:
object
This is a simple implementation of a Key Randomizer, designed to add noise to animations.
TODO: add in methods to generate secades type of flicking randomization, current implementation is too regular.
-
noiseFunc
(initialValue, randomRange, damp)¶ really simple noise func, maybe I’ll flesh this out at somepoint
-
classmethod
showOptions
()¶
-
interactiveWrapper
(*args)¶
-
addNoise
(curves, time=(), step=1, currentKeys=True, randomRange=[-1, 1], damp=1, percent=False, keepKeys=False)¶ Simple noise function designed to add noise to keyframed animation data.
Parameters: - curves – Maya animCurves to process
- time – timeRange to process
- step – frame step used in the processor
- currentKeys – ONLY randomize keys that already exists
- randomRange – range [upper, lower] bounds passed to teh randomizer
- damp – damping passed into the randomizer
- keepkeys – if True maintain current keys
-
curveMenuFunc
(*args)¶
-
-
class
FilterCurves
¶ Bases:
object
-
classmethod
show
()¶
-
simplifyWrapper
(*args)¶ straight simplify of curves using a managed cmds.simplfy call
-
resampleCurves
(*args)¶ straight resample of curves using a managed cmds.bakeResults call :param args[0]: this is the step used in the resample
-
snapAnimCurvesToFrms
(*args)¶ called after the interaction filters, snap
-
classmethod
-
class
MirrorHierarchy
(nodes=[], filterSettings=None, **kws)¶ Bases:
object
This class is designed to mirror pose and animation data on any given hierarchy. The hierarchy is filtered like everything else in the Red9 pack, using a filterSettings node thats passed into the __init__
>>> mirror=MirrorHierarchy(cmds.ls(sl=True)[0]) >>> # set the settings object to run metaData >>> mirror.settings.metaRig=True >>> mirror.settings.printSettings() >>> mirror.mirrorData(mode='Anim')
>>> # useful code snippets: >>> # offset all selected nodes mirrorID by 5 >>> mirror=r9Anim.MirrorHierarchy() >>> mirror.incrementIDs(cmds.ls(sl=True), offset=5) >>> >>> # set all the mirror axis on the selected >>> for node in cmds.ls(sl=True): >>> mirror.setMirrorIDs(node,axis='translateX,rotateY,rotateZ') >>> >>> # copy mirrorId's from one node to another >>> for src, dest in zip(srcNodes, destNodes): >>> mirror.copyMirrorIDs(src,dest)
TODO: We need to do a UI for managing these marker attrs and the Index lists TODO: allow the mirror block to include an offset so that if you need to inverse AND offset
by 180 to get left and right working you can still do so.Parameters: - nodes – initial nodes to process
- filterSettings – filterSettings object to process hierarchies
-
setMirrorIDs
(node, side=None, slot=None, axis=None)¶ Add/Set the default attrs required by the MirrorSystems.
Parameters: - node – nodes to take the attrs
- side – valid values are ‘Centre’,’Left’ or ‘Right’ or 0, 1, 2
- slot – bool Mainly used to pair up left and right paired controllers
- axis – eg ‘translateX,rotateY,rotateZ’ simple comma separated string If this is set then it overrides the default mirror axis. These are the channels who have their attribute/animCurve values inversed during mirror. NOT we allow axis to have a null string ‘None’ so it can be passed in blank when needed
Note
slot index can’t be ZERO
-
deleteMirrorIDs
(node)¶ Remove the given node from the MirrorSystems
-
copyMirrorIDs
(src, dest)¶ Copy mirrorIDs between nodes, note the nodes list passed in is zipped into pairs This will copy all the mirrorData from src to dest, useful for copying data between systems when the MirrorMap fails due to naming.
-
incrementIDs
(nodes, offset)¶ offset the mirrorIndex on selected nodes by a given offset
-
getNodes
()¶ Get the list of nodes to start processing
-
getMirrorSide
(node)¶ This is an enum Attr to denote the Side of the controller in the Mirror system
-
getMirrorIndex
(node)¶ get the mirrorIndex, these slots are used to denote matching pairs such that Left and Right Controllers to switch will have the same index
-
getMirrorCompiledID
(node)¶ This return the mirror data in a compiled mannor for the poseSaver such that mirror data for a node : Center, ID 10 == Center_10
-
getMirrorAxis
(node)¶ get any custom attributes set at node level to inverse, if none found return the default axis setup in the __init__
Parameters: node – node return the axis from Note
if mirrorAxis attr has been added to the node but is empty then no axis will be inversed at all. If the attr doesn’t exist then the default inverse axis will be used
-
getMirrorSets
(nodes=None)¶ Filter the given nodes into the mirrorDict such that {‘Centre’:{id:node,},’Left’:{id:node,},’Right’:{id:node,}}
Parameters: nodes – only process a given list of nodes, else run the filterSettings call from the initial nodes passed to the class
-
printMirrorDict
(short=True)¶ Pretty print the Mirror Dict
-
switchPairData
(objA, objB, mode='Anim')¶ take the left and right matched pairs and exchange the animData or poseData across between them
Parameters: - objA –
- objB –
- mode – ‘Anim’ or ‘Pose’
-
makeSymmetrical
(nodes=None, mode='Anim', primeAxis='Left')¶ similar to the mirrorData except this is designed to take the data from an object in one side of the mirrorDict and pass that data to the opposite matching node, thus making the anim/pose symmetrical according to the mirror setups. Really useful for facial setups!
Parameters: - nodes – optional specific listy of nodes to process, else we run the filterSetting code on the initial nodes past to the class
- mode – ‘Anim’ ot ‘Pose’ process as a single pose or an animation
- primeAxis – ‘Left’ or ‘Right’ whether to take the data from the left or right side of the setup
-
mirrorData
(nodes=None, mode='Anim')¶ Using the FilterSettings obj find all nodes in the return that have the mirrorSide attr, then process the lists into Side and Index slots before Mirroring the animation data. Swapping left for right and inversing the required animCurves
Parameters: - nodes – optional specific listy of nodes to process, else we run the filterSetting code on the initial nodes past to the class
- mode – ‘Anim’ ot ‘Pose’ process as a single pose or an animation
TODO: Issue where if nodeA on Left has NO key data at all, and nodeB on right does, then nodeB will be left incorrect. We need to clean the data if there are no keys.
-
saveMirrorSetups
(filepath)¶ Store the mirrorSetups out to file
-
loadMirrorSetups
(filepath, nodes=None, clearCurrent=True, matchMethod='stripPrefix')¶
-
class
CameraTracker
(fixed=True)¶ -
static
cameraTrackView
(start=None, end=None, step=None, fixed=True, keepOffset=False)¶ CameraTracker is a simple wrap over the internal viewFit call but this manages the data over time. Works by taking the current camera, in the current 3dView, and fitting it to frame the currently selected objects per frame, or rather per frameStep.
Parameters: - start – start frame
- end – end frame
- step – frame step to increment between fit
- fixed – switch between tracking or panning framing fit
- keepOffset – keep the current camera offset rather than doing a full viewFit
- TODO::
- add option for cloning the camera rather than using the current directly
-
classmethod
show
()¶
-
static
-
class
ReconnectAnimData
¶ Bases:
object
-
classmethod
show
()¶
-
static
reConnectReferencedAnimData
(*args)¶ As per my blog posts on Lost Animaton’s see here for details: http://markj3d.blogspot.co.uk/2011/07/lost-animation-when-loading-referenced.html
-
static
reConnectAnimDataBlind
(stripNamespace=True, stripLayerNaming=False, *args)¶ Blind reconnect based on names. As per my blog posts on Lost Animaton’s see here for details: http://markj3d.blogspot.co.uk/2012/09/lost-animation-part2.html
Parameters: - stripNamespace – Change this to False if the curves are not in the rootNamespace but in the sameNamespace as the controllers.
- stripLayerNaming – allows for the additional ‘Merged_Layer_inputB’ naming conventions
-
classmethod