Esempio n. 1
0
def faceEvaluationSwitch():
    '''
    find all deformers on geos
    when switchAttr = False,
    set nodes to HasNoEffect
    '''
    geos = [nt.Transform(u'FACE:LT_eyelashes_geo'),
            nt.Transform(u'FACE:RT_eyelashes_geo'),
            nt.Transform(u'FACE:CT_face_geo'),
            nt.Transform(u'CT_face_geo_lattice'),
            nt.Transform(u'CT_face_geo_latticeWeights')]
    
    # add switch to face ctrl
    faceCtl = pm.PyNode('FACE:CT_face_ctrl')
    faceCtl.addAttr('disableFace', at='bool', dv=0)
    faceCtl.attr('disableFace').showInChannelBox(True)
    
    for geo in geos:
        dfmNames = mel.findRelatedDeformer(geo)
        for dfmName in dfmNames:
            dfm = pm.PyNode(dfmName)
            faceCtl.attr('disableFace') >> dfm.nodeState
            
    # also hide inner mouth geo
    mouthGeoGrp = pm.PyNode('FACE:CT_mouth_geo_grp')
    rt.connectSDK(faceCtl.attr('disableFace'), 
                  mouthGeoGrp.v, {0:1, 1:0})
Esempio n. 2
0
def create(ctl, tipGeo, weights, name, keys, addGeos=[], useScale=False):
    '''
    tipGeo - vtx of the tip of the eye
    weights - list of weights for each loop radiating outwards (including geoTip)
    e.g. [1, 1, 1, 1, 1, .95, 0.75, 0.5, .25, .1]
    addGeo - list of additional geometry for cluster to deform
    name - 'pupil' or 'iris'
    
    e.g.:
    geo = nt.Mesh(u'LT_eyeball_geoShape')
    tipGeo = geo.vtx[381]
    ctl = nt.Transform(u'LT_eye_ctl')
    name = '_iris'
    
    keys = {'sx': {0.01:0.01, 1:1, 2:2},
            'sy': {0.01:0.01, 1:1, 2:2},
            'sz': {0.01:0.01, 1:1, 2:3.75}}
    weights = [1, 1, 1, 1, 1, .95, 0.75, 0.5, .25, .1]
    '''
    geo = tipGeo.node()
    dfm, hdl = pm.cluster(tipGeo, n=ctl+name+'_dfm', foc=True)
    dfg = pm.group(hdl, n=ctl+name+'_dfg')
    rp = hdl.getRotatePivot(space='world')
    sp = hdl.getScalePivot(space='world')
    dfg.setRotatePivot(rp, space='world')
    dfg.setScalePivot(sp, space='world')
    dfh = pm.group(dfg, n=ctl+name+'_dfh')
    
    ctl.addAttr(name, min=0.01, max=2, dv=1, k=True)
    
    for attr, key in keys.items():
        rt.connectSDK(ctl.attr(name), hdl.attr(attr), key)

    loopNums = len(weights) - 1
    vertLoops = mesh.VertexLoops([tipGeo], loopNums)
    
    # add membership
    pm.select(vertLoops[:])
    for vertLoop in vertLoops[:]:
        for eachVert in vertLoop:
            dfm.setGeometry(eachVert)
            
    for loopId, weight in enumerate(weights):
        for eachVert in vertLoops[loopId]:
            print eachVert
            dfm.setWeight(geo, 0, eachVert, weight)
            
    # add additional geometries
    for eachGeo in addGeos:
        dfm.setGeometry(eachGeo, foc=True)
        
    if useScale:
        # modulate cluster scale by control scale
        for eachAttr in ('sx', 'sy', 'sz'):
            scaleInput = hdl.attr(eachAttr).inputs(p=True)[0]
            mdl = pm.createNode('multDoubleLinear', n=hdl+'_'+eachAttr+'_scale_mdl')
            scaleInput >> mdl.input1
            ctl.attr(eachAttr) >> mdl.input2
            mdl.output >> hdl.attr(eachAttr)   
    return dfh
Esempio n. 3
0
def modulateEyelashACS():
    '''
    '''
    """
    # left side 9 to 19
    acsNodes = [pm.PyNode('FACE:LT_eye_aimAt_bnd_%d_eyelash_acs'%jntId)
                for jntId in range(9,20)]
    
    drv = pm.PyNode('FACE:LT_eyelid_upper_pri_ctrl')
    drv.addAttr('eyelidDownMod')
    rt.connectSDK(drv.ty, drv.eyelidDownMod, {0:1, -0.5:0})
    
    for node in acsNodes:
        mod = modulate.multiplyInput(node.rz, 1, '_eyelidDownMod')
        drv.eyelidDownMod >> mod 
        """
    # right side 9 to 19
    acsNodes = [pm.PyNode('FACE:RT_eye_aimAt_bnd_%d_eyelash_acs'%jntId)
                for jntId in range(9,20)]
    
    drv = pm.PyNode('FACE:RT_eyelid_upper_pri_ctrl')
    drv.addAttr('eyelidDownMod')
    rt.connectSDK(drv.ty, drv.eyelidDownMod, {0:1, -0.5:0})
    
    for node in acsNodes:
        mod = modulate.multiplyInput(node.rz, 1, '_eyelidDownMod')
        drv.eyelidDownMod >> mod 
def connectBsp(driverAttr, drivenAttr, geo, bspGeos, scaleTime=100):
    '''
    bspGeos is a dictionary of geos used for this bspTarget at various weights
    {-0.1: nt.mesh,
    0.1: nt.mesh}
    '''
    # get closest vertex on geo for offset calculation
    driverCtl = driverAttr.node()
    driverPt = pm.dt.Point(driverCtl.getRotatePivot(space='world'))
    
    faceId = geo.getClosestPoint(driverPt)[1]
    verts = [geo.vtx[i] for i in geo.f[faceId].getVertices()]
    closestVert = min(verts, key=lambda x:(x.getPosition(space='world') - 
                                           driverPt).length())
    closestVertId = closestVert.index()
    
    # check that we've got the correct vert
    # pm.select(closestVert)
    print closestVertId
    
    # assuming that offsets are only in translation
    attrId = {'tx':0, 'ty':1, 'tz':2}
    driverAttrId = attrId[driverAttr.attrName()]
    
    # position values need to be calculated into ctrl space
    ctlInvMat = driverCtl.getMatrix(worldSpace=True).inverse()
    
    # make sure that ctl is zeroed before calculating offsets
    driverAttr.set(0)
    
    # get offsets for each bspGeo
    # assign to a dictionary for creating sdk later
    sdkKeys = {0:0}
    for weight, bspGeo in bspGeos.items():
        bspVertPt = bspGeo.vtx[closestVertId].getPosition(space='object')
        print bspVertPt
        offset = bspVertPt * ctlInvMat
        print offset
        offset = offset[driverAttrId]
        sdkKeys[offset] = weight
        
    # connect to bsp attr
    rt.connectSDK(driverAttr, drivenAttr, sdkKeys)
    
    # set keys for ctl for preview
    for offset, weight in sdkKeys.items():
        driverAttr.setKey(t=weight*scaleTime, v=offset)
        # save keys as attributes to be used later
        weightStr = str(weight).replace('.','_').replace('-','neg')
        weightAttr = 'bspWeight_' + drivenAttr.getAlias()+ '_' + weightStr
        try:
            driverCtl.addAttr(weightAttr)
        except RuntimeError:
            driverCtl.attr(weightAttr).set(l=False)
        driverCtl.attr(weightAttr).set(offset)
        driverCtl.attr(weightAttr).set(l=True)
        
    pm.select(driverCtl)
    
    return sdkKeys
def setPriWeightsKeys(attrValues, driver, oldDriverValue, newDriverValue):
    '''
    attrValues - dictionary {bnd.attr : newValue}
    current weights are set for oldDriverValue
    weights from dictionary are set for newDriverValue
    '''
    for attr, newWeight in attrValues.items():
        oldWeight = pm.PyNode(attr).get()
        rt.connectSDK(driver, attr,
                      {oldDriverValue:oldWeight,
                       newDriverValue:newWeight})
Esempio n. 6
0
def createPtDriverSys(nodeName, attachGeo=None):
    '''
    Create driver system based on vertex selection in viewport
    Returns drvSysGrp, and a list of locators that can be used to drive offset controls
    '''
    
    # get vertex selections
    selVerts = mc.ls(os=True, fl=True)

    # create control placement locators on each vert
    drvLocs = []
    origLocs = []
    popcNodes = []
    ctlNum = len(selVerts)
    for ctlId in range(ctlNum):
        loc = mc.spaceLocator(n=nodeName+'_wireOffset_drvLoc%d'%ctlId)[0]
        targetVert = selVerts[ctlId]
        mc.select(targetVert, loc, r=True)
        meval('doCreatePointOnPolyConstraintArgList 2 {   "0" ,"0" ,"0" ,"1" ,"" ,"1" ,"0" ,"0" ,"0" ,"0" };')
        meval('CBdeleteConnection "%s.rx";' % loc)
        meval('CBdeleteConnection "%s.ry";' % loc)
        meval('CBdeleteConnection "%s.rz";' % loc)
        mc.setAttr(loc+'.r', 0,0,0)
        drvLocs.append(loc)
        
        # if attachGeo is defined, use attachGeo to drive pointOnPolyConstraint
        popcNode = mc.listRelatives(loc, c=True, type='pointOnPolyConstraint')[0]
        if attachGeo:
            # make origLoc to preserve position
            origLoc = mc.group(n=loc.replace('_drvLoc', '_drvLocOrig'), em=True)
            rt.parentSnap(origLoc, loc)
            mc.parent(origLoc, w=True)
            
            # swap input mesh for popcNode -> this will move drvLoc
            mc.connectAttr(attachGeo, popcNode+'.target[0].targetMesh', f=True)
            
            # parent origLoc back under driverLoc, and use origLoc as driverLoc instead
            mc.parent(origLoc, loc)
            origLocs.append(origLoc)
            
        popcNodes.append(popcNode)
    
    drvLocGrp = mc.group(drvLocs, n=nodeName+'_wireOffset_drvLocs_grp')
    drvSysGrp = mc.group(drvLocGrp, n=nodeName+'_wireOffset_drvSys_grp')
    rt.connectVisibilityToggle(drvLocs, drvSysGrp, 'drvLocsVis', False)
    
    mc.addAttr(drvSysGrp, ln='enabled', at='bool', k=True, dv=True)
    for eachPopc in popcNodes:
        rt.connectSDK(drvSysGrp+'.enabled', eachPopc+'.nodeState', {1:0, 0:2})
    
    if attachGeo:
        return drvSysGrp, origLocs
    
    return drvSysGrp, drvLocs
def setPriWeightsKeys(attrValues, driver, oldDriverValue, newDriverValue):
    '''
    attrValues - dictionary {bnd.attr : newValue}
    current weights are set for oldDriverValue
    weights from dictionary are set for newDriverValue
    '''
    for attr, newWeight in attrValues.items():
        oldWeight = pm.PyNode(attr).get()
        rt.connectSDK(driver, attr, {
            oldDriverValue: oldWeight,
            newDriverValue: newWeight
        })
Esempio n. 8
0
def modulateFleshyEyesUp():
    '''
    DONT USE THIS
    '''
    node = nt.Transform(u'FACE:LT_eyeball_bnd')
    node.addAttr('finalVectorAngle', k=True)
    # replace outputs
    outAttrs = node.vectorAngle.outputs(p=True)
    node.vectorAngle >> node.finalVectorAngle
    for plug in outAttrs:
        node.finalVectorAngle >> plug
    # modulate finalVectorAngle
    mod = modulate.multiplyInput(node.finalVectorAngle, 1, '_eyeY_mod')
    rt.connectSDK('FACE:LT_eyeball_bnd.paramNormalized', mod, {0:0.2, 0.4:1, 0.6:1, 1:0.2})
Esempio n. 9
0
def modulatePivotWeightOnBnd(ctlAttr, bnds, pivot, keys):
    '''
    '''
    ctl = ctlAttr.node()
    attr = ctlAttr.attrName()
    ctl.addAttr(attr+'_mod_'+pivot)
    modAttr = ctl.attr(attr+'_mod_'+pivot)
    
    rt.connectSDK(ctlAttr, modAttr, keys, modAttr.attrName()+'_modulate_SDK')
    
    for eachBnd in bnds:
        allAttrs = pm.listAttr(eachBnd, ud=True)
        attrsToMod = [eachBnd.attr(attr) for attr in allAttrs if pivot+'_loc_weight_' in attr]
        for eachAttr in attrsToMod:
            modAttr >> eachAttr
Esempio n. 10
0
def addSidePivotsToFoot(sideAttr, jnt, inPivot, outPivot):
    # actual stuff
    outGrp = pm.group(em=True, n=jnt+'_outPivot_grp')
    outGrp.setMatrix(outPivot.getMatrix(ws=True))
    inGrp = pm.group(em=True, n=jnt+'_inPivot_grp')
    inGrp.setMatrix(inPivot.getMatrix(ws=True))
    # add home pivots
    outHm = rt.addFreezeGrp(outGrp, '_hm')
    inHm = rt.addFreezeGrp(inGrp, '_hm')
    # hierarchy
    jntPar = jnt.getParent()
    outHm.setParent(jntPar)
    inHm.setParent(outGrp)
    jnt.setParent(inGrp)
    # connect sideAttr to grp.rz
    rt.connectSDK(sideAttr, inGrp.rz, {0:0, 90:90})
    rt.connectSDK(sideAttr, outGrp.rz, {-90:-90, 0:0})
Esempio n. 11
0
def mirror_animCurve(acrv):
    """
    """
    # mirror acrv from LT to RT
    # time & values remain the same
    indices = acrv.ktv.get(mi=True)
    ktvs = [acrv.ktv[i].get() for i in indices]
    ktvs_tbl = {}
    for t, v in ktvs:
        ktvs_tbl[t] = v
    # swap names for input and output
    inPlugLf = acrv.input.inputs(p=True)[0]
    inPlugRt = pm.PyNode(inPlugLf.replace("LT_", "RT_"))
    outPlugLf = acrv.output.outputs(p=True)[0]
    outPlugRt = pm.PyNode(outPlugLf.replace("LT_", "RT_"))
    # make new sdk
    rt.connectSDK(inPlugRt, outPlugRt, ktvs_tbl, acrv + "_mirrorToRt")
Esempio n. 12
0
def addSidePivotsToFoot(sideAttr, jnt, inPivot, outPivot):
    # actual stuff
    outGrp = pm.group(em=True, n=jnt + '_outPivot_grp')
    outGrp.setMatrix(outPivot.getMatrix(ws=True))
    inGrp = pm.group(em=True, n=jnt + '_inPivot_grp')
    inGrp.setMatrix(inPivot.getMatrix(ws=True))
    # add home pivots
    outHm = rt.addFreezeGrp(outGrp, '_hm')
    inHm = rt.addFreezeGrp(inGrp, '_hm')
    # hierarchy
    jntPar = jnt.getParent()
    outHm.setParent(jntPar)
    inHm.setParent(outGrp)
    jnt.setParent(inGrp)
    # connect sideAttr to grp.rz
    rt.connectSDK(sideAttr, inGrp.rz, {0: 0, 90: 90})
    rt.connectSDK(sideAttr, outGrp.rz, {-90: -90, 0: 0})
Esempio n. 13
0
def mirror_animCurve(acrv):
    '''
    '''
    # mirror acrv from LT to RT
    # time & values remain the same
    indices = acrv.ktv.get(mi=True)
    ktvs = [acrv.ktv[i].get() for i in indices]
    ktvs_tbl = {}
    for t, v in ktvs:
        ktvs_tbl[t] = v
    # swap names for input and output
    inPlugLf = acrv.input.inputs(p=True)[0]
    inPlugRt = pm.PyNode(inPlugLf.replace('LT_', 'RT_'))
    outPlugLf = acrv.output.outputs(p=True)[0]
    outPlugRt = pm.PyNode(outPlugLf.replace('LT_', 'RT_'))
    # make new sdk
    rt.connectSDK(inPlugRt, outPlugRt, ktvs_tbl, acrv + '_mirrorToRt')
