def createBeingsSplineObjs(numIkCtls, numBndJnts, ctlSep=2, namer=None, ctlKwargs=None, doubleEndPoints=False): """ Create the components needed for a spline setup - ik controls, joints, a nurbs plane and a nurbs curve. @param numIkCtls: the number of ik controls to create @param numBndJnts: the number of bind joints to create. An extra 'tip' joint will also be created, so the total joints returned will be 1+numBndJnts """ if not namer: namer = utils.Namer('char', 'cn', 'spine') result = {} MC.select(cl=1) bndJnts = [] bndPosInc = ((numIkCtls-1) * ctlSep)/float(numBndJnts-1) for i in range(numBndJnts): pos = [0, i*bndPosInc, 0] name = namer(alphaSuf = i, r='bnd') if i == numBndJnts-1: name = namer('tip', r='bnd') j = MC.joint(p=pos, n=name) bndJnts.append(j) ikCtls = [] if not ctlKwargs: ctlKwargs = {'s': [2.5,.5, 2.5]} for i in range(numIkCtls): ikCtl = control.makeControl(namer('layout_ctl', r='ik', alphaSuf=i), **ctlKwargs) if i < numIkCtls: MC.setAttr('%s.ty' % ikCtl, i * ctlSep) else: MC.setAttr('%s.ty' % ikCtl, ((i-1) * ctlSep)+bndPosInc) ikCtls.append(ikCtl) result['curve'] = crv = curveFromNodes(ikCtls, name=namer('ikspline_crv'), doubleEndPoints=doubleEndPoints) result['surface'] = srf = surfaceFromNodes(ikCtls, name=namer('ikspline_srf'), doubleEndPoints=doubleEndPoints) result['ikCtls'] = ikCtls utils.fixInverseScale(bndJnts) result['jnts'] = bndJnts bindControlsToShape(ikCtls, crv, doubleEndPoints=doubleEndPoints) bindControlsToShape(ikCtls, srf, doubleEndPoints=doubleEndPoints) return result
def _makeRig(self, namer): jntCnt = self.options.getValue('numJnts') ikCtlCnt = self.options.getValue('numIkCtls') jntToks = self.__getToks(bndJnts=True) ctlToks = self.__getToks(ikCtls=True) bndJnts = [namer(t, r='bnd') for t in jntToks] MC.makeIdentity(bndJnts, apply=True, r=1, t=1, s=1) namer.setTokens(r='fk') fkCtls = [namer(t, r='fk') for t in jntToks[1:]] fkCtls = control.setupFkCtls(bndJnts[1:], fkCtls, jntToks[1:], namer) for ctl in fkCtls: control.setLockTag(ctl, uk=['rx', 'ry', 'rz']) for i, tok in enumerate(jntToks): self.setPlugNode(tok, bndJnts[i]) namer.setTokens(r='ik') ikJnts = utils.dupJntList(bndJnts[1:], jntToks[1:], namer) MC.setAttr('%s.v' % ikJnts[0], 0) ikCtls = [] for tok in ctlToks: n = namer(tok, r='ik') utils.insertNodeAbove(n) control.setLockTag(n, uk=['r', 't']) ikCtls.append(n) self.setPlugNode(tok, n) #doubling the cvs on the end allows us to build a curve with only 2 controls, #but causes popping otherwise. Only use if needed doubleEndPoints = False if ikCtlCnt == 1: doubleEndPoints = True crv = curveFromNodes(ikCtls, name=namer('ikspline_crv'), doubleEndPoints=doubleEndPoints ) srf = surfaceFromNodes(ikCtls, name=namer('ikspline_srf'), doubleEndPoints=doubleEndPoints) bindControlsToShape(ikCtls, crv, doubleEndPoints=doubleEndPoints) bindControlsToShape(ikCtls, srf, doubleEndPoints=doubleEndPoints) ikNode = setupSpineIkNode(ikCtls, ikJnts, nodeName='splinik', namer=namer, crv=crv, surf=srf) self.setNodeCateogry(ikNode, 'dnt') MC.setAttr("%s.v" % ikNode, 0) #parent the fk control to the ik control MC.parent(fkCtls[0], ikCtls[0]) utils.fixInverseScale(fkCtls[0]) #constrain the pelvis jnt to the first ik control MC.parentConstraint(ikCtls[0], bndJnts[0]) MC.scaleConstraint(ikCtls[0], bndJnts[0]) #tag this node so the master connect the uniform scale core.Root.tagInputScaleAttr(ikNode, 'inputScaleAmt') MC.addAttr(ikCtls[-1], ln='fkIk', dv=1, k=1, min=0, max=1) MC.addAttr(ikCtls[-1], ln='stretchAmt', dv=0, k=1, min=0, max=1) MC.addAttr(ikCtls[-1], ln='evenStretchAmt', dv=0, k=1, min=0, max=1) control.setLockTag(ikCtls[-1], uk=['fkIk', 'stretchAmt', 'evenStretchAmt']) MC.connectAttr('%s.stretchAmt' % ikCtls[-1], '%s.stretchAmt' % ikNode) MC.connectAttr('%s.evenStretchAmt' % ikCtls[-1], '%s.evenStretchAmt' % ikNode) #parent the ikCtls parentToFirst = [] parentToLast = [] numParentedCtlsPerSide = (ikCtlCnt/2)-1 parentToFirst = ikCtls[1:1+numParentedCtlsPerSide] parentToFirst = ikCtls[-1:-1-numParentedCtlsPerSide- ikCtlCnt % 2] _logger.debug('parentToFirst: %s' % parentToFirst) _logger.debug('parentToLast: %s' % parentToLast) for node in parentToFirst: zero = MC.listRelatives(node, parent=1)[0] MC.parent(zero, ikCtls[0]) for node in parentToLast: zero = MC.listRelatives(node, parent=1)[0] MC.parent(zero, ikCtls[-1]) ikReverse = utils.blendJointChains(fkCtls, ikJnts, bndJnts[1:], '%s.fkIk' % ikCtls[-1], namer) for ctl in fkCtls: MC.connectAttr('%s.outputX' % (ikReverse), '%s.v' % ctl) for ctl in ikCtls[1:-1]: MC.connectAttr('%s.fkIk' % (ikCtls[-1]), '%s.v' % ctl)
def _makeLayout(self, namer): MC.select(cl=1) jnts = [] layoutCtls= [] rigCtls = [] #the number of ik controls will really be 1 greater than this, because #we will parent the first ik control the the first fk control and hide #it numIkCtls = self.options.getValue('numIkCtls') numJnts = self.options.getValue('numJnts') ctlKwargs = {'shape': 'sphere', 'color': 'purple', 's': [1.5, .5, 1.5]} doubleEndPoints=False if numIkCtls == 2: doubleEndPoints=True nurbsObjs = createBeingsSplineObjs(numIkCtls, numJnts, namer=namer, ctlKwargs = ctlKwargs, doubleEndPoints=doubleEndPoints) jntToks = self.__getToks(bndJnts=True) #create a pelvis joint that will remain oriented to the base control jnts = nurbsObjs['jnts'] baseJnt = MC.joint(name=jntToks[0]) utils.fixInverseScale([baseJnt]) jnts.insert(0, baseJnt) for i in range(len(jnts)): jnts[i] = MC.rename(jnts[i], namer(jntToks[i], r='bnd')) self.registerBindJoint(jnts[i]) tipXform = MC.xform(jnts[-1], q=1, t=1, ws=1) tipXform[1] = tipXform[1] + 2 MC.select(jnts[-1]) tip = MC.joint(p=tipXform, n=namer('tip', r='bnd')) jnts.append(tip) bindNodesToSurface(jnts[:-1], nurbsObjs['surface'], skipTipOrient=True) #MC.orientConstraint(nurbsObjs['ikCtls'][-1], jnts[-2]) #create ik rig controls ikRigCtls = [] ikToks = self.__getToks(ikCtls=True) for i, ctl in enumerate(nurbsObjs['ikCtls']): self.registerControl(ctl, 'layout', uk=['ty','tz']) kwargs = {'color': 'yellow', 'shape': 'square', 's': [2, 2, 2]} n = namer(ikToks[i], r='ik') rigCtl = control.makeControl(n, **kwargs) MC.parent(rigCtl, ctl) MC.makeIdentity(rigCtl, t=1, r=1, s=1) control.setEditable(rigCtl, True) self.registerControl(rigCtl, 'rig') ikRigCtls.append(rigCtl) for i, tok in enumerate(jntToks[1:]): kwargs = {'color':'green', 'shape':'doublePin', 's': [2,2,2]} rigCtl = control.makeControl(namer(tok, r='fk'), **kwargs) utils.snap(jnts[i+1], rigCtl) MC.parent(rigCtl, jnts[i+1]) control.setEditable(rigCtl, True) self.registerControl(rigCtl, 'rig') #make a tip joint control tipCtl = control.makeControl(namer('tip_layout'), shape='cube', s=[.75, .75, .75], color='purple') utils.snap(tip, tipCtl) MC.parent(tipCtl, nurbsObjs['ikCtls'][-1]) self.registerControl(tipCtl, 'layout', uk=['ty', 'tz']) MC.pointConstraint(tipCtl, jnts[-1]) MC.aimConstraint(tipCtl, jnts[-2], aimVector = [0,1,0], upVector = [1,0,0], worldUpVector=[1,0,0])