def addOffsetRig(): #=============================================================================== # SETUP LOCATORS FOR ALIGN AND AIM #=============================================================================== # add offsetAimLocs to blockAimCrv globalGrp = 'CT_teethOffset_mod_0' mc.group(n=globalGrp, em=True) name = 'CT_teethOffset' targetCrv = 'CT_teethBlockAim_crv_0' locs = [] for locId in range(12): loc = mc.spaceLocator(n=name + '_aim_loc_%d' % locId)[0] mc.setAttr(loc + '.localScale', 0.1, 0.1, 0.1) rt.attachToMotionPath(targetCrv, (float(locId) + 0.5) / 12, loc, True) locs.append(loc) mc.group(locs, n='CT_teethOffset_aim_loc_grp', p=globalGrp) rt.connectVisibilityToggle(locs, globalGrp, 'aimLocs', False) # add offsetAlignLocs to blockDrvCrv targetCrv = 'CT_teethBlockDrv_crv_0' locs = [] for locId in range(12): loc = mc.spaceLocator(n=name + '_align_loc_%d' % locId)[0] mc.setAttr(loc + '.localScale', 0.1, 0.1, 0.1) rt.alignOnMotionPath(targetCrv, (float(locId) + 0.5) / 12, loc, name + '_aim_loc_%d.matrix' % locId, True, ua=1, inverseUp=True) locs.append(loc) mc.group(locs, n='CT_teethOffset_align_loc_grp', p=globalGrp) rt.connectVisibilityToggle(locs, globalGrp, 'alignLocs', False)
def addOffsetRig(): #=============================================================================== # SETUP LOCATORS FOR ALIGN AND AIM #=============================================================================== # add offsetAimLocs to blockAimCrv globalGrp = 'CT_teethOffset_mod_0' mc.group(n=globalGrp, em=True) name = 'CT_teethOffset' targetCrv = 'CT_teethBlockAim_crv_0' locs=[] for locId in range(12): loc = mc.spaceLocator(n=name+'_aim_loc_%d'%locId)[0] mc.setAttr(loc+'.localScale', 0.1,0.1,0.1) rt.attachToMotionPath(targetCrv, (float(locId)+0.5)/12, loc, True) locs.append(loc) mc.group(locs, n='CT_teethOffset_aim_loc_grp', p=globalGrp) rt.connectVisibilityToggle(locs, globalGrp, 'aimLocs', False) # add offsetAlignLocs to blockDrvCrv targetCrv = 'CT_teethBlockDrv_crv_0' locs=[] for locId in range(12): loc = mc.spaceLocator(n=name+'_align_loc_%d'%locId)[0] mc.setAttr(loc+'.localScale', 0.1,0.1,0.1) rt.alignOnMotionPath(targetCrv, (float(locId)+0.5)/12, loc, name+'_aim_loc_%d.matrix'%locId, True, ua=1, inverseUp=True) locs.append(loc) mc.group(locs, n='CT_teethOffset_align_loc_grp', p=globalGrp) rt.connectVisibilityToggle(locs, globalGrp, 'alignLocs', False)
def addJntsOnSurfIntersection(surf1, surf2, jntsNum): ''' Places jnts along intersection curve between surf1 and surf2 naming convention based on surf1 ''' # intersect surfaces crvGrp, intNode = mc.intersect(surf1, surf2, fs=True, ch=True, o=True, cos=False)[:2] intNode = mc.rename(intNode, surf1+'_ints') crvGrp = mc.rename(crvGrp, surf1+'_ints_crv_grp') crv = mc.listRelatives(crvGrp, c=True)[0] crv = mc.rename(crv, surf1+'_ints_crv') # rebuild curve to jntNum spans rbdCrv, rbdNode = mc.rebuildCurve(crv, ch=True, o=True, rpo=False, spans=jntsNum, rt=0, kr=2, n=crv+'_rbd_crv') rbdNode = mc.rename(rbdNode, crv+'_rbd') # offset curve to control size of eye hole offsetCrv, offsetNode = mc.offsetCurve(rbdCrv, ch=True, distance=0, o=True, ugn=0, n=crv+'_offset_crv') offsetNode = mc.rename(offsetNode, crv+'_offset') locs = [] locName = '_'.join(surf1.split('_')[:2]) # attach locators to intersection curve for locId in range(jntsNum): loc = mc.spaceLocator(n=locName+'_loc_%d' % locId)[0] rt.attachToMotionPath(offsetCrv, locId, loc, fm=False) mc.setAttr(loc+'.localScale', 0.05, 0.05, 0.05) locs.append(loc) # normal constraint to surf1 for loc in locs: mc.normalConstraint(surf2, loc, aim=(1,0,0)) jnts = [] # add joints under locators for loc in locs: mc.select(cl=True) jnt = mc.joint(n=loc.replace('_loc_','_jnt_')) rt.parentSnap(jnt, loc) mc.setAttr(jnt+'.jointOrient', 0,0,0) jnts.append(jnt) # groups grp = mc.group(crvGrp, offsetCrv, rbdCrv, locs, n=surf1+'_intersect_loc_grp') # create offset attribute mc.addAttr(grp, ln='collideOffset', at='double', dv=0, k=True) offsetPlug = cn.create_multDoubleLinear(grp+'.collideOffset', -1) mc.connectAttr(offsetPlug, offsetNode+'.distance', f=True) # connect debug rt.connectVisibilityToggle(offsetCrv, grp, 'offsetCrv', False) rt.connectVisibilityToggle(rbdCrv, grp, 'rebuildCrv', False) rt.connectVisibilityToggle(crvGrp, grp, 'intersectCrv', False) rt.connectVisibilityToggle(locs, grp, 'crvLocs', False) rt.connectVisibilityToggle(jnts, grp, 'crvJnts', False)
def globalRig(): """ Make global teeth rig """ # teeth aim locs globalGrp = 'CT_teethBlockGlobal_mod_0' locNum = 7 name = 'CT_teethBlock' targetCrv = 'CT_teethBlockAim_crv_0' locs = [] for locId in range(locNum): loc = mc.spaceLocator(n=name + '_aim_loc_%d' % locId)[0] mc.setAttr(loc + '.localScale', 0.1, 0.1, 0.1) rt.attachToMotionPath(targetCrv, float(locId) / (locNum - 1), loc, True) locs.append(loc) mc.group(locs, n='CT_teethBlock_aim_loc_grp') rt.connectVisibilityToggle(locs, globalGrp, 'aimLocs', False) # teeth bind jnt for each aimLoc targetCrv = 'CT_teethBlockDrv_crv_0' jnts = [] for jntId in range(locNum): mc.select(cl=True) jnt = mc.joint(n=name + '_bnd_jnt_%d' % jntId) mc.setAttr(jnt + '.radius', 0.5) rt.alignOnMotionPath(targetCrv, float(jntId) / (locNum - 1), jnt, name + '_aim_loc_%d.matrix' % jntId, True, ua=1, inverseUp=True) jnts.append(jnt) mc.group(jnts, n='CT_teethBlock_bnd_jnts_grp') rt.connectVisibilityToggle(jnts, globalGrp, 'bndJnts', False) jnts = mc.ls(sl=True) import utils.wrappers.abRiggingTools as abRT # add bnd jnts for bite # for each bndjnt, make another jnt below it for bndJnt in jnts: mc.select(cl=True) biteJnt = mc.joint(n=bndJnt + '_bite') mc.setAttr(biteJnt + '.radius', 0.5) abRT.snapToPosition(bndJnt, biteJnt) mc.xform(biteJnt, t=(0, -1, 0), r=True) mc.parentConstraint(bndJnt, biteJnt, mo=True) mc.parent(biteJnt, 'CT_teethBlock_bnd_jnts_grp')
def globalRig(): """ Make global teeth rig """ # teeth aim locs globalGrp = 'CT_teethBlockGlobal_mod_0' locNum = 7 name = 'CT_teethBlock' targetCrv = 'CT_teethBlockAim_crv_0' locs=[] for locId in range(locNum): loc = mc.spaceLocator(n=name+'_aim_loc_%d'%locId)[0] mc.setAttr(loc+'.localScale', 0.1,0.1,0.1) rt.attachToMotionPath(targetCrv, float(locId)/(locNum-1), loc, True) locs.append(loc) mc.group(locs, n='CT_teethBlock_aim_loc_grp') rt.connectVisibilityToggle(locs, globalGrp, 'aimLocs', False) # teeth bind jnt for each aimLoc targetCrv = 'CT_teethBlockDrv_crv_0' jnts=[] for jntId in range(locNum): mc.select(cl=True) jnt = mc.joint(n=name+'_bnd_jnt_%d'%jntId) mc.setAttr(jnt+'.radius', 0.5) rt.alignOnMotionPath(targetCrv, float(jntId)/(locNum-1), jnt, name+'_aim_loc_%d.matrix'%jntId, True, ua=1, inverseUp=True) jnts.append(jnt) mc.group(jnts, n='CT_teethBlock_bnd_jnts_grp') rt.connectVisibilityToggle(jnts, globalGrp, 'bndJnts', False) jnts = mc.ls(sl=True) import utils.wrappers.abRiggingTools as abRT # add bnd jnts for bite # for each bndjnt, make another jnt below it for bndJnt in jnts: mc.select(cl=True) biteJnt = mc.joint(n=bndJnt+'_bite') mc.setAttr(biteJnt+'.radius', 0.5) abRT.snapToPosition(bndJnt, biteJnt) mc.xform(biteJnt, t=(0,-1,0), r=True) mc.parentConstraint(bndJnt, biteJnt, mo=True) mc.parent(biteJnt, 'CT_teethBlock_bnd_jnts_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 addJntsOnSurfIntersection(surf1, surf2, jntsNum): ''' Places jnts along intersection curve between surf1 and surf2 naming convention based on surf1 ''' # intersect surfaces crvGrp, intNode = mc.intersect(surf1, surf2, fs=True, ch=True, o=True, cos=False)[:2] intNode = mc.rename(intNode, surf1 + '_ints') crvGrp = mc.rename(crvGrp, surf1 + '_ints_crv_grp') crv = mc.listRelatives(crvGrp, c=True)[0] crv = mc.rename(crv, surf1 + '_ints_crv') # rebuild curve to jntNum spans rbdCrv, rbdNode = mc.rebuildCurve(crv, ch=True, o=True, rpo=False, spans=jntsNum, rt=0, kr=2, n=crv + '_rbd_crv') rbdNode = mc.rename(rbdNode, crv + '_rbd') # offset curve to control size of eye hole offsetCrv, offsetNode = mc.offsetCurve(rbdCrv, ch=True, distance=0, o=True, ugn=0, n=crv + '_offset_crv') offsetNode = mc.rename(offsetNode, crv + '_offset') locs = [] locName = '_'.join(surf1.split('_')[:2]) # attach locators to intersection curve for locId in range(jntsNum): loc = mc.spaceLocator(n=locName + '_loc_%d' % locId)[0] rt.attachToMotionPath(offsetCrv, locId, loc, fm=False) mc.setAttr(loc + '.localScale', 0.05, 0.05, 0.05) locs.append(loc) # normal constraint to surf1 for loc in locs: mc.normalConstraint(surf2, loc, aim=(1, 0, 0)) jnts = [] # add joints under locators for loc in locs: mc.select(cl=True) jnt = mc.joint(n=loc.replace('_loc_', '_jnt_')) rt.parentSnap(jnt, loc) mc.setAttr(jnt + '.jointOrient', 0, 0, 0) jnts.append(jnt) # groups grp = mc.group(crvGrp, offsetCrv, rbdCrv, locs, n=surf1 + '_intersect_loc_grp') # create offset attribute mc.addAttr(grp, ln='collideOffset', at='double', dv=0, k=True) offsetPlug = cn.create_multDoubleLinear(grp + '.collideOffset', -1) mc.connectAttr(offsetPlug, offsetNode + '.distance', f=True) # connect debug rt.connectVisibilityToggle(offsetCrv, grp, 'offsetCrv', False) rt.connectVisibilityToggle(rbdCrv, grp, 'rebuildCrv', False) rt.connectVisibilityToggle(crvGrp, grp, 'intersectCrv', False) rt.connectVisibilityToggle(locs, grp, 'crvLocs', False) rt.connectVisibilityToggle(jnts, grp, 'crvJnts', False)
def createSplineMPs(MPs, newMPsNum, name, twistOffset): ''' creates spline along mps adds new MPs along spline twistOffset - vector to offset twistCrv returns [(drvCrv, twistCrv, oldDrvCrv), MPJnts] ''' numOfMPs = len(MPs) # create twist curve for aiming locs twistCrv = mc.curve(p=[(pt,pt,pt) for pt in range(numOfMPs)]) twistCrv = mc.rename(twistCrv, name+'_twist_crv') # get point from MPs to drive curve CVs for mp in MPs: pmm = mc.createNode('pointMatrixMult', n=mp+'_pmm_0') mc.connectAttr(mp+'.worldMatrix', pmm+'.inMatrix', f=True) mc.setAttr(pmm+'.inPoint', *twistOffset) mc.connectAttr(pmm+'.output', twistCrv+'.cp[%d]' % MPs.index(mp)) # create driver curve for locs drvCrv = mc.curve(p=[(pt,pt,pt) for pt in range(numOfMPs)]) drvCrv = mc.rename(drvCrv, name+'_drv_crv') # get point from MPs to drive curve CVs for mp in MPs: pmm = mc.createNode('pointMatrixMult', n=mp+'_pmm_0') mc.connectAttr(mp+'.worldMatrix', pmm+'.inMatrix', f=True) mc.connectAttr(pmm+'.output', drvCrv+'.cp[%d]' % MPs.index(mp)) # make driver curve uniform oldDrvCrv = drvCrv drvCrv = rt.makeUniformCrv(drvCrv, newMPsNum, name+'_uniform_crv') # add aimLocs to twistCurve aimLocs = [] for locId in range(newMPsNum): loc = mc.spaceLocator(n=name+'_aimLoc_%d' % locId)[0] rt.attachToMotionPath(twistCrv, float(locId)/(newMPsNum-1), loc, 1) mc.setAttr(loc+'.localScale', 0.1,0.1,0.1) aimLocs.append(loc) aimLocsGrp = mc.group(aimLocs, n='CT_%s_aimLocs_grp'%name) MPJnts = [] for jntId in range(newMPsNum): jnt = mc.joint(n=name+'_MPJnt_%d' % jntId) rt.alignOnMotionPath(drvCrv, float(jntId)/(newMPsNum-1), jnt, aimLocs[jntId]+'.worldMatrix', 1) MPJnts.append(jnt) MPJntsGrp = mc.group(MPJnts, n='CT_%s_MPJnts_grp'%name) # connect viz for debug rt.connectVisibilityToggle(oldDrvCrv, MPs[0], 'drvCrv', default=False) rt.connectVisibilityToggle((aimLocsGrp, twistCrv), MPs[0], 'twistLocs', default=False) rt.connectVisibilityToggle((MPJntsGrp, drvCrv), MPs[0], 'drvMPs', default=False) mc.group(oldDrvCrv, twistCrv, drvCrv, aimLocsGrp, MPJntsGrp, n=name+'_splineMPs_grp') return (drvCrv, twistCrv, oldDrvCrv), MPJnts