Esempio n. 14
0
def modulatePivotWeightOnBnd(ctlAttr, bnds, pivot, keys):
    '''
    '''
    ctl = ctlAttr.node()
    attr = ctlAttr.attrName()
    ctl.addAttr(attr + '_mod_' + pivot)
    modAttr = ctl.attr(attr + '_mod_' + pivot)

    rt.connectSDK(ctlAttr, modAttr, keys, modAttr.attrName() + '_modulate_SDK')

    for eachBnd in bnds:
        allAttrs = pm.listAttr(eachBnd, ud=True)
        attrsToMod = [
            eachBnd.attr(attr) for attr in allAttrs
            if pivot + '_loc_weight_' in attr
        ]
        for eachAttr in attrsToMod:
            modAttr >> eachAttr
Esempio n. 15
0
def createDfmSys(nodeName, drvLocs, ctls, geo):
    '''
    drvLocs are used to drive baseCrv
    ctls are used to drive wireCrv
    wire deforms geo
    
    return dfmSysGrp
    '''
    
    # create baseCrv
    baseCrv = rt.makeCrvThroughObjs(drvLocs, nodeName+'_wireOffset_baseCrv', True, 3)
    
    # create wireCrv
    wireCrv = rt.makeCrvThroughObjs(ctls, nodeName+'_wireOffset_wireCrv', True, 3)
    
    # create wireDfm
    wireDfm, wireCrv = mc.wire(geo, wire=wireCrv, n=nodeName+'_wireOffset_wireDfm', dds=(0,5))
    wireBaseUnwanted = wireCrv+'BaseWire'
    # replace base
    mc.connectAttr(baseCrv+'.worldSpace[0]', wireDfm+'.baseWire[0]', f=True)
    mc.delete(wireBaseUnwanted)
    
    # create dfmSysGrp
    dfmSysGrp = mc.group(baseCrv, wireCrv, n=nodeName+'_wireOffset_dfmSys_grp')
    rt.connectVisibilityToggle(wireCrv, dfmSysGrp, 'wireCrvVis', False)
    rt.connectVisibilityToggle(baseCrv, dfmSysGrp, 'baseCrvVis', False)
    
    mc.addAttr(dfmSysGrp, ln='envelope', at='double', k=True, dv=1)
    mc.addAttr(dfmSysGrp, ln='dropoff', at='double', k=True, dv=5)
    mc.addAttr(dfmSysGrp, ln='rotation', at='double', k=True, dv=0)
    
    mc.connectAttr(dfmSysGrp+'.envelope', wireDfm+'.envelope', f=True)
    mc.connectAttr(dfmSysGrp+'.dropoff', wireDfm+'.dds[0]', f=True)
    mc.connectAttr(dfmSysGrp+'.rotation', wireDfm+'.rotation', f=True)
    
    mc.addAttr(dfmSysGrp, ln='enabled', at='bool', k=True, dv=True)
    rt.connectSDK(dfmSysGrp+'.enabled', wireDfm+'.nodeState', {1:0, 0:2})
    
    return dfmSysGrp
Esempio n. 16
0
def addElbowSnap(pvCtl, shoulderGrp, handCtl, handIkH, elbowMdl, wristMdl,
                 stretchyRange):
    '''
    '''
    elbowDistPlug = create_distanceBetween(shoulderGrp, pvCtl)
    wristDistPlug = create_distanceBetween(pvCtl, handIkH)

    initElbowTx = mc.getAttr(elbowMdl + '.input2X')
    initWristTx = mc.getAttr(wristMdl + '.input2X')

    # check if transX needs to be negative
    if initElbowTx < 0:
        # make distance values negative
        elbowDistPlug = create_multDoubleLinear(elbowDistPlug, -1)
        wristDistPlug = create_multDoubleLinear(wristDistPlug, -1)

    # add attribute to pvCtl to control elbowSnap
    mc.addAttr(pvCtl, ln='elbowSnap', at='double', dv=0, min=0, max=1, k=True)

    # blend between original length to new length
    # elbow
    elbowBlend = mc.createNode('blendTwoAttr', n='elbowSnap_blend')
    mc.connectAttr(pvCtl + '.elbowSnap', elbowBlend + '.ab', f=True)
    mc.setAttr(elbowBlend + '.input[0]', initElbowTx)
    mc.connectAttr(elbowDistPlug, elbowBlend + '.input[1]', f=True)
    # wrist
    wristBlend = mc.createNode('blendTwoAttr', n='elbowSnap_blend')
    mc.connectAttr(pvCtl + '.elbowSnap', wristBlend + '.ab', f=True)
    mc.setAttr(wristBlend + '.input[0]', initWristTx)
    mc.connectAttr(wristDistPlug, wristBlend + '.input[1]', f=True)

    # connect into mdls
    mc.connectAttr(elbowBlend + '.output', elbowMdl + '.input2X', f=True)
    mc.connectAttr(wristBlend + '.output', wristMdl + '.input2X', f=True)

    # when elbowSnap is 0, stretchMax is 10
    # when elbowSnap is 1, stretchMax is 0
    rt.connectSDK(pvCtl + '.elbowSnap', stretchyRange + '.maxX', {0: 1, 1: 0})
def connectBspDriver(ctls, bspDriver, geo, weights):
    '''
    ctls = [nt.Transform(u'LT_upper_sneer_lip_pri_ctrl'),
            nt.Transform(u'LT_lower_pinch_lip_ctrl'),
            nt.Transform(u'LT_upper_pinch_lip_ctrl'),
            nt.Transform(u'LT_corner_lip_ctrl'),
            nt.Transform(u'LT_upper_sneer_lip_ctrl'),
            nt.Transform(u'LT_lower_sneer_lip_ctrl'),
            nt.Transform(u'LT_lower_sneer_lip_pri_ctrl'),
            nt.Transform(u'LT_corner_lip_pri_ctrl')]
    
    bspDriver = pm.PyNode('blendShapeCt_face_geo.cheekPuff_Lf')
    geo = nt.Mesh(u'CT_face_geoShape')
    weights = [0, 0.1]
    '''
    bspDriverName = bspDriver.getAlias()

    for ctl in ctls:

        bspDrvGrp = pm.group(em=True, n=ctl + '_bsgDriverGrp_' + bspDriverName)
        m = ctl.getMatrix(worldSpace=True)
        bspDrvGrp.setMatrix(m, worldSpace=True)
        p = ctl.getParent()
        p | bspDrvGrp | ctl

        ctlPos = ctl.getRotatePivot(space='world')
        bspDriver.set(weights[0])

        faceId = geo.getClosestPoint(ctlPos)[1]
        verts = [geo.vtx[i] for i in geo.f[faceId].getVertices()]
        closestVert = min(verts,
                          key=lambda x:
                          (x.getPosition(space='world') - ctlPos).length())
        closestVertPos = closestVert.getPosition(space='world')
        bspDriver.set(weights[1])
        newPos = closestVert.getPosition(space='world')
        offset = newPos - closestVertPos
        newCtlPos = ctlPos + offset
        bspDrvGrp.setTranslation(newCtlPos, space='world')

        tx = bspDrvGrp.tx.get()
        ty = bspDrvGrp.ty.get()
        tz = bspDrvGrp.tz.get()

        rt.connectSDK(bspDriver, bspDrvGrp.tx, {weights[0]: 0, weights[1]: tx})
        rt.connectSDK(bspDriver, bspDrvGrp.ty, {weights[0]: 0, weights[1]: ty})
        rt.connectSDK(bspDriver, bspDrvGrp.tz, {weights[0]: 0, weights[1]: tz})
def connectBspDriver(ctls, bspDriver, geo, weights):
    '''
    ctls = [nt.Transform(u'LT_upper_sneer_lip_pri_ctrl'),
            nt.Transform(u'LT_lower_pinch_lip_ctrl'),
            nt.Transform(u'LT_upper_pinch_lip_ctrl'),
            nt.Transform(u'LT_corner_lip_ctrl'),
            nt.Transform(u'LT_upper_sneer_lip_ctrl'),
            nt.Transform(u'LT_lower_sneer_lip_ctrl'),
            nt.Transform(u'LT_lower_sneer_lip_pri_ctrl'),
            nt.Transform(u'LT_corner_lip_pri_ctrl')]
    
    bspDriver = pm.PyNode('blendShapeCt_face_geo.cheekPuff_Lf')
    geo = nt.Mesh(u'CT_face_geoShape')
    weights = [0, 0.1]
    '''
    bspDriverName = bspDriver.getAlias()
    
    for ctl in ctls:
    
        bspDrvGrp = pm.group(em=True, n=ctl+'_bsgDriverGrp_'+bspDriverName)
        m = ctl.getMatrix(worldSpace=True)
        bspDrvGrp.setMatrix(m, worldSpace=True)
        p = ctl.getParent()
        p | bspDrvGrp | ctl
        
        ctlPos = ctl.getRotatePivot(space='world')
        bspDriver.set(weights[0])
        
        faceId = geo.getClosestPoint(ctlPos)[1]
        verts = [geo.vtx[i] for i in geo.f[faceId].getVertices()]
        closestVert = min(verts, key=lambda x:(x.getPosition(space='world') - 
                                               ctlPos).length())
        closestVertPos = closestVert.getPosition(space='world')
        bspDriver.set(weights[1])
        newPos = closestVert.getPosition(space='world')
        offset = newPos - closestVertPos
        newCtlPos = ctlPos + offset
        bspDrvGrp.setTranslation(newCtlPos, space='world')
        
        tx = bspDrvGrp.tx.get()
        ty = bspDrvGrp.ty.get()
        tz = bspDrvGrp.tz.get()
        
        rt.connectSDK(bspDriver, bspDrvGrp.tx, {weights[0]:0, weights[1]:tx})
        rt.connectSDK(bspDriver, bspDrvGrp.ty, {weights[0]:0, weights[1]:ty})
        rt.connectSDK(bspDriver, bspDrvGrp.tz, {weights[0]:0, weights[1]:tz})
Esempio n. 19
0
from pymel.core.language import Mel

mel = Mel()

import pymel.core.nodetypes as nt

import utils.rigging as rt
# coeffs
coeffs = pm.group(em=True, n='CT_lipCurlOut_coeffs')
coeffs.addAttr('leftLower', k=True)
coeffs.addAttr('leftUpper', k=True)
coeffs.addAttr('rightLower', k=True)
coeffs.addAttr('rightUpper', k=True)

# direct drives
rt.connectSDK('LT_lowerSneer_lip_pri_ctrl.rx', coeffs.leftLower, {0: 0, 45: 1})
rt.connectSDK('LT_upperSneer_lip_pri_ctrl.rx', coeffs.leftUpper, {
    0: 0,
    -45: 1
})
rt.connectSDK('RT_lowerSneer_lip_pri_ctrl.rx', coeffs.rightLower, {
    0: 0,
    45: 1
})
rt.connectSDK('RT_upperSneer_lip_pri_ctrl.rx', coeffs.rightUpper, {
    0: 0,
    -45: 1
})

# modulate by centers
import rigger.utils.modulate as modulate
Esempio n. 20
0
def addStickyControlSystem():
    '''
    same as addStickyToFRS, but with arguments
    adds connections to individual sticky master nodes
    '''
    #lf_ctl = pm.PyNode('LT_corner_lip_pri_ctrl')
    #rt_ctl = pm.PyNode('RT_corner_lip_pri_ctrl')
    jaw_ctl = pm.PyNode('CT__jaw_pri_ctrl')
    jaw_ctg = jaw_ctl.getParent()
    
    lf_pinch = pm.PyNode('LT_upperPinch_lip_bnd_sticky_master')
    lf_sneer = pm.PyNode('LT_upperSneer_lip_bnd_sticky_master')
    lf_side = pm.PyNode('LT_upperSide_lip_bnd_sticky_master')
    rt_pinch = pm.PyNode('RT_upperPinch_lip_bnd_sticky_master')
    rt_sneer = pm.PyNode('RT_upperSneer_lip_bnd_sticky_master')
    rt_side = pm.PyNode('RT_upperSide_lip_bnd_sticky_master')
    ct_stick = pm.PyNode('CT_upper_lip_bnd_sticky_master')
    
    jaw_ctl.addAttr('leftSealAmount', k=True, dv=0, min=0, max=1)
    jaw_ctl.addAttr('rightSealAmount', k=True, dv=0, min=0, max=1)
    jaw_ctl.addAttr('leftSealHeight', k=True, dv=0.5, min=0, max=1)
    jaw_ctl.addAttr('rightSealHeight', k=True, dv=0.5, min=0, max=1)
    
    jaw_ctg.addAttr('lf_pinch_amt_lf', k=True)
    jaw_ctg.addAttr('lf_sneer_amt_lf', k=True)
    jaw_ctg.addAttr('lf_side_amt_lf', k=True)
    jaw_ctg.addAttr('lf_center_amt_lf', k=True)
    jaw_ctg.addAttr('rt_pinch_amt_lf', k=True)
    jaw_ctg.addAttr('rt_sneer_amt_lf', k=True)
    jaw_ctg.addAttr('rt_side_amt_lf', k=True)
    
    jaw_ctg.addAttr('lf_pinch_amt_rt', k=True)
    jaw_ctg.addAttr('lf_sneer_amt_rt', k=True)
    jaw_ctg.addAttr('lf_side_amt_rt', k=True)
    jaw_ctg.addAttr('lf_center_amt_rt', k=True)
    jaw_ctg.addAttr('rt_pinch_amt_rt', k=True)
    jaw_ctg.addAttr('rt_sneer_amt_rt', k=True)
    jaw_ctg.addAttr('rt_side_amt_rt', k=True)
    
    rt.connectSDK(jaw_ctl.leftSealAmount, jaw_ctg.lf_pinch_amt_lf, {0:0, 0.25:1})
    rt.connectSDK(jaw_ctl.leftSealAmount, jaw_ctg.lf_sneer_amt_lf, {0:0, 0.75:1})
    rt.connectSDK(jaw_ctl.leftSealAmount, jaw_ctg.lf_side_amt_lf, {0.25:0, 0.9:0.75})
    rt.connectSDK(jaw_ctl.leftSealAmount, jaw_ctg.lf_center_amt_lf, {0.5:0, 1:0.5})
    rt.connectSDK(jaw_ctl.leftSealAmount, jaw_ctg.rt_side_amt_lf, {0.75:0, 1:0.25})
    rt.connectSDK(jaw_ctl.leftSealAmount, jaw_ctg.rt_sneer_amt_lf, {0:0, 1:0})
    rt.connectSDK(jaw_ctl.leftSealAmount, jaw_ctg.rt_pinch_amt_lf, {0:0, 1:0})
    
    rt.connectSDK(jaw_ctl.rightSealAmount, jaw_ctg.lf_pinch_amt_rt, {0:0, 0:0})
    rt.connectSDK(jaw_ctl.rightSealAmount, jaw_ctg.lf_sneer_amt_rt, {0:0, 0:0})
    rt.connectSDK(jaw_ctl.rightSealAmount, jaw_ctg.lf_side_amt_rt, {0.75:0, 1:0.25})
    rt.connectSDK(jaw_ctl.rightSealAmount, jaw_ctg.lf_center_amt_rt, {0.5:0, 1:0.5})
    rt.connectSDK(jaw_ctl.rightSealAmount, jaw_ctg.rt_side_amt_rt, {0.25:0, 0.9:0.75})
    rt.connectSDK(jaw_ctl.rightSealAmount, jaw_ctg.rt_sneer_amt_rt, {0:0, 0.75:1})
    rt.connectSDK(jaw_ctl.rightSealAmount, jaw_ctg.rt_pinch_amt_rt, {0:0, 0.25:1})
    
    # connect sealAmounts
    connectStickyToSeal(jaw_ctg.lf_pinch_amt_lf, jaw_ctg.lf_pinch_amt_rt, lf_pinch)
    connectStickyToSeal(jaw_ctg.lf_sneer_amt_lf, jaw_ctg.lf_sneer_amt_rt, lf_sneer)
    connectStickyToSeal(jaw_ctg.lf_side_amt_lf, jaw_ctg.lf_side_amt_rt, lf_side)
    connectStickyToSeal(jaw_ctg.lf_center_amt_lf, jaw_ctg.lf_center_amt_rt, ct_stick)
    connectStickyToSeal(jaw_ctg.rt_side_amt_lf, jaw_ctg.rt_side_amt_rt, rt_side)
    connectStickyToSeal(jaw_ctg.rt_sneer_amt_lf, jaw_ctg.rt_sneer_amt_rt, rt_sneer)
    connectStickyToSeal(jaw_ctg.rt_pinch_amt_lf, jaw_ctg.rt_pinch_amt_rt, rt_pinch)
    
    # jaw_ctl.addAttr('autoSticky', k=True, dv=0, min=0, max=1)
    
    # connect sealHeights
    jaw_ctl.leftSealHeight >> lf_pinch.midVal
    jaw_ctl.leftSealHeight >> lf_sneer.midVal
    jaw_ctl.leftSealHeight >> lf_side.midVal
    jaw_ctl.rightSealHeight >> rt_pinch.midVal
    jaw_ctl.rightSealHeight >> rt_sneer.midVal
    jaw_ctl.rightSealHeight >> rt_side.midVal
    # for center, use average between both sides
    ct_avg_pma = pm.createNode('plusMinusAverage', n='CT_stickyLips_avg_pma')
    ct_avg_pma.operation.set(3)
    jaw_ctl.leftSealHeight >> ct_avg_pma.input3D[0].i3x
    jaw_ctl.rightSealHeight >> ct_avg_pma.input3D[1].i3x
    ct_avg_pma.output3D.o3x >> ct_stick.midVal
    
    pm.group(lf_pinch, lf_side, lf_sneer,
             rt_pinch, rt_side, rt_sneer,
             ct_stick, n='CT_stickylips_grp')
