Created
September 7, 2016 18:47
-
-
Save splinecraft/b556b5d2d0c58374bb1cbe4bf6cdc6ee to your computer and use it in GitHub Desktop.
Maya keyframe randomizer
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
""" | |
http://blog.cameronleger.com/mel/keyrandomizer/ | |
MAYA KEYFRAME RANDOMIZER | |
This is a Maya python script used for randomizing keyframe values or times. When applied over a range, a different randomization will be applied to each attribute and each key for it. Using the GUI you can select what attributes to modify, whether to modify them in space and/or time, and the ranges for modification. First, copy&paste this into the script editor, select all of it, and save it to your shelf. Then, select the objects you want to adjust their keyframes and run the script. | |
The first two checkboxes are for space / time modification. Spatial Keyframes will modify attribute values for each keyframe. Temporal Keyframes will modify the frame that the keyframes are on. | |
Min / Max Randomness is the amount to be applied to each value. The amount is added, so 0-1 will only produce positive alterations and -1-0 will only produce negative alterations. The value is a floating point number, so 0-1 will always randomly choose a decimal in between. | |
Start / End Frames is the frame range for randomization to happen. Anything outside of this range will not be affected. | |
The list of values to change are on the right side. Every value checked will be randomized in the frame range specified by the amount specified. If you choose a master box, such as translation, it will affect the three associated boxes equally, like translateX Y and Z. So selecting translate and translateY will randomize all translate values and then only translateY afterwards. | |
If you need to edit any additional attributes, you can add them in the attributes[] list near the top of the script. Keep in mind, if all selected objects don’t have the attribute or you don’t call it exactly as PyMEL calls the attributes, the script might error out. | |
NOTE: This script requires PyMEL. To use this script, you should paste the following into the Python section of the Script Window, and then execute the code. Or you could drag the selected code in the Python tab to the Shelf to create a shelf item for it. | |
""" | |
## This script requires pymel | |
## This script offers a way of randomizing many | |
## objects' keyframes in time and space | |
## You can select individual channels or their master channel | |
## Import pymel and the random module | |
from pymel.core import * | |
import random | |
## ---- VARIABLES ---- ## | |
## List of attributes to modify | |
attributes = ['translateX', 'translateY', 'translateZ', 'translate', 'rotateX', 'rotateY', 'rotateZ', 'rotate', 'scaleX', 'scaleY', 'scaleZ', 'scale', 'visibility'] | |
## New blank dictionary | |
attributeBoxes = {} | |
## New blank list | |
attributesToChange = [] | |
## ---- FUNCTIONS ---- ## | |
## Given a minimum and a maximum value, it checks | |
## if the minimum is actually lower than the maxmimum | |
## Equal values are okay, because then someone just | |
## wants to increase/decrease all values equally | |
def checkValues(min, max): | |
if min > max: | |
informBox("Error", "Your minimum value is higher than your maximum value", ok="Okay.") | |
return False | |
else: | |
return True | |
## Creates a new list of all the attributes to modify | |
def createList(): | |
tempAttribs = [] | |
## For each attribute and corresponding checkbox | |
for attr, box in attributeBoxes.iteritems(): | |
## If the box was checked and returned True | |
if box.getValue() is True: | |
## Append the key name to the modify list | |
attributesToChange.append(attr) | |
## Gets all of the values from the GUI | |
def randomize(): | |
## Prints the values from the checkboxes | |
createList() | |
## Create a tuple of the time range | |
timeFrame = (minFrame.getValue(), maxFrame.getValue()) | |
## Get the selection | |
selected = ls(selection=True) | |
## For each object in the selection | |
for object in selected: | |
## And each attribute for the object | |
for attribute in attributesToChange: | |
## Get the list of keys of that attribute in the time range | |
keyList = keyframe(object+"."+attribute, time=timeFrame, query=True) | |
## For each key | |
for key in keyList: | |
## Depending on what should change | |
## Change the objects attribute to a new random value | |
## The value is relative to it's current value | |
if spaceRand.getValue() is True: | |
changeAmount = random.uniform(maxRand.getValue(), minRand.getValue()) | |
keyframe(object+"."+attribute, valueChange=changeAmount, relative=True, time=(key, key)) | |
if timeRand.getValue() is True: | |
changeAmount = random.uniform(maxRand.getValue(), minRand.getValue()) | |
keyframe(object+"."+attribute, timeChange=changeAmount, relative=True, time=(key, key)) | |
deleteUI(gui, window=True) | |
## The function to call whenever the user pressed the button | |
def startRandomization(*Args): | |
## If both number ranges are fine, continue | |
if checkValues(minRand.getValue(), maxRand.getValue()) is not False: | |
if checkValues(minFrame.getValue(), maxFrame.getValue()) is not False: | |
randomize() | |
## ---- GUI SECTION ---- ## | |
## Makes a flow layout to arrange two columns side by side | |
gui = window(title="Key Randomizer", width=440) | |
mainLayout = flowLayout() | |
col01 = columnLayout(rowSpacing=5, parent=mainLayout, width=220) | |
col02 = columnLayout(rowSpacing=5, parent=mainLayout, width=220) | |
separator(h=20, parent=col01) | |
text(label="Which keyframes to randomize?", parent=col01) | |
spaceRand = checkBox(label="Spatial Keyframes", value=False, parent=col01) | |
timeRand = checkBox(label="Temporal Keyframes", value=False, parent=col01) | |
separator(h=20, parent=col01) | |
text(label="Min / Max Randomness", parent=col01) | |
minRand = floatField(value=-.5, parent=col01) | |
maxRand = floatField(value=.5, parent=col01) | |
separator(h=20, parent=col01) | |
text(label="Start / End Frames", parent=col01) | |
minFrame = intField(value=1, parent=col01) | |
maxFrame = intField(value=48, parent=col01) | |
separator(h=20, parent=col01) | |
goButton = button(label="Go!", command=startRandomization, parent=col01) | |
separator(h=20, parent=col02) | |
## For each item in the list of attributes, add a checkbox | |
## And store the name of the value as the key and the checkbox | |
## As the value in the blank dictionary we created earlier | |
for attribute in attributes: | |
attributeBoxes[attribute] = checkBox(label=attribute, value=False, parent=col02) | |
gui.show() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment