FK_IK Nodal Setup Script

Great progress today!

I was able to figure out the nodal setup to smoothly blend from FK to IK using orient constraints. My script has lots of comments, so hopefully you can follow along.

import maya.cmds as cmds

"""
This is a class that will take a set of 3 bones plus a driver attr and make a orient blend for them.
The driver must already have the attribute "IK_FK_Blend" on it.

Numerically, this node system does this:
    1    1    1   .5     0
    0   .5    1    1     1
"""

class ikFkBlend(object):
    def __init__(self,ik,fk,bind,switch):
        # init the ik fk and bind variables. These are just the names of the joints given
        self.ik = ik
        self.fk = fk
        self.bind = bind
        self.switch = switch
       
        # create the orient constraint that orients the bind to a blend of those two joints (1 and 1)
        self.orientConst = cmds.orientConstraint(ik,fk,bind)
        
        # our md_blend node divides our switch attribute value by -10 so that it will work with our weights which are between 1 and 0
        self.md_blend = cmds.createNode("multiplyDivide",n="md_blend#")
        cmds.setAttr(self.md_blend + ".i2x",-10)
        # an op of 2 is divide
        cmds.setAttr(self.md_blend + ".op",2)
        cmds.connectAttr(self.switch + ".IK_FK_Blend",self.md_blend + ".i1x")
        
        # our reverse_fk node takes our md_blend value and flips it so that we go from 1 down to zero when our switch value goes over 0.
        # If we didn't have this the values would go 1 1 1 .1 .2 .3 instead of 1 1 1 .9 .8 .7
        self.reverse_fk = cmds.createNode("reverse",n="reverse_fk#")
        cmds.connectAttr(self.md_blend + ".ox",self.reverse_fk + ".ix")
        
        # our fk_cond is a less than condition. If the swtich value is less than 0 it is equal to the reverse_fk value. Otherwise it's 1
        self.fk_cond = cmds.createNode("condition",n="fk_cond#")
        # an op of 4 is "less than"
        cmds.setAttr(self.fk_cond + ".op",4)
        cmds.setAttr(self.fk_cond + ".st",0)
        cmds.setAttr(self.fk_cond + ".cfr",1)
        cmds.connectAttr(self.reverse_fk + ".ox",self.fk_cond + ".ctr")
        cmds.connectAttr(self.switch + ".IK_FK_Blend",self.fk_cond + ".ft")
        
        # that should read as something like "b_shoulder_orientConstraint1.fk_shoulderW0"
        cmds.connectAttr(self.fk_cond + ".ocr",self.orientConst[0] + "." + self.fk + "W1")
        
        # this takes our blend node and multiplies it by -1
        self.ik_inv = cmds.createNode("multiplyDivide",n="ik_inv#")
        cmds.setAttr(self.ik_inv + ".i2x",-1)
        cmds.connectAttr(self.md_blend + ".ox",self.ik_inv + ".i1x")
        
        # this node reverses that value, allowing the value to count up from 0
        # If we hadn't reversed the md_blend value, the values would be 1 - -.5 and would give us values outside of our weight range
        self.reverse_ik = cmds.createNode("reverse",n="reverse_ik#")
        cmds.connectAttr(self.ik_inv + ".ox",self.reverse_ik + ".ix")
        
        # our ik condition is a greater than op that makes the out value 1 unless the switch value is greater than 0. If it is, the value is equal to teh reverse_ik val.
        self.ik_cond = cmds.createNode("condition",n="ik_condition#")
        # set the op to 2, or "greater than"
        cmds.setAttr(self.ik_cond + ".op",2)
        cmds.setAttr(self.ik_cond + ".st",0)
        cmds.setAttr(self.ik_cond + ".cfr",1)
        cmds.connectAttr(self.switch + ".IK_FK_Blend",self.ik_cond + ".ft")
        cmds.connectAttr(self.reverse_ik + ".ox",self.ik_cond + ".ctr")
        
        cmds.connectAttr(self.ik_cond + ".ocr",self.orientConst[0] + "." + self.ik + "W0")
        
elbowBlend = ikFkBlend("ik_elbow","fk_elbow","b_elbow","ik_fk_blend")
        
        

 

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