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})
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
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})
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 })
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})
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
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})
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")
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})
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')
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
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
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})
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
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')
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
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')
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())
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})
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)
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)
# 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)
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})
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
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
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
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')
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) '''
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',
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)
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})
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')
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)
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 })
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