"""
Transforms scaleX values to translateX values on a list of keyed joints.
Author: ckurtz35@gmail.com
"""
# Imports
import maya.cmds
import maya.api.OpenMaya
def get_distance( obj_one, obj_two ):
"""
Gets the distance between two objects. Equivalent to using
the distance tool in Maya.
"""
# Get the objects' translation
trans_one = maya.cmds.xform( obj_one, t = 1, q = 1 )
trans_two = maya.cmds.xform( obj_two, t = 1, q = 1 )
# Convert the translation into MVector objects.
vector_one = maya.api.OpenMaya.MVector( trans_one )
vector_two = maya.api.OpenMaya.MVector( trans_two )
# Subtracting the two vectors gives us a new one that
# describes the distance between the two.
new_vec = vector_two - vector_one
# Taking the length of the vector gives us the
# actual distance
distance = new_vec.length( )
return distance
def main( joints ):
"""
Transforms scaleX values into translateX values on a set of joints.
"""
# Preventing the UI from refreshing
# speeds things up.
maya.cmds.refresh( suspend = True )
# Locators are used to get the distance
# between joints later on.
loc_one = maya.cmds.spaceLocator( )
loc_two = maya.cmds.spaceLocator( )
for jnt in joints:
# The child joint position determines the length of the current joint.
child_jnt = maya.cmds.listRelatives( jnt, children = 1, type = "joint" )
if not child_jnt:
continue
child_jnt = child_jnt[ 0 ]
# Constrain the locators to the two joints.
constraint_one = maya.cmds.pointConstraint( jnt, loc_one, mo = False )
constraint_two = maya.cmds.pointConstraint( child_jnt, loc_two, mo = False )
# We need to convert the scale value for each keyframe.
# CHANGE AXIS HERE IF NEEDED.
key_frames = maya.cmds.keyframe( "{0}.scaleX".format( jnt ), query = 1 )
if not key_frames:
continue
for k in key_frames:
maya.cmds.currentTime( k, edit = True )
# Getting the distance before and after we set the
# scale to 1 will give us the distance delta ( difference )
distance = get_distance( loc_one, loc_two )
maya.cmds.xform( jnt, s = [ 1.0, 1.0, 1.0 ] )
# CHANGE AXIS HERE IF NEEDED.
maya.cmds.setKeyframe( jnt, at = "scaleX", time = k )
new_distance = get_distance( loc_one, loc_two )
delta = distance - new_distance
# CHANGE AXIS HERE IF NEEDED.
child_len = maya.cmds.getAttr( "{0}.translateX".format( child_jnt ) )
# The distance delta is added to the child's translateX to get
# the correct length for our current joint.
if child_len < 0:
new_len = child_len - delta
else:
new_len = child_len + delta
# CHANGE AXIS HERE IF NEEDED.
maya.cmds.setAttr( "{0}.translateX".format( child_jnt ), new_len )
# CHANGE AXIS HERE IF NEEDED.
maya.cmds.setKeyframe( child_jnt, at = "translateX", time = k )
maya.cmds.delete( constraint_one )
maya.cmds.delete( constraint_two )
maya.cmds.delete( loc_one )
maya.cmds.delete( loc_two )
maya.cmds.refresh( suspend = False )