Esempio n. 21
0
def createCrvDriverSys(nodeName, ctlNum, form=0, attachGeo=None):
    '''
    Create driver system based on edge loop selection in viewport
    nodeName [string]
    ctlNum [int] - number of controls to add along curve
    form - [int] 0 = open, 1 = periodic
    Returns drvSysGrp, and a list of locators that can be used to drive offset controls
    '''
    
    # select edge loop in UI
    drvCrv, p2cNode = mc.polyToCurve(form=form, degree=1, n=nodeName+'_wireOffset_crv')
    p2cNode = mc.rename(p2cNode, nodeName+'_wireOffset_p2c')
    crvSpans = mc.getAttr(drvCrv+'.spans')

    
    # create control placement locators on drvCrv
    drvLocs = []
    for ctlId in range(ctlNum):
        loc = mc.spaceLocator(n=nodeName+'_wireOffset_drvLoc%d'%ctlId)[0]
        param = float(ctlId) / ctlNum * crvSpans
        rt.attachToMotionPath(drvCrv, param, loc, False)
        drvLocs.append(loc)
        
    # if curve is open, we will create an extra ctl, where param = crvSpans 
    if mc.getAttr(drvCrv+'.form') != 2:
        loc = mc.spaceLocator(n=nodeName+'_wireOffset_drvLoc%d'%ctlNum)[0]
        param = crvSpans
        rt.attachToMotionPath(drvCrv, param, loc, False)
        drvLocs.append(loc)
        
    
    drvLocGrp = mc.group(drvLocs, n=nodeName+'_wireOffset_drvLocs_grp')
    drvSysGrp = mc.group(drvCrv, drvLocGrp, n=nodeName+'_wireOffset_drvSys_grp')
    
    rt.connectVisibilityToggle(drvLocs, drvSysGrp, 'drvLocsVis', False)
    rt.connectVisibilityToggle(drvCrv, drvSysGrp, 'drvCrvVis', False)
    
    mc.addAttr(drvSysGrp, ln='enabled', at='bool', k=True, dv=True)
    rt.connectSDK(drvSysGrp+'.enabled', p2cNode+'.nodeState', {1:0, 0:2})
    
        
    # if attachGeo is defined, use attachGeo to drive polyToCurve
    if attachGeo:
        # make an origLoc for each driverLoc to preserve orig positions
        origLocs = []
        for eachLoc in drvLocs:
            origLoc = mc.group(n=eachLoc.replace('_drvLoc', '_drvLocOrig'), em=True)
            rt.parentSnap(origLoc, eachLoc)
            mc.parent(origLoc, w=True)
            origLocs.append(origLoc)
            
        # switch the input mesh for polyToCurve -> this will move drvLocs
        mc.connectAttr(attachGeo, p2cNode+'.inputPolymesh', f=True)
        
        # parent orig loc back under driver loc, preserving transforms
        for drv, orig in zip(drvLocs, origLocs):
            mc.parent(orig, drv)
            
        return drvSysGrp, origLocs
    
    return drvSysGrp, drvLocs
Esempio n. 22
0
def addStickyToFRS():
    '''
    decrepretated - only use for Ori
    assume all FRS nodes are already named correctly
    
    '''
    #lf_ctl = pm.PyNode('LT_corner_lip_pri_ctrl')
    #rt_ctl = pm.PyNode('RT_corner_lip_pri_ctrl')
    jaw_ctl = pm.PyNode('CT__jaw_pri_ctrl')
    jaw_ctg = jaw_ctl.getParent()
    
    lf_pinch = pm.PyNode('LT_upperPinch_lip_bnd_sticky_master')
    lf_sneer = pm.PyNode('LT_upperSneer_lip_bnd_sticky_master')
    lf_side = pm.PyNode('LT_upperSide_lip_bnd_sticky_master')
    rt_pinch = pm.PyNode('RT_upperPinch_lip_bnd_sticky_master')
    rt_sneer = pm.PyNode('RT_upperSneer_lip_bnd_sticky_master')
    rt_side = pm.PyNode('RT_upperSide_lip_bnd_sticky_master')
    ct_stick = pm.PyNode('CT_upper_lip_bnd_sticky_master')
    
    jaw_ctl.addAttr('leftSealAmount', k=True, dv=0, min=0, max=10)
    jaw_ctl.addAttr('rightSealAmount', k=True, dv=0, min=0, max=10)
    jaw_ctl.addAttr('leftSealHeight', k=True, dv=0.5, min=0, max=1)
    jaw_ctl.addAttr('rightSealHeight', k=True, dv=0.5, min=0, max=1)
    
    jaw_ctg.addAttr('lf_pinch_amt_lf', k=True)
    jaw_ctg.addAttr('lf_sneer_amt_lf', k=True)
    jaw_ctg.addAttr('lf_side_amt_lf', k=True)
    jaw_ctg.addAttr('lf_center_amt_lf', k=True)
    jaw_ctg.addAttr('rt_pinch_amt_lf', k=True)
    jaw_ctg.addAttr('rt_sneer_amt_lf', k=True)
    jaw_ctg.addAttr('rt_side_amt_lf', k=True)
    
    jaw_ctg.addAttr('lf_pinch_amt_rt', k=True)
    jaw_ctg.addAttr('lf_sneer_amt_rt', k=True)
    jaw_ctg.addAttr('lf_side_amt_rt', k=True)
    jaw_ctg.addAttr('lf_center_amt_rt', k=True)
    jaw_ctg.addAttr('rt_pinch_amt_rt', k=True)
    jaw_ctg.addAttr('rt_sneer_amt_rt', k=True)
    jaw_ctg.addAttr('rt_side_amt_rt', k=True)
    
    rt.connectSDK(jaw_ctl.leftSealAmount, jaw_ctg.lf_pinch_amt_lf, {0:0, 4:1})
    rt.connectSDK(jaw_ctl.leftSealAmount, jaw_ctg.lf_sneer_amt_lf, {2:0, 6:1})
    rt.connectSDK(jaw_ctl.leftSealAmount, jaw_ctg.lf_side_amt_lf, {4:0, 8:1})
    rt.connectSDK(jaw_ctl.leftSealAmount, jaw_ctg.lf_center_amt_lf, {6:0, 10:0.5})
    rt.connectSDK(jaw_ctl.leftSealAmount, jaw_ctg.rt_side_amt_lf, {0:0, 10:0})
    rt.connectSDK(jaw_ctl.leftSealAmount, jaw_ctg.rt_sneer_amt_lf, {0:0, 10:0})
    rt.connectSDK(jaw_ctl.leftSealAmount, jaw_ctg.rt_pinch_amt_lf, {0:0, 10:0})
    
    rt.connectSDK(jaw_ctl.rightSealAmount, jaw_ctg.lf_pinch_amt_rt, {0:0, 10:0})
    rt.connectSDK(jaw_ctl.rightSealAmount, jaw_ctg.lf_sneer_amt_rt, {0:0, 10:0})
    rt.connectSDK(jaw_ctl.rightSealAmount, jaw_ctg.lf_side_amt_rt, {0:0, 10:0})
    rt.connectSDK(jaw_ctl.rightSealAmount, jaw_ctg.lf_center_amt_rt, {6:0, 10:0.5})
    rt.connectSDK(jaw_ctl.rightSealAmount, jaw_ctg.rt_side_amt_rt, {4:0, 8:1})
    rt.connectSDK(jaw_ctl.rightSealAmount, jaw_ctg.rt_sneer_amt_rt, {2:0, 6:1})
    rt.connectSDK(jaw_ctl.rightSealAmount, jaw_ctg.rt_pinch_amt_rt, {0:0, 4:1})
    
    # connect sealAmounts
    connectStickyToSeal(jaw_ctg.lf_pinch_amt_lf, jaw_ctg.lf_pinch_amt_rt, lf_pinch)
    connectStickyToSeal(jaw_ctg.lf_sneer_amt_lf, jaw_ctg.lf_sneer_amt_rt, lf_sneer)
    connectStickyToSeal(jaw_ctg.lf_side_amt_lf, jaw_ctg.lf_side_amt_rt, lf_side)
    connectStickyToSeal(jaw_ctg.lf_center_amt_lf, jaw_ctg.lf_center_amt_rt, ct_stick)
    connectStickyToSeal(jaw_ctg.rt_side_amt_lf, jaw_ctg.rt_side_amt_rt, rt_side)
    connectStickyToSeal(jaw_ctg.rt_sneer_amt_lf, jaw_ctg.rt_sneer_amt_rt, rt_sneer)
    connectStickyToSeal(jaw_ctg.rt_pinch_amt_lf, jaw_ctg.rt_pinch_amt_rt, rt_pinch)
    
    # jaw_ctl.addAttr('autoSticky', k=True, dv=0, min=0, max=1)
    
    # connect sealHeights
    jaw_ctl.leftSealHeight >> lf_pinch.midVal
    jaw_ctl.leftSealHeight >> lf_sneer.midVal
    jaw_ctl.leftSealHeight >> lf_side.midVal
    jaw_ctl.rightSealHeight >> rt_pinch.midVal
    jaw_ctl.rightSealHeight >> rt_sneer.midVal
    jaw_ctl.rightSealHeight >> rt_side.midVal
    # for center, use average between both sides
    ct_avg_pma = pm.createNode('plusMinusAverage', n='CT_stickyLips_avg_pma')
    ct_avg_pma.operation.set(3)
    jaw_ctl.leftSealHeight >> ct_avg_pma.input3D[0].i3x
    jaw_ctl.rightSealHeight >> ct_avg_pma.input3D[1].i3x
    ct_avg_pma.output3D.o3x >> ct_stick.midVal
    
    pm.group(lf_pinch, lf_side, lf_sneer,
             rt_pinch, rt_side, rt_sneer,
             ct_stick, n='CT_stickylips_grp')
Esempio n. 23
0
def addJacketCollarRig():
    # jacket collar rig
    collarjnts = pm.ls(sl=True)
    # add hm, grp and auto nulls
    for jnt in collarjnts:
        ctl = pm.circle(r=0.5, sweep=359, normal=(1,0,0), n=jnt.replace('_jnt', '_ctl'))
        auto = pm.group(ctl, n=jnt.replace('_jnt', '_auto'))
        grp = pm.group(auto, n=jnt.replace('_jnt', '_grp'))
        hm = pm.group(grp, n=jnt.replace('_jnt', '_hm'))
        wMat = jnt.getMatrix(worldSpace=True)
        hm.setMatrix(wMat, worldSpace=True)
        collarparent = jnt.getParent()
        collarparent | hm
        auto | jnt
    # auto
    import rigger.modules.poseReader as poseReader
    reload(poseReader)
    xfo = nt.Joint(u'Mathilda_neck_jnt')
    poseReader.radial_pose_reader(xfo, (1,0,0), (1,0,0))
    # connect auto to sdks
    import utils.rigging as rt
    import rigger.utils.modulate as modulate
    angleMult = pm.PyNode('Mathilda_neck_jnt.vectorAngle')
    # Left collar A
    rt.connectSDK('Mathilda_neck_jnt.param', 'LT_collarA_auto.rz',
                    {3.25:0, 4.6:50, 5.5:0})
    mod = modulate.multiplyInput(pm.PyNode('LT_collarA_auto.rz'), 0, '_angle')
    angleMult >> mod
    # Letf collar B
    rt.connectSDK('Mathilda_neck_jnt.param', 'LT_collarB_auto.rz',
                    {4:0, 5:180, 6:180, 7:0})
    mod = modulate.multiplyInput(pm.PyNode('LT_collarB_auto.rz'), 0, '_angle')
    angleMult >> mod
    # Letf collar C
    rt.connectSDK('Mathilda_neck_jnt.param', 'LT_collarC_auto.rz',
                    {0:200, 1.4:0, 4:0, 5.5:200, 6.6:280, 8:0})
    mod = modulate.multiplyInput(pm.PyNode('LT_collarC_auto.rz'), 0, '_angle')
    angleMult >> mod
    # center collar
    rt.connectSDK('Mathilda_neck_jnt.param', 'CT_collar_auto.rz',
                    {0:320, 2.5:0, 5.5:0, 8:320})
    mod = modulate.multiplyInput(pm.PyNode('CT_collar_auto.rz'), 0, '_angle')
    angleMult >> mod
    # right collar A
    rt.connectSDK('Mathilda_neck_jnt.param', 'RT_collarA_auto.rz',
                    {4.75:0, 3.4:50, 2.5:0})
    mod = modulate.multiplyInput(pm.PyNode('RT_collarA_auto.rz'), 0, '_angle')
    angleMult >> mod
    # right collar B
    rt.connectSDK('Mathilda_neck_jnt.param', 'RT_collarB_auto.rz',
                    {4:0, 3:180, 2:180, 1:0})
    mod = modulate.multiplyInput(pm.PyNode('RT_collarB_auto.rz'), 0, '_angle')
    angleMult >> mod
    # right collar C
    rt.connectSDK('Mathilda_neck_jnt.param', 'RT_collarC_auto.rz',
                    {0:200, 6.6:0, 4:0, 2.5:200, 1.4:280, 8:0})
    mod = modulate.multiplyInput(pm.PyNode('RT_collarC_auto.rz'), 0, '_angle')
    angleMult >> mod
    
    pm.select(pm.PyNode(u'Mathilda_neck_jnt.param').outputs())
