Example #1
0
def setupSpineIkNode(ctlList, jntList, surf=None, crv=None, nodeName='beings_splineik', namer=None):
    """
    Create an ik spline system using controls in the ctlList that will drive jnts in jntList
    """
    if not namer:
        namer = utils.Namer('char', 'cn', 'spine')
    if not surf:
        surf = surfaceFromNodes(ctlList)
    surf = getShape(surf)
    if not crv:
        crv = curveFromNodes(ctlList)
    crv = getShape(crv)

    ikNode = MC.createNode('transform', name=namer(nodeName))
    MC.parent(MC.listRelatives(surf, parent=1)[0], ikNode)
    MC.parent(MC.listRelatives(crv, parent=1)[0], ikNode)

    namer.setTokens(r='ik')
    names = ['stretch_%s' % ascii_lowercase[i] for i in range(len(jntList))]
    stretchJnts = utils.dupJntList(jntList, names, namer)

    #rebuild the curve so that we get more even parameterization for 'even stretch'
    #joints.  Use a 7 degree curve so we can build with a single span
    evenStretchCrv = MC.rebuildCurve(MC.listRelatives(crv, parent=1)[0],
                    ch=1, rpo=0, rt=0, end=1, kr=2, kcp=0, kep=1, kt=0, s=1, d=7, tol=0.01)[0]
    evenStretchCrv = MC.rename(evenStretchCrv, "%s_evenstretch" % crv)
    MC.parent(evenStretchCrv, ikNode)
    evenStretchCrv = getShape(evenStretchCrv)


    nodes = {'posi':[], 'cps': [], 'posiUp':[], 'xform':[], 'xformUp':[]}

    #for each joint, get the param at the rebuilt curve.  Use this position to get
    #the closest point on the surface, then get the u and v values at that surface
    #point.
    for i, jnt in enumerate(stretchJnts):
        suff = ascii_lowercase[i]
        #get point on rebuild curve near each jnt
        poci = MC.createNode('pointOnCurveInfo', n='%s_%s_evenstretch_poci' % (ikNode, suff))
        MC.connectAttr("%s.worldSpace[0]" % evenStretchCrv, '%s.ic' % poci)
        MC.setAttr('%s.pr' % poci, closestParamOnCurve(jnt, evenStretchCrv))

        #get closest point on surface
        cps = MC.createNode("closestPointOnSurface", n='%s_%s_evenstretch_cps' % (ikNode, suff))
        MC.connectAttr("%s.worldSpace[0]" % surf, '%s.is' % cps)
        MC.connectAttr("%s.p" % poci, "%s.ip" % cps)
        nodes['cps'].append(cps)


    MC.addAttr(ikNode, ln='evenStretchAmt', min=0, max=1, k=1)

    for i, jnt in enumerate(stretchJnts):

        #create a point on surface info node at each point
        suff = ascii_lowercase[i]
        posi = MC.createNode('pointOnSurfaceInfo', n='%s_%s_posi' % (ikNode, suff))
        posiUp = MC.createNode('pointOnSurfaceInfo', n='%s_%s_up_posi' % (ikNode, suff))
        MC.connectAttr('%s.worldSpace[0]' % surf, '%s.is' % posi)
        MC.connectAttr('%s.worldSpace[0]' % surf, '%s.is' % posiUp)

        u, v = closestParamOnSurface(jnt, surf)

        for node in [posi, posiUp]:
            blender = MC.createNode("blendColors", name='%s_%s_evenstretch_blc' % (ikNode, suff))
            MC.connectAttr('%s.evenStretchAmt' % ikNode, '%s.blender' % blender)
            #as the evenStretchAmt increases, shift towards the u value of the even stretch crv
            MC.connectAttr("%s.u" % nodes['cps'][i], "%s.c1r" % blender)
            MC.setAttr("%s.c2r" % blender, u)
            MC.connectAttr("%s.opr" % blender, '%s.u' % node)


        MC.setAttr('%s.v' % posi, v)
        MC.setAttr('%s.v' % posiUp, v-.25)

        posXform = MC.createNode("transform", n='%s_%s_grp' % (ikNode, suff))
        upXform = MC.createNode("transform", n='%s_%s_up_grp' % (ikNode, suff))
        MC.parent(posXform, ikNode)
        MC.parent(upXform, ikNode)

        MC.connectAttr("%s.p" % posi, "%s.t" % posXform)
        MC.connectAttr("%s.p" % posiUp, "%s.t" % upXform)

        MC.pointConstraint(posXform, jnt)
        utils.fixJointConstraints(posXform)

        nodes['posi'].append(posi)
        nodes['posiUp'].append(posiUp)
        nodes['xform'].append(posXform)
        nodes['xformUp'].append(upXform)

    #now that all the xforms are created, aim them at each other and
    #measure the start stretch distance
    MC.addAttr(ikNode, ln='inputScaleAmt', dv=1, k=1)

    for i in range(len(stretchJnts)-1):
        suff = ascii_lowercase[i]
        nextSuff = ascii_lowercase[i+1]

        dst = MC.createNode('distanceBetween', n='%s_%s_to_%s_dist' % \
                      (ikNode,suff, nextSuff))

        MC.connectAttr("%s.p" % nodes['posi'][i], '%s.p1' % dst)
        MC.connectAttr("%s.p" % nodes['posi'][i+1], '%s.p2' % dst)
        MC.addAttr(ikNode, ln = "origDistToNext_%s" % suff, h=False,
                   dv=MC.getAttr("%s.d" % dst))
        stretchMdn = MC.createNode("multiplyDivide",
                                   n='%s_%s_stretch_mdn' % (ikNode, suff))

        MC.connectAttr('%s.d' % dst, '%s.input1X' % stretchMdn)
        MC.connectAttr('%s.origDistToNext_%s' % (ikNode, suff),
                       '%s.input2X' % stretchMdn)
        MC.setAttr('%s.operation' % stretchMdn, 2)

        stretchSclMdn = MC.createNode("multiplyDivide",
                                   n='%s_%s_stretch_scl_mdn' % (ikNode, suff))

        MC.setAttr('%s.operation' % stretchSclMdn, 2)
        MC.connectAttr('%s.outputX' % stretchMdn, '%s.input1X' % stretchSclMdn)
        MC.connectAttr('%s.inputScaleAmt' % ikNode, '%s.input2X' % stretchSclMdn)

        MC.addAttr(ikNode, ln = "stretchAmt_%s" % suff, k=1)
        MC.connectAttr('%s.outputX' % stretchSclMdn, '%s.stretchAmt_%s' \
                       % (ikNode, suff))

        #connect stretch amount to joint scale
        MC.connectAttr('%s.stretchAmt_%s' % (ikNode, suff),
                       '%s.sy' % stretchJnts[i])


        #aim the xforms
        MC.aimConstraint(nodes['xform'][i+1],
                         nodes['xform'][i],
                         aimVector=[0,1,0],
                         upVector=[1,0,0],
                         worldUpType='object',
                         worldUpObject=nodes['xformUp'][i])


        MC.orientConstraint(nodes['xform'][i], stretchJnts[i])
        utils.fixJointConstraints(stretchJnts[i])
        utils.fixJointConstraints(nodes['xform'][i])

    MC.orientConstraint(ctlList[-1], stretchJnts[-1])
    utils.fixJointConstraints(stretchJnts[-1])

    nsJnts, nsPosJnts, esUps = setupIkSplineJnts(jntList, crv, surf, ikNode,
                         namer = namer,
                         nodeName='%s_ns' % nodeName,
                         tipCtl = ctlList[-1])

    MC.addAttr(ikNode, ln='stretchAmt', min=0, max=1, dv=0, k=1)
    utils.blendJointChains(nsJnts, stretchJnts, jntList, '%s.stretchAmt' % ikNode, namer)

    MC.setAttr("%s.v" % nsJnts[0], 0)
    MC.setAttr("%s.v" % stretchJnts[0], 0)


    return ikNode
