Stretchy Joint Chain Script

Here’s a quick thing I wrote up that simply makes the selected joints stretchy.
You just select the first and last joint and then all the ones in between will stretch to a new distance dimension shape. It works with joints of varying lengths.

Check it out:

import maya.cmds as cmds

"""
# StretchyJoint
# Benjamin Morgan
# 6/11/16
# Select start and end joint. Makes the joints inbetween stretch to the length of a distance dimension.
# Also creates an IK that can be deleted if not needed. 
"""



class StretchyJoint(object):
    def __init__(self):
        
        if len(cmds.ls(sl=1,o=1,type="joint")) != 2:
            cmds.confirmDialog(title="error",m="Please Select Start and End Joints")
            return
        
        # Init start and end joint attributes
        self.firstJoint = cmds.ls(sl=1,o=1,type="joint")[0]
        self.endJoint = cmds.ls(sl=1,o=1,type="joint")[1]
        self.firstJointPos = cmds.xform(self.firstJoint,q=1,t=1,ws=1)
        self.endJointPos = cmds.xform(self.endJoint,q=1,t=1,ws=1)
        
        # Gets the children between the two joints
        cmds.select(self.firstJoint,self.endJoint,hi=1)
        self.jointChain = cmds.ls(sl=1,o=1,type="joint")
        
        # Create the distance dimension
        self.startLoc = cmds.spaceLocator(n="startLoc#")
        self.endLoc = cmds.spaceLocator(n="endLoc#")
        cmds.xform(self.startLoc,t=(self.firstJointPos[0],self.firstJointPos[1],self.firstJointPos[2]))
        cmds.xform(self.endLoc,t=(self.endJointPos[0],self.endJointPos[1],self.endJointPos[2]))
        cmds.select(cl=1)
        cmds.select(self.startLoc,self.endLoc)
        self.distDim = cmds.distanceDimension()
        cmds.select(cl=1)
        cmds.select(self.distDim)
        self.distDimShape = cmds.pickWalk(d="down")[0]
        
        # Basic setup for finding the factor by which the distance has been changed. 
        self.distFactor = cmds.createNode("multiplyDivide",n="distFactor#")
        cmds.setAttr(self.distFactor + ".op",2)
        cmds.setAttr(self.distFactor + ".i2x",cmds.getAttr(self.distDimShape + ".distance"))
        cmds.connectAttr(self.distDimShape + ".distance",self.distFactor + ".i1x")
        
        # Start at 1 because we don't want the first joint's tx to change or else the whole chain will move
        i = 1
        while i < len(self.jointChain):
            # This node multiplies the joint's default length by the factor of stretch (ex: 2 * 1.5)
            comp = cmds.createNode("multiplyDivide",n=self.jointChain[i] + "Comp#")
            cmds.setAttr(comp + ".i1x",cmds.getAttr(self.jointChain[i] +".tx"))
            cmds.connectAttr(self.distFactor + ".ox",comp + ".i2x")
            cmds.connectAttr(comp + ".ox",self.jointChain[i] + ".tx")
            i += 1
        
        # Create the IK controls.
        cmds.group(self.startLoc,self.endLoc,self.distDim,n="ctrl_GRP#")
        self.jointIK = cmds.ikHandle(sj=self.firstJoint,ee=self.endJoint)
        self.ikGrp = cmds.group(self.jointIK[0],n="jointIK_GRP#")
        cmds.parent(self.ikGrp,self.endLoc)
        cmds.setAttr(self.ikGrp + ".visibility",0)
        
        
myStretchyJoint = StretchyJoint()

Advertisements
Image

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s