Esempio n. 24
0
def addLowerLipCurlsSDKs():
    '''
    '''
    # lower lips
    coeffs = pm.group(em=True, n='CT_lowerLipCurls_coeffs')
    coeffs.addAttr('leftPinch', k=True)
    coeffs.addAttr('leftSneer', k=True)
    coeffs.addAttr('leftSide', k=True)
    coeffs.addAttr('centerMid', k=True)
    coeffs.addAttr('rightSide', k=True)
    coeffs.addAttr('rightSneer', k=True)
    coeffs.addAttr('rightPinch', k=True)
    rt.connectSDK('LT_lowerPinch_lip_ctrl.rx',
    coeffs.leftPinch, {-90:-1, 0:0, 90:1})
    rt.connectSDK('LT_lowerSneer_lip_ctrl.rx',
    coeffs.leftSneer, {-90:-1, 0:0, 90:1})
    rt.connectSDK('LT_lowerSide_lip_ctrl.rx',
    coeffs.leftSide, {-90:-1, 0:0, 90:1})
    rt.connectSDK('CT_lower_lip_ctrl.rx',
    coeffs.centerMid, {-90:-1, 0:0, 90:1})
    rt.connectSDK('RT_lowerSneer_lip_ctrl.rx',
    coeffs.rightSneer, {-90:-1, 0:0, 90:1})
    rt.connectSDK('RT_lowerSide_lip_ctrl.rx',
    coeffs.rightSide, {-90:-1, 0:0, 90:1})
    rt.connectSDK('RT_lowerPinch_lip_ctrl.rx',
    coeffs.rightPinch, {-90:-1, 0:0, 90:1})
    
    priCtls = [nt.Transform(u'RT_lowerSneer_lip_pri_ctrl'),
                nt.Transform(u'CT_lower_lip_pri_ctrl'),
                nt.Transform(u'LT_lowerSneer_lip_pri_ctrl')]
                
    attrs = ['leftPinch',
    'leftSneer',
    'leftSide',
    'centerMid',
    'rightSide',
    'rightSneer',
    'rightPinch']
           
        
    for pCtl in priCtls:
        token = pCtl.split('_')[0]
        for attr in attrs:
            mod = modulate.addInput(coeffs.attr(attr), 0, token)
            rt.connectSDK(pCtl.rx, mod, {-90:-1, 0:0, 90:1})
            
    rt.connectSDK(coeffs.leftPinch, 
    'blendShapeCt_face_geo.lipCurlIn_lowerPinch_Lf', {0:0, -1:1})
    rt.connectSDK(coeffs.leftSneer, 
    'blendShapeCt_face_geo.lipCurlIn_lowerSneer_Lf', {0:0, -1:1})
    rt.connectSDK(coeffs.leftSide, 
    'blendShapeCt_face_geo.lipCurlIn_lowerSide_Lf', {0:0, -1:1})
    rt.connectSDK(coeffs.centerMid, 
    'blendShapeCt_face_geo.lipCurlIn_lower_Ct', {0:0, -1:1})
    rt.connectSDK(coeffs.rightPinch, 
    'blendShapeCt_face_geo.lipCurlIn_lowerPinch_Rt', {0:0, -1:1})
    rt.connectSDK(coeffs.rightSneer, 
    'blendShapeCt_face_geo.lipCurlIn_lowerSneer_Rt', {0:0, -1:1})
    rt.connectSDK(coeffs.rightSide, 
    'blendShapeCt_face_geo.lipCurlIn_lowerSide_Rt', {0:0, -1:1})
Esempio n. 25
0
def build():
    '''
    '''
    mesh = nt.Mesh(u'CT_face_geoShape')
    placementGrp = nt.Transform(u'CT_placement_grp')

    #---------------------------------------------------------------------- bind
    if 'bind' in data.build_actions:
        bindGrp = face.createBndsFromPlacement(placementGrp)
        pm.refresh()
    else:
        bindGrp = nt.Transform(u'CT_bnd_grp')

    #--------------------------------------------------------- sec motion system
    if 'sec_motion_system' in data.build_actions:
        face.buildSecondaryControlSystem(placementGrp, bindGrp, mesh)
        pm.refresh()

    #------------------------------------------------------------ pri ctl system first
    if 'primary_ctl_system_first' in data.build_actions:
        # run a simple first pass
        # which can be used to block out mappings
        bndsForPriCtls = data.all_bnds_for_priCtls
        priCtl.setupPriCtlFirstPass(bindGrp, bndsForPriCtls)
        priCtl.driveAttachedPriCtlsRun(bindGrp)

    #------------------------------------------------------------ pri ctl system second
    if 'primary_ctl_system_second' in data.build_actions:
        if data.priCtlMappings:
            # if priCtlMappings is set up, use the data
            priCtlMappings = data.priCtlMappings
            priCtl.setupPriCtlSecondPass(priCtlMappings)
            priCtl.driveAttachedPriCtlsRun(bindGrp)
            pm.refresh()
        else:
            pm.warning('no data for pri ctl system')

    #-------------------------------------------------------------- load weights
    if 'load_weights' in data.build_actions:
        priCtlWeights = data.priCtlWeights
        priCtl.setPriCtlSecondPassWeights(priCtlWeights)
        pm.refresh()

    #--------------------------------------------------------------------- clean
    if 'clean' in data.build_actions:
        print 'clean'
        face.cleanFaceRig()
        pm.select(cl=True)
        pm.refresh()

    #--------------------------------------------------------------- skin_layers
    if 'skin_layers' in data.build_actions:
        mll = skin.setupSkinLayers(None,
                                   layers=[
                                       'base', 'jaw', 'cheeks', 'crease',
                                       'lips', 'mouthbag', 'nose', 'brow'
                                   ])
        _, skn = mll.getTargetInfo()
        pm.PyNode(skn).skinningMethod.set(1)
        pm.PyNode(skn).deformUserNormals.set(0)

    #---------------------------------------------------------------------- eyes
    if 'eyes' in data.build_actions:
        buildEyeRig(placementGrp)

    #------------------------------------------------------------------ eyeballs
    if 'eyeballs' in data.build_actions:
        #------------------------------------------ EYEBALL RIG (SIMPLE AIM CONSTRAINTS)
        eye.buildEyeballRig()
        eye.addEyeAim(prefix='LT_',
                      distance=25)  # BROKEN if there is already a
        # node named LT_eyeball_grp!!!
        eye.addEyeAim(prefix='RT_', distance=25)  # BROKEN

    #--------------------------------------------------------------- fleshy_eyes
    if 'fleshy_eyes' in data.build_actions:
        import rigger.modules.poseReader as poseReader
        reload(poseReader)
        xfo = pm.PyNode('LT_eyeball_bnd')
        poseReader.radial_pose_reader(xfo)
        xfo = pm.PyNode('RT_eyeball_bnd')
        poseReader.radial_pose_reader(xfo)
        eye.addFleshyEye()

    #--------------------------------------------------------------- sticky lips
    if 'sticky_lips' in data.build_actions:
        import rigger.modules.sticky as sticky
        reload(sticky)
        sticky.Sticky(up_bnd=pm.PyNode('CT_upper_lip_bnd'),
                      low_bnd=pm.PyNode('CT_lower_lip_bnd'),
                      center=pm.PyNode('CT__jaw_pri_ctrl'))
        sticky.Sticky(up_bnd=pm.PyNode('LT_upperSide_lip_bnd'),
                      low_bnd=pm.PyNode('LT_lowerSide_lip_bnd'),
                      center=pm.PyNode('CT__jaw_pri_ctrl'))
        sticky.Sticky(up_bnd=pm.PyNode('LT_upperSneer_lip_bnd'),
                      low_bnd=pm.PyNode('LT_lowerSneer_lip_bnd'),
                      center=pm.PyNode('CT__jaw_pri_ctrl'))
        sticky.Sticky(up_bnd=pm.PyNode('LT_upperPinch_lip_bnd'),
                      low_bnd=pm.PyNode('LT_lowerPinch_lip_bnd'),
                      center=pm.PyNode('CT__jaw_pri_ctrl'))
        sticky.Sticky(up_bnd=pm.PyNode('RT_upperSide_lip_bnd'),
                      low_bnd=pm.PyNode('RT_lowerSide_lip_bnd'),
                      center=pm.PyNode('CT__jaw_pri_ctrl'))
        sticky.Sticky(up_bnd=pm.PyNode('RT_upperSneer_lip_bnd'),
                      low_bnd=pm.PyNode('RT_lowerSneer_lip_bnd'),
                      center=pm.PyNode('CT__jaw_pri_ctrl'))
        sticky.Sticky(up_bnd=pm.PyNode('RT_upperPinch_lip_bnd'),
                      low_bnd=pm.PyNode('RT_lowerPinch_lip_bnd'),
                      center=pm.PyNode('CT__jaw_pri_ctrl'))

        sticky.addStickyToFRS()
        sticky.patchOldSticky()

    #----------------------------------------------------------------- auto_sdks
    if 'auto_sdks' in data.build_actions:
        import utils.rigging as rt
        pCtl = pm.PyNode('CT__mouthMover_pri_ctrl')
        offsetGrp = priCtl.addOffset(pCtl, 'child', suffix='_autoRotate')
        rt.connectSDK(pCtl.tx, offsetGrp.ry, {-1.2: -15, 0: 0, 1.2: 15})
        rt.connectSDK(pCtl.tx, offsetGrp.rz, {-1.2: -12, 0: 0, 1.2: 12})
        rt.connectSDK(pCtl.tx, offsetGrp.tz, {-1.2: 0.4, 0: 0, 1.2: 0.4})

        # squint
        pCtl = pm.PyNode('LT__squint_pri_ctrl')
        offsetGrp = priCtl.addOffset(pCtl, 'parent', suffix='_autoVolume')
        rt.connectSDK(pCtl.ty, offsetGrp.tz, {0: 0, 1: 0.5})
        pCtl = pm.PyNode('RT__squint_pri_ctrl')
        offsetGrp = priCtl.addOffset(pCtl, 'parent', suffix='_autoVolume')
        rt.connectSDK(pCtl.ty, offsetGrp.tz, {0: 0, 1: 0.5})

        # inbrow
        import rigger.modules.secCtl as secCtl
        reload(secCtl)
        sCtl = pm.PyNode('LT_in_brow_ctrl')
        offsetGrp = secCtl.addOffset(sCtl, 'parent', suffix='_autoVolume')
        rt.connectSDK(sCtl.tx, offsetGrp.tz, {0: 0, -1: 0.2})
        sCtl = pm.PyNode('RT_in_brow_ctrl')
        offsetGrp = secCtl.addOffset(sCtl, 'parent', suffix='_autoVolume')
        rt.connectSDK(sCtl.tx, offsetGrp.tz, {0: 0, 1: 0.2})

    if 'finish_mathilda' in data.build_actions:
        # a few mathilda specific things to finalize rig
        # for demo reel purposes

        # 1. lock all TZs for better volume
        allCtls = pm.ls('*_ctrl', type='transform')
        for ctl in allCtls:
            ctl.tz.set(l=True, k=False)

        # 2. hide eye aim locators
        eyeAimLocs = [
            nt.Transform(u'LT_eye_aim_loc'),
            nt.Transform(u'RT_eye_aim_loc')
        ]
        for loc in eyeAimLocs:
            loc.v.set(False)

        # 3. go to object mode so we can select controls
        pm.selectMode(object=True)

        # 4. bind tongue and teeth
        geos = [
            nt.Transform(u'CT_lowerGums_geo'),
            nt.Transform(u'CT_tongue_geo'),
            nt.Transform(u'CT_lowerTeeth_geo')
        ]
        for geo in geos:
            pm.parentConstraint(pm.PyNode('CT__jaw_bnd'), geo, mo=True)
        '''
        # 5. reference all geos to make it easier to select controls
        allGeos = pm.PyNode('CT_geo_grp').getChildren(ad=True, type='mesh')
        for geo in allGeos:
            geo.overrideEnabled.set(True)
            geo.overrideDisplayType.set(True)
        '''

        # 6. smooth face mesh to make it look nicer
        pm.PyNode('CT_face_geoShape').displaySmoothMesh.set(2)
Esempio n. 26
0
def makeDynamicWire(jnts, geo, name, ctl):
    '''
    '''
    # make curve through joints
    startCrv = rt.makeCrvThroughObjs(jnts, name+'_startCrv', True, 2)
    
    # make curve dynamic
    mc.select(startCrv, r=True)
    meval('makeCurvesDynamic 2 { "0", "0", "1", "1", "0"};')
    
    # get a handle on new (badly named) nodes
    hairSys = mc.ls(sl=True)[0]
    foll = mc.listConnections(hairSys+'.outputHair[0]', d=True)[0]
    dynCrv = mc.listConnections(foll+'.outCurve', d=True)[0]
    
    # rename nodes properly
    hairSys = mc.rename(hairSys, name+'_hairSysShape')
    foll = mc.rename(foll, name+'_foll')
    dynCrv = mc.rename(dynCrv, name+'_dynCrv')
    
    # rename group and transform nodes as well
    hairSysTransform = mc.listRelatives(hairSys, p=True)[0]
    hairSysTransform = mc.rename(hairSysTransform, name+'_hairSys')
    
    startGrp = mc.listRelatives(foll, p=True)[0]
    startGrp = mc.rename(startGrp, name+'_hairSysFollicles')
    
    outputGrp = mc.listRelatives(dynCrv, p=True)[0]
    outputGrp = mc.rename(outputGrp, name+'_hairSysOutputCrvs')
    
    # since we now have start curve and end curve, we can make the wire deformer
    wireDfm, wireCrv = mc.wire(geo, wire=dynCrv, n=name+'_dyn_wireDfm', dds=(0,50))
    wireBaseUnwanted = wireCrv+'BaseWire'
    # replace base
    mc.connectAttr(startCrv+'.worldSpace[0]', wireDfm+'.baseWire[0]', f=True)
    mc.delete(wireBaseUnwanted)
    
    # group nodes nicely
    masterGrp = mc.group(hairSysTransform, startGrp, outputGrp, n=name+'_hairSysMaster_grp')
    rt.connectVisibilityToggle([startGrp, outputGrp], masterGrp, 'curvesVis', False)
    rt.connectVisibilityToggle(hairSysTransform, masterGrp, 'hairSysVis', False)
    
    # attributes on ctl
    mc.addAttr(ctl, ln='tDynamics', nn='DYNAMICS', at='enum', en='-----', k=True)
    #mc.setAttr(ctl+'.tDynamics', l=True)
    mc.addAttr(ctl, ln='enabled', at='bool', dv=True, k=True)
    mc.addAttr(ctl, ln='weight', at='double', min=0, max=1, dv=1, k=True)
    
    mc.connectAttr(ctl+'.weight', wireDfm+'.envelope', f=True)
    rt.connectSDK(ctl+'.enabled', hairSys+'.simulationMethod', {0:0, 1:3})
    
    # expose follicle attributes to ctl
    mc.addAttr(ctl, ln='pointLock', at='enum', en='No Attach:Base:Tip:Both Ends', k=True, dv=1)
    mc.connectAttr(ctl+'.pointLock', foll+'.pointLock', f=True)
    
    # expose hairSystem attributes to ctl
    mc.addAttr(ctl, ln='startCurveAttract', at='double', min=0, max=1, dv=0.05, k=True)
    mc.addAttr(ctl, ln='mass', at='double', min=0, dv=1, k=True)
    mc.addAttr(ctl, ln='drag', at='double', min=0, dv=0.05, k=True)
    mc.addAttr(ctl, ln='damp', at='double', min=0, dv=0, k=True)
    
    mc.connectAttr(ctl+'.startCurveAttract', hairSys+'.startCurveAttract', f=True)
    mc.connectAttr(ctl+'.mass', hairSys+'.mass', f=True)
    mc.connectAttr(ctl+'.drag', hairSys+'.drag', f=True)
    mc.connectAttr(ctl+'.damp', hairSys+'.damp', f=True)
    