Example #2
0
    def _makeLayout(self, namer):
        jntCnt =  self.options.getValue('numBones') + 1

        MC.select(cl=1)
        jnts = []
        layoutCtlZeros = []
        rigCtls = []
        ups = []
        for i in range(jntCnt):
            jnt = MC.joint(p=[0,i*2, 0], n=namer(r='bnd', alphaSuf=i))
            self.registerBindJoint(jnt)
            jnts.append(jnt)
            if i < jntCnt -1:
                rigCtl = control.makeControl(namer(r='fk', alphaSuf=i), color='green',
                                         shape='cube')

                control.setEditable(rigCtl, True)
                self.registerControl(rigCtl, 'rig')
                rigCtls.append(rigCtl)

            layoutCtl = control.makeControl(namer('layout_ctl', r='fk', alphaSuf=i),
                                            color='purple', shape='sphere')

            if i < (jntCnt-1):
                upCtl = control.makeControl(namer('layout_twist_ctl', r='fk', alphaSuf=i),
                                            color='blue', shape='triangle', t=[1.5,0,0],
                                            s=[.2, .2, .2])

                up = MC.createNode('transform', n=namer('layout_twist_up', r='fk', alphaSuf=i))
                MC.parent(up, upCtl)
                MC.setAttr('%s.t' % up, 2, 0, 0, type='double3')
                ups.append(up)
                utils.snap(jnt, upCtl)
                MC.parent(upCtl, layoutCtl)
                self.registerControl(upCtl, 'layout', uk=['ry'])

            utils.snap(jnt, layoutCtl)
            utils.snap(jnt, rigCtl)

            layoutCtlZeros.append(utils.insertNodeAbove(layoutCtl))
            MC.parent(rigCtl, jnt)


            MC.pointConstraint(layoutCtl, jnt)

            utils.fixJointConstraints(jnt)


            self.registerControl(layoutCtl, 'layout', uk=['t'])


            MC.select(jnt)

        MC.select(cl=1)

        #aim each fkControl at the next one
        for i in range(len(layoutCtlZeros)-1):


            nextCtl = MC.listRelatives(layoutCtlZeros[i+1])[0]
            thisZero = layoutCtlZeros[i]
            thisCtl = MC.listRelatives(thisZero)[0]

            control.centeredCtl(jnts[i], jnts[i+1], rigCtls[i])

            upVec = [1,0,0]

            MC.aimConstraint(nextCtl, thisCtl,
                             aimVector=[0,1,0],
                             upVector=[1,0,0],
                             worldUpVector=[1,0,0])

            MC.aimConstraint(nextCtl, jnts[i],
                             aimVector=[0,1,0],
                             upVector=upVec,
                             worldUpType='object',
                             worldUpObject = ups[i])

            utils.fixJointConstraints(thisCtl)

            lck = ['tx', 'ty', 'tz', 'rx', 'rz', 'sx', 'sy', 'sz']
            for attr in lck:
                par = MC.listRelatives(ups[i], parent=1)[0]
                #MC.setAttr('%s.%s' % (ups[i], attr) , l=1)
                MC.setAttr('%s.%s' % (par, attr) , l=1)
