1. #Spline autorig.  Select a curve and run what's below.  Can be used for non-straight curves
  2. #orients joints along Z axis, creates duplicate rot joints.
  3. import maya.cmds as mc
  4. #Create list of curve
  5. sel_crv=mc.ls(sl=True)
  6. if len(sel_crv) != 1:
  7.     mc.error("Select a curve you dingus.")
  8. mc.select(cl=1)
  9. #Rebuild Curve?
  10. #----Set parameters----#
  11. #Joints
  12. num_jnts=49
  13. name_jnts="tentacle"
  14. #Number of Controls NOT YET FUNCTIONAL
  15. #num_ctls=7
  16. #Create Joint
  17. prime_jnt=mc.joint(n=name_jnts)
  18. #Duplicate-rename curve
  19. spline_crv=mc.duplicate(sel_crv,n=name_jnts+'_crv')
  20. mc.delete(sel_crv)
  21. #Attach to motion trail
  22. mc.select(prime_jnt, spline_crv[0], r=True)
  23. jnt_mopath=mc.pathAnimation(upAxis='z', fractionMode=True, 
  24.     endTimeU=num_jnts, 
  25.     startTimeU=1, 
  26.     worldUpType="vector", 
  27.     inverseUp=False, 
  28.     inverseFront=False, 
  29.     follow=True, 
  30.     bank=False, 
  31.     followAxis='y', 
  32.     worldUpVector=(0, 1, 0),
  33.     name=name_jnts+'_motionPath')
  34. #Create animated sweep/snapshot
  35. mc.selectKey(jnt_mopath, add=1, k=1, t=(1, num_jnts))
  36. mc.keyTangent(itt='linear', ott='linear')
  37. #Create spline jnt chain
  38. sik_jnt_list=[]
  39. ct=1
  40. mc.currentTime(ct)
  41. while ct > num_jnts+1:
  42.     mc.error('Oh shit')
  43.     break
  44. while ct != num_jnts+1:
  45.     mc.currentTime(ct)
  46.     new_jnt=mc.duplicate(prime_jnt, n=prime_jnt+'_sik_JNT_'+str(ct).zfill(3))
  47.     sik_jnt_list.append(new_jnt)
  48.     ct=ct+1
  49. #Parent joint chain in ascending number
  50. sik_jnt_list.reverse()
  51. i=0
  52. for each_jnt in sik_jnt_list[0:-1]:
  53.     i=i+1
  54.     mc.parent(each_jnt, sik_jnt_list[i])
  55. mc.makeIdentity(sik_jnt_list[-1],n=0, s=1, r=1, t=1, apply=True, pn=1)
  56. mc.joint(sik_jnt_list[-1],zso=1, ch=1, e=1, oj='zyx', secondaryAxisOrient='yup')
  57. #Spline IK
  58. mc.select(sik_jnt_list[-1],sik_jnt_list[0],spline_crv[0],r=True)
  59. sik_handle=mc.ikHandle(scv=True, roc=True, pcv=False, ccv=False, c=spline_crv[0], sol='ikSplineSolver', tws='easeIn', n=name_jnts+'_ikHandle')
  60. jnt_div_scale=mc.createNode('multiplyDivide', n=name_jnts+'_div_scale')
  61. mc.setAttr(jnt_div_scale+'.operation', 2)
  62. crv_len=mc.arclen(spline_crv[0]) 
  63. crv_info=mc.arclen(spline_crv[0],ch=1)
  64. mc.setAttr(jnt_div_scale+'.input2X', crv_len)
  65. mc.connectAttr(crv_info+'.arcLength',jnt_div_scale+'.input1.input1X')
  66. for each_jnt in sik_jnt_list:
  67.     mc.connectAttr(jnt_div_scale+'.outputX',each_jnt[0]+'.sz')
  68. mc.delete(prime_jnt)
  69. sik_grp=mc.group(sik_handle[0],spline_crv[0],sik_jnt_list[-1], n=name_jnts+'_sik_GRP')
  70. ##########CLUSTER DEFORMER GENERATION##########
  71. #Find number of cvs by adding degrees and spans
  72. degs = mc.getAttr( spline_crv[0]+'.degree' )
  73. spans = mc.getAttr( spline_crv[0]+'.spans' )
  74. cvs_cnt = degs + spans
  75. #-2 for first two cvs, then -1 because 0 counts as a number in python lists
  76. cv_adjust = cvs_cnt-3
  77. start_cv = spline_crv[0]+'.cv[0:1]'
  78. #mid_cvs=spline_crv[0]+'.cv[2:'+str(cv_adjust)+']'
  79. end_cv = spline_crv[0]+'.cv['+str(cv_adjust+1)+':]'
  80. #maintain "i" for numbering clusters
  81. i = 0
  82. strt_clstr = mc.cluster(start_cv,n=(spline_crv[0])[0:-4]+'_'+str(i+1).zfill(3))
  83. i = i+2
  84. #-2 to make number iterate through an amount of times equal to number of middle CVs exist
  85. mid_clstr_list = []
  86. while i < cv_adjust+1:
  87.     mid_clstr=mc.cluster(spline_crv[0]+'.cv['+str(i)+']',n=(spline_crv[0])[0:-4]+'_'+str(i).zfill(3))
  88.     mid_clstr_list.append(mid_clstr[1])
  89.     i=i+1
  90. end_clstr=mc.cluster(end_cv,n=(spline_crv[0])[0:-4]+'_'+str(i).zfill(3))
  91. #Get list of created clusters
  92. spline_clusters=[]
  93. spline_clusters.append(strt_clstr[1])
  94. for clstrs in mid_clstr_list:
  95.     spline_clusters.append(clstrs)
  96. spline_clusters.append(end_clstr[1])
  97. clstr_grp=mc.group(spline_clusters,n=name_jnts+'_clstr_GRP')
  98. mc.parent(clstr_grp,sik_grp)
  99. #Use if ikHandle root on curve is false.  Consider parentConst instead
  100. #mc.pointConstraint(spline_clusters[0],sik_jnt_list[-1],mo=True)
  101. #joints are too big
  102. rot_jnt_list=[]
  103. rot_jnt_grp_list=[]
  104. for ea_jnt in sik_jnt_list:
  105.     #set radius of jnt
  106.     mc.setAttr(ea_jnt[0]+'.radius',0.5)
  107.     #extract number data
  108.     jnt_num=(ea_jnt[0])[-3:]
  109.     #duplicate out rotation bind joints to control twist
  110.     rot_jnt=mc.duplicate(ea_jnt[0],n=name_jnts+'_rot_JNT_'+jnt_num, po=True)
  111.     rot_jnt_list.append(rot_jnt)
  112.     rot_jnt_grp=mc.group(rot_jnt,n=name_jnts+'_rot_OFF_'+jnt_num)
  113.     rot_jnt_grp_list.append(rot_jnt_grp)
  114.     mc.parent(rot_jnt_grp,ea_jnt[0])