Esempio n. 27
0
# add lipCurls in local bnds
#===============================================================================
lipCurlGrps = [
    nt.Transform(u'LT_upperSide_lip_local_bnd_lipCurl'),
    nt.Transform(u'CT_upper_lip_local_bnd_lipCurl'),
    nt.Transform(u'LT_upperPinch_lip_local_bnd_lipCurl'),
    nt.Transform(u'LT_upperSneer_lip_local_bnd_lipCurl'),
    nt.Transform(u'RT_upperSide_lip_local_bnd_lipCurl'),
    nt.Transform(u'RT_upperPinch_lip_local_bnd_lipCurl'),
    nt.Transform(u'RT_upperSneer_lip_local_bnd_lipCurl')
]

grp = lipCurlGrps[0]
for grp in lipCurlGrps:
    grp.addAttr('lipCurlVal', k=True)
    rt.connectSDK(grp.lipCurlVal, grp.ty, {-1: -0.0625, 0: 0, 1: 0.125})
    rt.connectSDK(grp.lipCurlVal, grp.tz, {-1: -0.25, 0: 0, 1: 0.5})
    rt.connectSDK(grp.lipCurlVal, grp.rx, {-1: 40, 0: 0, 1: -40})

lipCurlGrps = [
    nt.Transform(u'LT_lowerPinch_lip_local_bnd_lipCurl'),
    nt.Transform(u'CT_lower_lip_local_bnd_lipCurl'),
    nt.Transform(u'LT_lowerSneer_lip_local_bnd_lipCurl'),
    nt.Transform(u'LT_lowerSide_lip_local_bnd_lipCurl'),
    nt.Transform(u'RT_lowerPinch_lip_local_bnd_lipCurl'),
    nt.Transform(u'RT_lowerSneer_lip_local_bnd_lipCurl'),
    nt.Transform(u'RT_lowerSide_lip_local_bnd_lipCurl')
]

for grp in lipCurlGrps:
    grp.addAttr('lipCurlVal', k=True)
Esempio n. 28
0
def addLipCurlsSDKs():
    '''
    '''
    # upper lips
    coeffs = pm.group(em=True, n='CT_upperLipCurls_coeffs')
    coeffs.addAttr('leftPinch', k=True)
    coeffs.addAttr('leftSneer', k=True)
    coeffs.addAttr('leftSide', k=True)
    coeffs.addAttr('centerMid', k=True)
    coeffs.addAttr('rightSide', k=True)
    coeffs.addAttr('rightSneer', k=True)
    coeffs.addAttr('rightPinch', k=True)
    rt.connectSDK('FACE:LT_upper_pinch_lip_ctrl.rx',
    coeffs.leftPinch, {-90:1, 0:0, 90:-1})
    rt.connectSDK('FACE:LT_upper_sneer_lip_ctrl.rx',
    coeffs.leftSneer, {-90:1, 0:0, 90:-1})
    rt.connectSDK('FACE:LT_upper_side_lip_ctrl.rx',
    coeffs.leftSide, {-90:1, 0:0, 90:-1})
    rt.connectSDK('FACE:CT_upper_lip_ctrl.rx',
    coeffs.centerMid, {-90:1, 0:0, 90:-1})
    rt.connectSDK('FACE:RT_upper_sneer_lip_ctrl.rx',
    coeffs.rightSneer, {-90:1, 0:0, 90:-1})
    rt.connectSDK('FACE:RT_upper_side_lip_ctrl.rx',
    coeffs.rightSide, {-90:1, 0:0, 90:-1})
    rt.connectSDK('FACE:RT_upper_pinch_lip_ctrl.rx',
    coeffs.rightPinch, {-90:1, 0:0, 90:-1})
    
    priCtls = [nt.Transform(u'FACE:RT_upper_sneer_lip_pri_ctrl'),
                nt.Transform(u'FACE:CT_upper_lip_pri_ctrl'),
                nt.Transform(u'FACE:LT_upper_sneer_lip_pri_ctrl')]
                
    attrs = ['leftPinch',
    'leftSneer',
    'leftSide',
    'centerMid',
    'rightSide',
    'rightSneer',
    'rightPinch']
           
    import rigger.utils.modulate as modulate     
    for pCtl in priCtls:
        token = pCtl.split(':')[1].split('_')[0]
        for attr in attrs:
            mod = modulate.addInput(coeffs.attr(attr), 0, token)
            rt.connectSDK(pCtl.rx, mod, {-90:1, 0:0, 90:-1})
            
    rt.connectSDK(coeffs.leftPinch, 
    'FACE:blendShapeCt_face_geo.upLipTweakPinch_curlOut_Lf', {0:0, 1:1})
    rt.connectSDK(coeffs.leftPinch, 
    'FACE:blendShapeCt_face_geo.upLipTweakPinch_curlIn_Lf', {0:0, -1:1})
    
    rt.connectSDK(coeffs.leftSneer, 
    'FACE:blendShapeCt_face_geo.upLipTweakSneer_curlOut_Lf', {0:0, 1:1})
    rt.connectSDK(coeffs.leftSneer, 
    'FACE:blendShapeCt_face_geo.upLipTweakSneer_curlIn_Lf', {0:0, -1:1})
    
    rt.connectSDK(coeffs.leftSide, 
    'FACE:blendShapeCt_face_geo.upLipTweakSide_curlOut_Lf', {0:0, 1:1})
    rt.connectSDK(coeffs.leftSide, 
    'FACE:blendShapeCt_face_geo.upLipTweakSide_curlIn_Lf', {0:0, -1:1})
    
    rt.connectSDK(coeffs.centerMid, 
    'FACE:blendShapeCt_face_geo.upLipTweakMid_curlOut_Ct', {0:0, 1:1})
    rt.connectSDK(coeffs.centerMid, 
    'FACE:blendShapeCt_face_geo.upLipTweakMid_curlIn_Ct', {0:0, -1:1})
    
    rt.connectSDK(coeffs.rightPinch, 
    'FACE:blendShapeCt_face_geo.upLipTweakPinch_curlOut_Rt', {0:0, 1:1})
    rt.connectSDK(coeffs.rightPinch, 
    'FACE:blendShapeCt_face_geo.upLipTweakPinch_curlIn_Rt', {0:0, -1:1})
    
    rt.connectSDK(coeffs.rightSneer, 
    'FACE:blendShapeCt_face_geo.upLipTweakSneer_curlOut_Rt', {0:0, 1:1})
    rt.connectSDK(coeffs.rightSneer, 
    'FACE:blendShapeCt_face_geo.upLipTweakSneer_curlIn_Rt', {0:0, -1:1})
    
    rt.connectSDK(coeffs.rightSide, 
    'FACE:blendShapeCt_face_geo.upLipTweakSide_curlOut_Rt', {0:0, 1:1})
    rt.connectSDK(coeffs.rightSide, 
    'FACE:blendShapeCt_face_geo.upLipTweakSide_curlIn_Rt', {0:0, -1:1})
    
    # lower lips
    coeffs = pm.group(em=True, n='CT_lowerLipCurls_coeffs')
    coeffs.addAttr('leftPinch', k=True)
    coeffs.addAttr('leftSneer', k=True)
    coeffs.addAttr('leftSide', k=True)
    coeffs.addAttr('centerMid', k=True)
    coeffs.addAttr('rightSide', k=True)
    coeffs.addAttr('rightSneer', k=True)
    coeffs.addAttr('rightPinch', k=True)
    rt.connectSDK('FACE:LT_lower_pinch_lip_ctrl.rx',
    coeffs.leftPinch, {-90:-1, 0:0, 90:1})
    rt.connectSDK('FACE:LT_lower_sneer_lip_ctrl.rx',
    coeffs.leftSneer, {-90:-1, 0:0, 90:1})
    rt.connectSDK('FACE:LT_lower_side_lip_ctrl.rx',
    coeffs.leftSide, {-90:-1, 0:0, 90:1})
    rt.connectSDK('FACE:CT_lower_lip_ctrl.rx',
    coeffs.centerMid, {-90:-1, 0:0, 90:1})
    rt.connectSDK('FACE:RT_lower_sneer_lip_ctrl.rx',
    coeffs.rightSneer, {-90:-1, 0:0, 90:1})
    rt.connectSDK('FACE:RT_lower_side_lip_ctrl.rx',
    coeffs.rightSide, {-90:-1, 0:0, 90:1})
    rt.connectSDK('FACE:RT_lower_pinch_lip_ctrl.rx',
    coeffs.rightPinch, {-90:-1, 0:0, 90:1})
    
    priCtls = [nt.Transform(u'FACE:RT_lower_sneer_lip_pri_ctrl'),
                nt.Transform(u'FACE:CT_lower_lip_pri_ctrl'),
                nt.Transform(u'FACE:LT_lower_sneer_lip_pri_ctrl')]
                
    attrs = ['leftPinch',
    'leftSneer',
    'leftSide',
    'centerMid',
    'rightSide',
    'rightSneer',
    'rightPinch']
           
    import rigger.utils.modulate as modulate     
    for pCtl in priCtls:
        token = pCtl.split(':')[1].split('_')[0]
        for attr in attrs:
            mod = modulate.addInput(coeffs.attr(attr), 0, token)
            rt.connectSDK(pCtl.rx, mod, {-90:-1, 0:0, 90:1})
            
    rt.connectSDK(coeffs.leftPinch, 
    'FACE:blendShapeCt_face_geo.lowLipTweakPinch_curlOut_Lf', {0:0, 1:1})
    rt.connectSDK(coeffs.leftPinch, 
    'FACE:blendShapeCt_face_geo.lowLipTweakPinch_curlIn_Lf', {0:0, -1:1})
    
    rt.connectSDK(coeffs.leftSneer, 
    'FACE:blendShapeCt_face_geo.lowLipTweakSneer_curlOut_Lf', {0:0, 1:1})
    rt.connectSDK(coeffs.leftSneer, 
    'FACE:blendShapeCt_face_geo.lowLipTweakSneer_curlIn_Lf', {0:0, -1:1})
    
    rt.connectSDK(coeffs.leftSide, 
    'FACE:blendShapeCt_face_geo.lowLipTweakSide_curlOut_Lf', {0:0, 1:1})
    rt.connectSDK(coeffs.leftSide, 
    'FACE:blendShapeCt_face_geo.lowLipTweakSide_curlIn_Lf', {0:0, -1:1})
    
    rt.connectSDK(coeffs.centerMid, 
    'FACE:blendShapeCt_face_geo.lowLipTweakMid_curlOut_Ct', {0:0, 1:1})
    rt.connectSDK(coeffs.centerMid, 
    'FACE:blendShapeCt_face_geo.lowLipTweakMid_curlIn_Ct', {0:0, -1:1})
    
    rt.connectSDK(coeffs.rightPinch, 
    'FACE:blendShapeCt_face_geo.lowLipTweakPinch_curlOut_Rt', {0:0, 1:1})
    rt.connectSDK(coeffs.rightPinch, 
    'FACE:blendShapeCt_face_geo.lowLipTweakPinch_curlIn_Rt', {0:0, -1:1})
    
    rt.connectSDK(coeffs.rightSneer, 
    'FACE:blendShapeCt_face_geo.lowLipTweakSneer_curlOut_Rt', {0:0, 1:1})
    rt.connectSDK(coeffs.rightSneer, 
    'FACE:blendShapeCt_face_geo.lowLipTweakSneer_curlIn_Rt', {0:0, -1:1})
    
    rt.connectSDK(coeffs.rightSide, 
    'FACE:blendShapeCt_face_geo.lowLipTweakSide_curlOut_Rt', {0:0, 1:1})
    rt.connectSDK(coeffs.rightSide, 
    'FACE:blendShapeCt_face_geo.lowLipTweakSide_curlIn_Rt', {0:0, -1:1})
Esempio n. 29
0
import rigger.modules.poseReader as poseReader
reload(poseReader)
xfo = pm.PyNode('LT_eyeball_bnd')
poseReader.radial_pose_reader(xfo)
xfo = pm.PyNode('RT_eyeball_bnd')
poseReader.radial_pose_reader(xfo)
eye.addFleshyEye()
# adjust sdk tangents

#------------------------------------------------------------------- MOUTH MOVER
# create offset for mouth pri control
import rigger.modules.priCtl as priCtl
reload(priCtl)
pCtl = pm.PyNode('CT_mouthMover_pri_ctrl')
offsetGrp = priCtl.addOffset(pCtl, 'child', '_autoRotate')
rt.connectSDK(pCtl.tx, offsetGrp.ry, {-1:-15, 0:0, 1:15})
rt.connectSDK(pCtl.tx, offsetGrp.rz, {-1:-15, 0:0, 1:15})
rt.connectSDK(pCtl.tx, offsetGrp.tz, {-1:0.25, 0:0, 1:0.25})

# create offset for cheek pri ctrl
pCtl = pm.PyNode('LT_cheek_pri_ctrl')
offsetGrp = priCtl.addOffset(pCtl, 'child', '_autoVolume')
rt.connectSDK(pCtl.ty, offsetGrp.tz, {-1:-0.25, 0:0, 1:0.5})

# create offset for cheek pri ctrl
pCtl = pm.PyNode('RT_cheek_pri_ctrl')
offsetGrp = priCtl.addOffset(pCtl, 'child', '_autoVolume')
rt.connectSDK(pCtl.ty, offsetGrp.tz, {-1:-0.25, 0:0, 1:0.5})

#------------------------------------------------------------ EYE SQUASH LATTICE
import rigger.modules.eyeLattice as eyeLattice
Esempio n. 30
0
import rigger.modules.poseReader as poseReader
reload(poseReader)
xfo = pm.PyNode('LT_eyeball_bnd')
poseReader.radial_pose_reader(xfo)
xfo = pm.PyNode('RT_eyeball_bnd')
poseReader.radial_pose_reader(xfo)
eye.addFleshyEye()
# adjust sdk tangents

#------------------------------------------------------------------- MOUTH MOVER
# create offset for mouth pri control
import rigger.modules.priCtl as priCtl
reload(priCtl)
pCtl = pm.PyNode('CT_mouthMover_pri_ctrl')
offsetGrp = priCtl.addOffset(pCtl, 'child', '_autoRotate')
rt.connectSDK(pCtl.tx, offsetGrp.ry, {-1: -15, 0: 0, 1: 15})
rt.connectSDK(pCtl.tx, offsetGrp.rz, {-1: -15, 0: 0, 1: 15})
rt.connectSDK(pCtl.tx, offsetGrp.tz, {-1: 0.25, 0: 0, 1: 0.25})

# create offset for cheek pri ctrl
pCtl = pm.PyNode('LT_cheek_pri_ctrl')
offsetGrp = priCtl.addOffset(pCtl, 'child', '_autoVolume')
rt.connectSDK(pCtl.ty, offsetGrp.tz, {-1: -0.25, 0: 0, 1: 0.5})

# create offset for cheek pri ctrl
pCtl = pm.PyNode('RT_cheek_pri_ctrl')
offsetGrp = priCtl.addOffset(pCtl, 'child', '_autoVolume')
rt.connectSDK(pCtl.ty, offsetGrp.tz, {-1: -0.25, 0: 0, 1: 0.5})