Example #3
0
def setupIkSplineJnts(jntList, crv, surf, ikNode,
                         nodeName='beings_splineik', namer=None,
                         tipCtl=None):

    """
    Setup a splineIk system, but use a nurbs surface to control orientation.
    This allows full twist control along the length of the chain

    @param jntList: the list of original joints; they will be duplicated
    @param crv: the curve to use for the spline ik system
    @param surf: the surface to use for the twist
    @param namer: the namer to use for naming; a generic will be assigned if none provided
    @param tipCtl: a control to use for orienting the last joint.  If none provided,
    it will be oriented to the plane
    """
    if not namer:
        namer = utils.Namer('char', 'cn', 'spine')


    namer.setTokens(r='ik')
    #use the splineik node to get joints to 'slip' alone the curve.  These are intermediate
    #joints, we're just using their position to get us a point on the nurbs surface so we
    #can use the surface for orientation
    jntNames = ['%s_pos_jnt_%s' % (nodeName, ascii_lowercase[i]) for i in range(len(jntList))]
    splinePosJnts = utils.dupJntList(jntList, jntNames, namer)
    for jnt in splinePosJnts:
        control.setLockTag(jnt, uu=['t', 'r'])

    #these are the actual joints that will be oriented and positioned correctly
    jntNames = ['%s_jnt_%s' % (nodeName,ascii_lowercase[i]) for i in range(len(jntList))]
    splineJnts = utils.dupJntList(jntList, jntNames, namer)

    handle, ee = MC.ikHandle(solver='ikSplineSolver',
                             sj=splinePosJnts[0], ee=splinePosJnts[-1], curve=crv,
                             simplifyCurve=False, parentCurve=False, createCurve=False)
    MC.parent(handle, ikNode)
    xforms = []
    ups = []

    for i, jnt in enumerate(splinePosJnts):
        dcm = MC.createNode('decomposeMatrix', n=namer('%s_splinejnt_dcm' % nodeName, alphaSuf=i))
        cps = MC.createNode('closestPointOnSurface', n=namer('%s_splinejnt_cps' % nodeName, alphaSuf=i))

        posi = MC.createNode('pointOnSurfaceInfo', n=namer('%s_splinejnt_posi' % nodeName, alphaSuf=i))
        xform = MC.createNode('transform', n=namer('%s_splinejnt_grp' % nodeName, alphaSuf=i))
        xformUp = MC.createNode('transform', n=namer('%s_splinejnt_up_grp' % nodeName, alphaSuf=i))
        MC.parent(xform, ikNode)
        MC.parent(xformUp, ikNode)


        MC.connectAttr('%s.worldMatrix' % jnt, '%s.inputMatrix' % dcm)
        MC.connectAttr("%s.worldSpace[0]" % surf, '%s.inputSurface' % cps)
        MC.connectAttr("%s.outputTranslate" % dcm, "%s.ip" % cps)
        MC.connectAttr("%s.p" % cps, "%s.t" % xform)

        MC.connectAttr("%s.worldSpace[0]" % surf, '%s.inputSurface' % posi)
        MC.connectAttr("%s.u" % cps, "%s.u" % posi)
        MC.setAttr("%s.v" % cps, MC.getAttr("%s.v" % cps) + .1)
        MC.connectAttr("%s.p" % posi, "%s.t" % xformUp)
        xforms.append(xform)
        ups.append(xformUp)
        MC.pointConstraint(splinePosJnts[i], splineJnts[i])

    for i in range(len(splinePosJnts)-1):
        MC.aimConstraint(splinePosJnts[i+1],
                         xforms[i],
                         aimVector=[0,1,0],
                         upVector=[1,0,0],
                         worldUpType='object',
                         worldUpObject=ups[i])

        utils.fixJointConstraints(xforms[i])
        MC.orientConstraint(xforms[i], splineJnts[i])
        utils.fixJointConstraints(splineJnts[i])
    if tipCtl:
        MC.orientConstraint(tipCtl, splineJnts[-1])
        utils.fixJointConstraints(splineJnts[-1])

    MC.setAttr("%s.v" % splinePosJnts[0], 0)
    MC.setAttr("%s.v" % handle, 0)

    return (splineJnts, splinePosJnts, ups)