- #Spline autorig.  Select a curve and run what's below.  Can be used for non-straight curves
 - #orients joints along Z axis, creates duplicate rot joints.
 - import maya.cmds as mc
 - #Create list of curve
 - sel_crv=mc.ls(sl=True)
 - if len(sel_crv) != 1:
 -     mc.error("Select a curve you dingus.")
 - mc.select(cl=1)
 - #Rebuild Curve?
 - #----Set parameters----#
 - #Joints
 - num_jnts=49
 - name_jnts="tentacle"
 - #Number of Controls NOT YET FUNCTIONAL
 - #num_ctls=7
 - #Create Joint
 - prime_jnt=mc.joint(n=name_jnts)
 - #Duplicate-rename curve
 - spline_crv=mc.duplicate(sel_crv,n=name_jnts+'_crv')
 - mc.delete(sel_crv)
 - #Attach to motion trail
 - mc.select(prime_jnt, spline_crv[0], r=True)
 - jnt_mopath=mc.pathAnimation(upAxis='z', fractionMode=True, 
 -     endTimeU=num_jnts, 
 -     startTimeU=1, 
 -     worldUpType="vector", 
 -     inverseUp=False, 
 -     inverseFront=False, 
 -     follow=True, 
 -     bank=False, 
 -     followAxis='y', 
 -     worldUpVector=(0, 1, 0),
 -     name=name_jnts+'_motionPath')
 - #Create animated sweep/snapshot
 - mc.selectKey(jnt_mopath, add=1, k=1, t=(1, num_jnts))
 - mc.keyTangent(itt='linear', ott='linear')
 - #Create spline jnt chain
 - sik_jnt_list=[]
 - ct=1
 - mc.currentTime(ct)
 - while ct > num_jnts+1:
 -     mc.error('Oh shit')
 -     break
 - while ct != num_jnts+1:
 -     mc.currentTime(ct)
 -     new_jnt=mc.duplicate(prime_jnt, n=prime_jnt+'_sik_JNT_'+str(ct).zfill(3))
 -     sik_jnt_list.append(new_jnt)
 -     ct=ct+1
 - #Parent joint chain in ascending number
 - sik_jnt_list.reverse()
 - i=0
 - for each_jnt in sik_jnt_list[0:-1]:
 -     i=i+1
 -     mc.parent(each_jnt, sik_jnt_list[i])
 - mc.makeIdentity(sik_jnt_list[-1],n=0, s=1, r=1, t=1, apply=True, pn=1)
 - mc.joint(sik_jnt_list[-1],zso=1, ch=1, e=1, oj='zyx', secondaryAxisOrient='yup')
 - #Spline IK
 - mc.select(sik_jnt_list[-1],sik_jnt_list[0],spline_crv[0],r=True)
 - sik_handle=mc.ikHandle(scv=True, roc=True, pcv=False, ccv=False, c=spline_crv[0], sol='ikSplineSolver', tws='easeIn', n=name_jnts+'_ikHandle')
 - jnt_div_scale=mc.createNode('multiplyDivide', n=name_jnts+'_div_scale')
 - mc.setAttr(jnt_div_scale+'.operation', 2)
 - crv_len=mc.arclen(spline_crv[0]) 
 - crv_info=mc.arclen(spline_crv[0],ch=1)
 - mc.setAttr(jnt_div_scale+'.input2X', crv_len)
 - mc.connectAttr(crv_info+'.arcLength',jnt_div_scale+'.input1.input1X')
 - for each_jnt in sik_jnt_list:
 -     mc.connectAttr(jnt_div_scale+'.outputX',each_jnt[0]+'.sz')
 - mc.delete(prime_jnt)
 - sik_grp=mc.group(sik_handle[0],spline_crv[0],sik_jnt_list[-1], n=name_jnts+'_sik_GRP')
 - ##########CLUSTER DEFORMER GENERATION##########
 - #Find number of cvs by adding degrees and spans
 - degs = mc.getAttr( spline_crv[0]+'.degree' )
 - spans = mc.getAttr( spline_crv[0]+'.spans' )
 - cvs_cnt = degs + spans
 - #-2 for first two cvs, then -1 because 0 counts as a number in python lists
 - cv_adjust = cvs_cnt-3
 - start_cv = spline_crv[0]+'.cv[0:1]'
 - #mid_cvs=spline_crv[0]+'.cv[2:'+str(cv_adjust)+']'
 - end_cv = spline_crv[0]+'.cv['+str(cv_adjust+1)+':]'
 - #maintain "i" for numbering clusters
 - i = 0
 - strt_clstr = mc.cluster(start_cv,n=(spline_crv[0])[0:-4]+'_'+str(i+1).zfill(3))
 - i = i+2
 - #-2 to make number iterate through an amount of times equal to number of middle CVs exist
 - mid_clstr_list = []
 - while i < cv_adjust+1:
 -     mid_clstr=mc.cluster(spline_crv[0]+'.cv['+str(i)+']',n=(spline_crv[0])[0:-4]+'_'+str(i).zfill(3))
 -     mid_clstr_list.append(mid_clstr[1])
 -     i=i+1
 - end_clstr=mc.cluster(end_cv,n=(spline_crv[0])[0:-4]+'_'+str(i).zfill(3))
 - #Get list of created clusters
 - spline_clusters=[]
 - spline_clusters.append(strt_clstr[1])
 - for clstrs in mid_clstr_list:
 -     spline_clusters.append(clstrs)
 - spline_clusters.append(end_clstr[1])
 - clstr_grp=mc.group(spline_clusters,n=name_jnts+'_clstr_GRP')
 - mc.parent(clstr_grp,sik_grp)
 - #Use if ikHandle root on curve is false.  Consider parentConst instead
 - #mc.pointConstraint(spline_clusters[0],sik_jnt_list[-1],mo=True)
 - #joints are too big
 - rot_jnt_list=[]
 - rot_jnt_grp_list=[]
 - for ea_jnt in sik_jnt_list:
 -     #set radius of jnt
 -     mc.setAttr(ea_jnt[0]+'.radius',0.5)
 -     #extract number data
 -     jnt_num=(ea_jnt[0])[-3:]
 -     #duplicate out rotation bind joints to control twist
 -     rot_jnt=mc.duplicate(ea_jnt[0],n=name_jnts+'_rot_JNT_'+jnt_num, po=True)
 -     rot_jnt_list.append(rot_jnt)
 -     rot_jnt_grp=mc.group(rot_jnt,n=name_jnts+'_rot_OFF_'+jnt_num)
 -     rot_jnt_grp_list.append(rot_jnt_grp)
 -     mc.parent(rot_jnt_grp,ea_jnt[0])