#------------------------------------------------------------ EYE SQUASH LATTICE
import rigger.modules.eyeLattice as eyeLattice
def connectBsp(driverAttr, drivenAttr, geo, bspGeos, scaleTime=100):
    '''
    bspGeos is a dictionary of geos used for this bspTarget at various weights
    {-0.1: nt.mesh,
    0.1: nt.mesh}
    '''
    # get closest vertex on geo for offset calculation
    driverCtl = driverAttr.node()
    driverPt = pm.dt.Point(driverCtl.getRotatePivot(space='world'))

    faceId = geo.getClosestPoint(driverPt)[1]
    verts = [geo.vtx[i] for i in geo.f[faceId].getVertices()]
    closestVert = min(verts,
                      key=lambda x:
                      (x.getPosition(space='world') - driverPt).length())
    closestVertId = closestVert.index()

    # check that we've got the correct vert
    # pm.select(closestVert)
    print closestVertId

    # assuming that offsets are only in translation
    attrId = {'tx': 0, 'ty': 1, 'tz': 2}
    driverAttrId = attrId[driverAttr.attrName()]

    # position values need to be calculated into ctrl space
    ctlInvMat = driverCtl.getMatrix(worldSpace=True).inverse()

    # make sure that ctl is zeroed before calculating offsets
    driverAttr.set(0)

    # get offsets for each bspGeo
    # assign to a dictionary for creating sdk later
    sdkKeys = {0: 0}
    for weight, bspGeo in bspGeos.items():
        bspVertPt = bspGeo.vtx[closestVertId].getPosition(space='object')
        print bspVertPt
        offset = bspVertPt * ctlInvMat
        print offset
        offset = offset[driverAttrId]
        sdkKeys[offset] = weight

    # connect to bsp attr
    rt.connectSDK(driverAttr, drivenAttr, sdkKeys)

    # set keys for ctl for preview
    for offset, weight in sdkKeys.items():
        driverAttr.setKey(t=weight * scaleTime, v=offset)
        # save keys as attributes to be used later
        weightStr = str(weight).replace('.', '_').replace('-', 'neg')
        weightAttr = 'bspWeight_' + drivenAttr.getAlias() + '_' + weightStr
        try:
            driverCtl.addAttr(weightAttr)
        except RuntimeError:
            driverCtl.attr(weightAttr).set(l=False)
        driverCtl.attr(weightAttr).set(offset)
        driverCtl.attr(weightAttr).set(l=True)

    pm.select(driverCtl)

    return sdkKeys
Esempio n. 32
0
def addReverseRoll(jnts, bendPivot, leftPivot, rightPivot):
    '''
    add reverse roll to hand or foot setups
    
    jnts - 
    [base,
    [digitBase, digitEnd],
    ...
    ]
    
    digitBase joints will be parentConstrained to the new "stableDigitJoints" that sticks with the IK handles
    (so you should pass in an offset grp above the actual joint)
    
    ***
    ASSUME ONE SPLIT JOINT BETWEEN BASE AND DIGIT 
    TO BE CUSTOMIZED
    ***
    
    returns rollGrp, baseJnt
    
    EXAMPLE USE ON HAND:
    rollGrp (TRS, and attributes Bend & Side) should be driven by Ik/FKHand
    rollLocs rotations are driven by attributes on the Hand
    baseStableJnt is a child of the rollLocs, and therefore rotate with pivots at the rollLocs
    baseStableJnt drives the child of Ik/FkHand
    
    '''
    
    #===========================================================================
    # BUILD DRIVER JOINT CHAIN
    #===========================================================================
    
    baseJnt = jnts[0]
    digitJnts = jnts[1:]
    basePos = mc.xform(baseJnt, q=True, t=True, ws=True)
    
    # base joint
    mc.select(cl=True)
    baseStableJnt = mc.joint(n=baseJnt+'_stable')
    rt.parentSnap(baseStableJnt, baseJnt)
    mc.setAttr(baseStableJnt+'.jointOrient', 0,0,0)
    mc.parent(baseStableJnt, w=True)
    
    ikHs = []
    
    # digit joints
    for base, tip in digitJnts:
        
        #=======================================================================
        # MAKE JOINTS
        #=======================================================================
        
        mc.select(cl=True)
        
        # split joint
        digitPos = mc.xform(base, q=True, t=True, ws=True)
        # get midPoint between base to digitBase
        midPoint = [(b + d)/2 for b, d in zip(basePos, digitPos)]
        splitJnt = mc.joint(p=midPoint, n=base+'_mid')
        
        # digit base jnt
        digitBaseJnt = mc.joint(p=digitPos, n=base+'_stable')
        
        # digit end jnt
        tipPos = mc.xform(tip, q=True, t=True, ws=True)
        digitEndJnt = mc.joint(p=tipPos, n=base+'_stableTip')
        
        # orient joint chain
        mc.joint(splitJnt, oj='xyz', ch=True, sao='yup', e=True)
        mc.setAttr(digitEndJnt+'.jointOrient', 0,0,0)
        
        mc.parent(splitJnt, baseStableJnt)
        
        #=======================================================================
        # MAKE IKHANDLE
        #=======================================================================
        
        ikH = mc.ikHandle(solver='ikSCsolver', n=base+'_ikH', sj=digitBaseJnt, ee=digitEndJnt)[0]
        ikHs.append(ikH)
        
        #=======================================================================
        # PARENT CONSTRAINT original joints to stable joints
        #=======================================================================
        mc.parentConstraint(digitBaseJnt, base, mo=True)
    
    ikHdlGrp = mc.group(ikHs, n=baseJnt+'reverseRoll_ikHdl_grp')
    
    # parent baseStableJnt under locators to make multiple pivots
    
    rollGrp = abRT.groupFreeze(baseStableJnt)
    mc.parent(bendPivot, rollGrp)
    mc.parent(leftPivot, bendPivot)
    mc.parent(rightPivot, leftPivot)
    mc.parent(baseStableJnt, rightPivot)
    mc.parent(ikHdlGrp, rollGrp)
    
    # hide locators for debugging
    rt.connectVisibilityToggle([bendPivot, leftPivot, rightPivot], rollGrp, 'debugPivotLocs', False)
    
    # add attributes for controlling bend and side-to-side
    mc.addAttr(rollGrp, ln='bend', at='double', min=-10, max=10, dv=0, k=True)
    mc.addAttr(rollGrp, ln='side', at='double', min=-10, max=10, dv=0, k=True)
    
    rt.connectSDK(rollGrp+'.bend', bendPivot+'.rz', {-10:90, 10:-90})
    rt.connectSDK(rollGrp+'.side', leftPivot+'.rx', {0:0, 10:-90})
    rt.connectSDK(rollGrp+'.side', rightPivot+'.rx', {0:0, -10:90})
            
    return rollGrp, baseStableJnt
Esempio n. 33
0
def addStickyControlSystem():
    '''
    same as addStickyToFRS, but with arguments
    adds connections to individual sticky master nodes
    '''
    #lf_ctl = pm.PyNode('LT_corner_lip_pri_ctrl')
    #rt_ctl = pm.PyNode('RT_corner_lip_pri_ctrl')
    jaw_ctl = pm.PyNode('CT__jaw_pri_ctrl')
    jaw_ctg = jaw_ctl.getParent()

    lf_pinch = pm.PyNode('LT_upperPinch_lip_bnd_sticky_master')
    lf_sneer = pm.PyNode('LT_upperSneer_lip_bnd_sticky_master')
    lf_side = pm.PyNode('LT_upperSide_lip_bnd_sticky_master')
    rt_pinch = pm.PyNode('RT_upperPinch_lip_bnd_sticky_master')
    rt_sneer = pm.PyNode('RT_upperSneer_lip_bnd_sticky_master')
    rt_side = pm.PyNode('RT_upperSide_lip_bnd_sticky_master')
    ct_stick = pm.PyNode('CT_upper_lip_bnd_sticky_master')

    jaw_ctl.addAttr('leftSealAmount', k=True, dv=0, min=0, max=1)
    jaw_ctl.addAttr('rightSealAmount', k=True, dv=0, min=0, max=1)
    jaw_ctl.addAttr('leftSealHeight', k=True, dv=0.5, min=0, max=1)
    jaw_ctl.addAttr('rightSealHeight', k=True, dv=0.5, min=0, max=1)

    jaw_ctg.addAttr('lf_pinch_amt_lf', k=True)
    jaw_ctg.addAttr('lf_sneer_amt_lf', k=True)
    jaw_ctg.addAttr('lf_side_amt_lf', k=True)
    jaw_ctg.addAttr('lf_center_amt_lf', k=True)
    jaw_ctg.addAttr('rt_pinch_amt_lf', k=True)
    jaw_ctg.addAttr('rt_sneer_amt_lf', k=True)
    jaw_ctg.addAttr('rt_side_amt_lf', k=True)

    jaw_ctg.addAttr('lf_pinch_amt_rt', k=True)
    jaw_ctg.addAttr('lf_sneer_amt_rt', k=True)
    jaw_ctg.addAttr('lf_side_amt_rt', k=True)
    jaw_ctg.addAttr('lf_center_amt_rt', k=True)
    jaw_ctg.addAttr('rt_pinch_amt_rt', k=True)
    jaw_ctg.addAttr('rt_sneer_amt_rt', k=True)
    jaw_ctg.addAttr('rt_side_amt_rt', k=True)

    rt.connectSDK(jaw_ctl.leftSealAmount, jaw_ctg.lf_pinch_amt_lf, {
        0: 0,
        0.25: 1
    })
    rt.connectSDK(jaw_ctl.leftSealAmount, jaw_ctg.lf_sneer_amt_lf, {
        0: 0,
        0.75: 1
    })
    rt.connectSDK(jaw_ctl.leftSealAmount, jaw_ctg.lf_side_amt_lf, {
        0.25: 0,
        0.9: 0.75
    })
    rt.connectSDK(jaw_ctl.leftSealAmount, jaw_ctg.lf_center_amt_lf, {
        0.5: 0,
        1: 0.5
    })
    rt.connectSDK(jaw_ctl.leftSealAmount, jaw_ctg.rt_side_amt_lf, {
        0.75: 0,
        1: 0.25
    })
    rt.connectSDK(jaw_ctl.leftSealAmount, jaw_ctg.rt_sneer_amt_lf, {
        0: 0,
        1: 0
    })
    rt.connectSDK(jaw_ctl.leftSealAmount, jaw_ctg.rt_pinch_amt_lf, {
        0: 0,
        1: 0
    })

    rt.connectSDK(jaw_ctl.rightSealAmount, jaw_ctg.lf_pinch_amt_rt, {
        0: 0,
        0: 0
    })
    rt.connectSDK(jaw_ctl.rightSealAmount, jaw_ctg.lf_sneer_amt_rt, {
        0: 0,
        0: 0
    })
    rt.connectSDK(jaw_ctl.rightSealAmount, jaw_ctg.lf_side_amt_rt, {
        0.75: 0,
        1: 0.25
    })
    rt.connectSDK(jaw_ctl.rightSealAmount, jaw_ctg.lf_center_amt_rt, {
        0.5: 0,
        1: 0.5
    })
    rt.connectSDK(jaw_ctl.rightSealAmount, jaw_ctg.rt_side_amt_rt, {
        0.25: 0,
        0.9: 0.75
    })
    rt.connectSDK(jaw_ctl.rightSealAmount, jaw_ctg.rt_sneer_amt_rt, {
        0: 0,
        0.75: 1
    })
    rt.connectSDK(jaw_ctl.rightSealAmount, jaw_ctg.rt_pinch_amt_rt, {
        0: 0,
        0.25: 1
    })

    # connect sealAmounts
    connectStickyToSeal(jaw_ctg.lf_pinch_amt_lf, jaw_ctg.lf_pinch_amt_rt,
                        lf_pinch)
    connectStickyToSeal(jaw_ctg.lf_sneer_amt_lf, jaw_ctg.lf_sneer_amt_rt,
                        lf_sneer)
    connectStickyToSeal(jaw_ctg.lf_side_amt_lf, jaw_ctg.lf_side_amt_rt,
                        lf_side)
    connectStickyToSeal(jaw_ctg.lf_center_amt_lf, jaw_ctg.lf_center_amt_rt,
                        ct_stick)
    connectStickyToSeal(jaw_ctg.rt_side_amt_lf, jaw_ctg.rt_side_amt_rt,
                        rt_side)
    connectStickyToSeal(jaw_ctg.rt_sneer_amt_lf, jaw_ctg.rt_sneer_amt_rt,
                        rt_sneer)
    connectStickyToSeal(jaw_ctg.rt_pinch_amt_lf, jaw_ctg.rt_pinch_amt_rt,
                        rt_pinch)

    # jaw_ctl.addAttr('autoSticky', k=True, dv=0, min=0, max=1)

    # connect sealHeights
    jaw_ctl.leftSealHeight >> lf_pinch.midVal
    jaw_ctl.leftSealHeight >> lf_sneer.midVal
    jaw_ctl.leftSealHeight >> lf_side.midVal
    jaw_ctl.rightSealHeight >> rt_pinch.midVal
    jaw_ctl.rightSealHeight >> rt_sneer.midVal
    jaw_ctl.rightSealHeight >> rt_side.midVal
    # for center, use average between both sides
    ct_avg_pma = pm.createNode('plusMinusAverage', n='CT_stickyLips_avg_pma')
    ct_avg_pma.operation.set(3)
    jaw_ctl.leftSealHeight >> ct_avg_pma.input3D[0].i3x
    jaw_ctl.rightSealHeight >> ct_avg_pma.input3D[1].i3x
    ct_avg_pma.output3D.o3x >> ct_stick.midVal

    pm.group(lf_pinch,
             lf_side,
             lf_sneer,
             rt_pinch,
             rt_side,
             rt_sneer,
             ct_stick,
             n='CT_stickylips_grp')
