Ok, so I'm making an auto rigger for the spine: but there is one thing I must do before I move on, I just need to do one thing: I want the joint chain to fit between the two locators, unfortunately this task is a bit above my mental paygrade at the moment: here is the script if anyone wants to take a crack at it:
'''
import DS_hybrid_spineOmatic_V1
reload (DS_hybrid_spineOmatic_V1)
DS_hybrid_spineOmatic_V1.gui()
'''
import re
import maya.cmds as cmds
import maya.mel as mel
if cmds.window("spineWin", exists =True):
cmds.deleteUI("spineWin", window = True)
myWindow = cmds.window("spineWin",t='DS_hybrid_spineOmatic_V1',w=200, h=500, toolbox=True)
column = cmds.columnLayout(adj=True)
'''
To DO:
-You're going to have a series of scrips splitting into an IKFK spine and a ribon spine: this script will build the IKFK spine
'''
def gui():
cmds.button( label="Generate Spine Proxy Locators", c = buildProxies)
cmds.separator( w=200, h=3)
cmds.button( label="Build Spine Joints", c = buildJointChain)
cmds.separator( w=200, h=9)
cmds.setParent('..')
cmds.showWindow(myWindow)
def buildProxies(*args):
locAmount = 2
for i in range(locAmount):
countLoc = i+1
spaceLoc = cmds.spaceLocator(n = 'spineLoc_{}_PRX'.format(countLoc), p = [0,i*2.5,0])
cmds.makeIdentity(spaceLoc, a=1, t=1)
mel.eval('CenterPivot;')
cmds.select(cl=True)
def buildJointChain(*args):
cmds.select(cl=True) #this line clears your selection
jntAmount = 7
for jNum in range(jntAmount):
countJnt = jNum+1
spaceJnt = cmds.joint(n = 'spineJnt_{}_Bound'.format(countJnt), p = [0,jNum*1,0])
It doesn't have any errors: this is more of a technical question. I just need the joint chain to be equidistant between the 2 locators
You could probably do this purely with math, but since Maya already has its own framework to do this we can just use constraints to achieve this effect.
The idea is that we pick two objects it needs to constrain to, then we just adjust both constraint weights so that at first it blends perfectly with the first object, then half-way it'll be 50% of both, then finally blend perfectly to the end object. The 2nd weight will always be the exact opposite of the 1st weight, otherwise it wouldn't blend as expected.
Here's how we can go about doing that:
import maya.cmds as cmds
count = 20 # Amount of joints to create.
start = "locator1" # Change to object to start from.
end = "locator2" # Chagne to object to end to.
steps = 1.0 / (count - 1) # Will use count to calculate how much it should increase percentage by each iteration. Need to do -1 so the joints reach both start and end points.
perc = 0 # This will always go between a range of 0.0 - 1.0, and we'll use this in the constraint's weights.
for i in range(count):
jnt = cmds.createNode("joint") # Create a new joint.
cmds.setAttr(jnt + ".displayLocalAxis", True) # Display its orientation.
constraint = cmds.parentConstraint(start, jnt, weight=1.0 - perc)[0] # Apply 1st constraint, with inverse of current percentage.
cmds.parentConstraint(end, jnt, weight=perc) # Apply 2nd constraint, with current percentage as-is.
cmds.delete(constraint) # Don't need this anymore.
perc += steps # Increase percentage for next iteration.
The main thing is perc
will always be a range between 0.0 - 1.0, so the weights will always blend fine no matter how much you adjust the amount of joints to create. And since we're using cmds.parentConstraint
it will blend rotation too. If you don't want that then just switch it to cmds.pointConstraint
.
Here's an example with 6 joints between 2 locators (both locators are orientated differently so we see how they blend along the chain):
And the same example with 20 joints:
Oh one thing I forgot is parenting them all together. You can just append the new joints to a list as you go, then parent it to the last joint in the list (with the exception of the first one since there's nothing to parent to)