""" Package :- IKFK Dynamic Module :- IK_FK Spline Dynamic Description :- Make joint chain ik fk spline dynamic Creator :- Sanjeev Dhama Site :- https://www.sanjeevdhama.com """ import maya.cmds as cmds #============================================= Window UI ============================================ class splineDynamic(): def __init__(self,*arg): if cmds.window('ikFKSpline' ,exists = True): cmds.deleteUI('ikFKSpline',window = True) mywinodw = cmds.window('ikFKSpline',t='RigEdit IK FK Spline Dyn',mnb=0,mxb=0,wh =(210,150),bgc=(.45,.45,.45)) layerColor = (.55,.55,.55) btnColor = (.60,.65,.60) mainFramLayouout = cmds.frameLayout(lv=0,vis=0) splineFormLayout = cmds.formLayout() authorName = cmds.text(l='Author :- S.Dhama') framLayout = cmds.frameLayout(lv =0) formLayout = cmds.formLayout(bgc=layerColor) ikfKSplineTxt = cmds.text(l='-: Make Joint Chain IK FK Spline :-') self.ctrlNameField = cmds.textField(text='Ctrl_Name') noOfIKCtrlTxt = cmds.text(l='No Of IK Ctrl') self.ikCtrlField = cmds.intField(v=4,min=2,max=30,w=40) applyBtn = cmds.button(l='Apply',bgc=btnColor,c = self.runSetup) cmds.showWindow('ikFKSpline') cmds.formLayout(splineFormLayout,e=True,af=[(authorName, 'bottom',-01),(authorName, 'right',1)]) cmds.formLayout(splineFormLayout,e=True,af=[(framLayout, 'top',03),(framLayout, 'left',03), (framLayout, 'right',03),(framLayout, 'bottom',10)]) cmds.formLayout(formLayout,e=True,af=[(ikfKSplineTxt, 'top',5),(ikfKSplineTxt, 'left',20)]) cmds.formLayout(formLayout,e=True,af=[(self.ctrlNameField, 'top',30),(self.ctrlNameField, 'left',20),\ (self.ctrlNameField, 'right',20)]) cmds.formLayout(formLayout,e=True,af=[(self.ikCtrlField, 'top',60),(self.ikCtrlField, 'left',50)]) cmds.formLayout(formLayout,e=True,af=[(noOfIKCtrlTxt, 'top',63),(noOfIKCtrlTxt, 'left',40)]) cmds.formLayout(formLayout,e=True,af=[(self.ikCtrlField, 'top',60),(self.ikCtrlField, 'left',130)]) cmds.formLayout(formLayout,e=True,af=[(applyBtn, 'top',95),(applyBtn, 'left',40),\ (applyBtn, 'right',40)]) #============================================ IK FK Spline =========================================== def defCtrlMaker(self,defCtrlName): aCtrl = cmds.circle(n=defCtrlName+'_A',nr=(1,0,0),r=.3) bCtrl = cmds.circle(n=defCtrlName+'_B',nr=(0,1,0),r=.3) cCtrl = cmds.circle(n=defCtrlName+'_C',nr=(0,0,1),r=.3) bcCtrl = cmds.parent(cCtrl[0]+'Shape',aCtrl[0],s=1,r=1) cmds.delete(cCtrl) abcCtrl = cmds.parent(bCtrl[0]+'Shape',aCtrl[0],s=1,r=1) cmds.delete(bCtrl) aCtrlShape = cmds.listRelatives(aCtrl,s=1) for shapes in aCtrlShape: cmds.setAttr(shapes+'.overrideEnabled',1) cmds.setAttr(shapes+'.overrideColor',18) ctrlName = cmds.rename(aCtrl[0],defCtrlName) cmds.setAttr(ctrlName+'.v',l=1,k=0) return ctrlName def ikCtrlMaker(self,ikCtrlName='ss'): ikCtrl = cmds.curve(n=ikCtrlName,d= 1, p= [(-0.5 ,0.5, 0.5 ),( 0.5, 0.5, 0.5 ),( 0.5, 0.5, -0.5 ),\ ( -0.5, 0.5, -0.5 ),( -0.5, 0.5 ,0.5 ),( -0.5 ,-0.5, 0.5 ),(-0.5, -0.5, -0.5 ),( 0.5, -0.5, -0.5 ),\ ( 0.5, -0.5, 0.5 ),( -0.5, -0.5, 0.5 ),( 0.5, -0.5, 0.5 ),( 0.5, 0.5, 0.5 ),(0.5, 0.5, -0.5 ),\ ( 0.5, -0.5 ,-0.5 ),(-0.5, -0.5, -0.5 ),( -0.5, 0.5, -0.5)],k=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]) ikCtrlShape = cmds.listRelatives(ikCtrl,s=1) for shapes in ikCtrlShape: cmds.setAttr(shapes+'.overrideEnabled',1) cmds.setAttr(shapes+'.overrideColor',13) ctrlName = cmds.rename(ikCtrl,ikCtrlName) cmds.setAttr(ctrlName+'.v',k=0) cmds.setAttr(ctrlName+'.sx',l=1,k=0) cmds.setAttr(ctrlName+'.sy',l=1,k=0) cmds.setAttr(ctrlName+'.sz',l=1,k=0) return ctrlName def orientJntChain(self,*arg): mySell = cmds.ls(sl=1) cmds.makeIdentity(mySell,apply=1,t=1,r=1,s=1) endJntList = [] for i in range(len(mySell)): cmds.select(mySell[i],hi=1,r=1) newList = cmds.ls(sl=1) jntSize = len(newList) endJnt = newList[jntSize-1] endJntList.append(endJnt) dupJnts = cmds.duplicate(endJntList,po=1) for j in range(len(dupJnts)): cmds.parent(dupJnts[j],endJntList[j]) cmds.joint(mySell,e = 1,zso=1,oj='xyz',sao = 'yup',ch = 1) cmds.delete(dupJnts) cmds.select(mySell,r=1) def runSetup(self,*arg): jntSell = cmds.ls(sl=1,typ='joint') if jntSell: defCtrlList = [] ikCtrlList = [] ikCtrlGrpList = [] ikJntList = [] fkJntList = [] drvJntList =[] sknJntList =[] curvBindJntList = [] fkCtrlGrpList = [] fkCtrlList = [] noOfIKCtrl = cmds.intField(self.ikCtrlField,q=1,v=1)-1 name = cmds.textField(self.ctrlNameField,q=1,tx=1) globalCtrl = '' for i in cmds.ls(type = 'nurbsCurve'): crv = cmds.listRelatives(i,p=1)[0] if cmds.objExists(crv+'.globalCtrl'): globalCtrl = crv if not globalCtrl: globalCtrl = cmds.circle(n=name+'_Global_Ctrl',nr=(0,1,0),r=2,ch=0)[0] cmds.addAttr(globalCtrl,ln='globalCtrl',k=0,dt='string') cmds.addAttr(globalCtrl,ln='globalScale',min=.1,max=10,k=1) cmds.setAttr(globalCtrl+'.globalScale',1) cmds.setAttr(globalCtrl+'.v',k=0,l=1) attrList = ['sx','sy','sz'] for index in attrList: cmds.connectAttr(globalCtrl+'.globalScale',globalCtrl+'.'+index) cmds.setAttr(globalCtrl+'.'+index,k=0,l=1) cmds.select(jntSell[0],hi=1,r=1) for i in range(len(cmds.ls(sl=1))): ikJntName = cmds.rename((cmds.ls(sl=1)[i]),name+'_'+str('%0.2d' % i)+'_IK_Jnt') ikJntList.append(ikJntName) newSknJnt = cmds.ls(sl=1) cmds.select(ikJntList[0],r=1) self.orientJntChain() newJntSize = len(newSknJnt) endJnt = newJntSize-1 lastJnt = newSknJnt[endJnt] sknJnt = cmds.duplicate(newSknJnt[0],rc=1) fkJnt = cmds.duplicate(newSknJnt[0],rc=1) drvJnt = cmds.duplicate(newSknJnt[0],rc=1) for i in range(newJntSize): fkJntName = cmds.rename(fkJnt[i],name+'_'+str('%0.2d' % i)+'_FK_Jnt') fkJntList.append(fkJntName) for i in range(newJntSize): drvJntName = cmds.rename(drvJnt[i],name+'_'+str('%0.2d' % i)+'_Drv_Jnt') drvJntList.append(drvJntName) #================================= Making Ctrls ================================= for i in range(newJntSize-1): fkCtrl = cmds.circle(n = name+'_'+str('%0.2d' % i)+'_FK_Ctrl',nr=(1,0,0),r=.4) cmds.setAttr(fkCtrl[0]+'Shape.overrideEnabled',1,) cmds.setAttr(fkCtrl[0]+'Shape.overrideColor',17) cmds.setAttr(fkCtrl[0]+'.scaleX',l=1,k=0) cmds.setAttr(fkCtrl[0]+'.scaleY',l=1,k=0) cmds.setAttr(fkCtrl[0]+'.scaleZ',l=1,k=0) cmds.setAttr(fkCtrl[0]+'.v',l=1,k=0) fkCtrlList.append(fkCtrl) fkCtrlGrp = cmds.group(fkCtrl,n=fkCtrl[0]+'_Grp') fkCtrlOffsetGrp = cmds.group(fkCtrlGrp,n=fkCtrl[0]+'_Offset_Grp') fkCtrlMainGrp = cmds.group(fkCtrlOffsetGrp,n=fkCtrl[0]+'_Main_Grp') fkCtrlGrpList.append(fkCtrlMainGrp) cmds.delete(cmds.parentConstraint(newSknJnt[i],fkCtrlMainGrp)) cmds.parentConstraint(fkCtrl[0],name+'_'+str('%0.2d' % i)+'_FK_Jnt') for i in range(newJntSize-2): cmds.parent(fkCtrlGrpList[i+1],fkCtrlList[i]) baseCtrl = cmds.circle(n=name+'_Base_Ctrl',nr=(1,0,0),r=1)[0] cmds.addAttr(baseCtrl,ln = 'baseCtrl',k=0,dt='string') cmds.setAttr(baseCtrl+'.baseCtrl',str(name),type = 'string',l=1) cmds.addAttr(baseCtrl,ln='objName',dt='string') cmds.setAttr(baseCtrl+'.objName',name,type = 'string') cmds.setAttr(baseCtrl+'Shape.overrideEnabled',1,) cmds.setAttr(baseCtrl+'Shape.overrideColor',6) baseCtrlGrp = cmds.group(baseCtrl,n=baseCtrl+'_Grp') baseCtrlOffsetGrp = cmds.group(baseCtrlGrp,n=baseCtrl+'_Offset_Grp') baseCtrlMainGrp = cmds.group(baseCtrlOffsetGrp,n=baseCtrl+'_Main_Grp') cmds.delete(cmds.parentConstraint(newSknJnt[0],baseCtrlMainGrp)) cmds.parent(fkCtrlGrpList[0],baseCtrl) cmds.select(baseCtrlMainGrp,r=1) cmds.DeleteHistory() #========================== Set And Add Attr To Base_Ctrl =========================== cmds.setAttr(baseCtrl+'.scaleX',l=1,k=0) cmds.setAttr(baseCtrl+'.scaleY',l=1,k=0) cmds.setAttr(baseCtrl+'.scaleZ',l=1,k=0) cmds.setAttr(baseCtrl+'.v',l=1,k=0) cmds.addAttr(baseCtrl,ln='dynamicAttr',k=0) cmds.setAttr(baseCtrl+'.dynamicAttr',cb=1,l=1) cmds.addAttr(baseCtrl,ln='IKFK',min=0,max=1,k=1) cmds.addAttr(baseCtrl,ln='stretchy',at ='double',min=0,max=1,k=1) cmds.addAttr(baseCtrl,ln='twist',at ='long',k=1) cmds.addAttr(baseCtrl,ln='defCtrlVis',at='enum',en='No:yes',k=1) cmds.setAttr(baseCtrl+'.defCtrlVis',cb=1,k=0) for i in range(newJntSize): sknJntName = cmds.rename(sknJnt[i],name+'_'+str('%0.2d' % i)+'_Def_Skn_Jnt') defCtrlName = name+'_'+str('%0.2d' % i)+'_Def_Ctrl' defCtrl = self.defCtrlMaker(defCtrlName) defCtrlGrp = cmds.group(defCtrl,n=defCtrl+'_Grp') defCtrlOffsetGrp = cmds.group(defCtrlGrp,n=defCtrl+'_Offset_Grp') defCtrlMainGrp = cmds.group(defCtrlOffsetGrp,n=defCtrl+'_Main_Grp') cmds.delete(cmds.parentConstraint(sknJntName,defCtrlMainGrp)) cmds.parentConstraint(defCtrl,sknJntName) cmds.parentConstraint(drvJntList[i],defCtrlMainGrp) cmds.connectAttr(baseCtrl+'.defCtrlVis',defCtrlMainGrp+'.v') sknJntList.append(sknJntName) defCtrlList.append(defCtrlMainGrp) defCtrlListGrp = cmds.group(defCtrlList,n=name+'_Def_Ctrl_Grp') #================================== Making IK_Ctrl ================================== splineIK = cmds.ikHandle(n=name+'_Spline_IK',sj=newSknJnt[0],\ ee=lastJnt,sol='ikSplineSolver',ccv=1,ns=newJntSize,pcv=0) splineIkCrv = cmds.rename(splineIK[2],name+'_Spline_IK_Curve') cvPosesList = [] for tempPose in range(newJntSize): jntPos = cmds.xform(newSknJnt[tempPose],q=1,ws=1,t=1) cvPosesList.append(jntPos) tempCurv = cmds.curve(n='temp_curve',d=1,p=cvPosesList) cmds.rebuildCurve(tempCurv,spans=noOfIKCtrl) tempCurvShape = cmds.listRelatives(tempCurv,s=1) poc = cmds.pointOnCurve(tempCurv,top=1,ch=1) pocCurvInfo = cmds.listConnections(tempCurvShape,type = 'pointOnCurveInfo') for i in range(noOfIKCtrl+1): newPos = i*(1.0/noOfIKCtrl) cmds.setAttr(pocCurvInfo[0]+'.parameter',newPos) jntPos = cmds.getAttr(pocCurvInfo[0]+'.position') joints = cmds.joint(n=name+'_'+str("%0.2d" %i)+'_Curve_Bind_Jnt',p=jntPos[0]) curvBindJntList.append(joints) cmds.select(curvBindJntList[0],r=1) self.orientJntChain() ikCtrlVisRev = cmds.createNode('reverse',n=name+'_IK_Vis_Rev') cmds.connectAttr(baseCtrl+'.IKFK',ikCtrlVisRev+'.inputX') for i in range(noOfIKCtrl+1): ikCtrlName = name+'_'+str('%0.2d' % i)+'_IK_Ctrl' ikCtrl = self.ikCtrlMaker(ikCtrlName) ikCtrlList.append(ikCtrl) ikCtrlGrp = cmds.group(ikCtrl,n=ikCtrl+'_Grp') ikCtrlOffsetGrp = cmds.group(ikCtrlGrp,n=ikCtrl+'_Offset_Grp') ikCtrlMainGrp = cmds.group(ikCtrlOffsetGrp,n=ikCtrl+'_Main_Grp') ikCtrlGrpList.append(ikCtrlMainGrp) cmds.delete(cmds.parentConstraint(curvBindJntList[i],ikCtrlMainGrp)) cmds.parentConstraint(ikCtrl,curvBindJntList[i]) cmds.parent(ikCtrlMainGrp,baseCtrl) cmds.connectAttr(ikCtrlVisRev+'.outputX',ikCtrlMainGrp+'.v') for attr in range(len(ikCtrlList)-1): cmds.addAttr(ikCtrlList[attr+1],ln='parent',at='enum',en='Global:'+ikCtrlList[attr],k=True) prtCnt = cmds.parentConstraint(ikCtrlList[attr],ikCtrlGrpList[attr+1],mo=1,w=1)[0] prtCntTrg = cmds.parentConstraint(prtCnt,q=1,tl=1)[0] cmds.connectAttr(ikCtrlList[attr+1]+'.parent',prtCnt+'.'+prtCntTrg+'W0') cmds.delete(tempCurv) crvBindJntGrp = cmds.group(curvBindJntList,n=name+'_Curve_Bind_Jnt_Grp') cmds.setAttr(crvBindJntGrp+'.v',0,l=1) cmds.select(curvBindJntList,splineIkCrv,r=1) cmds.skinCluster(curvBindJntList,splineIkCrv,dr=4.5) #=================================== Attr Connections ================================== ikBlendRev = cmds.createNode('reverse',n=name+'_IK_Blend_Rev') cmds.connectAttr(baseCtrl+'.IKFK',ikBlendRev+'.inputX') for i in range(newJntSize): tBlendColor = cmds.createNode('blendColors',n = name+'_'+str('%0.2d' % i)+'_T_Blend_Color') rBlendColor = cmds.createNode('blendColors',n = name+'_'+str('%0.2d' % i)+'_R_Blend_Color') cmds.connectAttr(ikJntList[i]+'.t',tBlendColor+'.color1') cmds.connectAttr(fkJntList[i]+'.t',tBlendColor+'.color2') cmds.connectAttr(ikJntList[i]+'.r',rBlendColor+'.color1') cmds.connectAttr(fkJntList[i]+'.r',rBlendColor+'.color2') cmds.connectAttr(tBlendColor+'.output',drvJntList[i]+'.t') cmds.connectAttr(rBlendColor+'.output',drvJntList[i]+'.r') cmds.connectAttr(ikBlendRev+'.outputX',tBlendColor+'.blender') cmds.connectAttr(ikBlendRev+'.outputX',rBlendColor+'.blender') cmds.connectAttr(baseCtrl+'.IKFK',fkCtrlGrpList[0]+'.v') #=================================== Stretchy Joints ================================== splineIKCrvArclen = cmds.arclen(splineIkCrv,ch=1) ikCrvInfo=cmds.rename(splineIKCrvArclen,name+'_Dyn_IK_Curv_Info') ikCrvInfoValue = cmds.getAttr(ikCrvInfo+'.arcLength') globalScaleMD = cmds.createNode('multiplyDivide',n=name+'_Global_Scale_MD') cmds.setAttr(globalScaleMD+'.operation',2) cmds.connectAttr(ikCrvInfo+'.arcLength',globalScaleMD+'.input1X') cmds.connectAttr(globalCtrl+'.globalScale',globalScaleMD+'.input2X') stretchyOnOffCND = cmds.createNode('condition',n=name+'_Stretchy_On_Off_CND') cmds.setAttr(stretchyOnOffCND+'.operation',3) cmds.setAttr(stretchyOnOffCND+'.colorIfFalseR',ikCrvInfoValue) cmds.connectAttr(globalScaleMD+'.outputX',stretchyOnOffCND+'.firstTerm') cmds.connectAttr(globalScaleMD+'.outputX',stretchyOnOffCND+'.colorIfTrueR') stretchyOnOffBC = cmds.createNode('blendColors',n=name+'_Stretchy_On_Off_BC') cmds.setAttr(stretchyOnOffBC+'.color2R',ikCrvInfoValue) cmds.connectAttr(baseCtrl+'.stretchy',stretchyOnOffBC+'.blender') cmds.connectAttr(stretchyOnOffCND+'.outColorR',stretchyOnOffBC+'.color1R') ikCrvArclenMD = cmds.createNode('multiplyDivide',n=name+'_Dyn_Curve_Arclen_MD') cmds.setAttr(ikCrvArclenMD+'.operation',2) cmds.setAttr(ikCrvArclenMD+'.input2X',ikCrvInfoValue) cmds.connectAttr(stretchyOnOffBC+'.outputR',ikCrvArclenMD+'.input1X') cmds.connectAttr(baseCtrl+'.twist',splineIK[0]+'.twist') for jntTx in range(newJntSize-1): txValue = cmds.getAttr(newSknJnt[jntTx+1]+'.tx') jntTxMD = cmds.createNode('multiplyDivide',n=name+'_Stretchy_MD') cmds.setAttr(jntTxMD+'.input2X',txValue) cmds.connectAttr(ikCrvArclenMD+'.outputX',jntTxMD+'.input1X') cmds.connectAttr(jntTxMD+'.outputX',ikJntList[jntTx+1]+'.tx') rigGrp = cmds.group(name+'_Spline_IK',name+'_Spline_IK_Curve',n=name+'_Rig_Grp') cmds.setAttr(rigGrp+'.v',0,l=1) cmds.select(baseCtrl,r=1) cmds.confirmDialog(bgc=(0.7,0.7,0.7),t='Confirm...', m='Setup added successfully', icn = 'information',b= 'OK') jntsGrp = cmds.group(sknJntList[0],n=name+'_Joints_Grp') ctrlsGrp = cmds.group(defCtrlListGrp,baseCtrlMainGrp,crvBindJntGrp, jntsGrp,fkJntList[0],ikJntList[0],drvJntList[0],n=name+'_Ctrls_Grp') cmds.parent(ctrlsGrp,globalCtrl) cmds.select(baseCtrl,r=1) print '<<<<<<<<<<<<<<<<<<< Done >>>>>>>>>>>>>>>>>>>>>>' else: cmds.confirmDialog(t='Selection', m='Please Select Base Joint Of Chain', b=['OK'], db='Yes', cancelButton='No' ) splineDynamic()