def curveAim(crv, aimCrv, numJnts, mo=True, aimVector=(0,1,0), upVector=(0,1,0), worldUpType="vector", worldUpVector=(0,1,0)): '''Takes two curves, creates joints on the first and aims objects at the second. Args: crv (pm.nt.nurbsCurve): nurbs curve to generate things on aimCrv (pm.nt.nurbsCurve): nurbs curve to aim things to numJnts (int): number of joints to be generated other : all of the aim vector constraint settings Returns list(grp, list(joints)) Usage: curveAim(pm.ls(sl=True)[0], pm.ls(sl=True)[1], 10) ''' grp = pm.group(em=True, n=aimCrv+'AIMDRV_GRP') joints = rig_makeJointsAlongCurve("seatbeltDrive", crv, numJnts) for joint in joints: joint.setParent(w=True) pociOrig = atc.rig_getClosestPointNode(joint, crv) print pociOrig.parameter.get() poci = pm.nodetypes.PointOnCurveInfo(n=joint+"_POCI") aimCrv.getShape().attr("worldSpace[0]").connect(poci.inputCurve) poci.parameter.set(pociOrig.parameter.get()) loc = pm.group(em=True, n=joint+'AIMDRV_GRP', p=grp) poci.position.connect(loc.t) pm.aimConstraint(loc, joint, mo=mo, aimVector=aimVector, upVector=upVector, worldUpType=worldUpType, worldUpVector=worldUpVector) return [grp, joints]
def __init__(self, *args, **kwargs): self._isJointControl = kwargs.pop("jointControl", False) | kwargs.pop("jc", False) self._style = kwargs.pop self._translateLocked = kwargs.pop("translate", True) | kwargs.pop("t", True) self._rotateLocked = kwargs.pop("rotate", True) | kwargs.pop("r", True) self._scaleLocked = kwargs.pop("scale", True) | kwargs.pop("s", True) self.name = kwargs.pop("name", "Control") self.name = kwargs.pop("n", self.name) self.parent = None if type(args[0]) == int: self.node = pm.group(em=True, n=self.name) self.setStyle(args[0]) # Wrap an existing node elif type(args[0]) == pm.nt.Transform: if type(args[0].getShape()) == pymel.core.nodetypes.NurbsCurve: self.node = args[0] else: if self._isJointControl: pm.select(cl=True) self.node = pm.joint(n=self.name) self.node.drawStyle.set(2) else: self.node = pm.group(em=True, n=self.name) else: pm.displayError("Invalid argument: {0}".format(args[0]))
def addJacketCollarRig(): # jacket collar rig collarjnts = pm.ls(sl=True) # add hm, grp and auto nulls for jnt in collarjnts: ctl = pm.circle(r=0.5, sweep=359, normal=(1,0,0), n=jnt.replace('_jnt', '_ctl')) auto = pm.group(ctl, n=jnt.replace('_jnt', '_auto')) grp = pm.group(auto, n=jnt.replace('_jnt', '_grp')) hm = pm.group(grp, n=jnt.replace('_jnt', '_hm')) wMat = jnt.getMatrix(worldSpace=True) hm.setMatrix(wMat, worldSpace=True) collarparent = jnt.getParent() collarparent | hm auto | jnt # auto import rigger.modules.poseReader as poseReader reload(poseReader) xfo = nt.Joint(u'Mathilda_neck_jnt') poseReader.radial_pose_reader(xfo, (1,0,0), (1,0,0)) # connect auto to sdks import utils.rigging as rt import rigger.utils.modulate as modulate angleMult = pm.PyNode('Mathilda_neck_jnt.vectorAngle') # Left collar A rt.connectSDK('Mathilda_neck_jnt.param', 'LT_collarA_auto.rz', {3.25:0, 4.6:50, 5.5:0}) mod = modulate.multiplyInput(pm.PyNode('LT_collarA_auto.rz'), 0, '_angle') angleMult >> mod # Letf collar B rt.connectSDK('Mathilda_neck_jnt.param', 'LT_collarB_auto.rz', {4:0, 5:180, 6:180, 7:0}) mod = modulate.multiplyInput(pm.PyNode('LT_collarB_auto.rz'), 0, '_angle') angleMult >> mod # Letf collar C rt.connectSDK('Mathilda_neck_jnt.param', 'LT_collarC_auto.rz', {0:200, 1.4:0, 4:0, 5.5:200, 6.6:280, 8:0}) mod = modulate.multiplyInput(pm.PyNode('LT_collarC_auto.rz'), 0, '_angle') angleMult >> mod # center collar rt.connectSDK('Mathilda_neck_jnt.param', 'CT_collar_auto.rz', {0:320, 2.5:0, 5.5:0, 8:320}) mod = modulate.multiplyInput(pm.PyNode('CT_collar_auto.rz'), 0, '_angle') angleMult >> mod # right collar A rt.connectSDK('Mathilda_neck_jnt.param', 'RT_collarA_auto.rz', {4.75:0, 3.4:50, 2.5:0}) mod = modulate.multiplyInput(pm.PyNode('RT_collarA_auto.rz'), 0, '_angle') angleMult >> mod # right collar B rt.connectSDK('Mathilda_neck_jnt.param', 'RT_collarB_auto.rz', {4:0, 3:180, 2:180, 1:0}) mod = modulate.multiplyInput(pm.PyNode('RT_collarB_auto.rz'), 0, '_angle') angleMult >> mod # right collar C rt.connectSDK('Mathilda_neck_jnt.param', 'RT_collarC_auto.rz', {0:200, 6.6:0, 4:0, 2.5:200, 1.4:280, 8:0}) mod = modulate.multiplyInput(pm.PyNode('RT_collarC_auto.rz'), 0, '_angle') angleMult >> mod pm.select(pm.PyNode(u'Mathilda_neck_jnt.param').outputs())
def createCtrl(fol, clusterHandle, name): masterGrp = pm.group(em=1, name="{0}_MASTER".format(name)) locCtrl = pm.group(em=1, name="{0}_LOC".format(name)) upCtrl = pm.group(em=1, name="{0}_UP".format(name)) ctrl = pm.group(em=1, name="{0}_Ctrl".format(name)) ctrl.setParent(upCtrl) upCtrl.setParent(locCtrl) locCtrl.setParent(fol) locCtrl.t.set(0, 0, 0) md = pm.createNode("multiplyDivide", name="{0}_MD".format(name)) clusterHandle.t >> md.input1 md.input2.set(-1, -1, -1) md.output >> upCtrl.t ctrl.t >> clusterHandle.t ctrl.r >> clusterHandle.r ctrl.displayHandle.set(1) fol.setParent(masterGrp) clusterHandle.setParent(masterGrp) currentTime = pm.currentTime(q=1) ctrl.t.setKey(t=currentTime) ctrl.t.setKey(t=currentTime + 5) ctrl.t.setKey(t=currentTime - 5) ctrl.r.setKey(t=currentTime) ctrl.r.setKey(t=currentTime + 5) ctrl.r.setKey(t=currentTime - 5) return ctrl
def createSortingGroups(self): pm.select(cl = True) #create nodesGrp self.nodesGrp = pm.group(n = self.prefix + '_nodes_grp') pm.select(cl = True) #create manipsGrp self.manipsGrp = pm.group(n = self.prefix + '_manips_grp') pm.select(cl = True) #create jointsGrp self.jointsGrp = pm.group(n = self.prefix + '_joints_grp') pm.select(cl = True) #Parent #nodesGrp pm.parent( self.foot_spline_ik_base_grp ,self.foot_spline_ik_tip_grp, self.foot_splineIk_curve_grp, self.leg_ik_handle_grp, self.nodesGrp) pm.select(cl = True) #manipsGrp pm.parent( self.pole_vector_linking_curve_grp, self.manip_foot_ik_tip_grp , self.manip_foot_ik_base_grp, self.leg_ik_pole_vector_locator_grp , self.manip_aim_indicator_grp , self.manip_leg_complete_grp, self.manip_leg_ik_grp, self.manip_leg_base_grp, self.manipsGrp) pm.select(cl = True) #jointsGrp pm.parent( self.foot_ik_tip_j_grp , self.foot_ik_base_j_grp, self.foot_ik_bound_j_grp , self.curve_bound_j_tip_grp, self.curve_bound_j_base_grp, self.leg_ik_j_grp, self.jointsGrp) pm.select(cl = True)
def create(xfo, parent, suffix=""): """ xfo - transform to drive with local offset the local reader will have the same world matrix as this parent - transform to parent under parent should have the same space as xfo parent moves in global space, but keeps the same local space for xfo to remain constant """ reader = pm.group(em=True, n=xfo + "_localReader" + suffix) readerHm = pm.group(reader, n=xfo + "_localReaderHm" + suffix) mat = xfo.getMatrix(worldSpace=True) readerHm.setMatrix(mat, worldSpace=True) rp = xfo.getRotatePivot(space="world") readerHm.setRotatePivot(rp, space="world") reader.setRotatePivot(rp, space="world") sp = xfo.getScalePivot(space="world") readerHm.setScalePivot(sp, space="world") reader.setScalePivot(sp, space="world") parent | readerHm reader.t >> xfo.t reader.r >> xfo.r reader.s >> xfo.s return reader
def create(self): grp = self.createGroup( self.groupName ) snap( self.hipsTranslationJnt, grp, type='parent') hipsTranslation = pm.group(n='hipsTranslation_hdl',em=True) snap( self.hipsTranslationJnt, hipsTranslation, type='parent') pm.parent( pm.parentConstraint( hipsTranslation, self.hipsTranslationJnt ), hipsTranslation) hipsTranslation.displayHandle.set(True) hips = pm.group(n='hips_hdl',em=True) snap( self.hipsJnt, hips, type='parent') pm.parent( pm.parentConstraint( hips, self.hipsJnt ), hips) hips.displayHandle.set(True) shoulder = pm.group(n='shoulder_hdl',em=True) snap( self.shoulderJnt, shoulder, type='parent') pm.parent( pm.parentConstraint( shoulder, self.shoulderJnt ), shoulder) setAttrs( shoulder, 'rx','ry','rz','sx','sy','sz','v', lock=True, keyable=False, channelBox=False ) shoulder.displayHandle.set(True) spines =[] for jnt in self.spineJnts: handle = pm.group(n=jnt+'_hdl',em=True) snap( jnt, handle, type='parent') pm.parent( pm.parentConstraint( handle, jnt ), handle) setAttrs( handle, 'rx','ry','rz','sx','sy','sz','v', lock=True, keyable=False, channelBox=False ) handle.displayHandle.set(True) spines.append(handle) pm.parent( hips, hipsTranslation) pm.parent( hipsTranslation, shoulder, spines, grp ) setColor( hipsTranslation, hips, shoulder, spines, c='red' )
def build(crv, name=''): ''' creates a Marco Giordano style eyelid rig ''' params = [curve.getClosestPointOnCurve(crv=crv, point = pmc.pointPosition(cv)) for cv in crv.cv[:]] mainGrp = pmc.group(empty=1, name='%s_grp' % name) baseGrp = pmc.group(empty=1, name='%s_base_grp' % name) baseGrp.setParent(mainGrp) mps = curve.nodesAlongCurve(crv=crv.name(), numNodes=len(params), name=name) for index in range(len(params)): mp = common.getPyNode(mps['mpNodes'][index]) mp.uValue.set(params[index]) mp.fractionMode.set(0) grp = common.getPyNode(mps['grps'][index]) aimGrp = pmc.group(empty=1, name='%s_%s_aim_grp' % (name, str(index))) aimGrp.setParent(baseGrp) con = pmc.aimConstraint(grp, aimGrp, mo=0, wut=2, wuo=baseGrp.name()) pmc.select(aimGrp, r=1) j = pmc.joint(name='%s_%s_jnt' % (name, str(index))) j.tx.set(10)
def createGroupsAndSortContent(self): pm.select(cl = True) #create nodesGrp self.nodesGrp = pm.group(n = self.prefix + '_nodes_grp') pm.select(cl = True) #create manipsGrp self.manipsGrp = pm.group(n = self.prefix + '_manips_grp') pm.select(cl = True) #create jointsGrp self.jointsGrp = pm.group(n = self.prefix + '_joints_grp') pm.select(cl = True) #Parent #nodesGrp pm.parent(self.dynamicChain_spline_ik_grp, self.bound_curve_spline_ik_grp, self.hairsystemNodesGrp, self.lowResCurveTrans, self.nodesGrp) pm.select(cl = True) #manipsGrp pm.parent(self.manip_dynamic_grp, self.manipIkSplineTopGrp, self.manip_master_grp, self.manipsGrp) pm.select(cl = True) #jointsGrp pm.parent(self.splineIkBoundJointsTopGrp, self.boundJointsGrp, self.ikSplineJointsGrp, self.ikDynamicJointsGrp, self.jointsGrp) pm.select(cl = True)
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 createPad(cls, *args): if args: inputObject = args[0] else: inputObject = pm.selected() if type(inputObject) != list: inputObject = [inputObject] pads = [] for obj in inputObject: pm.select(cl = True) paddingGroup = pm.group(em = True) upperPaddingGroup = pm.group(em = True) pm.parent(paddingGroup, upperPaddingGroup) movePivot = pm.parentConstraint(obj, upperPaddingGroup, mo = False) pm.delete(movePivot) pm.parent(obj, paddingGroup) pm.makeIdentity(apply = True, t = True, r = True, s = True, n = 0) pm.rename(paddingGroup, obj + '_sdkPad') pm.rename(upperPaddingGroup, obj + '_offsetPad') pads.append(upperPaddingGroup) return pads
def createGroupsAndSortContent(self): pm.select(cl = True) #create nodesGrp self.nodesGrp = pm.group(n = self.prefix + '_nodes_grp') pm.select(cl = True) #create manipsGrp self.manipsGrp = pm.group(n = self.prefix + '_manips_grp') pm.select(cl = True) #create jointsGrp self.jointsGrp = pm.group(n = self.prefix + '_joints_grp') pm.select(cl = True) #Parent #nodesGrp pm.parent(self.ikHandleAnimatedGrp, self.dynamicChain_spline_ik_grp, self.hairsystemNodesGrp, self.nodesGrp) pm.select(cl = True) #manipsGrp pm.parent(self.completeSwingManipGrp, self.fkAnimatedManipsGrp, self.manipIkAnimatedPoleVectorGrp, self.manipIkAnimatedGrp, self.manip_CtrlCenter_grp, self.manip_master_grp, self.manipsGrp) pm.select(cl = True) #jointsGrp pm.parent(self.ikDynamicJointsGrp, self.ikAnimatedJointsGrp, self.fkAnimatedJointsGrp, self.completeSwingJointsGrp, self.boundJointsGrp, self.jointsGrp) pm.select(cl = True)
def create_chain_for_curve(self, crv, obj=None, link_length=1): """ Uses the Curve and creates a chain based on the object that is passed into the function crv = curve to be used obj = object to be used linklength = lenght of the obj """ if obj is None: obj = self.create_link() link_length = (2*(self.radius - self.section_radius*2)+self.extrude) chain_length = int(pm.PyNode(crv).length()/link_length) chain = self.make_chain(obj=obj, link_length=link_length, chain_length=chain_length) joints = self.rig_chain(chain) ik = pm.ikHandle(startJoint=joints[0], endEffector=joints[-1], solver='ikSplineSolver', createCurve=False, curve=crv)[0] pm.rename(ik, self.name + "_ikHandle") control_group = pm.group(joints[0], ik, n="%sctrl_grp" % self.name) control_group.v.set(False) pm.group(crv, self.name, control_group, n="%s_grp" % self.name) self.add_cluster_handles(crv) pm.select(deselect=True) return self.name
def mirrorXfoFromTo(xfo_from, xfo_to): # create temp nodes grp1 = pm.group(em=True) grp2 = pm.group(grp1) grp3 = pm.group(em=True) xfo_from | grp2 pm.makeIdentity() grp3 | grp2 grp3.sx.set(-1) grp1.sx.set(-1) ''' # get original parent of xfo_rt so we can set it back later parent_rt = xfo_to.getParent() # snap xfo_rt to grp1's xfo grp1 | xfo_to pm.makeIdentity(xfo_to) if parent_rt: parent_rt | xfo_to else: xfo_to.setParent(None) ''' worldXfo = grp1.getMatrix(worldSpace=True) xfo_to.setMatrix(worldXfo, worldSpace=True) # delete temp nodes pm.delete(grp1, grp2, grp3) pm.select(xfo_to)
def create(self): grp = self.createGroup( self.groupName ) snap( self.headJnt, grp, type='parent') neck = pm.group(n='neck_hdl',em=True) head = pm.group(n='head_hdl',em=True) headEnd = pm.group(n='headEnd_hdl',em=True) snap( self.headJnt, head, type='parent') snap( self.headEndJnt, headEnd, type='parent') snap( self.neckJnt, neck, type='parent') pm.parent( headEnd, head ) pm.parent( head, neck, grp ) pm.parent( pm.parentConstraint( head, self.headJnt ), head) pm.parent( pm.parentConstraint( headEnd, self.headEndJnt ), headEnd) pm.parent( pm.parentConstraint( neck, self.neckJnt ), neck) setAttrs( head, 'sx','sy','sz','v', lock=True, keyable=False, channelBox=False ) setAttrs( headEnd, 'rx','ry','rz','sx','sy','sz','v', lock=True, keyable=False, channelBox=False ) setAttrs( neck, 'rx','ry','rz','sx','sy','sz','v', lock=True, keyable=False, channelBox=False ) head. displayHandle.set(True) headEnd.displayHandle.set(True) neck. displayHandle.set(True) setColor( neck, head, headEnd, c='red' ) self.neck = neck self.head = head self.headEnd = headEnd
def addSurfaceConstraintToBnd(bnd, surface): ''' ''' secDrv = bnd.getParent() matrix = secDrv.getMatrix(worldSpace=True) # create additional nulls gc = pm.group(em=True, n=bnd.nodeName().replace('_bnd', '_gc')) gc_offset = pm.group(em=True, n=bnd.nodeName().replace('_bnd', '_gc_offset')) acs = pm.group(em=True, n=bnd.nodeName().replace('_bnd', '_acs')) # point constraint first to get precise position to secDrv pm.pointConstraint(secDrv, gc) # geometry constraint to surface pm.geometryConstraint(surface, gc) # normal constraint, using secDrv-Y as up pm.normalConstraint(surface, gc, aim=(0,0,1), u=(0,1,0), wuo=secDrv, wut='objectrotation', wu=(0,1,0)) # ensure that gc_offset stores offset to secDrv gc_offset.setMatrix(matrix, worldSpace=True) acs.setMatrix(matrix, worldSpace=True) # hierarchy secDrv | gc | gc_offset | acs | bnd
def create(self): grp = self.createGroup( self.groupName ) toeBase = pm.group(n='toeBase_hdl',em=True) toeEnd = pm.group(n='toeEnd_hdl',em=True) snap( self.footJnt, grp, type='parent') snap( self.toeBaseJnt, toeBase, type='parent') snap( self.toeEndJnt, toeEnd, type='parent') pm.parent( toeBase, toeEnd, grp ) pm.parent( pm.parentConstraint( toeBase, self.toeBaseJnt ), toeBase) pm.parent( pm.parentConstraint( toeEnd, self.toeEndJnt ), toeEnd) toeBase.displayHandle.set(True) toeEnd.displayHandle.set(True) setColor( toeBase, toeEnd, c='red' ) self.toeBase = toeBase self.toeEnd = toeEnd # 부모처럼 움직일 노드에 컨스트레인 if pm.objExists('LeftFoot'): pm.parentConstraint( 'LeftFoot', grp, mo=True )
def createCurveBoundJoints(self): pm.select(cl = True) #curve_bound_j_base pm.select(cl = True) self.curve_bound_j_base = pm.joint(a = True, p= (0,0,0), co = True, n = self.prefix +'_curve_bound_j_base') pm.select(cl = True) #group self.curve_bound_j_base_grp = pm.group(self.curve_bound_j_base, n = self.prefix + '_curve_bound_j_base_grp') pm.select(cl = True) #translate self.curve_bound_j_base_grp.translate.set(self.leg_locator_tip_worldCoords) pm.select(cl = True) #curve_bound_j_tip pm.select(cl = True) self.curve_bound_j_tip = pm.joint(a = True, p= (0,0,0), co = True, n = self.prefix +'_curve_bound_j_tip') pm.select(cl = True) #group self.curve_bound_j_tip_grp = pm.group(self.curve_bound_j_tip, n = self.prefix + '_curve_bound_j_tip_grp') pm.select(cl = True) #translate self.curve_bound_j_tip_grp.translate.set(self.foot_locator_worldCoords) pm.select(cl = True)
def create(self): self.handle = pm.group(em=True) self.result = pm.group(em=True) self.aim = pm.group(em=True) self.up = pm.group(em=True) pm.parent(self.result, self.aim, self.up, self.handle ) # 초기위치 조정 mult = 20 self.aim.t.set(self.aimVec * mult) self.up.t.set(self.upVec * mult) self.aimConstraint = pm.aimConstraint(self.aim, self.result, aim=self.aimVec, u=self.upVec, wut='object', wuo=self.up) # 시각화 self.handle.displayHandle.set(True) #self.result.displayLocalAxis.set(True) # 어트리뷰트 잠금 setAttrs( self.result, 'tx','ty','tz','sx','sy','sz','v' ) setAttrs( self.aim, 'rx','ry','rz','sx','sy','sz','v' ) setAttrs( self.up, 'rx','ry','rz','sx','sy','sz','v' ) # 이름변경 self.setPrefix( self.prefix )
def __cleanUp(self): for i in (self.thumbChain.chain, self.indexChain.chain, self.middleChain.chain, self.ringChain.chain,self.pinkieChain.chain): iJoint = i[0].name() pm.parent(iJoint,self.handChain.chain[-1].name() ) self.bonesGrp = pm.group (empty = 1, n= nameUtils.getUniqueName(self.side, self.baseName + "Bones", "GRP")) self.bonesGrp.setMatrix(self.handChain.chain[0].wm.get()) self.handChain.chain[0].setParent(self.bonesGrp) self.ctlsGrp = pm.group (self.handChain.controlsArray[0].controlGrp, self.thumbChain.controlsArray[0].controlGrp, self.indexChain.controlsArray[0].controlGrp, self.middleChain.controlsArray[0].controlGrp, self.ringChain.controlsArray[0].controlGrp, self.pinkieChain.controlsArray[0].controlGrp, n= nameUtils.getUniqueName(self.side, self.baseName + "Controls", "GRP")) self.mainGrpLimb = pm.group (empty= 1, n= nameUtils.getUniqueName (self.side, self.baseName + "Main", "GRP")) for o in (self.bonesGrp, self.ctlsGrp): o.setParent(self.mainGrpLimb) for i in (self.thumbChain.controlsArray[0].controlGrp,self.indexChain.controlsArray[0].controlGrp,self.middleChain.controlsArray[0].controlGrp,self.ringChain.controlsArray[0].controlGrp,self.pinkieChain.controlsArray[0].controlGrp): pm.parent(i, self.handChain.controlsArray[0].controlName)
def clean_outliner(self, *args): """ Args: None Returns (None) """ base_name = '%s_flexiPlane' % self.flexiPlaneNameField.getText() surface = '%s_SURF' % base_name surfaceSkinJNT = '%s_surfSkin_JNT' % base_name fol_grp = '%s_FOL_GRP' % base_name ctrl_grp = '%s_CTRL_GRP' % base_name jnt_grp = '%s_JNT_GRP' % base_name bShp_grp = '%s_bShp_GRP' % base_name flexi_GRP = pm.group( em = True, name = base_name + '_GRP' ) parts_GRP = pm.group( em = True, name = base_name + '_parts_GRP' ) pm.parent( surface, parts_GRP ) pm.parent( surfaceSkinJNT, parts_GRP ) pm.parent( fol_grp, parts_GRP ) pm.parent( ctrl_grp, flexi_GRP ) pm.parent( jnt_grp, flexi_GRP ) pm.parent( bShp_grp, parts_GRP ) pm.parent( parts_GRP, flexi_GRP ) pm.setAttr( surface + '.visibility', 0) pm.select( cl = True )
def test_nonUniqueName(self): cmds.file(f=1, new=1) j1 = cmds.createNode('joint', name='j1') j2 = cmds.createNode('joint', name='j2', parent=j1) j3 = cmds.createNode('joint', name='j3', parent=j2) j4 = cmds.createNode('joint', name='j4', parent=j3) cmds.select(j1, j4) ikh1 = pm.ikHandle(name='ikh') self.assertEqual(len(ikh1), 2) self.assertTrue(isinstance(ikh1[0], pm.nt.IkHandle)) self.assertTrue(isinstance(ikh1[1], pm.nt.IkEffector)) self.assertEqual(ikh1[0].nodeName(), 'ikh') pm.group(ikh1, name='theGroup') self.assertEqual(cmds.ls('*ikh', long=True), ['|theGroup|ikh']) j3 = cmds.createNode('joint', name='j3') j4 = cmds.createNode('joint', name='j4', parent=j3) cmds.select(j3, j4) ikh2 = pm.ikHandle(name='ikh') self.assertEqual(len(ikh2), 2) self.assertTrue(isinstance(ikh2[0], pm.nt.IkHandle)) self.assertTrue(isinstance(ikh2[1], pm.nt.IkEffector)) self.assertEqual(ikh2[0].nodeName(), 'ikh')
def build_flexi_jnts(self, follicles): """ Args: None Returns (None) """ follicle_prefix = '%s_flexiPlane_' % self.flexiPlaneNameField.getText() jntGRP_name = self.flexiPlaneNameField.getText() + '_flexiPlane_JNT_GRP' pm.group( em = True, name = jntGRP_name ) for index,follicle in enumerate(follicles): jnt_name = self.format_string.format(PREFIX = self.flexiPlaneNameField.getText(), INDEX = 'flexiPlane_jnt%03d' % (index+1), SUFFIX = 'JNT') jnt_offset_name = jnt_name.replace('_JNT','Offset_GRP') tweek_ctrlCon_name = self.format_string.format(PREFIX = self.flexiPlaneNameField.getText(), INDEX = 'flexiPlane_tweak%03d' % (index+1), SUFFIX = 'CTRLCon_GRP') pm.joint( p = ( follicle.translateX.get(), 0, 0 ), n = jnt_name ) pm.select(jnt_name, r=True) offSetGRP.add_offset_grps() pm.parent( jnt_offset_name, jntGRP_name ) pm.select( clear = True ) tweak_ctrl_con = pm.PyNode(tweek_ctrlCon_name) joint_offset = pm.PyNode(jnt_offset_name) pm.parentConstraint( tweek_ctrlCon_name, jnt_offset_name ) pm.setAttr(jnt_name + '.rotateZ', -90) pm.makeIdentity( jnt_name, apply=True, translate=True, rotate=True )
def duplicateSequence(objects): '''duplicates the given objects as groups per frame with properly named objects Args: objects (list(pm.PyNode)): list of objects to be duplicated every frame Returns: nothing...yet. Usage: duplicateSequence(pm.ls(sl=True)) ''' for obj in objects: topGrp = obj.getParent().name().replace('GRP','ANIM_GRP') if pm.objExists(topGrp): topGrp = pm.PyNode(topGrp) else: topGrp = pm.group(em=True,n=topGrp) startFrame = pm.playbackOptions(q=True,ast=True) endFrame = pm.playbackOptions(q=True,aet=True) incr = 1 grp = pm.group(em=True, n=obj.name().replace('GEO','ANIM_GRP'), p=topGrp) i=0 for frame in range (startFrame, endFrame+1, incr): pm.currentTime(frame) dup=pm.duplicate(obj, n=obj.name().replace('GEO','%d_GEO'%i)) dup[0].setParent(grp) i+=1
def create_module(name): """ Creates a top group from an object name For now, just dummy checking if the suffix is all caps Args: name (str): name to parse or use Returns (pm.nt.Transform): resulting group node """ module = {} if name.split('_')[-1].isupper(): name = '_'.join( name.split('_')[:-1] ) grp_name = '%s_GRP'%name if pm.objExists(name): top_group = pm.PyNode(name) elif pm.objExists(grp_name): top_group = pm.PyNode(grp_name) else: top_group = pm.group(em=True, n='%s_GRP'%name) module['top_group'] = top_group for subgroup in ['skeleton','model','parts','controls']: subgroup_name = '%s_%s_GRP'%(name, subgroup) if not pm.objExists(subgroup_name): module[subgroup] = pm.group(em=True, n=subgroup_name) module[subgroup].setParent(top_group) top_group.addAttr('%s_vis'%subgroup, at='long', k=True, dv=1, min=0, max=1) top_group.attr('%s_vis'%subgroup).connect(module[subgroup].visibility) else: module[subgroup] = pm.PyNode(subgroup_name) return module
def assetOrganize(): sel = pm.ls(sl = 1) assetName, assetVar = buildNameAsset(sel) grpGeo = pm.group( sel, n = assetName + assetVar + '_Geo') # CREATE HIERARCITY grpAsset = pm.group( grpGeo , n = assetName + assetVar + '_001') lockTRS(grpGeo) # LOCK transform for i in sel: lockTRS(i)
def fix(self): pm.group(self.selection, name="GEO_GROUP_RENAME_ME") names = ", ".join(self.selection) msg = self.fix_msg.format(len(self.selection), names) return True, msg
def createGroups(self): pm.select(cl=1) self.mainGrp = pm.group(n=self.name + '_grp') pm.select(cl=1) self.jntGrp = pm.group(name=self.name+'_ik_jnt_grp') pm.rotate(self.jntGrp ,0,-90,0,r=1) pm.parent(self.jntGrp,self.mainGrp) pm.select(cl=1)
def grp_create(name, parent=None): if pm.objExists(name): return pm.PyNode(name) else: if parent: return pm.group(em=True, n=name, p=parent) else: return pm.group(em=True, n=name)
def createRig(self): pm.currentTime(0, e=True) global sel_objects sel_objects = pm.ls(sl=True, tr=True) if sel_objects == []: print '\n# Error: Please select an object first' pm.confirmDialog(title = 'Error: Nothing Selected', m = 'Please select an object to create the light rig around.', button = 'Ok', db = 'Ok') self.close() gui(dock=False) else: global light_name light_name = 'light1' name_request = pm.promptDialog( t='Light Name', m='Enter Your New Light\'s Name', ma='left', tx='Ex: key_light', st='text', b=['Ok', 'Cancel'], db='Ok', cb='Cancel', ds='Cancel') if name_request == 'Ok': light_name = pm.promptDialog(query=True, text=True) global sel_center sel_center = command.averageCoords(sel_objects) global rigOrbit, rigInterv, rigLight rigOrbit = pm.group(n='olp_orbitsGrp1', em=True) rigInterv = pm.group(n='olp_intervalsGrp1', em=True) rigLight = self.createLight(sel_center) self.setExpression() pm.createRenderLayer([sel_objects, rigOrbit, rigInterv, rigLight], noRecurse=True, name='{0}_layer'.format(light_name)) self.createVis() pm.xform(rigOrbit, a=True, t=sel_center) pm.xform(rigInterv, a=True, t=sel_center) pm.parent(rigLight, rigInterv) pm.parent(rigInterv, rigOrbit) pm.select(sel_objects, r=True) # GUI Components enable/disable self.enableDisable_component(self.createRig_btn, enabled=False) self.enableDisable_component(self.deleteRig_btn, enabled=True) self.enableDisable_component(self.distance_label, enabled=True) self.enableDisable_component(self.distance_float, enabled=True) self.enableDisable_component(self.orbit_label, enabled=True) self.enableDisable_component(self.orbit_int, enabled=True) self.enableDisable_component(self.interv_label, enabled=True) self.enableDisable_component(self.interv_int, enabled=True) self.enableDisable_component(self.showVis_ckbx, enabled=True)
def calibrationGeo(ren='vray', toggle=True): ''' Creates objects to assist in lighting calibration for photometric and VFX workflows. ''' ####: REN # 1 : mentalRay # 2 : V-ray ####: ARGS # 1 : create # 2 : delete if toggle is True: # cleanup check if pm.objExists('LGT_REF_OBJ') | pm.objExists( 'diff_18SG') | pm.objExists('diff_18'): pm.delete('diff_80', 'diff_18', 'refl_100', 'refl_75', 'diff_18SG', 'diff_80SG', 'refl_01SG', 'refl_02SG', 'LGT_REF_OBJ') # create four spheres & a plane tmp1 = pm.polySphere(r=1, n="fBall_D1", ch=0) diff01 = tmp1[0] tmp1 = pm.polySphere(r=1, n="fBall_D2", ch=0) diff02 = tmp1[0] tmp1 = pm.polySphere(r=1, n="fBall_R1", ch=0) refl01 = tmp1[0] tmp1 = pm.polySphere(r=1, n="fBall_R2", ch=0) refl02 = tmp1[0] tmp1 = pm.polyPlane(n="fGround", ch=1) grid01 = tmp1[0] objs = [diff01, diff02, refl01, refl02, grid01] #shds = [shd_diff_80, shd_diff_18, shd_refl_01, shd_refl_02] #shgs = [shg_diff_80, shg_diff_18, shg_refl_01, shg_refl_02] # group them pm.group(diff01, diff02, refl01, refl02, grid01, n="LGT_REF_OBJ") # move them around offset = 4.5 for o in objs: o.translateX.set(offset) offset = offset - 3 grid01.scaleX.set(50) grid01.scaleZ.set(50) grid01.translateX.set(0) grid01.translateY.set(-10) # create shaders # 80% diffuse goes to mesh diff01 shg_diff_80 = pm.sets(n="diff_80SG", renderable=1, empty=1) shd_diff_80 = pm.shadingNode('lambert', asShader=1, n="diff_80") shd_diff_80.diffuse.set(0.8) shd_diff_80.color.set(1, 1, 1) pm.surfaceShaderList(shd_diff_80, add=shg_diff_80) pm.sets(shg_diff_80, e=1, forceElement=diff01) # 18% diffuse goes to mesh diff02 shg_diff_18 = pm.sets(n="diff_18SG", renderable=1, empty=1) shd_diff_18 = pm.shadingNode('lambert', asShader=1, n="diff_18") shd_diff_18.diffuse.set(0.18) shd_diff_18.color.set(1, 1, 1) pm.surfaceShaderList(shd_diff_18, add=shg_diff_18) pm.sets(shg_diff_18, e=1, forceElement=diff02) ### REFLECTION SPHERES DEPEND ON DIFFERENT SHADERS FOR MENTALRAY / VRAY ### if ren is 'mray': # (MENTALRAY) 100% glossy mia goes to mesh refl01 shg_refl_01 = pm.sets(n="refl_01SG", renderable=1, empty=1) shd_refl_01 = pm.shadingNode('mia_material_x_passes', asShader=1, n="refl_100") shd_refl_01.diffuse_weight.set(0) shd_refl_01.reflectivity.set(1) pm.disconnectAttr('lambert1.outColor', shg_refl_01.surfaceShader) pm.connectAttr(shd_refl_01.message, shg_refl_01.miMaterialShader) pm.sets(shg_refl_01, e=1, forceElement=refl01) # (MENTALRAY) 75% glossy mia goes to mesh refl02 shg_refl_02 = pm.sets(n="refl_02SG", renderable=1, empty=1) shd_refl_02 = pm.shadingNode('mia_material_x_passes', asShader=1, n="refl_75") shd_refl_02.diffuse_weight.set(0) shd_refl_02.reflectivity.set(1) shd_refl_02.refl_gloss.set(0.75) pm.disconnectAttr('lambert1.outColor', shg_refl_02.surfaceShader) pm.connectAttr(shd_refl_02.message, shg_refl_02.miMaterialShader) pm.sets(shg_refl_02, e=1, forceElement=refl02) if ren is 'vray': # (VRAY) 100% glossy vraymtl goes to mesh refl01 shg_refl_01 = pm.sets(n="refl_01SG", renderable=1, empty=1) shd_refl_01 = pm.shadingNode('VRayMtl', asShader=1, n="refl_100") shd_refl_01.diffuseColorAmount.set(0) shd_refl_01.reflectionColor.set(1, 1, 1) pm.surfaceShaderList(shd_refl_01, add=shg_refl_01) pm.sets(shg_refl_01, e=1, forceElement=refl01) # (VRAY) 75% glossy vraymtl goes to mesh refl02 shg_refl_02 = pm.sets(n="refl_02SG", renderable=1, empty=1) shd_refl_02 = pm.shadingNode('VRayMtl', asShader=1, n="refl_75") shd_refl_02.diffuseColorAmount.set(0) shd_refl_02.reflectionColor.set(1, 1, 1) pm.surfaceShaderList(shd_refl_02, add=shg_refl_02) pm.sets(shg_refl_02, e=1, forceElement=refl02) if toggle is False: pm.delete('diff_80', 'diff_18', 'refl_100', 'refl_75', 'diff_18SG', 'diff_80SG', 'refl_01SG', 'refl_02SG', 'LGT_REF_OBJ')
def __init__(self, name='AimTwistDiv', start=None, end=None, mid=None): self.name = name if not start: self.start = pm.group(em=True, n=self.name + 'Start') else: self.start = start if not end: self.end = pm.group(em=True, n=self.name + 'End') else: self.end = end if not mid: self.mid = pm.group(em=True, n=self.name + 'Mid') else: self.mid = mid # cria nodes vecProd1 = pm.createNode('vectorProduct', n=self.name + 'VecProd1') vecProd2 = pm.createNode('vectorProduct', n=self.name + 'VecProd2') vecProd3 = pm.createNode('vectorProduct', n=self.name + 'VecProd3') vecProd4 = pm.createNode('vectorProduct', n=self.name + 'VecProd4') add1 = pm.createNode('plusMinusAverage', n=self.name + 'Add1') add2 = pm.createNode('plusMinusAverage', n=self.name + 'Add2') matrix4by4 = pm.createNode('fourByFourMatrix', n=self.name + 'FourByFour') decomposeMatrix1 = pm.createNode('decomposeMatrix', n=self.name + 'Decompose1') decomposeMatrix2 = pm.createNode('decomposeMatrix', n=self.name + 'Decompose2') decomposeMatrix3 = pm.createNode('decomposeMatrix', n=self.name + 'Decompose3') multiMatrix = pm.createNode('multMatrix', n=self.name + 'MultiMatrix') # ver se funciona so com worldMatrix self.start.worldMatrix[0] >> vecProd1.matrix vecProd1.input1.set((0, 1, 0)) vecProd1.operation.set(3) self.end.worldMatrix[0] >> vecProd2.matrix vecProd2.input1.set((0, 1, 0)) vecProd2.operation.set(3) vecProd1.output >> add1.input3D[0] vecProd2.output >> add1.input3D[1] add1.operation.set(1) self.start.worldMatrix[0] >> decomposeMatrix1.inputMatrix decomposeMatrix1.outputTranslate >> add2.input3D[1] self.end.worldMatrix[0] >> decomposeMatrix2.inputMatrix decomposeMatrix2.outputTranslate >> add2.input3D[0] add2.operation.set(2) add1.output3D >> vecProd3.input2 add2.output3D >> vecProd3.input1 vecProd3.operation.set(2) vecProd3.output >> vecProd4.input1 add2.output3D >> vecProd4.input2 vecProd4.operation.set(2) add2.output3Dx >> matrix4by4.in00 add2.output3Dy >> matrix4by4.in01 add2.output3Dz >> matrix4by4.in02 vecProd4.outputX >> matrix4by4.in10 vecProd4.outputY >> matrix4by4.in11 vecProd4.outputZ >> matrix4by4.in12 matrix4by4.output >> multiMatrix.matrixIn[0] self.mid.parentInverseMatrix[0] >> multiMatrix.matrixIn[1] multiMatrix.matrixSum >> decomposeMatrix3.inputMatrix decomposeMatrix3.outputRotate >> self.mid.rotate pm.pointConstraint(self.start, self.end, self.mid, mo=False)
def __init__(self, characterName='new', scale=1.0, mainCtrlAttachObj=''): """ :param characterName: str, character name :param scale: float, general scale of the rig :return: None """ # top group self.topGrp = pm.group(n=characterName + '_rig_GRP', em=1) self.rigCtrlLoc = pm.spaceLocator(n='rigCtrl_LOC') pm.rotate(self.rigCtrlLoc, [0, -90, 0], r=True, ws=True) #common.freezeTranform(self.rigCtrlLoc) pm.delete(pm.pointConstraint(mainCtrlAttachObj, self.rigCtrlLoc)) characterNameAt = 'characterName' sceneObjectTypeAt = 'sceneObjectType' for at in [characterNameAt, sceneObjectTypeAt]: pm.addAttr(self.topGrp, ln=at, dt='string') pm.setAttr(self.topGrp + '.' + characterNameAt, characterName, type='string', l=1) pm.setAttr(self.topGrp + '.' + sceneObjectTypeAt, self.sceneObjectType, type='string', l=1) # make global control self.globalCtrl = control.Control(prefix='global', scale=scale * 1, parent=self.topGrp, lockChannels=['t', 'r', 'v'], shape='circleY', doModify=False, doOffset=False) self.mainCtrl = control.Control(prefix='main', scale=scale * 1, parent=self.globalCtrl.getControl(), lockChannels=['s', 'v'], shape='move', doModify=False, doOffset=False) # model group self.modelGrp = pm.group(n='model_GRP', em=1, p=self.topGrp) self.fastModelGrp = pm.group(n='fastModel_GRP', em=1, p=self.modelGrp) self.mediumModelGrp = pm.group(n='mediumModel_GRP', em=1, p=self.modelGrp) self.mediumSlowGrp = pm.group(n='mediumSlowModel_GRP', em=1, p=self.modelGrp) self.slowModelGrp = pm.group(n='slowModel_GRP', em=1, p=self.modelGrp) self.allModelGrp = pm.group(n='allModel_GRP', em=1, p=self.modelGrp) self.rigModelGrp = pm.group(n='rigModel_GRP', em=1, p=self.modelGrp) pm.hide(self.rigModelGrp) # rig group self.rigGrp = pm.group(n='rig_GRP', em=1, p=self.mainCtrl.getControl()) # World Scale self.scaleLocator = pm.spaceLocator(n='scale_LOC') self.scaleLocator.inheritsTransform.set(0) self.scaleLocator.visibility.set(0) pm.connectAttr(self.globalCtrl.getControl().scale, self.scaleLocator.scale) pm.parent(self.scaleLocator, self.rigGrp) # make more groups self.jointsGrp = pm.group(n='skeleton_GRP', em=1, p=self.mainCtrl.getControl()) self.modulesGrp = pm.group(n='modules_GRP', em=1, p=self.mainCtrl.getControl()) self.rigCtrlGrp = pm.group(n='rigctrl_GRP', em=1, p=self.globalCtrl.getControl()) util.lock_and_hide_all(self.rigCtrlGrp) self.partGrp = pm.group(n='parts_GRP', em=1, p=self.rigGrp) pm.setAttr(self.partGrp + '.it', 0, l=1) # make halo self.haloCtrl = control.Control(prefix='halo', scale=1, parent=self.rigCtrlGrp, translateTo=mainCtrlAttachObj, rotateTo=self.rigCtrlLoc, lockChannels=['s'], shape='circleX', doOffset=True, doModify=True, objBBox=mainCtrlAttachObj) self.haloCtrl.getOffsetGrp().visibility.set(0) self.createHalo(mainCtrlAttachObj, 1) mainVisAts = ['modelVis', 'jointsVis'] mainDispAts = ['modelDisp', 'jointsDisp'] mainObjList = [self.modelGrp, self.jointsGrp] mainObjVisDvList = [1, 0] # add rig visibility connections for at, obj, dfVal in zip(mainVisAts, mainObjList, mainObjVisDvList): pm.addAttr(self.globalCtrl.getControl(), ln=at, at='enum', enumName='off:on', k=1, dv=dfVal) pm.setAttr(self.globalCtrl.getControl() + '.' + at, cb=1) pm.connectAttr(self.globalCtrl.getControl() + '.' + at, obj + '.v') # add rig display type connections for at, obj in zip(mainDispAts, mainObjList): pm.addAttr(self.globalCtrl.getControl(), ln=at, at='enum', enumName='normal:template:reference', k=1, dv=2) pm.setAttr(self.globalCtrl.getControl() + '.' + at, cb=1) pm.setAttr(obj + '.ove', 1) pm.connectAttr(self.globalCtrl.getControl() + '.' + at, obj + '.ovdt') # add rig display level connection displayLevel = 'displayLevel' levelGrp = [self.fastModelGrp, self.mediumModelGrp, self.slowModelGrp] pm.addAttr(self.globalCtrl.getControl(), ln=displayLevel, at='enum', enumName='fast:medium:slow', k=1, dv=1) pm.setAttr(self.globalCtrl.getControl() + '.' + displayLevel, cb=1) common.setDrivenKey(self.globalCtrl.getControl() + '.' + displayLevel, [0, 1, 2], levelGrp[0] + '.v', [1, 0, 0]) common.setDrivenKey(self.globalCtrl.getControl() + '.' + displayLevel, [0, 1, 2], levelGrp[1] + '.v', [0, 1, 0]) common.setDrivenKey(self.globalCtrl.getControl() + '.' + displayLevel, [0, 1, 2], levelGrp[2] + '.v', [0, 0, 1]) common.setDrivenKey(self.globalCtrl.getControl() + '.' + displayLevel, [0, 1, 2], self.mediumSlowGrp + '.v', [0, 1, 1]) # create display control self.displayCtrl = self.createDisplay(mainCtrlAttachObj, 1) self.ikfkCtrl = self.createIKFK(mainCtrlAttachObj, 1) pm.delete(self.rigCtrlLoc)
def group(cls, name=''): node = pm.group(em=1) cls.rename(node, name) return node
def ik_arm_base(side, start_jnt, end_jnt): """ This module is the base of creation the ik arm setup. :param side: str, side string for the arms :param start_jnt: str, start joint for the ik arm setup. :param end_jnt: str, end joint for the ik arm setup. :return: None """ ik_joints = [] real_joints = source_joints(start_jnt, end_jnt, None) ik_joints = dup_jnts(real_joints, 'ik_') parent_arm_jnt = pm.listRelatives(real_joints[0], p=True)[0] sub_group('ik_{}_arm_jnt_grp'.format(side), parent_arm_jnt, 'ik_setup_grp', 'b') sub_group(ik_joints[0], None, 'ik_{}_arm_jnt_grp'.format(side), None) pm.ikHandle(n='ik_{}_arm_iks'.format(side), sj=ik_joints[0], ee=ik_joints[-1], sol='ikRPsolver') target_loc_name = 'ik_{}_pv_loc'.format(side) sub_group('ik_pv_loc_ref', ik_joints[1], None, 't') loc_grp = create_loc( transformation_info('ik_pv_loc_ref')['t'], target_loc_name) pm.poleVectorConstraint(target_loc_name, 'ik_{}_arm_iks'.format(side)) pv_ctrl_grp, pv_ctrl = create_ctrl(target_loc_name, 'rombus_crv', 15, (5, 5, 5), '{}_Pv'.format(side)) pm.xform(pv_ctrl_grp, r=True, t=(0, 0, -40)) pm.parent(loc_grp, pv_ctrl) sub_group('ik_handle_ref', ik_joints[-1], None, 't') ik_handle_ctrl_grp, ik_handle_ctrl = create_ctrl('ik_handle_ref', 'cube_crv', 15, (10, 10, 10), '{}_Hand'.format(side)) pm.parent('ik_{}_arm_iks'.format(side), ik_handle_ctrl) for i, each in enumerate(real_joints, 0): ik_con_grp = 'ik_{}_con'.format(each) sub_group(ik_con_grp, each, ik_joints[i], 'b') pm.group('ik_{}_con'.format(real_joints[-1]), n='ik_{}_wrist_off'.format(side)) sub_group('ik_{}_wrist_off'.format(side), ik_joints[-1], ik_handle_ctrl, 'b') pm.addAttr(ik_handle_ctrl, ln="Ulna", at=float, dv=0) pm.setAttr('{}.Ulna'.format(ik_handle_ctrl), e=True, k=True) pm.connectAttr('{}.Ulna'.format(ik_handle_ctrl), '{}_con.rotateX'.format(ik_joints[-2])) ik_switch, fk_switch = fk_ik_switch('{}_arm'.format(side)) jnt_connect(real_joints, [ik_switch, fk_switch], None) ulna_cons = pm.parentConstraint('fk_{}'.format(real_joints[1]), 'ik_{}_con'.format(real_joints[2]), 'fk_{}_Arm_2_ctrl_grp'.format(side), mo=True) pm.connectAttr(fk_switch, '{}.{}W0'.format(ulna_cons, 'fk_{}'.format(real_joints[1]))) pm.connectAttr( ik_switch, '{}.{}W1'.format(ulna_cons, 'ik_{}_con'.format(real_joints[2]))) pm.parentConstraint(real_joints[-1], 'finger_{}_grp'.format(side), mo=True) sub_group(pv_ctrl_grp, None, 'ik_setup_grp', None) sub_group(ik_handle_ctrl_grp, None, 'ik_setup_grp', None) pm.parentConstraint(parent_arm_jnt, 'ik_{}_arm_jnt_grp'.format(side), mo=True) pm.connectAttr(fk_switch, 'fk_{}_Hand_1_ctrl_grp.v'.format(side)) pm.connectAttr(fk_switch, 'fk_{}_Arm_0_ctrl_grp.v'.format(side)) pm.connectAttr(ik_switch, '{}.v'.format(ik_handle_ctrl_grp)) pm.connectAttr(ik_switch, '{}.v'.format(pv_ctrl_grp)) pm.setAttr('ik_{}_arm_jnt_grp.v'.format(side), 0) pm.setAttr('{}.v'.format(loc_grp), 0) pm.setAttr('ik_{}_arm_iks.v'.format(side), 0) pm.delete('ik_pv_loc_ref', 'ik_handle_ref')
def __init__(self, cvList, skinGeo, prefix='face', headJnt='head_JNT', pointsNumber=5, scale=0.1, baseRig=None ): """ Build Facial Setup :param cvList: list of facial curves :param prefix: str, prefix to name new objects :param rigScale: float, scale factor for size of controls :param baseRig: instance of base.module.Base class """ cvList = pm.ls(cvList) skinGeo = pm.ls(skinGeo)[0] headJnt = pm.ls(headJnt)[0] # make rig module self.rigmodule = module.Module(prefix=prefix, baseObj=baseRig) # attributes self.spacing = 1.0 / (pointsNumber - 1) # setup deformation # geo setup faceGeo = pm.duplicate(skinGeo, n=prefix + '_GEO')[0] pm.parent(faceGeo, self.rigmodule.partsNoTransGrp) deform.blendShapeDeformer(skinGeo, [faceGeo], 'face_BS', frontOfChain=True) # joints setup headFaceJnt = pm.duplicate(headJnt, renameChildren=True)[0] jointsDuplicates = pm.listRelatives(headFaceJnt, c=True, ad=True) jointsDuplicates.append(headFaceJnt) for jnt in jointsDuplicates: pm.rename(jnt, str(jnt.name()).replace('_JNT1', 'Face_JNT')) pm.parent(jointsDuplicates[-1], self.rigmodule.jointsGrp) pm.skinCluster(faceGeo, headFaceJnt) faceGeoSkincluster = skin.findRelatedSkinCluster(faceGeo) pm.skinCluster(faceGeo, edit=True, ai=cvList, ug=True) faceGeoSkincluster.useComponents.set(1) pm.parent(pm.ls('*_CRVBase'), self.rigmodule.partsNoTransGrp) fullLocList = [] fullClusterList = [] for cv in pm.ls(cvList): pm.rebuildCurve(cv, ch=0, rpo=1, rt=0, end=1, kr=0, kcp=0, kep=1, kt=0, s=4, d=1, tol=0.01) pm.rebuildCurve(cv, ch=0, rpo=1, rt=0, end=1, kr=0, kcp=1, kep=1, kt=0, s=4, d=3, tol=0.01) pm.parent(cv, self.rigmodule.partsNoTransGrp) locList = self.setupCurve(cv, pointsNumber) fullLocList.extend(locList) # cluster chainCurveCVs = pm.ls(cv + '.cv[*]', fl=1) numChainCVs = len(chainCurveCVs) curveClusters = [] for i in range(numChainCVs): cls = pm.cluster(chainCurveCVs[i], n=str(cv.name()) + 'Cluster%d' % (i + 1))[1] curveClusters.append(cls) fullClusterList.extend(curveClusters) clusterGrp = pm.group(fullClusterList, n='faceCluster_GRP', p=self.rigmodule.partsNoTransGrp) follicleList = [] for loc, cls in zip(fullLocList, fullClusterList): ctrl = control.Control(str(loc.name()).replace('_LOC', ''), translateTo=loc, shape='sphere', parent=self.rigmodule.controlsGrp, doModify=True, scale=scale) follicle = followCtrl.makeControlFollowSkin(skinGeo, ctrl.getControl(), cls)[-1] follicleList.extend([follicle]) follicleGrp = pm.group(follicleList, n='faceFollicle_GRP', p=self.rigmodule.partsNoTransGrp)
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 createHairSystemForDynamicCurve(self): #Select dynamicCurve pm.select(cl=True) pm.select(self.highResCurveTrans, r=True) #makeCurveDynamic pm.runtime.MakeCurvesDynamic() pm.select(cl=True) #get Hairsystem and Follicle #---------------------------------------------------- futureListDynamicCurve = pm.listHistory( self.highResCurveTrans.getShape(), future=True, af=True) #Iterate futureList and get Hairsystem and follicle for node in futureListDynamicCurve: #HairSys if (pm.nodeType(node) == 'hairSystem'): self.dynamicHairsystem = node pm.rename(self.dynamicHairsystem.getParent(), self.prefix + '_dynamic_hair_system') #Follicle if (pm.nodeType(node) == 'follicle'): #follicle self.dynamicHairsystemFollicle = node pm.rename(self.dynamicHairsystemFollicle.getParent(), self.prefix + '_dynamic_hair_system_follicle') #follicle_grp self.dynamicHairsystemFollicleGrp = self.dynamicHairsystemFollicle.getParent( ).getParent() pm.rename(self.dynamicHairsystemFollicleGrp, self.prefix + '_dynamic_hair_system_follicle_grp') pm.select(cl=True) #get dynamicOutputCurve #---------------------------------------------------- connectionsList = pm.listConnections( self.dynamicHairsystemFollicle.outCurve, d=True) #dynamicOutputCurve self.dynamicOutputCurve = connectionsList[0] pm.rename(self.dynamicOutputCurve, self.prefix + '_dynamic_output_curve') pm.select(cl=True) #dynamicOutputCurveGrp self.dynamicOutputCurveGrp = self.dynamicOutputCurve.getParent() pm.rename(self.dynamicOutputCurveGrp, self.prefix + '_dynamic_output_curve_grp') pm.select(cl=True) #group hairSystem nodes #---------------------------------------------------- self.hairsystemNodesGrp = pm.group(n=self.prefix + '_hairSys_nodes_grp') pm.select(cl=True) #parent pm.parent(self.dynamicOutputCurveGrp, self.dynamicHairsystem.getParent(), self.dynamicHairsystemFollicleGrp, self.hairsystemNodesGrp) pm.select(cl=True) #Initial hairSys and follicle adjustments #---------------------------------------------------- #Set Follicle point lock attr to lock base pm.setAttr(self.dynamicHairsystemFollicle.pointLock, 1)
def setupFootBehavior(self): """ Main proc for creating the IK / FK switch """ # create locators for the blending arm and groups. # and then position into the right place footPositions = { 'ankle': (0, 0, 0), 'heel': (0, 0, 0), 'ball': (0, 0, 0), 'toe': (0, 0, 0) } # convert rigHelpers to PyNodes ankleHelper = pm.PyNode(self.side + '_leg_2_rigHelper') heelHelper = pm.PyNode(self.side + '_leg_3_rigHelper') ballHelper = pm.PyNode(self.side + '_leg_4_rigHelper') toeHelper = pm.PyNode(self.side + '_leg_5_rigHelper') # get rigHelpers positions footPositions['ankle'] = ankleHelper.getTranslation('world') footPositions['heel'] = heelHelper.getTranslation('world') footPositions['ball'] = ballHelper.getTranslation('world') footPositions['toe'] = toeHelper.getTranslation('world') # create locators for the blending and groups them orientFKLoc = pm.spaceLocator(name=self.side + '_footFKOrient_loc') orientIKLoc = pm.spaceLocator(name=self.side + '_footIKOrient_loc') orientFKGrp = pm.group(name=self.side + '_footFKOrient_grp', em=True) orientIKGrp = pm.group(name=self.side + '_footIKOrient_grp', em=True) locFKShape = pm.listRelatives(orientFKLoc, s=1)[0] locIKShape = pm.listRelatives(orientIKLoc, s=1)[0] # setup a smaller locator and moves to the ankle joint for loc in [locFKShape, locIKShape]: for scale in ['.localScaleX', '.localScaleY', '.localScaleZ']: pm.setAttr(loc + scale, 0.0005) pm.move(loc, (footPositions['ankle'][0], footPositions['ankle'][1], footPositions['ankle'][2])) # parent each locator to the corresponding group for loc, grp in zip([orientFKLoc, orientIKLoc], [orientFKGrp, orientIKGrp]): pm.parent(loc, grp) # parent each locator group (IK and FK) to the right place pm.parent(orientIKGrp, self.side + '_leg_ik_ctrl') pm.parent(orientFKGrp, self.side + '_leg1_FK_ctrl') pm.parent(self.side + '_leg_limb_ikh', self.side + '_leg_ik_ctrl') footPointConst = pm.pointConstraint(orientIKLoc, orientFKLoc, self.side + '_foot_grp') footOrientConst = pm.orientConstraint(orientIKLoc, orientFKLoc, self.side + '_foot_grp') # connect orientConstraint weights to footCtrl to be able to switch the weights from the FK/IK attribute pm.connectAttr( self.side + '_foot_ctrl.FK_IK', footOrientConst + '.' + self.side + '_footFKOrient_locW1') footReverseNode = pm.createNode('reverse', name=self.side + '_footRev') pm.connectAttr(self.side + '_foot_ctrl.FK_IK', footReverseNode + '.input.inputX') pm.connectAttr( footReverseNode + '.output.outputX', footOrientConst + '.' + self.side + '_footIKOrient_locW0') pm.connectAttr( self.side + '_foot_ctrl.FK_IK', footPointConst + '.' + self.side + '_footFKOrient_locW1') footPointReverseNode = pm.createNode('reverse', name=self.side + '_footPointConsRev') pm.connectAttr(self.side + '_foot_ctrl.FK_IK', footPointReverseNode + '.input.inputX') pm.connectAttr( footPointReverseNode + '.output.outputX', footPointConst + '.' + self.side + '_footIKOrient_locW0') # create groups setup for the foot footIkGrp = pm.group(name=self.side + '_footlRollIk_grp', em=True) heelIkGrp = pm.group(name=self.side + '_heelRollIk_grp', em=True) toeIkGrp = pm.group(name=self.side + '_toeRollIk_grp', em=True) ballIkGrp = pm.group(name=self.side + '_ballRollIk_grp', em=True) pm.move(heelIkGrp, (footPositions['heel'][0], footPositions['heel'][1], footPositions['heel'][2])) pm.move(toeIkGrp, (footPositions['toe'][0], footPositions['toe'][1], footPositions['toe'][2])) pm.move(ballIkGrp, (footPositions['ball'][0], footPositions['ball'][1], footPositions['ball'][2])) pm.move(footIkGrp, (footPositions['ankle'][0], footPositions['ankle'][1], footPositions['ankle'][2])) pm.parent(ballIkGrp, toeIkGrp) pm.parent(toeIkGrp, heelIkGrp) pm.parent(heelIkGrp, footIkGrp) pm.parent(self.side + '_leg_limb_ikh', ballIkGrp) pm.parent(footIkGrp, self.side + '_foot_ctrl') for rot in ['.rx', '.ry', '.rz']: pm.connectAttr(self.side + '_heelRoll_grp.rotate' + rot, heelIkGrp + '.rotate' + rot) for rot in ['.rx', '.ry', '.rz']: pm.connectAttr(self.side + '_toeRoll_grp.rotate' + rot, toeIkGrp + '.rotate' + rot) for rot in ['.rx', '.ry', '.rz']: pm.connectAttr(self.side + '_ballRoll_grp.rotate' + rot, ballIkGrp + '.rotate' + rot) for rot in ['.rx', '.ry', '.rz']: pm.connectAttr(self.side + '_foot_ctrl.rotate' + rot, footIkGrp + '.rotate' + rot) pm.parent(self.side + '_foot_grp', 'main_ctrl') pm.parent(self.side + '_foot0_jnt', self.side + '_foot_grp')
def createManipulators(self): pm.select(cl=True) #manip_master #---------------------------------------------------- #create manip master self.manip_master = pm.circle(r=1.5, name=self.prefix + '_manip_master', ch=False, nr=(0, 1, 0))[0] pm.select(cl=True) #create and parent under grp self.manip_master_grp = pm.group(n=self.prefix + '_manip_master_grp') pm.select(cl=True) pm.parent(self.manip_master, self.manip_master_grp) pm.select(cl=True) #translate self.manip_master_grp.translate.set(self.highResCurveCoordList[0]) pm.select(cl=True) #manip_ikSpline list #---------------------------------------------------- #manipIkSplineList self.manipIkSplineList = [] self.manipIkSplineGrpList = [] #iterate through low curve points list and create manip ik spline for index in range(len(self.lowResCurveCoordList)): pm.select(cl=True) #manipName manipName = self.prefix + '_manip_ik_spline_' + str(index + 1) if (index == 0): manipName = self.prefix + '_manip_ik_spline_' + 'base' if (index + 1 == len(self.lowResCurveCoordList)): manipName = self.prefix + '_manip_ik_spline_' + 'tip' #Create manip manip_ik_spline = pm.sphere(r=1, ch=False, n=manipName)[0] pm.select(cl=True) #create manip grp manip_ik_spline_grp = pm.group(n=manipName + '_grp') pm.select(cl=True) pm.parent(manip_ik_spline, manip_ik_spline_grp) pm.select(cl=True) #translate grp manip_ik_spline_grp.translate.set(self.lowResCurveCoordList[index]) pm.select(cl=True) #Append to lists self.manipIkSplineList.append(manip_ik_spline) self.manipIkSplineGrpList.append(manip_ik_spline_grp) pm.select(cl=True) #Create group for manip groups self.manipIkSplineTopGrp = pm.group(n=self.prefix + '_manip_ik_spline_top_grp') pm.select(cl=True) #parent all manips to top grp pm.parent(self.manipIkSplineGrpList, self.manipIkSplineTopGrp) pm.select(cl=True)
def RibbonCreation(self, Object01, Object02, foliculeNumber=5): print 'creating riboon in %s and %s' % (Object01, Object02) self.baseObjects.append(Object01) self.baseObjects.append(Object02) VP1 = om.MVector(pm.xform(Object01, a=True, ws=True, q=True, rp=True)) VP2 = om.MVector(pm.xform(Object02, a=True, ws=True, q=True, rp=True)) plano = self.nurbPlaneBetweenObjects(Object01, Object02) planoShape = pm.listRelatives(plano, shapes=True)[0] pm.select(cl=True) RibbonSize = VP1 - VP2 print "plano = %s" % plano print "len = %s" % RibbonSize.length() MainSkeleton = pm.group(em=True, name="%sTo%sRibbon" % (self.name_conv.get_a_short_name(Object01), self.name_conv.get_a_short_name(Object02))) self.name_conv.rename_name_in_format(MainSkeleton, useName=True) HairGroup = pm.group(em=True, name="%sTo%sHairSystem" % (self.name_conv.get_a_short_name(Object01), self.name_conv.get_a_short_name(Object02))) self.name_conv.rename_name_in_format(HairGroup, useName=True) nstep = 1.0 / (foliculeNumber - 1.0) Hys = pm.language.Mel.eval('createNode hairSystem') Hys = "hairSystem1" ArrayJoints = [] HairSystemIndex = [0] folicules = [] for n in range(foliculeNumber): pm.language.Mel.eval( 'createHairCurveNode("%s", "%s" ,%s ,.5 , 1 ,0 ,0 ,0 ,0 ,"" ,1.0 ,{%s} ,"" ,"" ,2 );' % (Hys, planoShape, nstep * n, n)) NewFolicule = self.name_conv.rename_name_in_format("follicle1") folicules.append(NewFolicule) pm.parent(NewFolicule, HairGroup) self.folicules = folicules pm.delete(pm.listRelatives(Hys, p=True)) index = 0 skinedJoints = pm.group(em=True, name="%sTo%sskinedJoints" % (self.name_conv.get_a_short_name(Object01), self.name_conv.get_a_short_name(Object02))) self.name_conv.rename_name_in_format(skinedJoints, useName=True) for eachFolicule in folicules: ArrayJoints.append( pm.joint(name="%sTo%sRibbonJoints" % (self.name_conv.get_a_short_name(Object01), self.name_conv.get_a_short_name(Object02)))) self.name_conv.rename_name_in_format(ArrayJoints[index], useName=True) pm.matchTransform(ArrayJoints[index], eachFolicule) pm.parentConstraint(eachFolicule, ArrayJoints[index]) index += 1 self.jointStructure = ArrayJoints controles = [] resetControles = [] locatorControlesList = [] locatorLookAtList = [] jointsLookAtList = [] groupLookAtList = [] GroupControls = pm.group(empty=True, name="%sTo%sControls" % (self.name_conv.get_a_short_name(Object01), self.name_conv.get_a_short_name(Object02))) self.name_conv.rename_name_in_format(GroupControls, useName=True) GroupJoints = pm.group(empty=True, name="%sTo%sGroupJointsLookAt" % (self.name_conv.get_a_short_name(Object01), self.name_conv.get_a_short_name(Object02))) self.name_conv.rename_name_in_format(GroupJoints, useName=True) self.allControls.append(GroupControls) self.joints.append(GroupJoints) for iloop in range(3): resetControlGroup, control = self.rig_controls.RMCircularControl( Object01, radius=RibbonSize.length() / 3, name="%sTo%sCtrl" % (self.name_conv.get_a_short_name(Object01), self.name_conv.get_a_short_name(Object02))) controles.append(control) resetControles.append(resetControlGroup) locatorControl = pm.spaceLocator( name="%sTo%sLocatorCntrl" % (self.name_conv.get_a_short_name(Object01), self.name_conv.get_a_short_name(Object02))) self.name_conv.rename_name_in_format(locatorControl, useName=True) locatorControlesList.append(locatorControl) pm.matchTransform(locatorControl, Object01) locatorLookAt = pm.spaceLocator( name="%sTo%sLocatorLookAt" % (self.name_conv.get_a_short_name(Object01), self.name_conv.get_a_short_name(Object02))) self.name_conv.rename_name_in_format(locatorLookAt, useName=True) locatorLookAtList.append(locatorLookAt) pm.matchTransform(locatorLookAt, Object01) pm.select(clear=True) jointsLookAt = pm.joint( name="%sTo%sJointsLookAt" % (self.name_conv.get_a_short_name(Object01), self.name_conv.get_a_short_name(Object02))) self.name_conv.rename_name_in_format(jointsLookAt, useName=True) jointsLookAtList.append(jointsLookAt) pm.matchTransform(jointsLookAt, Object01) groupLookAt = pm.group(empty=True, name="%sTo%sGroupLookAt" % (self.name_conv.get_a_short_name(Object01), self.name_conv.get_a_short_name(Object02))) self.name_conv.rename_name_in_format(groupLookAt, useName=True) self.kinematics.append(groupLookAt) groupLookAtList.append(groupLookAt) pm.matchTransform(groupLookAt, Object01) for each in groupLookAtList: pm.parent(each, MainSkeleton) pm.move(RibbonSize.length() / 2 * iloop, 0, 0, resetControlGroup, r=True, os=True, moveX=True) pm.move(RibbonSize.length() / 2 * iloop, 0, 0, locatorControl, r=True, os=True, moveX=True) pm.move(RibbonSize.length() / 2 * iloop, 0, 1, locatorLookAt, r=True, os=True, moveXYZ=True) pm.move(RibbonSize.length() / 2 * iloop, 0, 0, jointsLookAt, r=True, os=True, moveX=True) pm.move(RibbonSize.length() / 2 * iloop, 0, 0, groupLookAt, r=True, os=True, moveX=True) pm.parent(resetControlGroup, GroupControls) pm.parent(locatorControl, groupLookAt) pm.parent(locatorLookAt, groupLookAt) pm.parent(jointsLookAt, GroupJoints) pm.makeIdentity(control, apply=True, t=1, r=0, s=1, n=0) pm.makeIdentity(jointsLookAt, apply=True, t=1, r=0, s=1, n=0) pm.parentConstraint(locatorControl, jointsLookAt) pm.parentConstraint(control, groupLookAt) self.controls = controles self.resetControls = resetControles self.resetControls = resetControles pm.aimConstraint(controles[1], locatorControlesList[0], aim=[1, 0, 0], upVector=[0, 0, 1], wut='object', worldUpObject=locatorLookAtList[0]) pm.aimConstraint(controles[1], locatorControlesList[2], aim=[1, 0, 0], upVector=[0, 0, 1], wut='object', worldUpObject=locatorLookAtList[2]) pm.parent(GroupJoints, MainSkeleton) # pm.select(plano, replace=True) # print jointsLookAtList # for eachJoint in jointsLookAtList: # pm.select(eachJoint, add=True) pm.skinCluster(jointsLookAtList, plano) pm.parent(plano, HairGroup)
def addOffset(node): ''' - add a grp above node - add a nurbs plane under grp's parent (get the same local space) - unparent nurbs plane to world space (or whichever deformer space - e.g. headLattice) - add pointOnSurfaceInfo to get position and orientation for grp - use aimconstraint to convert vectors to orientation - return grp as offset example use for mathilda: import rigger.modules.surfOffset as surfOffset reload(surfOffset) nodes = pm.ls(sl=True) offsets = [] for n in nodes: offsetGrp = surfOffset.addOffset(n) offsets.append(offsetGrp[1]) pm.select(offsets) ''' nodeMatrix = node.getMatrix(worldSpace=True) offsetGrp = pm.group(em=True, n=node + '_surfOffset_grp') offsetGrp.setMatrix(nodeMatrix, worldSpace=True) # hierarchy # also check for sibling nodes, such as scaleX/Y xfos siblings = node.getSiblings() for sibling in siblings: offsetGrp | sibling parentNode = node.getParent() parentNode | offsetGrp | node # nurbs plane plane = pm.nurbsPlane(n=node + '_surfOffset_srf', ch=False, degree=1, axis=(0, 1, 0))[0] # parentNode | plane # don't # use separate hierachy planeGrp = pm.group(plane, n=node + '_surfOffsetSrf_grp') planeHm = pm.group(planeGrp, n=node + '_surfOffsetSrf_hm') planeHm.setMatrix(nodeMatrix, worldSpace=True) parentNode | planeHm # point on surface info posi = pm.createNode('pointOnSurfaceInfo', n=node + '_surfOffset_posi') plane.local >> posi.inputSurface posi.parameterU.set(0.5) posi.parameterV.set(0.5) ''' # convert vectors to orientation using aim constraint aimc = pm.createNode('aimConstraint', n=node+'_surfOffset_aimc') offsetGrp | aimc posi.normal >> aimc.tg[0].tt posi.tangentU >> aimc.worldUpVector aimc.aimVector.set((0,1,0)) aimc.upVector.set((1,0,0)) ''' ''' # use cross products instead of aim constraint vpZ = pm.createNode('vectorProduct', n=node+'_surfOffsetZVec_vp') posi.normal >> vpZ.input1 # Y posi.tangentU >> vpZ.input2 vpZ.operation.set(2) vpX = pm.createNode('vectorProduct', n=node+'_surfOffsetXVec_vp') posi.normal >> vpZ.input1 # Y posi.tangentU >> vpZ.input2 vpZ.operation.set(2)''' # just use vectors from posi to construct matrix! mat = pm.createNode('fourByFourMatrix', n=node + '_surfOffset_fbfm') # x-vector posi.tangentUx >> mat.in00 posi.tangentUy >> mat.in01 posi.tangentUz >> mat.in02 # y-vector posi.normalX >> mat.in10 posi.normalY >> mat.in11 posi.normalZ >> mat.in12 # z-vector posi.tangentVx >> mat.in20 posi.tangentVy >> mat.in21 posi.tangentVz >> mat.in22 # position posi.positionX >> mat.in30 posi.positionY >> mat.in31 posi.positionZ >> mat.in32 # drive grp dcm = pm.createNode('decomposeMatrix', n=node + '_surfOffset_dcm') mat.output >> dcm.inputMatrix dcm.outputTranslate >> offsetGrp.t dcm.outputRotate >> offsetGrp.r return offsetGrp, plane
def create(self): ''' ''' # use group node as placeholder master = pm.group(em=True, name=self.name + '_master') master.addAttr('upVal', k=True, at='float', dv=0, min=0, max=1) master.addAttr('lowVal', k=True, at='float', dv=1, min=0, max=1) master.addAttr('midVal', k=True, at='float', dv=0.5, min=0, max=1) master.addAttr('radius', k=True, at='float', dv=self.radius) master.addAttr('rotateUpMult', k=True, at='float') master.addAttr('rotateLowMult', k=True, at='float') master.addAttr('stickAmount', k=True, at='float', dv=0, min=0, max=1) # use setRange to interpolate upVal and lowVal to midVal, driven by stickAmount setr = pm.createNode('setRange', n=self.name + '_setr') master.midVal >> setr.maxX master.midVal >> setr.maxY master.stickAmount >> setr.valueX master.stickAmount >> setr.valueY setr.minX.set(0) setr.oldMaxX.set(1) setr.oldMaxY.set(1) setr.minY.set(1) setr.outValueX >> master.upVal setr.outValueY >> master.lowVal master.upVal >> master.rotateUpMult master.lowVal >> master.rotateLowMult """ # up_ctg world pt up_ctg_pmm = pm.createNode('pointMatrixMult', n=self.name+'_up_ctg_pmm') self.up_ctg.worldMatrix[0] >> up_ctg_pmm.inMatrix # calculate offset up_pos = self.up_ctg.getTranslation(space='world') low_pos = self.low_ctg.getTranslation(space='world') vec = low_pos - up_pos center_pos_world = up_pos + vec * 0.45 center_pos_world = pm.dt.Point(center_pos_world) up_ctg_inv_mat = self.up_ctg.getMatrix(worldSpace=True).inverse() up_offset = center_pos_world * up_ctg_inv_mat up_ctg_pmm.inPoint.set(up_offset) # low_ctg world pt low_ctg_pmm = pm.createNode('pointMatrixMult', n=self.name+'_low_ctg_pmm') self.low_ctg.worldMatrix[0] >> low_ctg_pmm.inMatrix center_pos_world = low_pos - vec * 0.45 center_pos_world = pm.dt.Point(center_pos_world) low_ctg_inv_mat = self.low_ctg.getMatrix(worldSpace=True).inverse() low_offset = center_pos_world * low_ctg_inv_mat low_ctg_pmm.inPoint.set(low_offset) # arc direction vector vp = pm.createNode('vectorProduct', n=self.name+'_arcDirection_vp') self.up_ctg.worldMatrix[0] >> vp.matrix vp.operation.set(3) vp.input1.set(1,0,0) # 2-pt-circular-arc arc = pm.createNode('makeTwoPointCircularArc', n=self.name+'_arc') up_ctg_pmm.output >> arc.point1 low_ctg_pmm.output >> arc.point2 master.radius >> arc.radius vp.output >> arc.directionVector # UPPER motion path up_mp = pm.createNode('motionPath', n=self.name+'_upper_mp') arc.outputCurve >> up_mp.geometryPath self.up_ctg.worldMatrix[0] >> up_mp.worldUpMatrix master.upVal >> up_mp.uValue up_mp.frontAxis.set(1) up_mp.upAxis.set(2) up_mp.inverseFront.set(True) up_mp.worldUpType.set(2) up_mp.worldUpVector.set(0,0,1) up_mp.fractionMode.set(True) # compose matrix for UPPER sticky xfo up_cm = pm.createNode('composeMatrix', n=self.name+'_upper_cm') up_mp.allCoordinates >> up_cm.inputTranslate up_mp.rotate >> up_cm.inputRotate # create sticky grp for UPPER_CTG up_sticky = pm.group(em=True, n=self.name+'_upper_sticky_grp') self.up_ctg | up_sticky pm.makeIdentity(up_sticky, t=True, r=True, s=True, a=False) up_sticky | self.up_ctl # multiply matrix into sticky grp space up_mm = pm.createNode('multMatrix', n=self.name+'_upper_mm') up_cm.outputMatrix >> up_mm.matrixIn[0] up_sticky.parentInverseMatrix >> up_mm.matrixIn[1] # decompose matrix up_dm = pm.createNode('decomposeMatrix', n=self.name+'_upper_dm') up_mm.matrixSum >> up_dm.inputMatrix # remember translate offset using PMA up_tr_pma = pm.createNode('plusMinusAverage', n=self.name+'_upper_tr_pma') up_dm.outputTranslate >> up_tr_pma.input3D[0] up_tr_pma.input3D[1].set(-1 * up_offset) # remember rotation offset using PMA up_pma = pm.createNode('plusMinusAverage', n=self.name+'_upper_pma') up_dm.outputRotate >> up_pma.input3D[0] up_pma.input3D[1].set(-up_dm.outputRotateX.get(), -up_dm.outputRotateY.get(), -up_dm.outputRotateZ.get()) # modulate rotations by a multiplier up_rot_md = pm.createNode('multiplyDivide', n=self.name+'_up_rot_md') up_pma.output3D >> up_rot_md.input1 master.rotateUpMult >> up_rot_md.input2X master.rotateUpMult >> up_rot_md.input2Y master.rotateUpMult >> up_rot_md.input2Z # connect into sticky grp up_tr_pma.output3D >> up_sticky.translate # up_rot_md.output >> up_sticky.rotate # have to fix rotations # connect sticky values to bnd up_bnd_sticky = pm.group(em=True, n=self.name+'_upper_sticky_bnd') bnd_parent = self.up_bnd.getParent() bnd_parent | up_bnd_sticky pm.makeIdentity(up_bnd_sticky, t=True, r=True, s=True, a=False) up_bnd_sticky | self.up_bnd up_sticky.translate >> up_bnd_sticky.translate up_sticky.rotate >> up_bnd_sticky.rotate # LOWER motion path low_mp = pm.createNode('motionPath', n=self.name+'_lower_mp') arc.outputCurve >> low_mp.geometryPath self.low_ctg.worldMatrix[0] >> low_mp.worldUpMatrix master.lowVal >> low_mp.uValue low_mp.frontAxis.set(1) low_mp.upAxis.set(2) low_mp.inverseFront.set(True) low_mp.worldUpType.set(2) low_mp.worldUpVector.set(0,0,1) low_mp.fractionMode.set(True) # compose matrix for LOWER sticky xfo low_cm = pm.createNode('composeMatrix', n=self.name+'_lower_cm') low_mp.allCoordinates >> low_cm.inputTranslate low_mp.rotate >> low_cm.inputRotate # create sticky grp for LOWER_CTG low_sticky = pm.group(em=True, n=self.name+'_lower_sticky_grp') self.low_ctg | low_sticky pm.makeIdentity(low_sticky, t=True, r=True, s=True, a=False) low_sticky | self.low_ctl # multiply matrix into sticky grp space low_mm = pm.createNode('multMatrix', n=self.name+'_lower_mm') low_cm.outputMatrix >> low_mm.matrixIn[0] low_sticky.parentInverseMatrix >> low_mm.matrixIn[1] # decompose matrix low_dm = pm.createNode('decomposeMatrix', n=self.name+'_lower_dm') low_mm.matrixSum >> low_dm.inputMatrix # remember translate offset using PMA low_tr_pma = pm.createNode('plusMinusAverage', n=self.name+'_lower_tr_pma') low_dm.outputTranslate >> low_tr_pma.input3D[0] low_tr_pma.input3D[1].set(-1 * low_offset) # remember rotation offset using PMA low_pma = pm.createNode('plusMinusAverage', n=self.name+'_lower_pma') low_dm.outputRotate >> low_pma.input3D[0] low_pma.input3D[1].set(-low_dm.outputRotateX.get(), -low_dm.outputRotateY.get(), -low_dm.outputRotateZ.get()) # modulate rotations by a multiplier low_rot_md = pm.createNode('multiplyDivide', n=self.name+'_low_rot_md') low_pma.output3D >> low_rot_md.input1 master.rotateLowMult >> low_rot_md.input2X # actually needs to be reversed! master.rotateLowMult >> low_rot_md.input2Y master.rotateLowMult >> low_rot_md.input2Z # connect into sticky grp low_tr_pma.output3D >> low_sticky.translate # low_rot_md.output >> low_sticky.rotate # have to fix rotations # connect sticky values to bnd low_bnd_sticky = pm.group(em=True, n=self.name+'_lower_sticky_bnd') bnd_parent = self.low_bnd.getParent() bnd_parent | low_bnd_sticky pm.makeIdentity(low_bnd_sticky, t=True, r=True, s=True, a=False) low_bnd_sticky | self.low_bnd low_sticky.translate >> low_bnd_sticky.translate low_sticky.rotate >> low_bnd_sticky.rotate """ pm.select(master) return master
def build_phase_1(self): self.side_prefix = str(self.ui.cb_side_prefix.currentText()) self.up_down_prefix = str(self.ui.cb_up_down_prefix.currentText()) self.joint_radius = float(self.ui.spin_joint_size.value()) if self.center_eye_position is None: self.show_warning( "Make sure you've set an object that's the center of the eye!") return if len(self.lid_vertices) == 0: self.show_warning( "Make sure you've set the points for the eyelid!") return if self.head_joint is None: self.show_warning("Make sure you've set the head joint!") return if self.head_skin is None: self.show_warning("Make sure you've set the head mesh!") return if pm.objExists("%s_%s_lid_aim_locator_group" % (self.side_prefix, self.up_down_prefix)): self.show_warning( "Check your side and up/down prefix, this already exists in the scene!" ) return # create the joint and locator groups pm.select(None) lid_aim_locator_group = pm.PyNode( pm.group(name="%s_%s_lid_aim_locator_group" % (self.side_prefix, self.up_down_prefix))) pm.select(None) lid_aim_locator_group.setTranslation(self.center_eye_position, worldSpace=True) pm.makeIdentity(lid_aim_locator_group, translate=True) # make a list we can append the positions of every vertex to, this list is used to build the high res curve vertex_position_list = [] # make a list to add the aim locators to, so we can iterate over this list when we need to connect the locators to the high res curve aim_locator_list = [] # build the locators and joints at the position of every vertex index = 1 for vertex in self.lid_vertices: vertex_position = pm.xform(vertex, query=True, worldSpace=True, translation=True) vertex_position_list.append(vertex_position) skin_joint = pm.joint( name="%s_%s_eyelid_skin_joint_%02d" % (self.side_prefix, self.up_down_prefix, index), position=vertex_position, radius=self.joint_radius) pm.select(None) center_joint = pm.joint( name="%s_%s_eyelid_center_joint_%02d" % (self.side_prefix, self.up_down_prefix, index), position=self.center_eye_position, radius=self.joint_radius) pm.parent(skin_joint, center_joint) self.add_joint_to_skin(skin_joint, self.head_skin) pm.joint(center_joint, edit=True, orientJoint="xyz", secondaryAxisOrient="yup", children=True, zeroScaleOrient=True) pm.parent(center_joint, self.head_joint) pm.select(None) aim_locator = pm.spaceLocator( absolute=True, name="%s_%s_eyelid_aim_locator_%02d" % (self.side_prefix, self.up_down_prefix, index)) aim_locator.translate.set(vertex_position) aim_locator.centerPivots() aim_locator_shape = pm.listRelatives(shapes=True)[0] aim_locator_shape.localScaleX.set(self.joint_radius) aim_locator_shape.localScaleY.set(self.joint_radius) aim_locator_shape.localScaleZ.set(self.joint_radius) aim_locator_list.append(aim_locator) pm.parent(aim_locator, lid_aim_locator_group) pm.aimConstraint(aim_locator, center_joint, maintainOffset=True, weight=1, aimVector=(1, 0, 0), upVector=(0, 1, 0), worldUpType="scene") index += 1 # build the high res curve eyelid_high_res_curve = pm.curve( name="%s_%s_eyelid_high_res_curve" % (self.side_prefix, self.up_down_prefix), point=vertex_position_list, degree=1) self.add_attribute( eyelid_high_res_curve, "eyelidCurve", "%s_%s_high" % (self.side_prefix, self.up_down_prefix)) eyelid_high_res_curve_shape = pm.listRelatives(eyelid_high_res_curve, shapes=True)[0] self.set_shape_node_color(eyelid_high_res_curve_shape, (1, 1, 0)) eyelid_high_res_curve.centerPivots() # build the low res curve eyelid_low_res_curve = pm.duplicate( eyelid_high_res_curve, name="%s_%s_eyelid_low_res_curve" % (self.side_prefix, self.up_down_prefix))[0] pm.displaySmoothness(eyelid_low_res_curve, divisionsU=3, divisionsV=3, pointsWire=16) pm.rebuildCurve(eyelid_low_res_curve, degree=3, endKnots=True, spans=2, keepRange=1, replaceOriginal=True, rebuildType=0) eyelid_low_res_curve.eyelidCurve.set( "%s_%s_low" % (self.side_prefix, self.up_down_prefix)) eyelid_low_res_curve_shape = pm.listRelatives(eyelid_low_res_curve, shapes=True)[0] self.set_shape_node_color(eyelid_low_res_curve_shape, (0, 0, 1)) eyelid_low_res_curve.centerPivots() # parent the curves in their group if not pm.objExists( "%s_eyelid_deformer_curve_group" % self.side_prefix): eyelid_deformer_curve_group = pm.group( eyelid_high_res_curve, eyelid_low_res_curve, name="%s_eyelid_deformer_curve_group" % self.side_prefix) else: eyelid_deformer_curve_group = pm.PyNode( "%s_eyelid_deformer_curve_group" % self.side_prefix) pm.parent(eyelid_high_res_curve, eyelid_deformer_curve_group) pm.parent(eyelid_low_res_curve, eyelid_deformer_curve_group) # connect the locators to the high res curve for locator in aim_locator_list: npoc = pm.createNode("nearestPointOnCurve", name="npoc") position = locator.getTranslation(space="world") eyelid_high_res_curve_shape.worldSpace >> npoc.inputCurve npoc.inPosition.set(position) u = npoc.parameter.get() pci_node = pm.createNode("pointOnCurveInfo", name=locator.name().replace( "locator", "PCI")) eyelid_high_res_curve_shape.worldSpace >> pci_node.inputCurve pci_node.parameter.set(u) pci_node.position >> locator.translate pm.delete(npoc) if not pm.objExists("DO_NOT_TOUCH"): pm.select(None) self.do_not_touch_group = pm.PyNode(pm.group(name="DO_NOT_TOUCH")) else: self.do_not_touch_group = pm.PyNode("DO_NOT_TOUCH") pm.parent(eyelid_deformer_curve_group, self.do_not_touch_group) pm.parent(lid_aim_locator_group, self.do_not_touch_group) self.do_not_touch_group.visibility.set(False) #eyelid_deformer_curve_group.visibility.set(False) self.show_success_message("Phase 1 built successfully!") return "success"
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 rotations_load_to_maya(rotations, positions, names=None): """ Load Rotations into Maya Loads a Quaternions array into the scene via the representation of axis Parameters ---------- rotations : (F, J) Quaternions array of rotations to load into the scene where F = number of frames J = number of joints positions : (F, J, 3) ndarray array of positions to load rotation axis at where: F = number of frames J = number of joints names : [str] List of joint names Returns ------- maxies : Group Grouped Maya Node of all Axis nodes """ import pymel.core as pm if names is None: names = ["joint_" + str(i) for i in range(rotations.shape[1])] maxis = [] frames = range(1, len(positions)+1) for i, name in enumerate(names): name = name + "_axis" axis = pm.group( pm.curve(p=[(0,0,0), (1,0,0)], d=1, n=name+'_axis_x'), pm.curve(p=[(0,0,0), (0,1,0)], d=1, n=name+'_axis_y'), pm.curve(p=[(0,0,0), (0,0,1)], d=1, n=name+'_axis_z'), n=name) axis.rotatePivot.set((0,0,0)) axis.scalePivot.set((0,0,0)) axis.childAtIndex(0).overrideEnabled.set(1); axis.childAtIndex(0).overrideColor.set(13) axis.childAtIndex(1).overrideEnabled.set(1); axis.childAtIndex(1).overrideColor.set(14) axis.childAtIndex(2).overrideEnabled.set(1); axis.childAtIndex(2).overrideColor.set(15) curvex = pm.nodetypes.AnimCurveTA(n=name + "_rotateX") curvey = pm.nodetypes.AnimCurveTA(n=name + "_rotateY") curvez = pm.nodetypes.AnimCurveTA(n=name + "_rotateZ") arotations = rotations[:,i].euler() curvex.addKeys(frames, arotations[:,0]) curvey.addKeys(frames, arotations[:,1]) curvez.addKeys(frames, arotations[:,2]) pm.connectAttr(curvex.output, axis.rotateX) pm.connectAttr(curvey.output, axis.rotateY) pm.connectAttr(curvez.output, axis.rotateZ) offsetx = pm.nodetypes.AnimCurveTU(n=name + "_translateX") offsety = pm.nodetypes.AnimCurveTU(n=name + "_translateY") offsetz = pm.nodetypes.AnimCurveTU(n=name + "_translateZ") offsetx.addKeys(frames, positions[:,i,0]) offsety.addKeys(frames, positions[:,i,1]) offsetz.addKeys(frames, positions[:,i,2]) pm.connectAttr(offsetx.output, axis.translateX) pm.connectAttr(offsety.output, axis.translateY) pm.connectAttr(offsetz.output, axis.translateZ) maxis.append(axis) return pm.group(*maxis, n='RotationAnimation')
def build_phase_2(self): if self.head_controller is None: self.show_warning("Make sure you've set a head controller!") return # there's a chance that the user doesn't run the entire script at once # so for phase 2 we're just find the curves again by the special attribute they received when they were made # It's not the prettiest way, but it works self.do_not_touch_group = pm.PyNode("DO_NOT_TOUCH") self.side_prefix = str(self.ui.cb_side_prefix.currentText()) eyelid_deformer_curve_group = pm.PyNode( "%s_eyelid_deformer_curve_group" % self.side_prefix) high_res_curve_up = None high_res_curve_down = None low_res_curve_up = None low_res_curve_down = None for node in pm.ls(type="transform"): if node.hasAttr("eyelidCurve"): if "high" in node.eyelidCurve.get( ) and self.side_prefix in node.eyelidCurve.get(): if "up" in node.eyelidCurve.get(): high_res_curve_up = node else: high_res_curve_down = node if "low" in node.eyelidCurve.get( ) and self.side_prefix in node.eyelidCurve.get(): if "up" in node.eyelidCurve.get(): low_res_curve_up = node else: low_res_curve_down = node # apply wire deformer to high res curves pm.wire(high_res_curve_up, groupWithBase=False, envelope=1, crossingEffect=0, localInfluence=0, wire=low_res_curve_up.name()) pm.wire(high_res_curve_down, groupWithBase=False, envelope=1, crossingEffect=0, localInfluence=0, wire=low_res_curve_down.name()) # make a list of the main lid controllers # these are the two controllers in the middle of the upper and lower eyelid that will hold the blink attribute main_lid_controllers = [] # make a list for the constrain controllers # these are the controllers on the edge of the eye, and on top and bottom, that are needed to constrain the helper controllers # that sit between them # 0 = corner at nose, 1 = main controller on top of eye, 2 = corner at outer edge of eye, 3 = main controller at the bottom of eye constrain_controllers = [] # make a list for the constrained groups on the helper controllers # these controllers sit between the corners and the main controllers # they each have a group called constrained in their hierarchy that we're going to constrain # that way we still have a driven group that we can use for automation (like moving the lids when the eye look up, down, left or right) # and we can still grab the controller itself to make adjustments # 0 = between corner at nose and top main, 1 = between top main and corner at edge # 2 = between corner at nose and bottom main, 3 = between bottom main and corner at edge helper_constrained_groups = [] # get the position for the controls joints of the low res curve, skin the low res curves to these joints # also create the controllers and have them constrain the joints for the low res curve pm.select(None) eye_controller_group = pm.group(name="%s_eye_controller_group" % self.side_prefix) pm.select(None) eye_controller_joint_group = pm.group( name="%s_eye_controller_joint_group" % self.side_prefix) #eye_controller_joint_group.visibility.set(False) control_joints_1 = [] for index, cv_location in enumerate(low_res_curve_up.getCVs()): pm.select(None) jnt = pm.joint(name="%s_eyelid_control_joint_%02d" % (self.side_prefix, index), position=cv_location, radius=self.ui.spin_joint_size.value()) control_joints_1.append(jnt) controller = pm.circle(normal=[0, 0, 1], name="%s_eyelid_%02d_controller" % (self.side_prefix, index))[0] driven = pm.group(controller, name=controller.name().replace( "controller", "driven")) constrained = pm.group(driven, name=driven.name().replace( "driven", "constrained")) offset = pm.group(constrained, name=constrained.replace("constrained", "offset")) offset.setTranslation(cv_location) offset.setScale((self.joint_radius * 10, self.joint_radius * 10, self.joint_radius * 10)) if self.ui.chk_flip_controller_orientation.isChecked(): print "Flipping offset group 180 degrees." offset.setRotation([0, 180, 0]) pm.parentConstraint(controller, jnt, maintainOffset=True) pm.parent(offset, eye_controller_group) if index == 2: main_lid_controllers.append(controller) self.lock_and_hide_attributes(controller, ["sx", "sy", "sz"]) if index == 0 or index == 2 or index == 4: constrain_controllers.append(controller) self.lock_and_hide_attributes(controller, ["sx", "sy", "sz"]) if index == 1 or index == 3: helper_constrained_groups.append(constrained) self.lock_and_hide_attributes( controller, ["sx", "sy", "sz", "rx", "ry", "rz"]) pm.parent(jnt, eye_controller_joint_group) pm.skinCluster(control_joints_1, low_res_curve_up, toSelectedBones=True) control_joints_2 = [] for index, cv_location in enumerate(low_res_curve_down.getCVs()): if index == 1 or index == 2 or index == 3: pm.select(None) jnt = pm.joint(name="%s_eyelid_control_joint_%02d" % (self.side_prefix, index + 5), position=cv_location, radius=self.ui.spin_joint_size.value()) control_joints_2.append(jnt) controller = pm.circle(normal=[0, 0, 1], name="%s_eyelid_%02d_controller" % (self.side_prefix, index + 5))[0] driven = pm.group(controller, name=controller.name().replace( "controller", "driven")) constrained = pm.group(driven, name=driven.name().replace( "driven", "constrained")) offset = pm.group(constrained, name=constrained.replace( "constrained", "offset")) offset.setTranslation(cv_location) offset.setScale( (self.joint_radius * 10, self.joint_radius * 10, self.joint_radius * 10)) pm.parentConstraint(controller, jnt, maintainOffset=True) pm.parent(offset, eye_controller_group) if index == 2: main_lid_controllers.append(controller) constrain_controllers.append(controller) self.lock_and_hide_attributes(controller, ["sx", "sy", "sz"]) if index == 1 or index == 3: helper_constrained_groups.append(constrained) self.lock_and_hide_attributes( controller, ["sx", "sy", "sz", "rx", "ry", "rz"]) pm.parent(jnt, eye_controller_joint_group) pm.skinCluster(control_joints_2, control_joints_1[0], control_joints_1[-1], low_res_curve_down, toSelectedBones=True) #constrain the inbetween helper constrain groups to the 4 main controllers on the edges and top and top bottom of the eye pm.parentConstraint(constrain_controllers[0], constrain_controllers[1], helper_constrained_groups[0], maintainOffset=True) pm.parentConstraint(constrain_controllers[1], constrain_controllers[2], helper_constrained_groups[1], maintainOffset=True) pm.parentConstraint(constrain_controllers[0], constrain_controllers[3], helper_constrained_groups[2], maintainOffset=True) pm.parentConstraint(constrain_controllers[3], constrain_controllers[2], helper_constrained_groups[3], maintainOffset=True) # Blinking # # set up the blink height blink_height_curve = pm.duplicate(low_res_curve_up, name="%s_blink_height_curve" % self.side_prefix)[0] blink_height_blend_shape = pm.blendShape( low_res_curve_down, low_res_curve_up, blink_height_curve, name="%s_blink_height_shapes" % self.side_prefix) for index, controller in enumerate(main_lid_controllers): if index == 0: self.add_attribute(controller, "blink_height", 0, type="float") self.add_attribute(controller, "blink", 0, type="float") pm.connectAttr( "%s.blink_height" % main_lid_controllers[0].name(), "%s_blink_height_shapes.%s" % (self.side_prefix, low_res_curve_down.name())) reverse_node = pm.createNode("reverse", name="%s_eye_blink_reverse" % self.side_prefix) pm.connectAttr("%s.blink_height" % main_lid_controllers[0].name(), "%s.inputX" % reverse_node.name()) pm.connectAttr( "%s.outputX" % reverse_node.name(), "%s_blink_height_shapes.%s" % (self.side_prefix, low_res_curve_up.name())) #set up the blink high_res_blink_curve_up = pm.duplicate( high_res_curve_up, name="%s_up_eyelid_high_blink_curve" % self.side_prefix)[0] high_res_blink_curve_down = pm.duplicate( high_res_curve_down, name="%s_down_eye_high_blink_curve" % self.side_prefix)[0] main_lid_controllers[0].blink_height.set(0) up_blink_wire_deformer = pm.wire(high_res_blink_curve_up, groupWithBase=False, envelope=1, crossingEffect=0, localInfluence=0, wire=blink_height_curve.name())[0] main_lid_controllers[0].blink_height.set(1) low_blink_wire_deformer = pm.wire(high_res_blink_curve_down, groupWithBase=False, envelope=1, crossingEffect=0, localInfluence=0, wire=blink_height_curve.name())[0] main_lid_controllers[0].blink_height.set(0) up_blink_wire_deformer.setWireScale(0, 0) low_blink_wire_deformer.setWireScale(0, 0) blink_up_blend_shape = pm.blendShape(high_res_blink_curve_up, high_res_curve_up, name="%s_up_blink_shapes" % self.side_prefix) blink_down_blend_shape = pm.blendShape(high_res_blink_curve_down, high_res_curve_down, name="%s_down_blink_shapes" % self.side_prefix) pm.connectAttr( "%s.blink" % main_lid_controllers[0], "%s_up_blink_shapes.%s" % (self.side_prefix, high_res_blink_curve_up.name())) pm.connectAttr( "%s.blink" % main_lid_controllers[1], "%s_down_blink_shapes.%s" % (self.side_prefix, high_res_blink_curve_down.name())) pm.parent(eye_controller_group, self.head_controller) pm.parent(eye_controller_joint_group, self.do_not_touch_group) self.show_success_message("Phase 2 built successfully!") return "success"
def generateFollowPlane(self, *args): startTime = pm.playbackOptions(q=1, min=1) endTime = pm.playbackOptions(q=1, max=1) sel_list = pm.ls(sl=1, ni=1, type="transform") if not sel_list: pm.confirmDialog(message='请选择物体', button=['确定']) return for sel in sel_list: # snapshot = pm.snapshot(sel,st=startTime,et=endTime)[1] snapshot = pm.createNode("snapshot") sel.selectHandle.connect(snapshot.localPosition) sel.worldMatrix[0].connect(snapshot.inputMatrix) snapshot.startTime.set(startTime) snapshot.endTime.set(endTime) snapshot.increment.set(1) anim_curve = pm.curve(n=sel + "_follow_curve", d=3, p=snapshot.pts.get()) pm.delete(snapshot) curve_length = pm.arclen(anim_curve, ch=0) plane, plane_node = pm.polyPlane(n=sel + "_follow_plane", sx=20, sy=3, w=curve_length, h=20) # NOTE 创建运动路径跟随 motion_path = pm.pathAnimation( plane, anim_curve, fractionMode=1, follow=1, followAxis="x", upAxis="y", worldUpType="vector", worldUpVector=(0, 1, 0), inverseUp=0, inverseFront=0, bank=0, startTimeU=startTime, endTimeU=endTime, ) motion_path = pm.PyNode(motion_path) flow_node, ffd_node, lattice_node, ffd_base = pm.flow(plane, dv=(100, 2, 2)) # NOTE 设置外部影响 ffd_node.outsideLattice.set(1) ffd_node.local.set(1) plane_node.width.set(50) lattice_node.v.set(0) ffd_base.v.set(0) # NOTE 设置 Parametric Length 匹配位置 motion_path.fractionMode.set(0) animCurve = motion_path.listConnections(type="animCurve")[0] # NOTE 关键帧设置为线性 animCurve.setTangentTypes(range(animCurve.numKeys()), inTangentType="linear", outTangentType="linear") # NOTE 打组 pm.group(lattice_node, ffd_base, plane, anim_curve, n=sel + "_follow_grp") pm.select(plane)
def fk_ik_switch(attr_name): """ This module creates an fk_ik switch ctrl crv and also an attr for selected fk_ik switch :param attr_name: str, attribute name for the selected fk ik switch node :return: str, attribute values of the default selection and reverse of the selection """ switch_ctrl_name = 'fk_ik_master_switch_ctrl' if not pm.objExists(switch_ctrl_name): custom_crv('cross_crv', switch_ctrl_name, 4) top_grp = pm.group(switch_ctrl_name, n='{}_grp'.format(switch_ctrl_name)) pm.xform(top_grp, t=(15, 0, 15), s=(3, 3, 3)) sub_group(top_grp, None, 'main_ctrl', None) pm.setAttr('{}.translateX'.format(switch_ctrl_name), lock=True, k=False, cb=False) pm.setAttr('{}.translateY'.format(switch_ctrl_name), lock=True, k=False, cb=False) pm.setAttr('{}.translateZ'.format(switch_ctrl_name), lock=True, k=False, cb=False) pm.setAttr('{}.rotateX'.format(switch_ctrl_name), lock=True, k=False, cb=False) pm.setAttr('{}.rotateY'.format(switch_ctrl_name), lock=True, k=False, cb=False) pm.setAttr('{}.rotateZ'.format(switch_ctrl_name), lock=True, k=False, cb=False) pm.setAttr('{}.scaleX'.format(switch_ctrl_name), lock=True, k=False, cb=False) pm.setAttr('{}.scaleY'.format(switch_ctrl_name), lock=True, k=False, cb=False) pm.setAttr('{}.scaleZ'.format(switch_ctrl_name), lock=True, k=False, cb=False) pm.setAttr('{}.visibility'.format(switch_ctrl_name), lock=True, k=False, cb=False) pm.addAttr(switch_ctrl_name, ln='{}_switch'.format(attr_name), at='enum', en='FK:IK:') pm.setAttr('{}.{}_switch'.format(switch_ctrl_name, attr_name), e=True, k=True) pm.shadingNode('reverse', asUtility=True, name='{}_switch_rev'.format(attr_name)) pm.connectAttr('{}.{}_switch'.format(switch_ctrl_name, attr_name), '{}_switch_rev.ix'.format(attr_name)) return '{}.{}_switch'.format( switch_ctrl_name, attr_name), '{}_switch_rev.ox'.format(attr_name)
def squash_stretch_IK(*args): list_loc = pm.ls(sl=True) list_loc_number = len(list_loc) if pm.objExists('IK_spline_stretch_squash_bind_grp'): print 'group already exist' else: pm.group(em=True, n='IK_spline_stretch_squash_bind_grp', w=True) if pm.objExists('IK_spline_stretch_squash_IK_handle_grp'): print 'group already exist' else: pm.group(em=True, n='IK_spline_stretch_squash_IK_handle_grp', w=True) if pm.objExists('IK_spline_stretch_squash_curve_grp'): print 'group already exist' else: pm.group(em=True, n='IK_spline_stretch_squash_curve_grp', w=True) if pm.objExists('IK_spline_stretch_squash_loc_grp'): print 'group already exist' else: pm.group(em=True, n='IK_spline_stretch_squash_loc_grp', w=True) if pm.objExists('IK_spline_stretch_squash_joint_ctrl_grp'): print 'group already exist' else: pm.group(em=True, n='IK_spline_stretch_squash_joint_ctrl_grp', w=True) ''' Retreiving data entry ''' intFieldData_num_joint = pm.intField(intFieldEntry_num_joint, editable=True, query=True, value=True) textFieldData_ik_spline_name = pm.textField(textFieldEntry_ik_spline_name, editable=True, query=True, text=True) for loc_seq in range(1, list_loc_number + 1): if loc_seq == list_loc_number: print(list_loc[list_loc_number - 1]), 'is the final locator' pm.delete(list_loc[list_loc_number - 1]) break elif (intFieldData_num_joint % 2) > 0: print 'Input joint number is odd number' break else: if pm.objExists('{0}_{1}_IK_spline_loc_grp'.format( textFieldData_ik_spline_name, loc_seq)): print 'Naming error - system with same name exist' break else: pm.group(em=True, n='{0}_{1}_IK_spline_loc_grp'.format( textFieldData_ik_spline_name, loc_seq), w=True) pm.parent( '{0}_{1}_IK_spline_loc_grp'.format( textFieldData_ik_spline_name, loc_seq), 'IK_spline_stretch_squash_loc_grp') loc_first = list_loc[loc_seq - 1] loc_second = list_loc[loc_seq] loc_first_X = pm.getAttr(loc_first.translateX) loc_first_Y = pm.getAttr(loc_first.translateY) loc_first_Z = pm.getAttr(loc_first.translateZ) loc_second_X = pm.getAttr(loc_second.translateX) loc_second_Y = pm.getAttr(loc_second.translateY) loc_second_Z = pm.getAttr(loc_second.translateZ) loc_mid_tranX = loc_first_X + ((loc_second_X - loc_first_X) / 2) loc_mid_tranY = loc_first_Y + ((loc_second_Y - loc_first_Y) / 2) loc_mid_tranZ = loc_first_Z + ((loc_second_Z - loc_first_Z) / 2) loc_mid = pm.spaceLocator(n='{0}_{1}_02_trans_loc'.format( textFieldData_ik_spline_name, loc_seq)) pm.setAttr('{0}.tx'.format(loc_mid), (loc_mid_tranX)) pm.setAttr('{0}.ty'.format(loc_mid), (loc_mid_tranY)) pm.setAttr('{0}.tz'.format(loc_mid), (loc_mid_tranZ)) if loc_seq == 1: pm.rename( loc_first, '{0}_{1}_01_trans_loc'.format(textFieldData_ik_spline_name, loc_seq)) pm.rename( loc_second, '{0}_{1}_01_trans_loc'.format(textFieldData_ik_spline_name, loc_seq + 1)) else: pm.rename( loc_second, '{0}_{1}_01_trans_loc'.format(textFieldData_ik_spline_name, loc_seq + 1)) curve_path = pm.curve(d=1, p=[(loc_first_X, loc_first_Y, loc_first_Z), (loc_mid_tranX, loc_mid_tranY, loc_mid_tranZ), (loc_second_X, loc_second_Y, loc_second_Z) ]) ''' Method on reconstruct curve and rename ''' pm.rebuildCurve(curve_path, ch=1, rpo=1, rt=0, end=1, kr=0, kcp=0, kep=1, kt=0, s=intFieldData_num_joint, d=3, tol=0.0001) name_curve = pm.rename( curve_path, '{0}_{1}_ik_spline_curve'.format(textFieldData_ik_spline_name, loc_seq)) pre_joint = '' root_joint = '' for i in range(0, intFieldData_num_joint): user_default_unit = pm.currentUnit(query=True, linear=True) pm.currentUnit(linear='cm') pm.select(cl=True) new_joint = pm.joint() mot_path = pm.pathAnimation(new_joint, c=curve_path, fm=True) pm.cutKey(mot_path + '.u') pm.setAttr(mot_path + '.u', i * (1.0 / (intFieldData_num_joint - 1))) pm.delete('{0}.{1}'.format(new_joint, 'tx'), icn=True) pm.delete('{0}.{1}'.format(new_joint, 'ty'), icn=True) pm.delete('{0}.{1}'.format(new_joint, 'tz'), icn=True) pm.currentUnit(linear='{0}'.format(user_default_unit)) renaming_item = pm.ls(sl=True) if i == 0: pre_joint = new_joint root_joint = new_joint pm.rename( renaming_item, '{0}_{1}_{2:02d}_IK_spline_bind'.format( textFieldData_ik_spline_name, loc_seq, i + 1)) continue elif i == intFieldData_num_joint - 1: pm.rename( renaming_item, '{0}_{1}_{2:02d}_IK_spline_waste'.format( textFieldData_ik_spline_name, loc_seq, i + 1)) else: pm.rename( renaming_item, '{0}_{1}_{2:02d}_IK_spline_bind'.format( textFieldData_ik_spline_name, loc_seq, i + 1)) pm.parent(new_joint, pre_joint) pre_joint = new_joint pm.joint(root_joint, e=True, zso=True, oj='xyz', ch=True, sao='yup') stretch_squash_ik_handle = pm.ikHandle( sol='ikSplineSolver', pcv=False, ccv=False, c=curve_path, roc=True, ns=2, sj=('{0}_{1}_01_IK_spline_bind'.format( textFieldData_ik_spline_name, loc_seq)), ee=('{0}_{1}_{2:02d}_IK_spline_bind'.format( textFieldData_ik_spline_name, loc_seq, intFieldData_num_joint - 1)), n='{0}_{1}_IK_spline'.format(textFieldData_ik_spline_name, loc_seq)) pre_joint = '' root_joint = '' for i in range(0, 3): user_default_unit = pm.currentUnit(query=True, linear=True) pm.currentUnit(linear='cm') pm.select(cl=True) new_joint = pm.joint() mot_path = pm.pathAnimation(new_joint, c=curve_path, fm=True) pm.cutKey(mot_path + '.u') pm.setAttr(mot_path + '.u', i * (1.0 / 2)) pm.delete('{0}.{1}'.format(new_joint, 'tx'), icn=True) pm.delete('{0}.{1}'.format(new_joint, 'ty'), icn=True) pm.delete('{0}.{1}'.format(new_joint, 'tz'), icn=True) pm.currentUnit(linear='{0}'.format(user_default_unit)) renaming_item = pm.ls(sl=True) if i == 0: pre_joint = new_joint root_joint = new_joint pm.rename( renaming_item, '{0}_{1}_{2:02d}_IK_spline_joint_ctrl'.format( textFieldData_ik_spline_name, loc_seq, i + 1)) else: pm.rename( renaming_item, '{0}_{1}_{2:02d}_IK_spline_joint_ctrl'.format( textFieldData_ik_spline_name, loc_seq, i + 1)) for n in renaming_item: pm.group(em=True, name='empty') pm.parent('empty', n) pm.setAttr('empty.translateX', 0) pm.setAttr('empty.translateY', 0) pm.setAttr('empty.translateZ', 0) pm.setAttr('empty.rotateX', 0) pm.setAttr('empty.rotateY', 0) pm.setAttr('empty.rotateZ', 0) pm.parent('empty', world=True) pm.parent(n, 'empty') for n in renaming_item: newname = n.split('_') number_name = len(newname) new_name_first = newname[0] + '_' for i in range(0, number_name): if i > number_name - 3 or i == number_name - 3: new_name = new_name_first print 'naming error' break else: if i < number_name - 3: new_name_second = newname[i + 1] + '_' new_name = new_name_first + new_name_second new_name_first = new_name else: break pm.rename('empty', new_name + 'joint_ctrl_pad') stretch_squash_joint_ctrl_grp = pm.group( '{0}_{1}_01_IK_spline_joint_ctrl_pad'.format( textFieldData_ik_spline_name, loc_seq), '{0}_{1}_02_IK_spline_joint_ctrl_pad'.format( textFieldData_ik_spline_name, loc_seq), '{0}_{1}_03_IK_spline_joint_ctrl_pad'.format( textFieldData_ik_spline_name, loc_seq), n='{0}_{1}_IK_spline_joint_ctrl_grp'.format( textFieldData_ik_spline_name, loc_seq)) loc_first_rot = pm.duplicate(loc_first, n='{0}_{1}_01_rot_loc'.format( textFieldData_ik_spline_name, loc_seq)) loc_mid_rot = pm.duplicate(loc_mid, n='{0}_{1}_02_rot_loc'.format( textFieldData_ik_spline_name, loc_seq)) loc_second_trans = pm.duplicate(loc_second, n='{0}_{1}_03_trans_loc'.format( textFieldData_ik_spline_name, loc_seq)) loc_second_rot = pm.duplicate(loc_second, n='{0}_{1}_03_rot_loc'.format( textFieldData_ik_spline_name, loc_seq)) pm.parent(loc_first_rot, loc_first) pm.parent(loc_mid_rot, loc_mid) pm.parent(loc_second_rot, loc_second_trans[0]) pm.select(loc_first, loc_mid, loc_second_trans[0]) list_loc_trans = pm.ls(sl=True) number_loc_trans = len(list_loc_trans) for n in list_loc_trans: pm.group(em=True, name='empty') pm.parent('empty', n) pm.setAttr('empty.translateX', 0) pm.setAttr('empty.translateY', 0) pm.setAttr('empty.translateZ', 0) pm.setAttr('empty.rotateX', 0) pm.setAttr('empty.rotateY', 0) pm.setAttr('empty.rotateZ', 0) pm.parent('empty', world=True) pm.parent(n, 'empty') newname = n.split('_') number_name = len(newname) new_name_first = newname[0] + '_' for i in range(0, number_name): if i > number_name - 1 or i == number_name - 1: new_name = new_name_first print 'naming error' break else: if i < number_name - 1: new_name_second = newname[i + 1] + '_' new_name = new_name_first + new_name_second new_name_first = new_name else: break pm.rename('empty', new_name + 'pad') pm.parent( '{0}_{1}_01_trans_loc_pad'.format(textFieldData_ik_spline_name, loc_seq), '{0}_{1}_02_trans_loc_pad'.format(textFieldData_ik_spline_name, loc_seq), '{0}_{1}_03_trans_loc_pad'.format(textFieldData_ik_spline_name, loc_seq), '{0}_{1}_IK_spline_loc_grp'.format( textFieldData_ik_spline_name, loc_seq)) pm.aimConstraint(loc_first, loc_mid_rot) pm.aimConstraint(loc_mid, loc_first_rot) pm.aimConstraint(loc_mid, loc_second_rot) pm.pointConstraint(loc_first, loc_second_trans[0], (loc_mid + '_pad')) pm.pointConstraint(loc_first, '{0}_{1}_01_IK_spline_joint_ctrl'.format( textFieldData_ik_spline_name, loc_seq), mo=True) pm.pointConstraint(loc_mid, '{0}_{1}_02_IK_spline_joint_ctrl'.format( textFieldData_ik_spline_name, loc_seq), mo=True) pm.pointConstraint(loc_second_trans[0], '{0}_{1}_03_IK_spline_joint_ctrl'.format( textFieldData_ik_spline_name, loc_seq), mo=True) pm.orientConstraint(loc_first_rot, '{0}_{1}_01_IK_spline_joint_ctrl'.format( textFieldData_ik_spline_name, loc_seq), mo=True) pm.orientConstraint(loc_mid_rot, '{0}_{1}_02_IK_spline_joint_ctrl'.format( textFieldData_ik_spline_name, loc_seq), mo=True) pm.orientConstraint(loc_second_rot, '{0}_{1}_03_IK_spline_joint_ctrl'.format( textFieldData_ik_spline_name, loc_seq), mo=True) curve_length_node = pm.createNode('curveInfo', n='{0}curve_length_{1}'.format( new_name, loc_seq)) pm.connectAttr('{0}.worldSpace[0]'.format(curve_path), '{0}.inputCurve'.format(curve_length_node)) curve_arc_length = pm.getAttr( '{0}.arcLength'.format(curve_length_node)) ratio_curve_stretch = pm.createNode( 'multiplyDivide', n='{0}ratio_curve_stretch_{1}'.format(new_name, loc_seq)) pm.setAttr('{0}.operation'.format(ratio_curve_stretch), 2) pm.connectAttr('{0}.arcLength'.format(curve_length_node), '{0}.input1X'.format(ratio_curve_stretch)) pm.setAttr('{0}.input2X'.format(ratio_curve_stretch), curve_arc_length) ratio_curve_squash = pm.createNode( 'multiplyDivide', n='{0}ratio_curve_squash_{1}'.format(new_name, loc_seq)) pm.setAttr('{0}.operation'.format(ratio_curve_squash), 2) pm.connectAttr('{0}.arcLength'.format(curve_length_node), '{0}.input2X'.format(ratio_curve_squash)) pm.setAttr('{0}.input1X'.format(ratio_curve_squash), curve_arc_length) exp_squash = pm.createNode('multiplyDivide', n='{0}exp_squash_{1}'.format( new_name, loc_seq)) pm.setAttr('{0}.operation'.format(exp_squash), 2) pm.setAttr('{0}.input2X'.format(exp_squash), intFieldData_num_joint - 1) for number_joint in range(0, intFieldData_num_joint - 1): pm.connectAttr( '{0}.outputX'.format(ratio_curve_stretch), '{0}_{1}_{2:02d}_IK_spline_bind.scaleX'.format( textFieldData_ik_spline_name, loc_seq, number_joint + 1)) exp_squash_plus = pm.createNode( 'plusMinusAverage', n='{0}exp_squash_plus_0{1}_{2}'.format( new_name, number_joint + 1, loc_seq)) pm.setAttr('{0}.input1D[0]'.format(exp_squash_plus), 1) if number_joint < (intFieldData_num_joint / 2): pm.setAttr('{0}.operation'.format(exp_squash_plus), 1) else: pm.setAttr('{0}.operation'.format(exp_squash_plus), 2) if number_joint == 0: print 'do nothing' elif number_joint > 0: pm.connectAttr('{0}.outputX'.format(exp_squash), '{0}.input1D[1]'.format(exp_squash_plus)) pm.connectAttr( '{0}exp_squash_plus_0{1}_{2}.output1D'.format( new_name, number_joint, loc_seq), '{0}.input1D[0]'.format(exp_squash_plus)) power_curve_squash = pm.createNode( 'multiplyDivide', n='{0}power_curve_squash_0{1}_{2}'.format( new_name, number_joint + 1, loc_seq)) pm.setAttr('{0}.operation'.format(power_curve_squash), 3) pm.connectAttr('{0}.outputX'.format(ratio_curve_squash), '{0}.input1X'.format(power_curve_squash)) pm.connectAttr('{0}.output1D'.format(exp_squash_plus), '{0}.input2X'.format(power_curve_squash)) pm.connectAttr( '{0}.outputX'.format(power_curve_squash), '{0}_{1}_{2:02d}_IK_spline_bind.scaleY'.format( textFieldData_ik_spline_name, loc_seq, number_joint + 1)) pm.connectAttr( '{0}.outputX'.format(power_curve_squash), '{0}_{1}_{2:02d}_IK_spline_bind.scaleZ'.format( textFieldData_ik_spline_name, loc_seq, number_joint + 1)) pm.skinCluster( '{0}_{1}_01_IK_spline_joint_ctrl'.format( textFieldData_ik_spline_name, loc_seq), '{0}_{1}_02_IK_spline_joint_ctrl'.format( textFieldData_ik_spline_name, loc_seq), '{0}_{1}_03_IK_spline_joint_ctrl'.format( textFieldData_ik_spline_name, loc_seq), '{0}_{1}_ik_spline_curve'.format(textFieldData_ik_spline_name, loc_seq)) pm.parent(curve_path, 'IK_spline_stretch_squash_curve_grp') pm.parent( '{0}_{1}_01_IK_spline_bind'.format( textFieldData_ik_spline_name, loc_seq), 'IK_spline_stretch_squash_bind_grp') pm.parent( '{0}_{1}_IK_spline'.format(textFieldData_ik_spline_name, loc_seq), 'IK_spline_stretch_squash_IK_handle_grp') pm.parent(stretch_squash_joint_ctrl_grp, 'IK_spline_stretch_squash_joint_ctrl_grp')
def build(name=None, crv=None, reg_node=None, log=False): '''Create ine node deformer and attributes on given plane, and IK control connected to the reg_node. name -- Prefix name. Str crv -- Curve to add deformer to. nt.Transform reg_node -- registration node. nt.Transform ''' general.check_type(name, 'name', [str]) general.check_type(crv, 'crv', [pm.nt.Transform]) general.check_type(reg_node, 'reg_node', [pm.nt.Transform]) cnt_attr = '%s1_ik_cnt' % name if not hasattr(reg_node, cnt_attr): raise errors.InputError('reg_node', reg_node, 'Missing attr: %s' % cnt_attr) attr = getattr(reg_node, cnt_attr) cnt = attr.listConnections()[0] if log: str_1 = 'Cnt: ', cnt general.logging.debug(str_1) crv2 = crv.duplicate() sineDef, sineHndl = pm.nonLinear(crv2, typ='sine', name='%s_sineDeformer' % name) bs = pm.blendShape(crv2, crv, foc=True, name='%s_sineBlendShape' % name)[0] attr = getattr(bs, crv2[0].name()) attr.set(1) sineDef.rename('%s_sineDeformer' % name) sineHndl.rename('%s_sineDeformerHandle' % name) attrs = { 'sineOffOn': [1, 0, 1], 'amplitude': 0.3, 'wavelength': 2, 'offset': 0, 'direction': 0 } for attr in attrs.keys(): if isinstance(attrs[attr], list): pm.addAttr(cnt, ln=attr, dv=attrs[attr][0], min=attrs[attr][1], max=attrs[attr][2], k=1) else: pm.addAttr(cnt, ln=attr, dv=attrs[attr], k=1) cnt.sineOffOn >> sineDef.envelope cnt.amplitude >> sineDef.amplitude cnt.wavelength >> sineDef.wavelength cnt.offset >> sineDef.offset cnt.direction >> sineHndl.rotateY # Setup the handle hndl_grp = pm.group(name='%s_hndlGrp' % name, em=1) pm.parent(sineHndl, hndl_grp) sineHndl.rz.set(180) sineDef.dropoff.set(1) sineDef.lowBound.set(0) sineDef.highBound.set(2) control.register_object(reg_node, 'sine_handle', sineHndl) return reg_node
def bdRigLegBones(side): ikAnimCon = pm.ls(side.upper() + '_Foot_CON', type='transform')[0] legBonesNames = ['Thigh', 'Shin', 'Foot', 'Toe'] legBones = [] for bone in legBonesNames: legBone = pm.ls(side + bone)[0] legBones.append(legBone) print legBone.name() toeEnd = pm.ls(side + 'Toe_end')[0] legBones.append(toeEnd) # START setup foot roll footIk = pm.ikHandle(sol='ikRPsolver', sticky='sticky', startJoint=legBones[0], endEffector=legBones[2], name=side + '_foot_ikHandle')[0] footIk.visibility.set(0) ballIk = pm.ikHandle(sol='ikSCsolver', sticky='sticky', startJoint=legBones[2], endEffector=legBones[3], name=side + '_ball_ikHandle')[0] ballIk.visibility.set(0) toeIk = pm.ikHandle(sol='ikSCsolver', sticky='sticky', startJoint=legBones[3], endEffector=legBones[4], name=side + '_toe_ikHandle')[0] toeIk.visibility.set(0) # create the groups that will controll the foot animations ( roll, bend, etc etc) footHelpers = pm.ls(side + '*_helper', type='transform') ankleLoc = bdCreateOffsetLoc(legBones[2], side + '_ankle_loc') footLoc = bdCreateOffsetLoc(legBones[2], side + '_foot_loc') ballLoc = bdCreateOffsetLoc(legBones[3], side + '_ball_loc') ballTwistLoc = bdCreateOffsetLoc(legBones[3], side + '_ball_twist_loc') toeLoc = bdCreateOffsetLoc(legBones[4], side + '_toe_loc') toeBendLoc = bdCreateOffsetLoc(legBones[3], side + '_toe_bend_loc') innerLoc = outerLoc = heelLoc = '' for helper in footHelpers: if 'inner' in helper.name(): innerLoc = bdCreateOffsetLoc(helper, side + '_inner_bank_loc') elif 'outer' in helper.name(): outerLoc = bdCreateOffsetLoc(helper, side + '_outer_bank_loc') elif 'heel' in helper.name(): heelLoc = bdCreateOffsetLoc(helper, side + '_heel_loc') # pm.delete(footHelpers) pm.parent(footIk, footLoc) pm.parent(ballIk, ballLoc) pm.parent(toeIk, toeBendLoc) pm.parent(toeBendLoc, toeLoc) pm.parent(footLoc, ballLoc) pm.parent(ballLoc, toeLoc) pm.parent(toeLoc, ballTwistLoc) pm.parent(ballTwistLoc, innerLoc) pm.parent(innerLoc, outerLoc) pm.parent(outerLoc, heelLoc) pm.parent(heelLoc, ankleLoc) # add atributes on the footGrp - will be conected later to an anim controler autoRollAttrList = ['Roll', 'ToeStart', 'BallStraight'] footAttrList = [ 'HeelTwist', 'BallTwist', 'TipTwist', 'Bank', 'ToeBend', 'KneeTwist' ] normalRollAttrList = ['HeelRoll', 'BallRoll', 'TipRoll'] pm.addAttr(ikAnimCon, ln='__AutoFootRoll__', nn='__AutoFootRoll__', at='bool') ikAnimCon.attr('__AutoFootRoll__').setKeyable(True) ikAnimCon.attr('__AutoFootRoll__').setLocked(True) pm.addAttr(ikAnimCon, ln='Enabled', nn='Enabled', at='long') ikAnimCon.attr('Enabled').setKeyable(True) ikAnimCon.attr('Enabled').setMin(0) ikAnimCon.attr('Enabled').setMax(1) ikAnimCon.attr('Enabled').set(1) pm.addAttr(ikAnimCon, ln='______', nn='______', at='bool') ikAnimCon.attr('______').setKeyable(True) ikAnimCon.attr('______').setLocked(True) for attr in autoRollAttrList: pm.addAttr(ikAnimCon, ln=attr, nn=attr, at='float') ikAnimCon.attr(attr).setKeyable(True) pm.addAttr(ikAnimCon, ln='__FootRoll__', nn='__FootRoll__', at='bool') ikAnimCon.attr('__FootRoll__').setKeyable(True) ikAnimCon.attr('__FootRoll__').setLocked(True) for attr in normalRollAttrList: pm.addAttr(ikAnimCon, ln=attr, nn=attr, at='float') ikAnimCon.attr(attr).setKeyable(True) pm.addAttr(ikAnimCon, ln='__FootAttr__', nn='__FootAttr__', at='bool') ikAnimCon.attr('__FootAttr__').setKeyable(True) ikAnimCon.attr('__FootAttr__').setLocked(True) for attr in footAttrList: pm.addAttr(ikAnimCon, ln=attr, nn=attr, at='float') ikAnimCon.attr(attr).setKeyable(True) ikAnimCon.attr('ToeStart').set(40) ikAnimCon.attr('BallStraight').set(80) bdCreateReverseFootRoll(ikAnimCon, heelLoc, ballLoc, toeLoc) # connect the attributes ikAnimCon.attr('HeelTwist').connect(heelLoc.rotateY) ikAnimCon.attr('BallTwist').connect(ballTwistLoc.rotateY) ikAnimCon.attr('TipTwist').connect(toeLoc.rotateY) ikAnimCon.attr('ToeBend').connect(toeBendLoc.rotateX) bdConnectBank(ikAnimCon, innerLoc, outerLoc) # START no flip knee knee mirror = 1 if side == 'r': mirror = -1 offset = 90 poleVectorLoc = pm.spaceLocator(name=side + '_knee_loc_PV') poleVectorLocGrp = pm.group(poleVectorLoc, n=poleVectorLoc + '_GRP') thighPos = legBones[0].getTranslation(space='world') poleVectorLocGrp.setTranslation( [thighPos[0] + mirror * 5, thighPos[1], thighPos[2]]) pm.poleVectorConstraint(poleVectorLoc, footIk) adlNode = pm.createNode('addDoubleLinear', name=side + '_adl_twist') adlNode.input2.set(mirror * offset) ikAnimCon.attr('KneeTwist').connect(adlNode.input1) adlNode.output.connect(footIk.twist) startTwist = mirror * offset limit = 0.001 increment = mirror * 0.01 while True: pm.select(cl=True) thighRot = pm.xform(legBones[0], q=True, ro=True, os=True) print thighRot[0] if ((thighRot[2] > limit)): startTwist = startTwist - increment adlNode.input2.set(startTwist) else: break # END knee pm.parent(ankleLoc, ikAnimCon)
def setUp(self): self.node = pm.group(em=True)
def makeIkFkJoints(joints, attribute=None, stretchy=False, jointPrefix='rig', ikJointPrefix='ikj', fkJointPrefix='fkj'): """ Creates 2 duplicate hierarchies from passed in joints (please make sure the list of joints are in same hierarchy) Blender is connected to attribute If stretchy is true, translation is connected for all the joints, except the root joint """ startJoint = joints[0] rootRotation = startJoint.getRotation('world') rootTranslation = startJoint.getTranslation('world') # pymel bug, duplicating without renaming may result in some console warnings and errors # use a temp name until we learn the actual names for each joints fkJoints = pmc.duplicate(joints, parentOnly=True, name='fkTEMP') # FK Joint setup # Use our prefix to uniquely rename duplicated joints based on the original copy # third parameter in jnt.replace allows me to limit the number of string replacements, # so I can avoid renaming joints containing 'right' in their name (I'm using 'rig' as my joint prefix) for jnt, fkj in izip(joints, fkJoints): fkj.rename(jnt.replace(jointPrefix, fkJointPrefix, 1)) # Self grouping the duplicated FK root joint # Remember to not freeze transforms to ensure a proper connection to the original fkGrp = pmc.group(empty=True, name='grp_fk_{0}_joints'.format(fkJoints[0].shortName())) fkGrp.setRotation(rootRotation, 'world') fkGrp.setTranslation(rootTranslation, 'world') # Could use a parent constrain here instead to the first parent # I prefer pointOrient for the extra control and future proofing parent = startJoint.firstParent2() if parent: pmc.parentConstraint(parent, fkGrp, maintainOffset=True) pmc.parent(fkJoints[0], fkGrp) # IK Joint setup # Mostly the same code, this could be remade into a simpler function ikJoints = pmc.duplicate(joints, parentOnly=True, name='ikTEMP') for jnt, ikj in izip(joints, ikJoints): ikj.rename(jnt.replace(jointPrefix, ikJointPrefix, 1)) ikGrp = pmc.group(empty=True, name='grp_ik_{0}_joints'.format(ikJoints[0].shortName())) ikGrp.setRotation(rootRotation, 'world') ikGrp.setTranslation(rootTranslation, 'world') if parent: pmc.parentConstraint(parent, ikGrp, maintainOffset=True) pmc.parent(ikJoints[0], ikGrp) # we may have a attribute that goes between 0-1, 0-10 or even 0-100 # Create remapValue node to help us remap the value, if needed outputAttr = None if attribute: if isinstance(attribute, basestring): outputAttr = pmc.Attribute(attribute) else: outputAttr = attribute attrMaxValue = outputAttr.getMax() if attrMaxValue > 1.0: attrNormalizeNode = pmc.shadingNode( 'remapValue', asUtility=True, name='rmv_{0}_ikfk_attr'.format(startJoint.shortName())) pmc.connectAttr(attribute, attrNormalizeNode.inputValue) attrNormalizeNode.inputMax.set(attrMaxValue) outputAttr = attrNormalizeNode.outValue # Connecting duplicate joint chains to original hierarchy # enumerate gives me an index, plus the joint to work with blendNodes = list() for i, jnt in enumerate(joints): fkJoint = fkJoints[i] ikJoint = ikJoints[i] # For this example, I connect my IKFK chains using blendColors nodes. # Using constraints instead is fine, but in place of this code, # you'll instead be connecting to the constraint's # weight values blender = pmc.shadingNode('blendColors', asUtility=True, name='bln_{0}_ikfk'.format(jnt.shortName())) blender.output.connect(jnt.rotate) fkJoint.rotate.connect(blender.color1) ikJoint.rotate.connect(blender.color2) blendNodes.append(blender) # Stretching joints by using X translation, # simpler to deal with and causes the least amount of headaches if stretchy is not None and jnt != startJoint: stretchyblender = pmc.shadingNode( 'blendColors', asUtility=True, name='bln_{0}_ikfk_stretch'.format(jnt.shortName())) fkJoint.translateX.connect(stretchyblender.color1R) ikJoint.translateX.connect(stretchyblender.color2R) stretchyblender.outputR.connect(jnt.translateX) blendNodes.append(stretchyblender) for bln in blendNodes: if outputAttr: outputAttr.connect(bln.blender) else: bln.blender.set(0) pmc.select(clear=True) return ikGrp, fkGrp, blendNodes
# coding:utf-8 __author__ = 'timmyliang' __email__ = '*****@*****.**' __date__ = '2019-11-20 10:08:56' """ 获取曲线 ControlPoint 的位置 """ import pymel.core as pm if __name__ == "__main__": jnt_list = pm.ls(sl=1, type="joint") crv = pm.curve(p=[jnt.getTranslation() for jnt in jnt_list]) pm.closeCurve(crv, ch=0, rpo=1) info = pm.createNode("curveInfo") crv.worldSpace[0].connect(info.inputCurve) for i, jnt in enumerate(jnt_list): loc = pm.spaceLocator(n="%s_loc" % jnt) loc.setParent(crv) loc.v.set(0) info.controlPoints[i].connect(loc.t) grp = pm.group(jnt, n="%s_crv_loc" % jnt) pm.parentConstraint(loc, grp, mo=1)
def generateControlRig(self, *args): global_grp = pm.group(em=1, n='global_node') ctrls_grp = pm.group(em=1, n='ctrls_grp') iks_grp = pm.group(em=1, n='iks_grp') jts_grp = pm.group(em=1, n='jts_grp') self.generateHipCtrls(self.ikfk) self.generateSpineCtrls() self.generateShoulderCtrls() self.generateHandControls() self.generateNeckHeadCtrls() l_knee_ctrl = self.generatePoleVectorCtrl('l', self.l_legJoints[0:3], self.l_leg_ikHandle[0]) r_knee_ctrl = self.generatePoleVectorCtrl('r', self.r_legJoints[0:3], self.r_leg_ikHandle[0]) l_elbow_ctrl = self.generatePoleVectorCtrl('l', self.l_armJoints[1:4], self.l_arm_ikHandle[0], _ctrlDist=5) r_elbow_ctrl = self.generatePoleVectorCtrl('r', self.r_armJoints[1:4], self.r_arm_ikHandle[0], _ctrlDist=5) self.generateFootCtrls() self.generateLegCtrls() self.generateClavCtrls() worldCtrl_rad = self.distanceBetween( pm.PyNode(self.l_legJoints[2]).getTranslation(space='world'), pm.PyNode(self.r_legJoints[2]).getTranslation(space='world')) self.world_ctrl = pm.circle(c=[0, 0, 0], n='world_ctrl', nr=[0, 1, 0], r=worldCtrl_rad) self.world_ctrl[0].getShape().overrideEnabled.set(True) self.world_ctrl[0].getShape().overrideColor.set(18) pm.parent(self.world_ctrl[0], ctrls_grp) if self.ikfk: self.generateArmCtrls() pm.parent(self.l_foot_grp, self.world_ctrl[0]) pm.parent(self.r_foot_grp, self.world_ctrl[0]) else: pm.parent(self.r_footCtrl[0].getParent(), self.world_ctrl[0]) pm.parent(self.l_footCtrl[0].getParent(), self.world_ctrl[0]) pm.parent(self.spineCtrls[0][0].getParent(), self.hip_ctrl[0]) pm.parent(self.hip_ctrl[0].getParent(), self.world_ctrl[0]) pm.parent(l_knee_ctrl, self.world_ctrl[0]) pm.parent(r_knee_ctrl, self.world_ctrl[0]) pm.parent(l_elbow_ctrl, self.world_ctrl[0]) pm.parent(r_elbow_ctrl, self.world_ctrl[0]) pm.parent(ctrls_grp, global_grp) pm.parent(self.l_arm_ikHandle[0], self.l_leg_ikHandle[0], self.r_arm_ikHandle[0], self.r_leg_ikHandle[0], iks_grp) pm.parent(iks_grp, global_grp) pm.parent(self.spineJoints[1], jts_grp) pm.parent(jts_grp, global_grp) pm.parent(self.l_hand_grp, self.world_ctrl[0]) pm.parent(self.r_hand_grp, self.world_ctrl[0]) pm.scaleConstraint(self.world_ctrl[0], jts_grp) fkAttrs = ['tx', 'ty', 'tz', 'sx', 'sy', 'sz'] scaleAttrs = ['sx', 'sy', 'sz'] for i in self.spineCtrls: self.lockHideAttr(i[0], fkAttrs) if self.ikfk: for i in self.l_leg_ctrls: self.lockHideAttr(i[0], fkAttrs) for i in self.r_leg_ctrls: self.lockHideAttr(i[0], fkAttrs) for i in self.l_arm_ctrls: self.lockHideAttr(i[0], fkAttrs) for i in self.r_arm_ctrls: self.lockHideAttr(i[0], fkAttrs) self.lockHideAttr(self.shoulder_ctrl[0], fkAttrs) self.lockHideAttr(self.hipsRotate_ctrl[0], fkAttrs) self.lockHideAttr(self.l_hand_ctrl[0], scaleAttrs) self.lockHideAttr(self.r_hand_ctrl[0], scaleAttrs) self.lockHideAttr(self.l_footCtrl[0], scaleAttrs) self.lockHideAttr(self.r_footCtrl[0], scaleAttrs) self.lockHideAttr(self.l_clav_ctrl[0], fkAttrs) self.lockHideAttr(self.r_clav_ctrl[0], fkAttrs) self.lockHideAttr(self.hip_ctrl[0], scaleAttrs) self.lockHideAttr(self.neck_ctrl[0], fkAttrs) self.lockHideAttr(self.head_ctrl[0], fkAttrs) ctrls = pm.listRelatives(ctrls_grp, ad=1) locAttrs = ['tx', 'ty', 'tz', 'rx', 'ry', 'rz', 'sx', 'sy', 'sz'] for i in ctrls: trans = pm.listRelatives(i, typ='transform', p=1, fullPath=1) if 'LocAlign_' in str(trans): self.lockHideAttr(trans[0], locAttrs) trans[0].overrideEnabled.set(True) trans[0].localScale.set([0, 0, 0])
def SinglePropRig(scene_object, referencePositionControl, centerPivot=False): #if Object.__class__ == list : #elif Object.__class__ in [str,unicode]: GRS = RMGenericRigStructure.genericRigStructure() NameConv = nameConvention.NameConvention() bbMesh = RMRigTools.boundingBoxInfo(scene_object) CtrlPosition = pm.xform(referencePositionControl, q=True, rp=True, worldSpace=True) NameList = scene_object.split(".") cntrlToMeshX = bbMesh.position[0] - CtrlPosition[0] cntrlToMeshY = bbMesh.position[1] - CtrlPosition[1] cntrlToMeshZ = bbMesh.position[2] - CtrlPosition[2] if len(NameList) > 1: Ctrl = RMRigShapeControls.RMCreateCubeLine( bbMesh.lenX, bbMesh.lenY, bbMesh.lenZ, offsetX=-bbMesh.minDistanceToCenterX + cntrlToMeshX, offsetY=-bbMesh.minDistanceToCenterY + bbMesh.lenY / 2 + cntrlToMeshY, offsetZ=-bbMesh.minDistanceToCenterZ + bbMesh.lenZ / 2 + cntrlToMeshZ, name=NameList[1]) if centerPivot == True: pm.xform(Ctrl, cp=1) joint = pm.joint(name=NameList[1] + "jnt") else: Ctrl = RMRigShapeControls.RMCreateCubeLine( bbMesh.lenX, bbMesh.lenY, bbMesh.lenZ, offsetX=-bbMesh.minDistanceToCenterX + cntrlToMeshX, offsetY=-bbMesh.minDistanceToCenterY + bbMesh.lenY / 2 + cntrlToMeshY, offsetZ=-bbMesh.minDistanceToCenterZ + bbMesh.lenZ / 2 + cntrlToMeshZ, name=NameList[0] + "Ctrl") if centerPivot == True: pm.xform(Ctrl, cp=1) joint = pm.joint(name=NameList[0] + "jnt") Ctrl = NameConv.rename_name_in_format(Ctrl, {'objectType': "control"}) ResetGroup = RMRigTools.RMCreateGroupOnObj(Ctrl) pm.parent(ResetGroup, GRS.groups["controls"]["group"]) rigJntGrp = pm.ls("*SimpleRigJoints*") if len(rigJntGrp) == 0: jointGroup = pm.group(empty=True, name="SimpleRigJoints") jointGroup = NameConv.rename_name_in_format(jointGroup, {}) pm.parent(jointGroup, GRS.groups["rig"]['group']) else: jointGroup = rigJntGrp if centerPivot != True: RMRigTools.RMAlign(referencePositionControl, ResetGroup, 3) joint = NameConv.rename_name_in_format(joint, {}) RMRigTools.RMAlign(referencePositionControl, joint, 3) ResetJoint = RMRigTools.RMCreateGroupOnObj(joint) pm.parent(ResetJoint, jointGroup) #if pm.objExists #for eachObject in Object: pm.parentConstraint(Ctrl, joint) pm.skinCluster(joint, scene_object)
def doRig(self, iniOffset=False): #grupos if pm.objExists(self.name+'stickyLip_sys'): pm.delete(self.name+'SkinJxts_grp') if pm.objExists(self.name+'DriverJoints_grp'): pm.delete(self.name+'DriverJoints_grp') if pm.objExists(self.name+'SkinJoints_grp'): pm.delete(self.name+'SkinJoints_grp') stickLipSysGrp = pm.group(em=True, name=self.name+'stickyLip_sys') driverJointsGrp = pm.group(em=True, name=self.name + 'DriverJoints_grp', p=stickLipSysGrp) skinJointsGrp = pm.group(em=True, name=self.name + 'SkinJoints_grp', p=stickLipSysGrp) ## do joints pos = pm.xform(self.upCorner, q=True, ws=True, t=True) pm.select(cl=True) jntUpper = pm.joint(n='Mid_upper') pm.xform(jntUpper, t=pos, ws=True) pos = pm.xform(self.lowCorner, q=True, ws=True, t=True) pm.select(cl=True) jntLower = pm.joint(n='Mid_lower') pm.xform(jntLower, t=pos, ws=True) L_edge = vtxWalk.getLoopByLocators(mesh=self.mesh, loc1=self.upCorner, loc2=self.lowCorner, loc3=self.outCorner) L_vertices = vtxWalk.edgeLoopToVextex(L_edge) #get corner pos again, because it can be tweaked cornerPos = pm.xform(self.outCorner, q=True, ws=True, t=True) cornerVertex = vtxWalk.getClosestVertex(mesh=self.mesh, pos=cornerPos) cornerIndex = L_vertices.index(cornerVertex) def createJointsOnVertices(name=None, verticesList=None): jointList = [] for i, vtx in enumerate(verticesList): pm.select(cl=True) jnt = pm.joint(n=name + str(i)) pos = pm.xform(vtx, q=True, t=True, ws=True) pm.xform(jnt, t=pos, ws=True) jointList.append(jnt) return jointList L_jointsUp = createJointsOnVertices(name='L_upper', verticesList=L_vertices[1:cornerIndex]) L_jointsUp.reverse() L_jointsLw = createJointsOnVertices(name='L_lower', verticesList=L_vertices[cornerIndex+1:-1]) R_edge = vtxWalk.getLoopByLocators(mesh=self.mesh, loc1=self.upCorner, loc2=self.lowCorner, loc3=self.inCorner) R_vertices = vtxWalk.edgeLoopToVextex(R_edge) #get corner pos again, because it can be tweaked cornerPos = pm.xform(self.inCorner, q=True, ws=True, t=True) cornerVertex = vtxWalk.getClosestVertex(mesh=self.mesh, pos=cornerPos) cornerIndex = R_vertices.index(cornerVertex) R_jointsUp = createJointsOnVertices(name='R_upper', verticesList=R_vertices[cornerIndex+1:-1]) R_jointsLw = createJointsOnVertices(name='R_lower', verticesList=R_vertices[1:cornerIndex]) R_jointsLw.reverse() pm.parent(jntLower, jntUpper, R_jointsLw, R_jointsUp, L_jointsUp, L_jointsLw, driverJointsGrp) ## init variaveis iniOffset = True self.L_ctrl = pm.spaceLocator(n='L_sticky_ctrl') self.R_ctrl = pm.spaceLocator(n='R_sticky_ctrl') pm.parent(self.L_ctrl, self.R_ctrl, stickLipSysGrp) self.L_ctrl.addAttr('sticky', at='float', k=1, dv=0, min=0) self.R_ctrl.addAttr('sticky', at='float', k=1, dv=0, min=0) self.L_ctrl.addAttr('offset', at='float', k=1, dv=0, min=0) self.R_ctrl.addAttr('offset', at='float', k=1, dv=0, min=0) self.L_ctrl.addAttr('height', at='float', k=1, dv=0, min=0, max=1) self.R_ctrl.addAttr('height', at='float', k=1, dv=0, min=0, max=1) self.L_ctrl.addAttr('overshoot', at='float', k=1, dv=0, min=0) def stickyPairSetup(name='sticky', upperJnt=None, lowerJnt=None, ctrl1=None, ctrl2=None, stickyMin1=0, stickyMin2=0, stickyMax1=0, stickyMax2=0, iniOffset=False): skinJoints=[] if hasattr(ctrl1, 'overshoot'): overCtrl = ctrl1 elif hasattr(ctrl2, 'overshoot'): overCtrl = ctrl2 else: overCtrl=None ##Calcula o centro (usar vetores pra facilitar a conta) a = pm.xform(upperJnt, q=True, ws=True, t=True) b = pm.xform(lowerJnt, q=True, ws=True, t=True) upperPos = om.MVector(a[0], a[1], a[2]) lowerPos = om.MVector(b[0], b[1], b[2]) centerPos = (upperPos+lowerPos)/2 #opcao de fazer o offset no centro ou alinhado aos vertices if iniOffset: upperOffsetPos = (centerPos.x, upperPos.y, centerPos.z) lowerOffsetPos = (centerPos.x, lowerPos.y, centerPos.z) else: upperOffsetPos = (centerPos.x, centerPos.y, centerPos.z) lowerOffsetPos = (centerPos.x, centerPos.y, centerPos.z) #cria os grupos(joints agora) pm.select(cl=True) upperOffsetJoint = pm.joint(name=name+'Upper_Offset') upperDriverJoint = pm.joint(name=name+'Upper_Driver') pm.xform(upperOffsetJoint, ws=True, t=upperOffsetPos) pm.parent(upperOffsetJoint, upperJnt) pm.select(cl=True) lowerOffsetJoint = pm.joint(name=name+'Lower_Offset') lowerDriverJoint = pm.joint(name=name+'Lower_Driver') pm.xform(lowerOffsetJoint, ws=True, t=lowerOffsetPos) pm.parent(lowerOffsetJoint, lowerJnt) pm.select(cl=True) upperOffsetBindJoint = pm.joint(name=name+'UpperSkin_Offset') upperBindJoint = pm.joint(name=name+'UpperSkin_jxt') pm.xform(upperOffsetBindJoint, ws=True, t=(upperPos.x,upperPos.y,upperPos.z)) skinJoints.append(upperOffsetBindJoint) pm.select(cl=True) lowerOffsetBindJoint = pm.joint(name=name+'LowerSkin_Offset') lowerBindJoint = pm.joint(name=name+'LowerSkin_jxt') pm.xform(lowerOffsetBindJoint, ws=True, t=(lowerPos.x,lowerPos.y,lowerPos.z)) skinJoints.append(lowerOffsetBindJoint) #cria os nodes para o blend de posicao do driver upperAddMatrix = pm.createNode('wtAddMatrix') upperMultiMatrix = pm.createNode('multMatrix') upperDecomposeMatrix = pm.createNode('decomposeMatrix') lowerAddMatrix = pm.createNode('wtAddMatrix') lowerMultiMatrix = pm.createNode('multMatrix') lowerDecomposeMatrix = pm.createNode('decomposeMatrix') stickyUpperSetRange = pm.createNode('setRange') stickyLowerSetRange = pm.createNode('setRange') stickyUpperAdd = pm.createNode('addDoubleLinear') stickylowerAdd = pm.createNode('addDoubleLinear') stickClamp = pm.createNode('clamp') stickOffset = pm.createNode('plusMinusAverage') stickyReverse = pm.createNode('reverse') overshootAddUpper = pm.createNode('addDoubleLinear') overshootAddLower = pm.createNode('addDoubleLinear') ctrl1.sticky >> stickyUpperSetRange.valueX ctrl2.sticky >> stickyUpperSetRange.valueY ctrl1.sticky >> stickyLowerSetRange.valueX ctrl2.sticky >> stickyLowerSetRange.valueY overCtrl.overshoot >> overshootAddLower.input2 overCtrl.overshoot >> overshootAddUpper.input2 ctrl1.height >> stickyReverse.inputX stickyUpperSetRange.minX.set(0) ctrl1.height >> stickyUpperSetRange.maxX ctrl1.height >> stickyUpperSetRange.maxY stickyLowerSetRange.minY.set(0) stickyReverse.outputX >> stickyLowerSetRange.maxX stickyReverse.outputX >> stickyLowerSetRange.maxY stickyUpperSetRange.oldMinX.set(stickyMin1) stickyUpperSetRange.oldMinY.set(stickyMin2) stickyLowerSetRange.oldMinX.set(stickyMin1) stickyLowerSetRange.oldMinY.set(stickyMin2) stickOffset.input2D[0].input2Dx.set(stickyMax1) ctrl1.offset >> stickOffset.input2D[1].input2Dx stickOffset.output2Dx >> stickyUpperSetRange.oldMaxX stickOffset.output2Dx >> stickyLowerSetRange.oldMaxX stickOffset.input2D[0].input2Dy.set(stickyMax2) ctrl2.offset >> stickOffset.input2D[1].input2Dy stickOffset.output2Dy >> stickyUpperSetRange.oldMaxY stickOffset.output2Dy >> stickyLowerSetRange.oldMaxY stickyUpperSetRange.outValueX >> stickyUpperAdd.input1 stickyUpperSetRange.outValueY >> stickyUpperAdd.input2 stickyUpperAdd.output >> stickClamp.inputR ctrl1.height >> stickClamp.maxR stickyLowerSetRange.outValueX >> stickylowerAdd.input1 stickyLowerSetRange.outValueY >> stickylowerAdd.input2 stickylowerAdd.output >> stickClamp.inputG stickyReverse.outputX >> stickClamp.maxG stickClamp.outputR >> overshootAddUpper.input1 stickClamp.outputG >> overshootAddLower.input1 #faz as conexoes para o blend da posicao do driver upperOffsetJoint.worldMatrix[0] >> upperAddMatrix.wtMatrix[0].matrixIn overshootAddUpper.output >> upperAddMatrix.wtMatrix[0].weightIn lowerOffsetJoint.worldMatrix[0] >> upperAddMatrix.wtMatrix[1].matrixIn overshootAddUpper.output >> upperAddMatrix.wtMatrix[1].weightIn upperOffsetJoint.worldInverseMatrix >> upperMultiMatrix.matrixIn[0] upperAddMatrix.matrixSum >> upperMultiMatrix.matrixIn[1] upperMultiMatrix.matrixSum >> upperDecomposeMatrix.inputMatrix upperDecomposeMatrix.outputTranslate >> upperDriverJoint.translate upperOffsetJoint.worldMatrix[0] >> lowerAddMatrix.wtMatrix[0].matrixIn overshootAddLower.output >> lowerAddMatrix.wtMatrix[0].weightIn lowerOffsetJoint.worldMatrix[0] >> lowerAddMatrix.wtMatrix[1].matrixIn overshootAddLower.output >> lowerAddMatrix.wtMatrix[1].weightIn lowerOffsetJoint.worldInverseMatrix >> lowerMultiMatrix.matrixIn[0] lowerAddMatrix.matrixSum >> lowerMultiMatrix.matrixIn[1] lowerMultiMatrix.matrixSum >> lowerDecomposeMatrix.inputMatrix lowerDecomposeMatrix.outputTranslate >> lowerDriverJoint.translate upperDriverJoint.translate >> upperBindJoint.translate lowerDriverJoint.translate >> lowerBindJoint.translate return skinJoints stickyMin1 = 0 stickyMax1 = 20 stickyMin2 = 20 stickyMax2 = 40 total = len(L_jointsUp) incr = 20.0 / (total+1) skinJoints=[] for i, jnts in enumerate(zip(L_jointsUp, L_jointsLw)): skinJoints += stickyPairSetup( name='L_sticky'+str(i), upperJnt=jnts[0], lowerJnt=jnts[1], ctrl1=self.L_ctrl, ctrl2=self.R_ctrl, stickyMin1=incr*i, stickyMin2=40-incr*(i+2), stickyMax1=incr*(i+1), stickyMax2=40-incr*(i+1), iniOffset=iniOffset) skinJoints += stickyPairSetup( name='mid_sticky', upperJnt=jntUpper, lowerJnt=jntLower, ctrl1=self.L_ctrl, ctrl2=self.R_ctrl, stickyMin1=incr * total, stickyMin2=incr * total, stickyMax1=incr*(total+1), stickyMax2=incr*(total+1), iniOffset=iniOffset) for i, jnts in enumerate(zip(R_jointsUp, R_jointsLw)): skinJoints += stickyPairSetup( name='R_sticky'+str(i), upperJnt=jnts[0], lowerJnt=jnts[1], ctrl1=self.R_ctrl, ctrl2=self.L_ctrl, stickyMin1=incr*i, stickyMin2=40-incr*(i+2), stickyMax1=incr*(i+1), stickyMax2=40-incr*(i+1), iniOffset=iniOffset) pm.parent(skinJoints, skinJointsGrp) self.skinJoints = [y[0] for y in [x.getChildren() for x in skinJoints]] jointsToAttach=L_jointsUp+L_jointsLw+R_jointsUp+R_jointsLw+[jntUpper, jntLower] jointsToAttach.append(self.mesh.getTransform()) attachTools.hookOnMesh(inputs=jointsToAttach, mode=3, follOn='vzRivet_grp')
def buildIkChain(start, end, pvLen=None, stretchDefault=1, endOrientType=util.EndOrient.TRUE_ZERO, twists={}, makeBendable=False, name='', groupName='', controlSpec={}): ''' :param int pvLen: How far from the center joint to be, defaults to half the length of the chain. .. todo:: * Have fk build as rotate only if not stretchy :param dict twists: Indicates how many twists each section has, ex {1: 2} means joint[1] has 2 twists, which means a 3 joint arm chain becomes shoulder, elbow, twist1, twist2, wrist ''' chain = util.getChain(start, end) # Simplify the names controlChain = util.dupChain(start, end) for j, orig in zip(controlChain, chain): j.rename(util.trimName(orig) + '_proxy') mainJointCount = len(chain) - sum(twists.values()) # Take the linear chain and figure out what are the "main ik", and which # are the twist joints. Also parent the mainArmature as a solo chain for ik application. mainArmature = [] subTwists = {} cur = 0 for i in range(mainJointCount): mainArmature.append(controlChain[cur]) if len( mainArmature ) > 1: # Need to reparent so the 'pivot' joints are independent of the twists if mainArmature[-1].getParent() != mainArmature[ -2]: # ... unless this section has no twists and is already parented. mainArmature[-1].setParent(mainArmature[-2]) cur += 1 if i in twists: subTwists[mainArmature[-1]] = [] for ti in range(twists[i]): subTwists[mainArmature[-1]].append(controlChain[cur]) controlChain[cur].setParent( w=True ) # This ends up being temporary so the ik is applied properly cur += 1 # actual ik node mainIk = ikHandle(sol='ikRPsolver', sj=mainArmature[0], ee=mainArmature[-1])[0] # NOT using Spring because it acts odd. If the pelvis turns, the poleVectors follow it. # Make as RP first so the ik doesn't flip around #PyNode('ikSpringSolver').message >> mainIk.ikSolver # Build the main ik control hide(mainIk) hide(controlChain) if not name: name = util.trimName(start) ctrl = controllerShape.build(name + '_Ik', controlSpec['main'], type=controllerShape.ControlType.IK) container = group(n=name + '_grp') container.setParent(node.mainGroup()) pdil.dagObj.moveTo(ctrl, end) pdil.dagObj.zero(ctrl).setParent(container) # Orient the main ik control if endOrientType == util.EndOrient.TRUE_ZERO: util.trueZeroSetup(end, ctrl) elif endOrientType == util.EndOrient.TRUE_ZERO_FOOT: util.trueZeroFloorPlane(end, ctrl) elif endOrientType == util.EndOrient.JOINT: pdil.dagObj.matchTo(ctrl, end) ctrl.rx.set(util.shortestAxis(ctrl.rx.get())) ctrl.ry.set(util.shortestAxis(ctrl.ry.get())) ctrl.rz.set(util.shortestAxis(ctrl.rz.get())) pdil.dagObj.zero(ctrl) elif endOrientType == util.EndOrient.WORLD: # Do nothing, it's built world oriented pass pdil.dagObj.lock(ctrl, 's') mainIk.setParent(ctrl) # I think orientTarget is for matching fk to ik orientTarget = duplicate(end, po=True)[0] orientTarget.setParent(ctrl) pdil.dagObj.lock(orientTarget) orientConstraint(orientTarget, mainArmature[-1]) hide(orientTarget) pdil.dagObj.lock(mainIk) attr, jointLenMultiplier, nodes = util.makeStretchyNonSpline( ctrl, mainIk, stretchDefault) # &&& Need to do the math for all the # Make the offset joints and setup all the parenting of twists subArmature = [] rotationOffsetCtrls = [] bendCtrls = [] for i, j in enumerate( mainArmature[:-1] ): # [:-1] Since last joint can't logically have twists if makeBendable: j.drawStyle.set( 2 ) # Probably should make groups but not drawing bones works for now. offset = duplicate(j, po=True)[0] offset.setParent(j) offset.rename(pdil.simpleName(j, '{}_Twist')) #subArmature.append(offset) ### OLD if True: ### NEW if not makeBendable: subArmature.append(offset) else: if i == 0: subArmature.append(offset) else: offsetCtrl = controllerShape.build( 'Bend%i' % (len(bendCtrls) + 1), { 'shape': 'band', 'size': 10, 'color': 'green 0.22', 'align': 'x' }) pdil.dagObj.matchTo(offsetCtrl, offset) offsetCtrl.setParent(offset) showHidden(offsetCtrl, a=True) subArmature.append(offsetCtrl) bendCtrls.append(offsetCtrl) rotationOffsetCtrls.append(offset) # &&& Deprectated? attrName = pdil.simpleName(j, '{}_Twist') ctrl.addAttr(attrName, at='double', k=True) ctrl.attr(attrName) >> offset.rx if i in twists: for subTwist in subTwists[j]: subTwist.setParent(j) #subArmature.append(subTwist) ### NEW comment out attrName = pdil.simpleName(subTwist) ctrl.addAttr(attrName, at='double', k=True) ctrl.attr(attrName) >> subTwist.rx if not makeBendable: subArmature.append(subTwist) else: if True: ### NEW offsetCtrl = controllerShape.build( 'Bend%i' % (len(bendCtrls) + 1), { 'shape': 'band', 'size': 10, 'color': 'green 0.22', 'align': 'x' }) pdil.dagObj.matchTo(offsetCtrl, subTwist) offsetCtrl.setParent(subTwist) subTwist.drawStyle.set( 2 ) # Probably should make groups but not drawing bones works fine for now. showHidden(offsetCtrl, a=True) subArmature.append(offsetCtrl) bendCtrls.append(offsetCtrl) #offset.rename( simpleName(j, '{0}_0ffset') ) #for mainJoint, (startSegment, endSegment) in zip( mainArmature, zip( rotationOffsetCtrls, rotationOffsetCtrls[1:] + [mainArmature[-1]] )): # if mainJoint in subTwists: # twistSetup(subTwists[mainJoint], startSegment, endSegment) # Since we don't want twists affecting eachother, base them off the mainArmature if False: ### SKipping this new stuff and resurrecting the old twists for startSegment, endSegment in zip(mainArmature, mainArmature[1:]): #print( 'HAS SUB TWISTS', startSegment in subTwists ) if startSegment in subTwists: twistSetup(ctrl, subTwists[startSegment], startSegment, endSegment, jointLenMultiplier) ''' # Build the groups to hold the twist controls groups = [] for i, (j, nextJ) in enumerate(zip(mainArmature[:-1], mainArmature[1:])): g = group(em=True) parentConstraint(j, g) g.rename( pdil.dagObj.simpleName(g, '{0}_grp') ) groups.append(g) g.setParent(container) if j in subTwists: #totalDist = pdil.dagObj.distanceBetween(j, nextJ) for subTwist in subTwists[j]: dist = pdil.dagObj.distanceBetween(j, subTwist) #disc = 'disc'() disc = controllerShape.build('Twist', {'shape': 'disc', 'align': 'x', 'size': 3}) disc.setParent(g) disc.t.set( 0, 0, 0 ) disc.r.set( 0, 0, 0 ) pdil.dagObj.lock(disc) disc.rx.unlock() disc.tx.unlock() # Manage the lengths of the twist joints and their controls mult = pdil.math.multiply( dist, jointLenMultiplier) mult >> disc.tx mult >> subTwist.tx disc.rx >> subTwist.rx ''' constraints = util.constrainAtoB(chain, subArmature + [mainArmature[-1]]) # PoleVector if not pvLen or pvLen < 0: pvLen = util.chainLength(mainArmature) * 0.5 out = util.calcOutVector(mainArmature[0], mainArmature[1], mainArmature[-1]) pvPos = out * pvLen + dt.Vector( xform(mainArmature[1], q=True, ws=True, t=True)) pvCtrl = controllerShape.build(name + '_pv', controlSpec['pv'], type=controllerShape.ControlType.POLEVECTOR) pdil.dagObj.lock(pvCtrl, 'r s') xform(pvCtrl, ws=True, t=pvPos) controllerShape.connectingLine(pvCtrl, mainArmature[1]) poleVectorConstraint(pvCtrl, mainIk) pdil.dagObj.zero(pvCtrl).setParent(container) # Socket offset control socketOffset = controllerShape.build( name + '_socket', controlSpec['socket'], type=controllerShape.ControlType.TRANSLATE) socketContainer = util.parentGroup(start) socketContainer.setParent(container) pdil.dagObj.moveTo(socketOffset, start) pdil.dagObj.zero(socketOffset).setParent(socketContainer) pdil.dagObj.lock(socketOffset, 'r s') pointConstraint(socketOffset, mainArmature[0]) # Reuse the socketOffset container for the controlling chain mainArmature[0].setParent(socketContainer) # hide( mainArmature[0] ) ''' Currently unable to get this to update, maybe order of operations needs to be enforced? # Add switch to reverse the direction of the bend reverseAngle = controlChain[1].jointOrient.get()[1] * -1.1 ctrl.addAttr( 'reverse', at='short', min=0, max=1, dv=0, k=True ) preferredAngle = pdil.math.condition( ctrl.reverse, '=', 0, 0, reverseAngle ) twist = pdil.math.condition( ctrl.reverse, '=', 0, 0, -180) preferredAngle >> controlChain[1].preferredAngleY twist >> mainIk.twist pdil.math.condition( mainIk.twist, '!=', 0, 0, 1 ) >> mainIk.twistType # Force updating?? ''' if True: # &&& LOCKABLE endToMidDist, g1 = pdil.dagObj.measure(ctrl, pvCtrl, 'end_to_mid') startToMidDist, g2 = pdil.dagObj.measure(socketOffset, pvCtrl, 'start_to_mid') parent(endToMidDist, g1, startToMidDist, g2, container) #ctrl.addAttr( 'lockPV', at='double', min=0.0, dv=0.0, max=1.0, k=True ) #switcher.input[0].set(1) #print('--'* 20) #print(mainArmature) for jnt, dist in zip(mainArmature[1:], [startToMidDist, endToMidDist]): axis = util.identifyAxis(jnt) lockSwitch = jnt.attr('t' + axis).listConnections(s=True, d=False)[0] if jnt.attr('t' + axis).get() < 0: pdil.math.multiply(dist.distance, -1) >> lockSwitch.input[1] else: dist.distance >> lockSwitch.input[1] util.drive(ctrl, 'lockPV', lockSwitch.attributesBlender, 0, 1) """ axis = identifyAxis(mainArmature[-1]) lockSwitchA = mainArmature[-1].attr('t' + axis).listConnections(s=True, d=False)[0] if mainArmature[-1].attr('t' + axis).get() < 0: pdil.math.multiply( endToMidDist.distance, -1) >> lockSwitchA.input[1] else: endToMidDist.distance, -1 >> lockSwitchA.input[1] lockSwitchB = mainArmature[-2].attr('t' + axis).listConnections(s=True, d=False)[0] startToMidDist.distance >> lockSwitchB.input[1] #print(lockSwitchA, lockSwitchB, '-'* 20) drive(ctrl, 'lockPV', lockSwitchA.attributesBlender, 0, 1) drive(ctrl, 'lockPV', lockSwitchB.attributesBlender, 0, 1) """ # Register all the parts of the control for easy identification at other times. ctrl = pdil.nodeApi.RigController.convert(ctrl) ctrl.container = container ctrl.subControl['socket'] = socketOffset for i, bend in enumerate(bendCtrls): ctrl.subControl['bend%i' % i] = bend ctrl.subControl['pv'] = pvCtrl # Add default spaces space.addMain(pvCtrl) #space.add( pvCtrl, ctrl, spaceName=shortName(ctrl, '{0}_posOnly') ) #space.add( pvCtrl, ctrl, spaceName=shortName(ctrl, '{0}_posOnly'), mode=space.TRANSLATE) space.add(pvCtrl, ctrl) space.add(pvCtrl, ctrl, mode=space.Mode.TRANSLATE) return ctrl, constraints
def loadHoldLocs(self, *args): import xml.dom.minidom import xml.dom characterName = "" xmlDir = turbineUtils.setupDirs(characterName, create=False)[2] # The name of the holding location allLocs=[] allJoints=[] bindJoints = self.jointUtils.getGameJoints() if bindJoints == None: cmds.headsUpMessage( 'No game joints exist in this scene. Holding locations will not be added.') return else: # We should create a holding loc for each game joint. cmds.select( clear=True ) # open the xml file for reading holdLocFile = (xmlDir + "/holdLocList.xml") fileObject = file(holdLocFile, 'r') # parse the xml file to get all of it's elements xmlDoc = xml.dom.minidom.parse(fileObject) # Get the joint elements into a list joints = xmlDoc.getElementsByTagName('joint') # iterate through all of the joint elements #Loads joint positions for joint in joints: # get the child elements of the joint in order to get the loc name children = joint.childNodes # loop through the child elements for child in children: # make sure the the current node type is not a text node if child.nodeType != child.TEXT_NODE: # Deal with holding loc name. ######################################################### if child.tagName == "locName": # if the node is locName node get it's children # to get the locName locAxis = child.childNodes for axis in locAxis: if axis.nodeType != axis.TEXT_NODE: locValue = axis.getAttribute("value") # get the name of the joint from the name attribute attached to the joint element. jointName = joint.getAttribute("name") if cmds.objExists(jointName): allJoints.append(jointName) jointPos = cmds.xform(jointName, q=True, ws=True, t=True, a=True) # Final name for the holding location locName = ("HoldingLocation_" + jointName + "_" + locValue) allLocs.append(locName) if cmds.objExists(locName) == False: locGrp = pm.group(em=True, w=True, n=locName) locGrp = cmds.ls(sl=True) locGrp = (locGrp)[0] # Move locGrp to joints position cmds.move(jointPos[0], jointPos[1], jointPos[2], locGrp, r=True) cmds.setAttr(locGrp + '.displayHandle', 1) cmds.setAttr(locGrp + '.displayLocalAxis', 1) # Add an "LocationType" attr to the holding loc cmds.addAttr(ln="LocationType", dt="string", k=False) cmds.setAttr(locGrp+".LocationType", locValue, type="string") # parent the holdLoc to the joint cmds.parent(locGrp, jointName) # close the file fileObject.close() # Return some info to let the user know if the holding locs were created. jntLen = len(allJoints) locLen = len(allLocs) return allLocs