Esempio n. 34
0
def build():
    '''
    '''
    mesh = nt.Mesh(u'CT_face_geoShape')   
    placementGrp = nt.Transform(u'CT_placement_grp')
    
    #---------------------------------------------------------------------- bind
    if 'bind' in data.build_actions:
        bindGrp = face.createBndsFromPlacement(placementGrp)
        pm.refresh()
    else:
        bindGrp = nt.Transform(u'CT_bnd_grp')
    
    #--------------------------------------------------------- sec motion system
    if 'sec_motion_system' in data.build_actions:
        face.buildSecondaryControlSystem(placementGrp, bindGrp, mesh)
        pm.refresh()
     
    #------------------------------------------------------------ pri ctl system first
    if 'primary_ctl_system_first' in data.build_actions:
        # run a simple first pass
        # which can be used to block out mappings
        bndsForPriCtls = data.all_bnds_for_priCtls
        priCtl.setupPriCtlFirstPass(bindGrp, bndsForPriCtls)
        priCtl.driveAttachedPriCtlsRun(bindGrp)
            
    #------------------------------------------------------------ pri ctl system second
    if 'primary_ctl_system_second' in data.build_actions:
        if data.priCtlMappings:
            # if priCtlMappings is set up, use the data
            priCtlMappings = data.priCtlMappings
            priCtl.setupPriCtlSecondPass(priCtlMappings)
            priCtl.driveAttachedPriCtlsRun(bindGrp)
            pm.refresh()
        else:
            pm.warning('no data for pri ctl system')
            
    #-------------------------------------------------------------- load weights
    if 'load_weights' in data.build_actions:
        priCtlWeights = data.priCtlWeights
        priCtl.setPriCtlSecondPassWeights(priCtlWeights)
        pm.refresh()
            
    #--------------------------------------------------------------------- clean
    if 'clean' in data.build_actions:
        print 'clean'
        face.cleanFaceRig()
        pm.select(cl=True)
        pm.refresh()
        
    #--------------------------------------------------------------- skin_layers
    if 'skin_layers' in data.build_actions:
        # initial bind
        mll = skin.setupSkinLayers(None, layers=[['base', None]])
        
        # split masks for up and low lips
        upVerts, lowVerts = skin.splitLipsVertices(mll)

        mll = skin.setupSkinLayers(mll, layers=[['neck', None],
                                                ('jaw', lowVerts),
                                                ('cheeks', upVerts),
                                                ('chin', lowVerts),
                                                ('crease', upVerts),
                                                ('lips', None),
                                                ('nose', None),
                                                ('brow', None)
                                                ])
        
        _, skn = mll.getTargetInfo()
        pm.PyNode(skn).skinningMethod.set(1)
        pm.PyNode(skn).deformUserNormals.set(0)
        
        
    #---------------------------------------------------------------------- eyes
    if 'eyes' in data.build_actions:
        buildEyeRig(placementGrp)
        
    #------------------------------------------------------------------ eyeballs
    if 'eyeballs' in data.build_actions:
        #------------------------------------------ EYEBALL RIG (SIMPLE AIM CONSTRAINTS)
        eye.buildEyeballRig()
        eye.addEyeAim(prefix='LT_', distance=25) # BROKEN if there is already a
        # node named LT_eyeball_grp!!!
        eye.addEyeAim(prefix='RT_', distance=25) # BROKEN
    
    #--------------------------------------------------------------- fleshy_eyes
    if 'fleshy_eyes' in data.build_actions:
        import rigger.modules.poseReader as poseReader
        reload(poseReader)
        xfo = pm.PyNode('LT_eyeball_bnd')
        poseReader.radial_pose_reader(xfo)
        xfo = pm.PyNode('RT_eyeball_bnd')
        poseReader.radial_pose_reader(xfo)
        eye.addFleshyEye()
        
    #--------------------------------------------------------------- sticky lips
    if 'sticky_lips' in data.build_actions:
        import rigger.modules.sticky as sticky
        reload(sticky)
        sticky.Sticky(up_bnd=pm.PyNode('CT_upper_lip_bnd'), 
                          low_bnd=pm.PyNode('CT_lower_lip_bnd'), 
                          center=pm.PyNode('CT__jaw_pri_ctrl'))
        sticky.Sticky(up_bnd=pm.PyNode('LT_upperSide_lip_bnd'), 
                          low_bnd=pm.PyNode('LT_lowerSide_lip_bnd'), 
                          center=pm.PyNode('CT__jaw_pri_ctrl'))
        sticky.Sticky(up_bnd=pm.PyNode('LT_upperSneer_lip_bnd'), 
                          low_bnd=pm.PyNode('LT_lowerSneer_lip_bnd'), 
                          center=pm.PyNode('CT__jaw_pri_ctrl'))
        sticky.Sticky(up_bnd=pm.PyNode('LT_upperPinch_lip_bnd'), 
                          low_bnd=pm.PyNode('LT_lowerPinch_lip_bnd'), 
                          center=pm.PyNode('CT__jaw_pri_ctrl'))
        sticky.Sticky(up_bnd=pm.PyNode('RT_upperSide_lip_bnd'), 
                          low_bnd=pm.PyNode('RT_lowerSide_lip_bnd'), 
                          center=pm.PyNode('CT__jaw_pri_ctrl'))
        sticky.Sticky(up_bnd=pm.PyNode('RT_upperSneer_lip_bnd'), 
                          low_bnd=pm.PyNode('RT_lowerSneer_lip_bnd'), 
                          center=pm.PyNode('CT__jaw_pri_ctrl'))
        sticky.Sticky(up_bnd=pm.PyNode('RT_upperPinch_lip_bnd'), 
                          low_bnd=pm.PyNode('RT_lowerPinch_lip_bnd'), 
                          center=pm.PyNode('CT__jaw_pri_ctrl'))
        
        sticky.addStickyToFRS()
        sticky.patchOldSticky()
        
    #----------------------------------------------------------------- auto_sdks
    if 'auto_sdks' in data.build_actions:
        import utils.rigging as rt
        pCtl = pm.PyNode('CT__mouthMover_pri_ctrl')
        offsetGrp = priCtl.addOffset(pCtl, 'child', suffix='_autoRotate')
        rt.connectSDK(pCtl.tx, offsetGrp.ry, {-1.2:-15, 0:0, 1.2:15})
        rt.connectSDK(pCtl.tx, offsetGrp.rz, {-1.2:-12, 0:0, 1.2:12})
        rt.connectSDK(pCtl.tx, offsetGrp.tz, {-1.2:0.4, 0:0, 1.2:0.4})
        
        # squint
        pCtl = pm.PyNode('LT__squint_pri_ctrl')
        offsetGrp = priCtl.addOffset(pCtl, 'parent', suffix='_autoVolume')
        rt.connectSDK(pCtl.ty, offsetGrp.tz, {0:0, 1:0.5})
        pCtl = pm.PyNode('RT__squint_pri_ctrl')
        offsetGrp = priCtl.addOffset(pCtl, 'parent', suffix='_autoVolume')
        rt.connectSDK(pCtl.ty, offsetGrp.tz, {0:0, 1:0.5})
        
        # inbrow
        import rigger.modules.secCtl as secCtl
        reload(secCtl)
        sCtl = pm.PyNode('LT_in_brow_ctrl')
        offsetGrp = secCtl.addOffset(sCtl, 'parent', suffix='_autoVolume')
        rt.connectSDK(sCtl.tx, offsetGrp.tz, {0:0, -1:0.2})
        sCtl = pm.PyNode('RT_in_brow_ctrl')
        offsetGrp = secCtl.addOffset(sCtl, 'parent', suffix='_autoVolume')
        rt.connectSDK(sCtl.tx, offsetGrp.tz, {0:0, 1:0.2})
        
    if 'finish_mathilda' in data.build_actions:
        # a few mathilda specific things to finalize rig
        # for demo reel purposes
        
        # 1. lock all TZs for better volume
        allCtls = pm.ls('*_ctrl', type='transform')
        for ctl in allCtls:
            ctl.tz.set(l=True, k=False)
            
        # 2. hide eye aim locators
        eyeAimLocs = [nt.Transform(u'LT_eye_aim_loc'),
                      nt.Transform(u'RT_eye_aim_loc')]
        for loc in eyeAimLocs:
            loc.v.set(False)
            
        # 3. go to object mode so we can select controls
        pm.selectMode(object=True)
        
        # 4. bind tongue and teeth
        '''
        geos = [nt.Transform(u'CT_lowerGums_geo'),
                nt.Transform(u'CT_tongue_geo'),
                nt.Transform(u'CT_lowerTeeth_geo')]
                '''
        geos = [nt.Transform(u'CT_tongue_geo'),
                nt.Transform(u'CT_lowerTeeth_geo')]
        for geo in geos:
            pm.parentConstraint(pm.PyNode('CT__jaw_bnd'), geo, mo=True)
        
        '''
Esempio n. 35
0
def addLowerLipCurls():
    coeffs = pm.group(em=True, n='CT_lowerLipCurls_add_coeffs')
    bsp = pm.PyNode('FACE:blendShapeCt_face_geo')
    
    coeffs.addAttr('leftPinch', k=True)
    coeffs.addAttr('leftSneer', k=True)
    coeffs.addAttr('leftSide', k=True)
    coeffs.addAttr('leftMid', k=True)
    coeffs.addAttr('centerMid', k=True)
    coeffs.addAttr('rightMid', k=True)
    coeffs.addAttr('rightSide', k=True)
    coeffs.addAttr('rightSneer', k=True)
    coeffs.addAttr('rightPinch', k=True)
    
    # direct connect main curls
    jawCtl = pm.PyNode('FACE:CT_jaw_pri_ctrl')
    rt.connectSDK(jawCtl.leftLowerLipCurl, coeffs.leftPinch, {-1:1, 0:0, 1:-1})
    rt.connectSDK(jawCtl.leftLowerLipCurl, coeffs.leftSneer, {-1:1, 0:0, 1:-1})
    rt.connectSDK(jawCtl.leftLowerLipCurl, coeffs.leftSide, {-1:1, 0:0, 1:-1})
    rt.connectSDK(jawCtl.leftLowerLipCurl, coeffs.leftMid, {-1:1, 0:0, 1:-1})
    rt.connectSDK(jawCtl.rightLowerLipCurl, coeffs.rightPinch, {-1:1, 0:0, 1:-1})
    rt.connectSDK(jawCtl.rightLowerLipCurl, coeffs.rightSneer, {-1:1, 0:0, 1:-1})
    rt.connectSDK(jawCtl.rightLowerLipCurl, coeffs.rightSide, {-1:1, 0:0, 1:-1})
    rt.connectSDK(jawCtl.rightLowerLipCurl, coeffs.rightMid, {-1:1, 0:0, 1:-1})
    
    # average for center
    pma = pm.createNode('plusMinusAverage', n='CT_lowerLipCurlsMidAvg_pma')
    pma.operation.set(3)
    coeffs.leftMid >> pma.input1D[0]
    coeffs.rightMid >> pma.input1D[1]
    pma.output1D >> coeffs.centerMid
    
    # disconnect secCtl rotateX
    ctls = [nt.Transform(u'FACE:RT_lower_pinch_lip_ctrl'),
            nt.Transform(u'FACE:RT_lower_sneer_lip_ctrl'),
            nt.Transform(u'FACE:RT_lower_side_lip_ctrl'),
            nt.Transform(u'FACE:CT_lower_lip_ctrl'),
            nt.Transform(u'FACE:LT_lower_side_lip_ctrl'),
            nt.Transform(u'FACE:LT_lower_sneer_lip_ctrl'),
            nt.Transform(u'FACE:LT_lower_pinch_lip_ctrl')]
    for ctl in ctls:
        outNode = ctl.r.outputs()[0]
        ctl.ry >> outNode.ry
        ctl.rz >> outNode.rz
        ctl.r // outNode.r
        
    # add secCtls to coeffs
    import rigger.utils.modulate as modulate
    reload(modulate)
    import utils.rigging as rt
    reload(rt)
    mod = modulate.addInput(coeffs.leftPinch, 0, '_secCtl')
    rt.connectSDK(ctls[6].rx, mod, {45:-1, 0:0, -45:1})
    mod = modulate.addInput(coeffs.leftSneer, 0, '_secCtl')
    rt.connectSDK(ctls[5].rx, mod, {45:-1, 0:0, -45:1})
    mod = modulate.addInput(coeffs.leftSide, 0, '_secCtl')
    rt.connectSDK(ctls[4].rx, mod, {45:-1, 0:0, -45:1})
    mod = modulate.addInput(coeffs.centerMid, 0, '_secCtl')
    rt.connectSDK(ctls[3].rx, mod, {45:-1, 0:0, -45:1})
    mod = modulate.addInput(coeffs.rightSide, 0, '_secCtl')
    rt.connectSDK(ctls[2].rx, mod, {45:-1, 0:0, -45:1})
    mod = modulate.addInput(coeffs.rightSneer, 0, '_secCtl')
    rt.connectSDK(ctls[1].rx, mod, {45:-1, 0:0, -45:1})
    mod = modulate.addInput(coeffs.rightPinch, 0, '_secCtl')
    rt.connectSDK(ctls[0].rx, mod, {45:-1, 0:0, -45:1})
    
    # connect to bsp
    coeffs.leftPinch >> bsp.lowLipPinchTweak_curl_Lf
    coeffs.leftSneer >> bsp.lowLipSneerTweak_curl_Lf
    coeffs.leftSide >> bsp.lowLipSideTweak_curl_Lf
    coeffs.centerMid >> bsp.lowLipTweak_curl_Ct
    coeffs.rightSide >> bsp.lowLipSideTweak_curl_Rt
    coeffs.rightSneer >> bsp.lowLipSneerTweak_curl_Rt
    coeffs.rightPinch >> bsp.lowLipPinchTweak_curl_Rt
import pymel.core as pm
from pymel.core.language import Mel
mel = Mel()

import pymel.core.nodetypes as nt

import utils.rigging as rt
# coeffs
coeffs = pm.group(em=True, n='CT_lipCurlOut_coeffs')
coeffs.addAttr('leftLower', k=True)
coeffs.addAttr('leftUpper', k=True)
coeffs.addAttr('rightLower', k=True)
coeffs.addAttr('rightUpper', k=True)

# direct drives
rt.connectSDK('LT_lowerSneer_lip_pri_ctrl.rx',
coeffs.leftLower, {0:0, 45:1})
rt.connectSDK('LT_upperSneer_lip_pri_ctrl.rx',
coeffs.leftUpper, {0:0, -45:1})
rt.connectSDK('RT_lowerSneer_lip_pri_ctrl.rx',
coeffs.rightLower, {0:0, 45:1})
rt.connectSDK('RT_upperSneer_lip_pri_ctrl.rx',
coeffs.rightUpper, {0:0, -45:1})

# modulate by centers
import rigger.utils.modulate as modulate
reload(modulate)

priCtls = [nt.Transform(u'CT_upper_lip_pri_ctrl'),
nt.Transform(u'CT_lower_lip_pri_ctrl')]
            
attrs = ['leftLower',
Esempio n. 37
0
def makeDynamicWire(jnts, geo, name, ctl):
    '''
    '''
    # make curve through joints
    startCrv = rt.makeCrvThroughObjs(jnts, name + '_startCrv', True, 2)

    # make curve dynamic
    mc.select(startCrv, r=True)
    meval('makeCurvesDynamic 2 { "0", "0", "1", "1", "0"};')

    # get a handle on new (badly named) nodes
    hairSys = mc.ls(sl=True)[0]
    foll = mc.listConnections(hairSys + '.outputHair[0]', d=True)[0]
    dynCrv = mc.listConnections(foll + '.outCurve', d=True)[0]

    # rename nodes properly
    hairSys = mc.rename(hairSys, name + '_hairSysShape')
    foll = mc.rename(foll, name + '_foll')
    dynCrv = mc.rename(dynCrv, name + '_dynCrv')

    # rename group and transform nodes as well
    hairSysTransform = mc.listRelatives(hairSys, p=True)[0]
    hairSysTransform = mc.rename(hairSysTransform, name + '_hairSys')

    startGrp = mc.listRelatives(foll, p=True)[0]
    startGrp = mc.rename(startGrp, name + '_hairSysFollicles')

    outputGrp = mc.listRelatives(dynCrv, p=True)[0]
    outputGrp = mc.rename(outputGrp, name + '_hairSysOutputCrvs')

    # since we now have start curve and end curve, we can make the wire deformer
    wireDfm, wireCrv = mc.wire(geo,
                               wire=dynCrv,
                               n=name + '_dyn_wireDfm',
                               dds=(0, 50))
    wireBaseUnwanted = wireCrv + 'BaseWire'
    # replace base
    mc.connectAttr(startCrv + '.worldSpace[0]',
                   wireDfm + '.baseWire[0]',
                   f=True)
    mc.delete(wireBaseUnwanted)

    # group nodes nicely
    masterGrp = mc.group(hairSysTransform,
                         startGrp,
                         outputGrp,
                         n=name + '_hairSysMaster_grp')
    rt.connectVisibilityToggle([startGrp, outputGrp], masterGrp, 'curvesVis',
                               False)
    rt.connectVisibilityToggle(hairSysTransform, masterGrp, 'hairSysVis',
                               False)

    # attributes on ctl
    mc.addAttr(ctl,
               ln='tDynamics',
               nn='DYNAMICS',
               at='enum',
               en='-----',
               k=True)
    #mc.setAttr(ctl+'.tDynamics', l=True)
    mc.addAttr(ctl, ln='enabled', at='bool', dv=True, k=True)
    mc.addAttr(ctl, ln='weight', at='double', min=0, max=1, dv=1, k=True)

    mc.connectAttr(ctl + '.weight', wireDfm + '.envelope', f=True)
    rt.connectSDK(ctl + '.enabled', hairSys + '.simulationMethod', {
        0: 0,
        1: 3
    })

    # expose follicle attributes to ctl
    mc.addAttr(ctl,
               ln='pointLock',
               at='enum',
               en='No Attach:Base:Tip:Both Ends',
               k=True,
               dv=1)
    mc.connectAttr(ctl + '.pointLock', foll + '.pointLock', f=True)

    # expose hairSystem attributes to ctl
    mc.addAttr(ctl,
               ln='startCurveAttract',
               at='double',
               min=0,
               max=1,
               dv=0.05,
               k=True)
    mc.addAttr(ctl, ln='mass', at='double', min=0, dv=1, k=True)
    mc.addAttr(ctl, ln='drag', at='double', min=0, dv=0.05, k=True)
    mc.addAttr(ctl, ln='damp', at='double', min=0, dv=0, k=True)

    mc.connectAttr(ctl + '.startCurveAttract',
                   hairSys + '.startCurveAttract',
                   f=True)
    mc.connectAttr(ctl + '.mass', hairSys + '.mass', f=True)
    mc.connectAttr(ctl + '.drag', hairSys + '.drag', f=True)
    mc.connectAttr(ctl + '.damp', hairSys + '.damp', f=True)
Esempio n. 38
0
import utils.rigging as rt
#===============================================================================
# add lipCurls in local bnds
#===============================================================================
lipCurlGrps = [nt.Transform(u'LT_upperSide_lip_local_bnd_lipCurl'),
nt.Transform(u'CT_upper_lip_local_bnd_lipCurl'),
nt.Transform(u'LT_upperPinch_lip_local_bnd_lipCurl'),
nt.Transform(u'LT_upperSneer_lip_local_bnd_lipCurl'),
nt.Transform(u'RT_upperSide_lip_local_bnd_lipCurl'),
nt.Transform(u'RT_upperPinch_lip_local_bnd_lipCurl'),
nt.Transform(u'RT_upperSneer_lip_local_bnd_lipCurl')]

grp = lipCurlGrps[0]
for grp in lipCurlGrps:
    grp.addAttr('lipCurlVal', k=True)
    rt.connectSDK(grp.lipCurlVal, grp.ty, {-1:-0.0625, 0:0, 1:0.125})
    rt.connectSDK(grp.lipCurlVal, grp.tz, {-1:-0.25, 0:0, 1:0.5})
    rt.connectSDK(grp.lipCurlVal, grp.rx, {-1:40, 0:0, 1:-40})
    
lipCurlGrps = [nt.Transform(u'LT_lowerPinch_lip_local_bnd_lipCurl'),
nt.Transform(u'CT_lower_lip_local_bnd_lipCurl'),
nt.Transform(u'LT_lowerSneer_lip_local_bnd_lipCurl'),
nt.Transform(u'LT_lowerSide_lip_local_bnd_lipCurl'),
nt.Transform(u'RT_lowerPinch_lip_local_bnd_lipCurl'),
nt.Transform(u'RT_lowerSneer_lip_local_bnd_lipCurl'),
nt.Transform(u'RT_lowerSide_lip_local_bnd_lipCurl')]

for grp in lipCurlGrps:
    grp.addAttr('lipCurlVal', k=True)
    rt.connectSDK(grp.lipCurlVal, grp.ty, {-1:0.0625, 0:0, 1:-0.125})
    rt.connectSDK(grp.lipCurlVal, grp.tz, {-1:-0.25, 0:0, 1:0.5})
Esempio n. 39
0
def addStickyToFRS():
    '''
    decrepretated - only use for Ori
    assume all FRS nodes are already named correctly
    
    '''
    #lf_ctl = pm.PyNode('LT_corner_lip_pri_ctrl')
    #rt_ctl = pm.PyNode('RT_corner_lip_pri_ctrl')
    jaw_ctl = pm.PyNode('CT__jaw_pri_ctrl')
    jaw_ctg = jaw_ctl.getParent()

    lf_pinch = pm.PyNode('LT_upperPinch_lip_bnd_sticky_master')
    lf_sneer = pm.PyNode('LT_upperSneer_lip_bnd_sticky_master')
    lf_side = pm.PyNode('LT_upperSide_lip_bnd_sticky_master')
    rt_pinch = pm.PyNode('RT_upperPinch_lip_bnd_sticky_master')
    rt_sneer = pm.PyNode('RT_upperSneer_lip_bnd_sticky_master')
    rt_side = pm.PyNode('RT_upperSide_lip_bnd_sticky_master')
    ct_stick = pm.PyNode('CT_upper_lip_bnd_sticky_master')

    jaw_ctl.addAttr('leftSealAmount', k=True, dv=0, min=0, max=10)
    jaw_ctl.addAttr('rightSealAmount', k=True, dv=0, min=0, max=10)
    jaw_ctl.addAttr('leftSealHeight', k=True, dv=0.5, min=0, max=1)
    jaw_ctl.addAttr('rightSealHeight', k=True, dv=0.5, min=0, max=1)

    jaw_ctg.addAttr('lf_pinch_amt_lf', k=True)
    jaw_ctg.addAttr('lf_sneer_amt_lf', k=True)
    jaw_ctg.addAttr('lf_side_amt_lf', k=True)
    jaw_ctg.addAttr('lf_center_amt_lf', k=True)
    jaw_ctg.addAttr('rt_pinch_amt_lf', k=True)
    jaw_ctg.addAttr('rt_sneer_amt_lf', k=True)
    jaw_ctg.addAttr('rt_side_amt_lf', k=True)

    jaw_ctg.addAttr('lf_pinch_amt_rt', k=True)
    jaw_ctg.addAttr('lf_sneer_amt_rt', k=True)
    jaw_ctg.addAttr('lf_side_amt_rt', k=True)
    jaw_ctg.addAttr('lf_center_amt_rt', k=True)
    jaw_ctg.addAttr('rt_pinch_amt_rt', k=True)
    jaw_ctg.addAttr('rt_sneer_amt_rt', k=True)
    jaw_ctg.addAttr('rt_side_amt_rt', k=True)

    rt.connectSDK(jaw_ctl.leftSealAmount, jaw_ctg.lf_pinch_amt_lf, {
        0: 0,
        4: 1
    })
    rt.connectSDK(jaw_ctl.leftSealAmount, jaw_ctg.lf_sneer_amt_lf, {
        2: 0,
        6: 1
    })
    rt.connectSDK(jaw_ctl.leftSealAmount, jaw_ctg.lf_side_amt_lf, {4: 0, 8: 1})
    rt.connectSDK(jaw_ctl.leftSealAmount, jaw_ctg.lf_center_amt_lf, {
        6: 0,
        10: 0.5
    })
    rt.connectSDK(jaw_ctl.leftSealAmount, jaw_ctg.rt_side_amt_lf, {
        0: 0,
        10: 0
    })
    rt.connectSDK(jaw_ctl.leftSealAmount, jaw_ctg.rt_sneer_amt_lf, {
        0: 0,
        10: 0
    })
    rt.connectSDK(jaw_ctl.leftSealAmount, jaw_ctg.rt_pinch_amt_lf, {
        0: 0,
        10: 0
    })

    rt.connectSDK(jaw_ctl.rightSealAmount, jaw_ctg.lf_pinch_amt_rt, {
        0: 0,
        10: 0
    })
    rt.connectSDK(jaw_ctl.rightSealAmount, jaw_ctg.lf_sneer_amt_rt, {
        0: 0,
        10: 0
    })
    rt.connectSDK(jaw_ctl.rightSealAmount, jaw_ctg.lf_side_amt_rt, {
        0: 0,
        10: 0
    })
    rt.connectSDK(jaw_ctl.rightSealAmount, jaw_ctg.lf_center_amt_rt, {
        6: 0,
        10: 0.5
    })
    rt.connectSDK(jaw_ctl.rightSealAmount, jaw_ctg.rt_side_amt_rt, {
        4: 0,
        8: 1
    })
    rt.connectSDK(jaw_ctl.rightSealAmount, jaw_ctg.rt_sneer_amt_rt, {
        2: 0,
        6: 1
    })
    rt.connectSDK(jaw_ctl.rightSealAmount, jaw_ctg.rt_pinch_amt_rt, {
        0: 0,
        4: 1
    })

    # connect sealAmounts
    connectStickyToSeal(jaw_ctg.lf_pinch_amt_lf, jaw_ctg.lf_pinch_amt_rt,
                        lf_pinch)
    connectStickyToSeal(jaw_ctg.lf_sneer_amt_lf, jaw_ctg.lf_sneer_amt_rt,
                        lf_sneer)
    connectStickyToSeal(jaw_ctg.lf_side_amt_lf, jaw_ctg.lf_side_amt_rt,
                        lf_side)
    connectStickyToSeal(jaw_ctg.lf_center_amt_lf, jaw_ctg.lf_center_amt_rt,
                        ct_stick)
    connectStickyToSeal(jaw_ctg.rt_side_amt_lf, jaw_ctg.rt_side_amt_rt,
                        rt_side)
    connectStickyToSeal(jaw_ctg.rt_sneer_amt_lf, jaw_ctg.rt_sneer_amt_rt,
                        rt_sneer)
    connectStickyToSeal(jaw_ctg.rt_pinch_amt_lf, jaw_ctg.rt_pinch_amt_rt,
                        rt_pinch)

    # jaw_ctl.addAttr('autoSticky', k=True, dv=0, min=0, max=1)

    # connect sealHeights
    jaw_ctl.leftSealHeight >> lf_pinch.midVal
    jaw_ctl.leftSealHeight >> lf_sneer.midVal
    jaw_ctl.leftSealHeight >> lf_side.midVal
    jaw_ctl.rightSealHeight >> rt_pinch.midVal
    jaw_ctl.rightSealHeight >> rt_sneer.midVal
    jaw_ctl.rightSealHeight >> rt_side.midVal
    # for center, use average between both sides
    ct_avg_pma = pm.createNode('plusMinusAverage', n='CT_stickyLips_avg_pma')
    ct_avg_pma.operation.set(3)
    jaw_ctl.leftSealHeight >> ct_avg_pma.input3D[0].i3x
    jaw_ctl.rightSealHeight >> ct_avg_pma.input3D[1].i3x
    ct_avg_pma.output3D.o3x >> ct_stick.midVal

    pm.group(lf_pinch,
             lf_side,
             lf_sneer,
             rt_pinch,
             rt_side,
             rt_sneer,
             ct_stick,
             n='CT_stickylips_grp')
Esempio n. 40
0
import utils.rigging as rt
import koalaRigger.lib.createNode as cn
import maya.cmds as mc

#===============================================================================
# JAWOPEN rig
#===============================================================================

# LT corner
rt.connectSDK('CT_lips_mod_0.lfCorner', 'LT_mouthCornerHold_bnd_0_parentConstraint1.CT_top_center_locW0', {-1:0, 0:1, 1:1})
rt.connectSDK('CT_lips_mod_0.lfCorner', 'LT_mouthCornerHold_bnd_0_parentConstraint1.CT_bottom_center_locW1', {-1:1, 0:1, 1:0})
# RT corner
rt.connectSDK('CT_lips_mod_0.rtCorner', 'RT_mouthCornerHold_bnd_0_parentConstraint1.CT_top_center_locW0', {-1:0, 0:1, 1:1})
rt.connectSDK('CT_lips_mod_0.rtCorner', 'RT_mouthCornerHold_bnd_0_parentConstraint1.CT_bottom_center_locW1', {-1:1, 0:1, 1:0})

# JawOpen down
rt.connectSDK('CT_lips_mod_0.jawOpen', 'CT_jawOpen_grp.rotateX', {-1:90, 0:0})
# JawOpen up
rt.connectSDK('CT_lips_mod_0.jawOpen', 'CT_jawOpenMouthUp_grp.rotateX', {0:0, 0.5:-7})

# MouthOpen up
rt.connectSDK('CT_lips_mod_0.jawOpen', 'CT_mouthOpen_grp.rx', {0:0, 0.5:-7})

#===============================================================================
# LIPS SEAL rig
#===============================================================================

# LT seal remaps
lfCnrRemap = mc.createNode('remapValue', n='LT_sealCnrRemap')
mc.connectAttr('CT_lips_mod_0.lfSeal', lfCnrRemap+'.inputValue', f=True)
mc.setAttr(lfCnrRemap+'.inputMin', 0)
Esempio n. 41
0
import utils.rigging as rt
import koalaRigger.lib.createNode as cn
import maya.cmds as mc

#===============================================================================
# JAWOPEN rig
#===============================================================================

# LT corner
rt.connectSDK(
    'CT_lips_mod_0.lfCorner',
    'LT_mouthCornerHold_bnd_0_parentConstraint1.CT_top_center_locW0', {
        -1: 0,
        0: 1,
        1: 1
    })
rt.connectSDK(
    'CT_lips_mod_0.lfCorner',
    'LT_mouthCornerHold_bnd_0_parentConstraint1.CT_bottom_center_locW1', {
        -1: 1,
        0: 1,
        1: 0
    })
# RT corner
rt.connectSDK(
    'CT_lips_mod_0.rtCorner',
    'RT_mouthCornerHold_bnd_0_parentConstraint1.CT_top_center_locW0', {
        -1: 0,
        0: 1,
        1: 1
    })
Esempio n. 42
0
def create(ctl, tipGeo, weights, name, keys, addGeos=[], useScale=False):
    '''
    tipGeo - vtx of the tip of the eye
    weights - list of weights for each loop radiating outwards (including geoTip)
    e.g. [1, 1, 1, 1, 1, .95, 0.75, 0.5, .25, .1]
    addGeo - list of additional geometry for cluster to deform
    name - 'pupil' or 'iris'
    
    e.g.:
    geo = nt.Mesh(u'LT_eyeball_geoShape')
    tipGeo = geo.vtx[381]
    ctl = nt.Transform(u'LT_eye_ctl')
    name = '_iris'
    
    keys = {'sx': {0.01:0.01, 1:1, 2:2},
            'sy': {0.01:0.01, 1:1, 2:2},
            'sz': {0.01:0.01, 1:1, 2:3.75}}
    weights = [1, 1, 1, 1, 1, .95, 0.75, 0.5, .25, .1]
    '''
    geo = tipGeo.node()
    dfm, hdl = pm.cluster(tipGeo, n=ctl + name + '_dfm', foc=True)
    dfg = pm.group(hdl, n=ctl + name + '_dfg')
    rp = hdl.getRotatePivot(space='world')
    sp = hdl.getScalePivot(space='world')
    dfg.setRotatePivot(rp, space='world')
    dfg.setScalePivot(sp, space='world')
    dfh = pm.group(dfg, n=ctl + name + '_dfh')

    ctl.addAttr(name, min=0.01, max=2, dv=1, k=True)

    for attr, key in keys.items():
        rt.connectSDK(ctl.attr(name), hdl.attr(attr), key)

    loopNums = len(weights) - 1
    vertLoops = mesh.VertexLoops([tipGeo], loopNums)

    # add membership
    pm.select(vertLoops[:])
    for vertLoop in vertLoops[:]:
        for eachVert in vertLoop:
            dfm.setGeometry(eachVert)

    for loopId, weight in enumerate(weights):
        for eachVert in vertLoops[loopId]:
            print eachVert
            dfm.setWeight(geo, 0, eachVert, weight)

    # add additional geometries
    for eachGeo in addGeos:
        dfm.setGeometry(eachGeo, foc=True)

    if useScale:
        # modulate cluster scale by control scale
        for eachAttr in ('sx', 'sy', 'sz'):
            scaleInput = hdl.attr(eachAttr).inputs(p=True)[0]
            mdl = pm.createNode('multDoubleLinear',
                                n=hdl + '_' + eachAttr + '_scale_mdl')
            scaleInput >> mdl.input1
            ctl.attr(eachAttr) >> mdl.input2
            mdl.output >> hdl.attr(eachAttr)
    return dfh