def addVertCrvs(): ''' ''' for side in 'LT_', 'RT_': for jntId in range(0, 13, 3): objs = [side+'jacketHori%s_crv_crv_jnt_%d' % (locId, jntId) for locId in reversed(range(1,11))] rt.makeCrvThroughObjs(objs, name=side+'jacketVert_crv_'+str(jntId/3), connect=True, degree=2)
def addVertCrvs(): ''' ''' for side in 'LT_', 'RT_': for jntId in range(0, 13, 3): objs = [ side + 'jacketHori%s_crv_crv_jnt_%d' % (locId, jntId) for locId in reversed(range(1, 11)) ] rt.makeCrvThroughObjs(objs, name=side + 'jacketVert_crv_' + str(jntId / 3), connect=True, degree=2)
def addHoriCrvs(): ''' ''' leftDir = ['_back', '_leftBack', '_left', '_leftFront', '_front'] rightDir = ['_back', '_rightBack', '_right', '_rightFront', '_front'] ''' for jntId in range(5): objs = ['jacketVert%s_crv_crv_jnt_%d' % (grpName, jntId) for grpName in leftDir] rt.makeCrvThroughObjs(objs, name='LT_jacketHori'+str(jntId)+'_crv', connect=True, degree=2) objs = ['jacketVert%s_crv_crv_jnt_%d' % (grpName, jntId) for grpName in rightDir] rt.makeCrvThroughObjs(objs, name='RT_jacketHori'+str(jntId)+'_crv', connect=True, degree=2) ''' ''' # start locs objs = ['jacketStart%s_loc_offset' % grpName for grpName in leftDir] rt.makeCrvThroughObjs(objs, name='LT_jacketStartHori_crv', connect=True, degree=2) objs = ['jacketStart%s_loc_offset' % grpName for grpName in rightDir] rt.makeCrvThroughObjs(objs, name='RT_jacketStartHori_crv', connect=True, degree=2) ''' # other locs for locId in range(1, 11): objs = [ 'torsoReader_%d%s_loc_pushOutLoc' % (locId, grpName) for grpName in leftDir ] rt.makeCrvThroughObjs(objs, name='LT_jacketHori' + str(locId) + '_crv', connect=True, degree=2) objs = [ 'torsoReader_%d%s_loc_pushOutLoc' % (locId, grpName) for grpName in rightDir ] rt.makeCrvThroughObjs(objs, name='RT_jacketHori' + str(locId) + '_crv', connect=True, degree=2)
def addHoriCrvs(): ''' ''' leftDir = ['_back', '_leftBack', '_left', '_leftFront', '_front'] rightDir = ['_back', '_rightBack', '_right', '_rightFront', '_front'] ''' for jntId in range(5): objs = ['jacketVert%s_crv_crv_jnt_%d' % (grpName, jntId) for grpName in leftDir] rt.makeCrvThroughObjs(objs, name='LT_jacketHori'+str(jntId)+'_crv', connect=True, degree=2) objs = ['jacketVert%s_crv_crv_jnt_%d' % (grpName, jntId) for grpName in rightDir] rt.makeCrvThroughObjs(objs, name='RT_jacketHori'+str(jntId)+'_crv', connect=True, degree=2) ''' ''' # start locs objs = ['jacketStart%s_loc_offset' % grpName for grpName in leftDir] rt.makeCrvThroughObjs(objs, name='LT_jacketStartHori_crv', connect=True, degree=2) objs = ['jacketStart%s_loc_offset' % grpName for grpName in rightDir] rt.makeCrvThroughObjs(objs, name='RT_jacketStartHori_crv', connect=True, degree=2) ''' # other locs for locId in range(1,11): objs = ['torsoReader_%d%s_loc_pushOutLoc' % (locId, grpName) for grpName in leftDir] rt.makeCrvThroughObjs(objs, name='LT_jacketHori'+str(locId)+'_crv', connect=True, degree=2) objs = ['torsoReader_%d%s_loc_pushOutLoc' % (locId, grpName) for grpName in rightDir] rt.makeCrvThroughObjs(objs, name='RT_jacketHori'+str(locId)+'_crv', connect=True, degree=2)
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 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)
def addIndividualOffsetRig(toothId, selVerts): """ returns top group node """ name = 'CT_toothOffset%d_' % toothId #=========================================================================== # ADD OFFSET CONTROLS #=========================================================================== # add offset controlA ctlA = rt.ctlCurve(name + 'ctlA', 'circle', 0, snap='CT_teethOffset_align_loc_%d' % toothId, size=1, ctlOffsets=['bend']) mc.aimConstraint('CT_teethOffset_aim_loc_%d' % toothId, ctlA.home, aim=(1, 0, 0), u=(0, 0, 1), wut='objectRotation', wuo='CT_teethOffset_align_loc_%d' % toothId, wu=(0, 0, 1)) mc.pointConstraint('CT_teethOffset_align_loc_%d' % toothId, ctlA.home) # add second offset control as child to first ctlB = rt.ctlCurve(name + 'ctlB', 'circle', 0, snap=ctlA.crv, size=1, ctlOffsets=['bend']) mc.parent(ctlB.home, ctlA.crv) mc.setAttr(ctlB.home + '.tx', 0.5) # local rig's bend should update CtlB mc.connectAttr('CT_teethLocal%d_bndB.ry' % (toothId + 1), ctlB.grp['bend'] + '.ry', f=True) #=============================================================================== # Connections from offsetCtls to localRig #=============================================================================== # since scale should always be local mc.connectAttr(ctlA.crv + '.sy', 'CT_teethLocal%d_bndA.sy' % (toothId + 1), f=True) mc.connectAttr(ctlA.crv + '.sz', 'CT_teethLocal%d_bndA.sz' % (toothId + 1), f=True) mc.connectAttr(ctlB.crv + '.sy', 'CT_teethLocal%d_bndB.sy' % (toothId + 1), f=True) mc.connectAttr(ctlB.crv + '.sz', 'CT_teethLocal%d_bndB.sz' % (toothId + 1), f=True) # twisting could also be local mc.connectAttr(ctlA.crv + '.rx', 'CT_teethLocal%d_bndA.rx' % (toothId + 1), f=True) mc.connectAttr(ctlB.crv + '.rx', 'CT_teethLocal%d_bndB.rx' % (toothId + 1), f=True) # slide tooth along path mc.addAttr(ctlA.crv, ln='slide', at='double', k=True) mc.connectAttr(ctlA.crv + '.slide', 'CT_teethLocal%d_bndA.ty' % (toothId + 1), f=True) #=============================================================================== # Complete CV point placement for curves #=============================================================================== # endLoc under ctlB endLoc = mc.spaceLocator(n=name + 'ctlB_endLoc')[0] rt.parentSnap(endLoc, ctlB.crv) mc.setAttr(endLoc + '.tx', 0.5) mc.setAttr(endLoc + '.localScale', 0.1, 0.1, 0.1) #=============================================================================== # second hierarchy for base curve #=============================================================================== ctlABase = mc.group(em=True, n=name + 'ctlABase_grp') mc.aimConstraint('CT_teethOffset_aim_loc_%d' % toothId, ctlABase, aim=(1, 0, 0), u=(0, 0, 1), wut='objectRotation', wuo='CT_teethOffset_align_loc_%d' % toothId, wu=(0, 0, 1)) mc.pointConstraint('CT_teethOffset_align_loc_%d' % toothId, ctlABase) ctlBBase = mc.group(em=True, n=name + 'ctlBBase_grp') rt.parentSnap(ctlBBase, ctlABase) mc.setAttr(ctlBBase + '.tx', 0.5) mc.connectAttr('CT_teethLocal%d_bndB.ry' % (toothId + 1), ctlBBase + '.ry', f=True) endBaseLoc = mc.spaceLocator(n=name + 'ctlB_endBaseLoc')[0] rt.parentSnap(endBaseLoc, ctlBBase) mc.setAttr(endBaseLoc + '.tx', 0.5) mc.setAttr(endBaseLoc + '.localScale', 0.1, 0.1, 0.1) # connect scale for base transforms mc.connectAttr(ctlA.crv + '.sy', ctlABase + '.sy', f=True) mc.connectAttr(ctlA.crv + '.sz', ctlABase + '.sz', f=True) mc.connectAttr(ctlB.crv + '.sy', ctlBBase + '.sy', f=True) mc.connectAttr(ctlB.crv + '.sz', ctlBBase + '.sz', f=True) #=============================================================================== # Make wire deformer #=============================================================================== # base curve baseCrv = rt.makeCrvThroughObjs([ctlABase, ctlBBase, endBaseLoc], name + 'baseCrv', True, 2) # wire curve wireCrv = rt.makeCrvThroughObjs([ctlA.crv, ctlB.crv, endLoc], name + 'wireCrv', True, 2) # make wire wireDfm, wireCrv = mc.wire(selVerts, wire=wireCrv, n=name + 'wire_dfm', dds=(0, 50)) wireBaseUnwanted = wireCrv + 'BaseWire' # replace base mc.connectAttr(baseCrv + '.worldSpace[0]', wireDfm + '.baseWire[0]', f=True) mc.delete(wireBaseUnwanted) #=========================================================================== # GROUPS & DEBUG UTILS #=========================================================================== dfmGrp = mc.group(baseCrv, wireCrv, n=name + 'dfg_0') ctlGrp = mc.group(ctlA.home, ctlABase, n=name + 'ctg_0') retGrp = mc.group(dfmGrp, ctlGrp, n=name + 'mod_0') rt.connectVisibilityToggle([endLoc, endBaseLoc], retGrp, 'endLocs', False) rt.connectVisibilityToggle(dfmGrp, retGrp, 'wires', False) return retGrp
def addIndividualOffsetRig(toothId, selVerts): """ returns top group node """ name = 'CT_toothOffset%d_'%toothId #=========================================================================== # ADD OFFSET CONTROLS #=========================================================================== # add offset controlA ctlA = rt.ctlCurve(name+'ctlA', 'circle', 0, snap='CT_teethOffset_align_loc_%d'%toothId, size=1, ctlOffsets=['bend']) mc.aimConstraint('CT_teethOffset_aim_loc_%d'%toothId, ctlA.home, aim=(1,0,0), u=(0,0,1), wut='objectRotation', wuo='CT_teethOffset_align_loc_%d'%toothId, wu=(0,0,1)) mc.pointConstraint('CT_teethOffset_align_loc_%d'%toothId, ctlA.home) # add second offset control as child to first ctlB = rt.ctlCurve(name+'ctlB', 'circle', 0, snap=ctlA.crv, size=1, ctlOffsets=['bend']) mc.parent(ctlB.home, ctlA.crv) mc.setAttr(ctlB.home+'.tx', 0.5) # local rig's bend should update CtlB mc.connectAttr('CT_teethLocal%d_bndB.ry'%(toothId+1), ctlB.grp['bend']+'.ry', f=True) #=============================================================================== # Connections from offsetCtls to localRig #=============================================================================== # since scale should always be local mc.connectAttr(ctlA.crv+'.sy', 'CT_teethLocal%d_bndA.sy'%(toothId+1), f=True) mc.connectAttr(ctlA.crv+'.sz', 'CT_teethLocal%d_bndA.sz'%(toothId+1), f=True) mc.connectAttr(ctlB.crv+'.sy', 'CT_teethLocal%d_bndB.sy'%(toothId+1), f=True) mc.connectAttr(ctlB.crv+'.sz', 'CT_teethLocal%d_bndB.sz'%(toothId+1), f=True) # twisting could also be local mc.connectAttr(ctlA.crv+'.rx', 'CT_teethLocal%d_bndA.rx'%(toothId+1), f=True) mc.connectAttr(ctlB.crv+'.rx', 'CT_teethLocal%d_bndB.rx'%(toothId+1), f=True) # slide tooth along path mc.addAttr(ctlA.crv, ln='slide', at='double', k=True) mc.connectAttr(ctlA.crv+'.slide', 'CT_teethLocal%d_bndA.ty'%(toothId+1), f=True) #=============================================================================== # Complete CV point placement for curves #=============================================================================== # endLoc under ctlB endLoc = mc.spaceLocator(n=name+'ctlB_endLoc')[0] rt.parentSnap(endLoc, ctlB.crv) mc.setAttr(endLoc+'.tx', 0.5) mc.setAttr(endLoc+'.localScale', 0.1,0.1,0.1) #=============================================================================== # second hierarchy for base curve #=============================================================================== ctlABase = mc.group(em=True, n=name+'ctlABase_grp') mc.aimConstraint('CT_teethOffset_aim_loc_%d'%toothId, ctlABase, aim=(1,0,0), u=(0,0,1), wut='objectRotation', wuo='CT_teethOffset_align_loc_%d'%toothId, wu=(0,0,1)) mc.pointConstraint('CT_teethOffset_align_loc_%d'%toothId, ctlABase) ctlBBase = mc.group(em=True, n=name+'ctlBBase_grp') rt.parentSnap(ctlBBase, ctlABase) mc.setAttr(ctlBBase+'.tx', 0.5) mc.connectAttr('CT_teethLocal%d_bndB.ry'%(toothId+1), ctlBBase+'.ry', f=True) endBaseLoc = mc.spaceLocator(n=name+'ctlB_endBaseLoc')[0] rt.parentSnap(endBaseLoc, ctlBBase) mc.setAttr(endBaseLoc+'.tx', 0.5) mc.setAttr(endBaseLoc+'.localScale', 0.1,0.1,0.1) # connect scale for base transforms mc.connectAttr(ctlA.crv+'.sy', ctlABase+'.sy', f=True) mc.connectAttr(ctlA.crv+'.sz', ctlABase+'.sz', f=True) mc.connectAttr(ctlB.crv+'.sy', ctlBBase+'.sy', f=True) mc.connectAttr(ctlB.crv+'.sz', ctlBBase+'.sz', f=True) #=============================================================================== # Make wire deformer #=============================================================================== # base curve baseCrv = rt.makeCrvThroughObjs([ctlABase, ctlBBase, endBaseLoc], name+'baseCrv', True, 2) # wire curve wireCrv = rt.makeCrvThroughObjs([ctlA.crv, ctlB.crv, endLoc], name+'wireCrv', True, 2) # make wire wireDfm, wireCrv = mc.wire(selVerts, wire=wireCrv, n=name+'wire_dfm', dds=(0,50)) wireBaseUnwanted = wireCrv+'BaseWire' # replace base mc.connectAttr(baseCrv+'.worldSpace[0]', wireDfm+'.baseWire[0]', f=True) mc.delete(wireBaseUnwanted) #=========================================================================== # GROUPS & DEBUG UTILS #=========================================================================== dfmGrp = mc.group(baseCrv, wireCrv, n=name+'dfg_0') ctlGrp = mc.group(ctlA.home, ctlABase, n=name+'ctg_0') retGrp= mc.group(dfmGrp, ctlGrp, n=name+'mod_0') rt.connectVisibilityToggle([endLoc, endBaseLoc], retGrp, 'endLocs', False) rt.connectVisibilityToggle(dfmGrp, retGrp, 'wires', False) return retGrp
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)