def setupIKCtrl(self, x, IKHandle): ############# MODIFY FOR INHERITANCE ############# side = self.prefixList[x] thisChain = self.IKChains[x] #create a control for the ik name = "%s_%s_IK_CTRL"%(side, self.limbName) if x==0: IKCtrl = rig.createControl(name, "cube", self.jAxis1, "blue") if x==1: IKCtrl = rig.createControl(name, "cube", self.jAxis1, "red") self.IKCtrls.append(IKCtrl) #strip to rotate and translate rig.stripToRotateTranslate(IKCtrl) #G.O. control group = rig.groupOrient(thisChain[2], IKCtrl, self.groupSuffix) ########## cmds.setAttr("%s.rotateX"%group, (0)) cmds.setAttr("%s.rotateY"%group, (0)) cmds.setAttr("%s.rotateZ"%group, (0)) #orient constraint joint 2 (wrist ankle) to control ########## # cmds.orientConstraint(IKCtrl, thisChain[2], mo=True) #parent ik handle to control cmds.parent(IKHandle, IKCtrl) return IKCtrl
def setupIKCtrl(self, x, IKHandle): ############# MODIFY FOR INHERITANCE ############# side = self.prefixList[x] thisChain = self.IKChains[x] #create a control for the ik name = "%s_%s_IK_CTRL"%(side, self.limbName) if x==0: IKCtrl = rig.createControl(name, "cube", self.jAxis1, "blue") if x==1: IKCtrl = rig.createControl(name, "cube", self.jAxis1, "red") self.IKCtrls.append(IKCtrl) #strip to rotate and translate rig.stripToRotateTranslate(IKCtrl) #G.O. control rig.groupOrient(thisChain[2], IKCtrl, self.groupSuffix) #orient constraint joint 2 (wrist ankle) to control cmds.orientConstraint(IKCtrl, thisChain[2]) #parent ik handle to control cmds.parent(IKHandle, IKCtrl) return IKCtrl
def setupFK(self, x): """sets up the fk portion of this limb""" thisChain = self.FKChains[x] side = self.prefixList[x] ctrlList = [] grpList = [] for i in range(len(thisChain)-1): #create control for joint (octagon) ctrlName = (thisChain[i].rstrip(self.jointSuffix) + self.controlSuffix) #create control if x==0: ctrl = rig.createControl(ctrlName, "sphere", self.jAxis1, "blue") if x==1: ctrl = rig.createControl(ctrlName, "sphere", self.jAxis1, "red") grpName = "%s_%s"%(ctrl,self.groupSuffix) rig.groupOrient(thisChain[i], ctrl, self.groupSuffix) #connect the joints to the controls #-----------catch this constraint with variable???? cmds.parentConstraint(ctrl, thisChain[i]) #deal with attrs rig.stripToRotateTranslate(ctrl) rig.lockTranslate(ctrl) cmds.addAttr(ctrl, at="short", ln="__EXTRA__", nn="__EXTRA__", k=True) cmds.setAttr("%s.__EXTRA__"%ctrl, l=True) cmds.addAttr(ctrl, at="float", ln="stretch", dv=1, min=0.3, max=3, k=True) cmds.connectAttr("%s.stretch"%ctrl, "%s.s%s"%(thisChain[i], self.jAxis1)) ctrlList.append(ctrl) grpList.append(grpName) #parent up the controls to each other for j in range((len(grpList)-1), 0, -1): cmds.parent(grpList[j], ctrlList[j-1]) #create lists of controls self.FKCtrlChains.append(ctrlList) #do the visibilty of the fk chain from the IK switch ikS = self.IKSwitches[x] rName = ("%s_%s_ikReverse"%(self.prefixList[x], self.limbName)) grpTop = cmds.listRelatives(self.FKCtrlChains[x][0], p=True)[0] cmds.shadingNode("reverse", asUtility=True, n=( rName)) cmds.connectAttr("%s.FKIK"%ikS, "%s.inputX"%rName) cmds.connectAttr("%s.outputX"%rName, "%s.visibility"%grpTop) #pass to bind setup self.setupBind(x)
def ctrlSetup(): cmds.select(hi=True) sel = cmds.ls(sl=True) ctrlList = [] groupList = [] for x in sel: if (cmds.listRelatives(x, p=True)): cmds.parent(x, w=True) #could rename joint here ctrl = rig.createControl("%s_CTRL" % x, "cube", "x", "red") ctrlList.append(ctrl) group = rig.groupOrient(x, ctrl) groupList.append(group) cmds.parent(x, ctrl) for x in range(len(ctrlList) - 1, 0, -1): #create a control for the move of the joint #snap this to the joint #parent the joint to the control #switch this to parenting the new control to the other control . . . cmds.parent(groupList[x], ctrlList[x - 1]) #strip to rotateTranslate, then lock the translate of the old control #strip to translate of the new control . . . (lock other channels other than up?2) #TO-DO----------------put a "local" control onto the joint to do the up/down stuff for each control
def ctrlSetup(): cmds.select(hi=True) sel = cmds.ls(sl=True) ctrlList = [] groupList = [] for x in sel: if (cmds.listRelatives(x, p=True)): cmds.parent(x, w=True) #could rename joint here ctrl = rig.createControl("%s_CTRL"%x, "cube", "x", "red") ctrlList.append(ctrl) group = rig.groupOrient(x, ctrl) groupList.append(group) cmds.parent(x, ctrl) for x in range(len(ctrlList)-1, 0, -1): #create a control for the move of the joint #snap this to the joint #parent the joint to the control #switch this to parenting the new control to the other control . . . cmds.parent(groupList[x], ctrlList[x-1]) #strip to rotateTranslate, then lock the translate of the old control #strip to translate of the new control . . . (lock other channels other than up?2) #TO-DO----------------put a "local" control onto the joint to do the up/down stuff for each control
def setupPV(self, IKHandle, type, x): """type can be "normal" (a control) or "noFlip" with hidden control and twist attribute. add to self.PVList """ # set values for this chain, side thisChain = self.IKChains[x] side = self.prefixList[x] pv = "%s_%s_PV" % (side, self.limbName) if type == "normal": if x == 0: thisPV = rig.createControl(pv, "sphere", self.jAxis1, "darkBlue") if x == 1: thisPV = rig.createControl(pv, "sphere", self.jAxis1, "darkRed") thisGrp = cmds.group(pv, n="%s_%s" % (pv, self.groupSuffix)) # get pos of joints 0 and 2 to position pv group topPosRaw = cmds.xform(thisChain[0], ws=True, q=True, t=True) topPos = om.MVector(topPosRaw[0], topPosRaw[1], topPosRaw[2]) lowPosRaw = cmds.xform(thisChain[2], ws=True, q=True, t=True) lowPos = om.MVector(lowPosRaw[0], lowPosRaw[1], lowPosRaw[2]) midPos = (topPos + lowPos) / 2 cmds.xform(thisGrp, ws=True, t=(midPos.x, midPos.y, midPos.z)) aim = cmds.aimConstraint(thisChain[1], thisGrp, aim=(0, 0, -1)) cmds.delete(aim) cmds.xform(thisGrp, os=True, r=True, t=(0, 0, -10)) # strip control to translate rig.stripToTranslate(thisPV) # -----------capture all constraints as list? # hook up pv cmds.poleVectorConstraint(thisPV, IKHandle) # add pv to list self.PVList.append(thisPV) # return pv return thisPV cmds.addAttr(thisPV, ln="follow", at="enum", en="world:foot") if type == "noFlip": pass pass
def setupPV(self, IKHandle, type, x): """type can be "normal" (a control) or "noFlip" with hidden control and twist attribute. add to self.PVList """ #set values for this chain, side thisChain = self.IKChains[x] side = self.prefixList[x] pv = "%s_%s_PV"%(side, self.limbName) if type == "normal": if x==0: thisPV = rig.createControl(pv, "sphere", self.jAxis1, "darkBlue") if x==1: thisPV = rig.createControl(pv, "sphere", self.jAxis1, "darkRed") thisGrp = cmds.group(pv, n="%s_%s"%(pv,self.groupSuffix)) #get pos of joints 0 and 2 to position pv group topPosRaw = cmds.xform(thisChain[0], ws=True, q=True, t=True) topPos = om.MVector(topPosRaw[0], topPosRaw[1], topPosRaw[2]) lowPosRaw = cmds.xform(thisChain[2], ws=True, q=True, t=True) lowPos = om.MVector(lowPosRaw[0], lowPosRaw[1], lowPosRaw[2]) midPos = (topPos + lowPos)/2 cmds.xform(thisGrp, ws=True, t=(midPos.x, midPos.y, midPos.z)) aim = cmds.aimConstraint(thisChain[1], thisGrp, aim=(0,0,-1)) cmds.delete(aim) cmds.xform(thisGrp, os=True, r=True, t=(0, 0, -10)) #strip control to translate rig.stripToTranslate(thisPV) #-----------capture all constraints as list? #hook up pv cmds.poleVectorConstraint(thisPV, IKHandle) #add pv to list self.PVList.append(thisPV) #return pv return(thisPV) cmds.addAttr(thisPV, ln="follow", at="enum", en="world:foot") if type == "noFlip": pass pass
def createControls(list): """for each thing in the list, creates a control. Requires zbw_rig.py module""" #for each cluster create a controlsOnCurve ctrlList = [] grpList = [] colorList = [ "red", "blue", "green", "darkRed", "lightRed", "medBlue", "lightBlue", "royalBlue", "darkGreen", "medGreen", "yellowGreen", "yellow", "darkYellow", "lightYellow", "purple", "darkPurple", "black", "brown", "darkBrown", "lightBrown", "pink", "orange" ] randColor = colorList[random.randint(0, len(colorList) - 1)] for clstr in list: #print list ctrlName = clstr.rpartition("Handle")[0] + "_CTRL" ctrl = rig.createControl(name=ctrlName, type="sphere", axis="x", color=randColor) #scale ctrl scl = cmds.floatFieldGrp(widgets["scaleFFG"], q=True, v1=True) / 2 pts = cmds.ls(ctrlName + ".cv[*]") cmds.select(pts) cmds.scale(scl, scl, scl) cmds.setAttr(clstr + ".v", 0) pos = cmds.xform(clstr, q=True, ws=True, rp=True) grp = cmds.group(em=True, name=ctrlName + "_GRP") cmds.parent(ctrl, grp) cmds.xform(grp, ws=True, t=pos) ctrlList.append(ctrlName) grpList.append(grp) for x in range(0, len(ctrlList)): cmds.parent(list[x], ctrlList[x]) oldName = cmds.textFieldGrp(widgets["nameTFG"], q=True, tx=True) cntrlGrp = cmds.group(name=oldName + "_CTRL_GRP", em=True) for group in grpList: cmds.parent(group, cntrlGrp) hier = cmds.checkBoxGrp(widgets["hierCBG"], q=True, v1=True) if hier: for x in range(len(ctrlList) - 1, 0, -1): cmds.parent(grpList[x], ctrlList[x - 1]) #cmds.parent(grpList[0], cntrlGrp) return (cntrlGrp)
def linkTwoCurves(*args): clusterList = [] cvsLists = [] groupList = [] sel = cmds.ls(sl=True) for crv in sel: cvs = cmds.ls("%s.cv[*]" % crv, fl=True) cvsLists.append(cvs) c1 = cvsLists[0] c2 = cvsLists[1] #check that they're equal if len(c1) == len(c2): for x in range(len(c1)): name = c1[x].split(".")[0] + "Clstr%s" % x clstr = cmds.cluster((c1[x], c2[x]), name=name)[1] clusterList.append(clstr) #--------------find some way to orient? cmds.setAttr("%s.visibility" % clstr, 0) for x in range(len(clusterList)): name = clusterList[x].replace("Clstr", "Ctrl") ctrl = rig.createControl(type="sphere", name=name, color="red") grp = cmds.group(em=True, name="%sGrp" % name) groupList.append(grp) cmds.parent(ctrl, grp) pos = cmds.xform(clusterList[x], q=True, ws=True, rp=True) rot = cmds.xform(clusterList[x], q=True, ws=True, ro=True) cmds.xform(grp, ws=True, t=pos) cmds.xform(grp, ws=True, ro=rot) cmds.parent(clusterList[x], ctrl) msterGrp = cmds.group(em=True, name="%sCtrlGrp" % sel[0]) cmds.parent(groupList, msterGrp) else: cmds.warning("dont' have the same # of cvs in curves")
def createRibbon(self, *args): self.name = cmds.textFieldGrp(self.widgets["ribbonNameTFG"], q=True, tx=True) self.numDiv = (cmds.intFieldGrp( self.widgets["jointsIFG"], q=True, v=True)[0]) - 1 #self.fk = cmds.checkBox(self.widgets["fkSetupCB"], q=True, v=True) self.height = cmds.floatFieldGrp(self.widgets["heightFFG"], q=True, v1=True) self.ratio = cmds.floatFieldGrp(self.widgets["ratioFFG"], q=True, v1=True) #self.axis = cmds.radioButtonGrp(self.widgets["axis"] , q=True, sl=True) #print("axis = :%s"%self.axis) self.ribbonName = "%s_ribbonGeo" % self.name self.numJoints = self.numDiv self.follicleList = [] self.follicleJntList = [] #self.own = cmds.checkBox(self.widgets["existingGeoCB"], q=True, v=True) #self.myGeo = cmds.textFieldButtonGrp(self.widgets["geoTFBG"], q=True, tx=True) #self.dir = cmds.radioButtonGrp(self.widgets["directionRBG"], q=True, sl=True ) #print("dir: %s"%self.dir) #self.centerPos = cmds.floatSliderGrp(self.widgets["centerPosFSG"], q=True, v=True ) self.follicleGrpList = [] #-----------make sure the num of divisions is at least 1 #-----------create the nurbs plane in the correct axis (just make the plane in the axis and figure out how to rotate joint local rotational axes to match it) DON'T WORRY ABOUT THIS SO MUCH (IT'S HIDDEN), WORRY ABOUT THE CONTROLS BEING ORIENTED CORRECTLY!!! # if self.own == 0: # self.dir = 2 # if self.dir == 1: # dir = "u" # uDiv = self.numDiv # vDiv = 1 # else: # dir = "v'" # uDiv = 1 # vDiv = self.numDiv # if self.axis == 1: axis = [0, 0, 1] # elif self.axis == 2: # axis = [0, 1, 0] # elif self.axis == 3: # axis = [0, 0, 1] #if self.own == 0: width = self.height / self.ratio #create the nurbsPlane cmds.nurbsPlane(ax=axis, w=width, lr=self.ratio, d=3, u=1, v=4, ch=0, n=self.ribbonName) cmds.rebuildSurface(self.ribbonName, ch=0, rpo=1, rt=0, end=1, kr=0, kcp=0, kc=0, su=1, du=1, sv=4, dv=3, tol=0.1, fr=0, dir=2) cmds.move(0, self.height / 2, 0, self.ribbonName) cmds.xform(self.ribbonName, ws=True, rp=[0, 0, 0]) # else: # self.ribbonName = self.myGeo #find the ratio for the uv's (one dir will be .5, the other a result of the num joints) factor = 1.0 / self.numJoints #-------keep follicle joints separate, not parente under each follicle, separate group for those #-------follicle jnts each go under a ctrl (star) that is under a group. That group gets parent constrained to the follicles #-------these joints should be aligned with the follicles??? does that make a difference? #create the follicles on the surface, joints on the follicles for x in range(self.numJoints + 1): val = x * factor folName = "%s_follicle%s" % (self.name, x) #create a follicle in the right direction # if self.dir ==1: # follicle = rig.follicle(self.ribbonName, folName, val, 0.5)[0] # else: follicle = rig.follicle(self.ribbonName, folName, 0.5, val)[0] self.follicleList.append(follicle) #create joint and parent to follicle jointName = "%s_fol%s_JNT" % (self.name, x) #---------have to figure out how to orient this correctly (just translate and rotate the joints (or the controls they're under)) #create joint control? then move the control and the joint under it to the correct rot and pos folPos = cmds.xform(follicle, q=True, ws=True, t=True) folRot = cmds.xform(follicle, q=True, ws=True, ro=True) cmds.select(cl=True) folJoint = cmds.joint(n=jointName, p=(0, 0, 0)) folGroup = cmds.group( folJoint, n="%s_GRP" % folJoint) #this could become control for the joint cmds.xform(folGroup, a=True, ws=True, t=folPos) cmds.xform(folGroup, a=True, ws=True, ro=folRot) self.follicleJntList.append(folJoint) self.follicleGrpList.append(folGroup) cmds.parent(folGroup, follicle) #create controls here: #create a loop that runs through the cvs in v, 0 to 6 origClusterList = [ "top_CLS", "topBez_CLS", "centerTop_CLS", "center_CLS", "centerEnd_CLS", "endBez_CLS", "end_CLS" ] origControlList = [ "top_CTRL", "topBez_CTRL", "centerTop_CTRL", "center_CTRL", "centerEnd_CTRL", "endBez_CTRL", "end_CTRL" ] clusterList = [] controlList = [] constrGrpList = [] attachGrpList = [] for v in range(0, 7): cmds.select(clear=True) clusNodeName = self.name + "_" + origClusterList[v] + "Base" #select u (0 and 1) for each v and cluster them fullCls = cmds.cluster("%s.cv[0:1][%d]" % (self.ribbonName, v), relative=False, n=clusNodeName)[0] clusHandle = clusNodeName + "Handle" clusName = clusHandle.rstrip("BaseHandle") cmds.rename(clusHandle, clusName) clusterList.append(clusName) #now setup the controls and groups for the clusters #goes control,group (const), group(attach) control = self.name + "_" + origControlList[v] constrGrp = self.name + "_" + origControlList[v] + "_const_GRP" attachGrp = self.name + "_" + origControlList[v] + "_attach_GRP" rig.createControl(name=control, type="circle", axis="y", color="darkGreen", *args) oldGrp = rig.groupOrient(clusName, control) cmds.rename(oldGrp, constrGrp) #parent clus to control cmds.parent(clusName, control) #get cluster position clusPos = cmds.pointPosition(clusName + ".rotatePivot") cmds.xform(constrGrp, ws=True, piv=(clusPos[0], clusPos[1], clusPos[2])) cmds.group(constrGrp, n=attachGrp) cmds.xform(attachGrp, ws=True, piv=(clusPos[0], clusPos[1], clusPos[2])) controlList.append(control) constrGrpList.append(constrGrp) attachGrpList.append(attachGrp)
def setupIK(self, x): """sets up the IK portion of the limb rig""" #set values for this chain, side thisChain = self.IKChains[x] side = self.prefixList[x] thisBind = self.bindChains[x] #create ik control from joint 0 to 2 mainIK = "%s_%s_IK"%(side, self.limbName) IKHandle = cmds.ikHandle(n=mainIK, sj=thisChain[0], ee=thisChain[2], sol="ikRPsolver")[0] self.IKHandles.append(IKHandle) #create a control for the ik IKCtrl = self.setupIKCtrl(x, IKHandle) #call pole vector method? - pass IK name, normal or no flip #-----------------get argument from UI about what kind of handles thisPv = self.setupPV(IKHandle, "normal", x) #create stretchy bits cmds.addAttr(IKCtrl, ln="__EXTRA__", nn="__EXTRA__", at="short", k=True) cmds.setAttr("%s.__EXTRA__"%IKCtrl, l=True) cmds.addAttr(IKCtrl, ln="autoStretch", at="float", min=0, max=1, k=True) cmds.addAttr(IKCtrl, ln="scaleMin", at="float", min=0.5, max=3, k=True, dv=1) #add "upScale" and "lowScale" (.5-3) cmds.addAttr(IKCtrl, ln="upScale", at="float", min=0.3, max=3, k=True, dv=1.0) cmds.addAttr(IKCtrl, ln="lowScale", at="float", min=0.3, max=3, k=True, dv=1.0) #from measure, get final add node add = self.measureAdds[x] #orient the IK wrist to the control? do it here or elsewhere (for inheritance?) cmds.orientConstraint(IKCtrl, thisChain[2]) #create distance node from thigh to ctrl distance = rig.measureDistance("%s_%s_ikCtrlDistance"%(side, self.limbName), self.measureChains[x][0], IKCtrl) ratioMult, defaultMult, defaultBlend, conditional, upScaleMult, loScaleMult = rig.scaleStretchIK(("%s_%s"%(side, self.limbName)), thisChain[0], thisChain[1], thisChain[2], "%s.output"%add, "%s.distance"%distance, IKCtrl, self.jAxis1) #create the ik switch (call as "diamond") ikSwitchName = "%s_%s_FKIKSwitch"%(side, self.limbName) if x == 0: thisIKSwitch = rig.createControl(ikSwitchName, "diamond", self.jAxis1, "lightBlue") if x == 1: thisIKSwitch = rig.createControl(ikSwitchName, "diamond", self.jAxis1, "pink") rig.stripTransforms(thisIKSwitch) cmds.addAttr(thisIKSwitch, ln="FKIK", k=True, at="float", min=0, max=1, dv=0) #create reverse thisIKSwitchRev = cmds.shadingNode("reverse", asUtility=True, n="%s_%s_IKSwtchReverse"%(side, self.limbName)) cmds.connectAttr("%s.FKIK"%thisIKSwitch, "%s.inputX"%thisIKSwitchRev) rig.groupOrient(thisBind[2], thisIKSwitch, self.groupSuffix) IKSwitchGrp = cmds.listRelatives(thisIKSwitch, p=True) #do stuff here to push the IKFK switch in the right direction if x== 0: offset = -3 if x==1: offset = 3 cmds.xform(IKSwitchGrp, os=True, r=True, t=(0, 0, offset)) self.IKSwitches.append(thisIKSwitch) self.IKSwitchesRev.append(thisIKSwitchRev) #set up visibility switching from this for IK and PV controls #get pv parent group pvGroup = cmds.listRelatives(thisPv, p=True)[0] ikCtrlGroup = cmds.listRelatives(IKCtrl, p=True)[0] cmds.connectAttr("%s.FKIK"%thisIKSwitch, "%s.v"%pvGroup) cmds.connectAttr("%s.FKIK"%thisIKSwitch, "%s.v"%ikCtrlGroup) #pass onto the FK part of the rig self.setupFK(x)
def extrude(*args): sel = cmds.ls(sl=True, exactType="transform") #keep = cmds.checkBoxGrp(widgets["keepCBG"], q=True, v1=True) if len(sel) < 3: cmds.warning( "You need to select the profile, then cap, then path curve in order!" ) return profileOrig = sel[0] cap = sel[1] curves = sel[2:] if not cmds.objExists("pastaRigSetupComponents_Grp"): cmds.group(empty=True, name="pastaRigSetupComponents_Grp") if not curveCheck(profileOrig): cmds.warning("Your first selection (profile) is not a curve!") return if not cmds.objExists("curveRebuild_originals_grp"): cmds.group(empty=True, name="curveRebuild_originals_grp") cmds.parent("curveRebuild_originals_grp", "pastaRigSetupComponents_Grp") cmds.parent(profileOrig, cap, "pastaRigSetupComponents_Grp") for curve in curves: if not curveCheck(curve): cmds.warning("{} is not a curve, skipping!".format(curve)) else: profile = cmds.duplicate(profileOrig, name="{}_profileCrv".format(curve))[0] newCap = cmds.duplicate(cap, returnRootsOnly=True, rebuildType=0, renameChildren=True, name="{}_capRig".format(curve))[0] # rigGrp = cmds.group(empty=True, name = "{}_rig_grp".format(curve)) curveResults = rebuildCurve(curve) newCrv = curveResults[0] rebuild = curveResults[1] cmds.parent(curve, "curveRebuild_originals_grp") capAxis = "y" capUp = "z" ctrl = rig.createControl(type="sphere", name="{}_CTRL".format(curve), color="blue") ctrlScale(ctrl) capGrp = cmds.group(empty=True, name="{}_cap_grp".format(curve)) deadGrp = cmds.group(empty=True, name="{}_noInherit_grp".format(curve)) cmds.parent(deadGrp, ctrl) #cmds.parent(ctrl, rigGrp) cmds.parent(newCap, capGrp) # add attrs to control cmds.addAttr(ctrl, ln="__xtraAttrs__", nn="__xtraAttrs__", at="bool", k=True) cmds.setAttr("{}.__xtraAttrs__".format(ctrl), l=True) cmds.addAttr(ctrl, ln="alongPath", at="float", min=0, max=100, k=True, dv=100.0) cmds.setAttr("{}.alongPath".format(ctrl), 100) cmds.addAttr(ctrl, ln="geoVis", at="long", min=0, max=1, k=True, dv=1) cmds.addAttr(ctrl, ln="pathCurveVis", at="long", min=0, max=1, k=True, dv=1) cmds.addAttr(ctrl, ln="__curveStuff__", nn="__curveStuff__", at="bool", k=True) cmds.setAttr("{}.__curveStuff__".format(ctrl), l=True) cmds.addAttr(ctrl, ln="density", at="float", min=0.02, max=8, k=True, dv=0.05) cmds.addAttr(ctrl, ln="radiusDivisions", at="float", k=True, min=1, max=3, dv=1.0) cmds.addAttr(ctrl, ln="reverseNormals", at="long", min=0, max=1, k=True) cmds.addAttr(ctrl, ln="capVisibility", at="long", min=0, max=1, k=True) cmds.setAttr("{}.capVisibility".format(ctrl), 1) cmds.addAttr(ctrl, ln="profileWidth", at="float", k=True, min=.001, max=3, dv=1.0) cmds.addAttr(ctrl, ln="capWidth", at="float", k=True, min=.01, max=2.0, dv=1.0) cmds.addAttr(ctrl, ln="capHeight", at="float", k=True, min=.01, max=2.0, dv=1.0) cmds.addAttr(ctrl, ln="rotateExtrusion", at="float", k=True, min=0, max=360) cmds.addAttr(ctrl, ln="rotateCap", at="float", k=True) cmds.addAttr(ctrl, ln="__textureAndRef__", nn="__textureAndRef__", at="bool", k=True) cmds.setAttr("{}.__textureAndRef__".format(ctrl), l=True) cmds.addAttr(ctrl, ln="textureRepeatMult", at="float", min=0.01, dv=1.0, k=True) cmds.addAttr(ctrl, ln="length", at="float", k=True) initLen = cmds.arclen(newCrv, ch=False) cmds.setAttr("{}.length".format(ctrl), initLen) cmds.setAttr("{}.length".format(ctrl), l=True) cmds.addAttr(ctrl, ln="geo", at="message") cmds.addAttr(ctrl, ln="fileTexture", at="message") cmds.addAttr(ctrl, ln="capRig", at="message") cmds.connectAttr("{}.message".format(newCap), "{}.capRig".format(ctrl)) # reference/driver attrs cmds.addAttr(ctrl, ln="prmHolder", at="float", k=True) cmds.addAttr(ctrl, ln="rptHolder", at="float", k=True) #cmds.setAttr("{}.radiusDivisions".format(ctrl), l=True) # connect mult to path mult = cmds.shadingNode("multiplyDivide", asUtility=True, name="{}_paraMult".format(curve)) cmds.connectAttr("{}.alongPath".format(ctrl), "{}.input1X".format(mult)) cmds.setAttr("{}.input2X".format(mult), 0.01) cmds.connectAttr("{}.profileWidth".format(ctrl), "{}.scaleX".format(profile)) cmds.connectAttr("{}.profileWidth".format(ctrl), "{}.scaleZ".format(profile)) # reverse for normals reverse = cmds.shadingNode("reverse", asUtility=True, name="{}_reverse".format(curve)) cmds.connectAttr("{}.reverseNormals".format(ctrl), "{}.inputX".format(reverse)) # cap, path and texture attrs and nodes cmds.connectAttr("{}.capVisibility".format(ctrl), "{}.v".format(capGrp)) repeatMult = cmds.shadingNode("multiplyDivide", asUtility=True, name="{}_RptMult".format(curve)) cmds.connectAttr("{}.outputX".format(mult), "{}.input1X".format(repeatMult)) cmds.connectAttr("{}.textureRepeatMult".format(ctrl), "{}.input2X".format(repeatMult)) cmds.connectAttr("{}.pathCurveVis".format(ctrl), "{}.visibility".format(newCrv)) #connect the rebuild density densityMult = cmds.shadingNode("multiplyDivide", asUtility=True, name="{}_DensityMult".format(curve)) cmds.connectAttr("{}.density".format(ctrl), "{}.input1X".format(densityMult)) cmds.connectAttr("{}.length".format(ctrl), "{}.input2X".format(densityMult)) cmds.connectAttr("{}.outputX".format(densityMult), "{}.spans".format(rebuild)) cmds.connectAttr("{}.outputX".format(repeatMult), "{}.rptHolder".format(ctrl)) cmds.connectAttr("{}.outputX".format(mult), "{}.prmHolder".format(ctrl)) cmds.setAttr("{}.prmHolder".format(ctrl), l=True) cmds.setAttr("{}.rptHolder".format(ctrl), l=True) cmds.connectAttr("{}.capWidth".format(ctrl), "{}.scaleX".format(capGrp)) cmds.connectAttr("{}.capWidth".format(ctrl), "{}.scaleZ".format(capGrp)) cmds.connectAttr("{}.capHeight".format(ctrl), "{}.scaleY".format(capGrp)) cmds.connectAttr("{}.rotateCap".format(ctrl), "{}.rotateY".format(newCap)) # position control at start of curve startPos = cmds.pointOnCurve(curve, parameter=0, position=True) cmds.xform(ctrl, ws=True, t=startPos) moPath = cmds.pathAnimation(capGrp, newCrv, fractionMode=True, follow=True, followAxis=capAxis, upAxis=capUp, worldUpType="scene", startTimeU=0.0, endTimeU=100.0) moPathAnimAttr = cmds.listConnections("{}.uValue".format(moPath), d=False, p=True)[0] start, end = getSliderRange() current = cmds.currentTime(q=True) cmds.currentTime(0) pPos = cmds.xform(capGrp, q=True, ws=True, rp=True) pRot = cmds.xform(capGrp, q=True, ws=True, ro=True) cmds.xform(profile, ws=True, t=pPos) cmds.xform(profile, ws=True, ro=pRot) cmds.currentTime(current) # extrude the curve extr = cmds.extrude(profile, newCrv, ch=True, range=True, polygon=True, extrudeType=2, useComponentPivot=True, fixedPath=True, useProfileNormal=True, reverseSurfaceIfPathReversed=True) extrGeo, extrNode = extr[0], extr[1] normal = cmds.polyNormal(extrGeo, normalMode=4, userNormalMode=0, ch=1)[0] cmds.connectAttr("{}.outputX".format(reverse), "{}.normalMode".format(normal)) cmds.connectAttr("{}.message".format(extrGeo), "{}.geo".format(ctrl)) cmds.connectAttr("{}.geoVis".format(ctrl), "{}.visibility".format(extrGeo)) cmds.connectAttr("{}.rotateExtrusion".format(ctrl), "{}.rotation".format(extrNode)) # get extrude connections connects = cmds.listConnections(extrNode) profNode, pathNode, tessNode = connects[0], connects[1], connects[ 2] # connect up stuff to extrusion cmds.connectAttr("{}.outputX".format(mult), "{}.maxValue".format(pathNode)) cmds.connectAttr("{}.radiusDivisions".format(ctrl), "{}.uNumber".format(tessNode)) cmds.parent(newCrv, ctrl) cmds.setAttr("{}.inheritsTransform".format(deadGrp), 0) cmds.parent(extrGeo, deadGrp) cmds.parent(profile, deadGrp) cmds.setAttr("{}.v".format(profile), 0) cmds.parent(capGrp, deadGrp) # motion path stuff cmds.delete(moPathAnimAttr.partition(".")[0]) cmds.connectAttr("{}.outputX".format(mult), "{}.uValue".format(moPath)) cmds.setAttr("{}.visibility".format(cap)) cmds.setAttr("{}.visibility".format(profileOrig))
def setupIK(self, x): """sets up the IK portion of the limb rig""" #set values for this chain, side thisChain = self.IKChains[x] side = self.prefixList[x] thisBind = self.bindChains[x] #create ik control from joint 0 to 2 mainIK = "%s_%s_IK"%(side, self.limbName) IKHandle = cmds.ikHandle(n=mainIK, sj=thisChain[0], ee=thisChain[2], sol="ikRPsolver")[0] self.IKHandles.append(IKHandle) #create a control for the ik IKCtrl = self.setupIKCtrl(x, IKHandle) #call pole vector method? - pass IK name, normal or no flip #-----------------get argument from UI about what kind of handles thisPv = self.setupPV(IKHandle, "normal", x) #create stretchy bits cmds.addAttr(IKCtrl, ln="__EXTRA__", nn="__EXTRA__", at="short", k=True) cmds.setAttr("%s.__EXTRA__"%IKCtrl, l=True) cmds.addAttr(IKCtrl, ln="autoStretch", at="float", min=0, max=1, k=True) cmds.addAttr(IKCtrl, ln="scaleMin", at="float", min=0.5, max=3, k=True, dv=1) #add "upScale" and "lowScale" (.5-3) cmds.addAttr(IKCtrl, ln="upScale", at="float", min=0.3, max=3, k=True, dv=1.0) cmds.addAttr(IKCtrl, ln="lowScale", at="float", min=0.3, max=3, k=True, dv=1.0) cmds.addAttr(IKCtrl, ln="__IKFOOT__", nn="__EXTRA__", at="short", k=True) cmds.setAttr("%s.__IKFOOT__"%IKCtrl, l=True) cmds.addAttr(IKCtrl, ln="ballRoll", at="float", k=True, dv=0) cmds.addAttr(IKCtrl, ln="toeRoll", at="float", k=True, dv=0) cmds.addAttr(IKCtrl, ln="heelRoll", at="float", k=True, dv=0) cmds.addAttr(IKCtrl, ln="toePivot", at="float", k=True, dv=0) cmds.addAttr(IKCtrl, ln="heelPivot", at="float", k=True, dv=0) cmds.addAttr(IKCtrl, ln="toeFlap", at="float", k=True, dv=0) #from measure, get final add node add = self.measureAdds[x] #orient the IK wrist to the control? do it here or elsewhere (for inheritance?) cmds.orientConstraint(IKCtrl, thisChain[2], mo=True) #create distance node from thigh to ctrl distance = rig.measureDistance("%s_%s_ikCtrlDistance"%(side, self.limbName), self.measureChains[x][0], IKCtrl) ratioMult, defaultMult, defaultBlend, conditional, upScaleMult, loScaleMult = rig.scaleStretchIK(("%s_%s"%(side, self.limbName)), thisChain[0], thisChain[1], thisChain[2], "%s.output"%add, "%s.distance"%distance, IKCtrl, self.jAxis1) #create the ik switch (call as "diamond") ikSwitchName = "%s_%s_FKIKSwitch"%(side, self.limbName) if x == 0: thisIKSwitch = rig.createControl(ikSwitchName, "diamond", self.jAxis1, "lightBlue") if x == 1: thisIKSwitch = rig.createControl(ikSwitchName, "diamond", self.jAxis1, "pink") rig.stripTransforms(thisIKSwitch) cmds.addAttr(thisIKSwitch, ln="FKIK", k=True, at="float", min=0, max=1, dv=0) #create reverse thisIKSwitchRev = cmds.shadingNode("reverse", asUtility=True, n="%s_%s_IKSwtchReverse"%(side, self.limbName)) cmds.connectAttr("%s.FKIK"%thisIKSwitch, "%s.inputX"%thisIKSwitchRev) rig.groupOrient(thisBind[2], thisIKSwitch, self.groupSuffix) IKSwitchGrp = cmds.listRelatives(thisIKSwitch, p=True) #do stuff here to push the IKFK switch in the right direction if x== 0: offset = -3 if x==1: offset = 3 cmds.xform(IKSwitchGrp, os=True, r=True, t=(0, 0, offset)) self.IKSwitches.append(thisIKSwitch) self.IKSwitchesRev.append(thisIKSwitchRev) #set up visibility switching from this for IK and PV controls #get pv parent group pvGroup = cmds.listRelatives(thisPv, p=True)[0] ikCtrlGroup = cmds.listRelatives(IKCtrl, p=True)[0] cmds.connectAttr("%s.FKIK"%thisIKSwitch, "%s.v"%pvGroup) cmds.connectAttr("%s.FKIK"%thisIKSwitch, "%s.v"%ikCtrlGroup) #pass onto the FK part of the rig self.setupFK(x)
#to connect a vis attr to the vis of the shape nodes import maya.cmds as cmds sel = cmds.ls(sl=True) for ctrl in sel: thisShape = cmds.listRelatives(ctrl, s=True, c=True) cmds.connectAttr("COG_CTRL.fineShaperCtrls", "%s.visibility"%thisShape[0]) #to add controls to selected cvs (via cluster, replace weighted node w/control) import maya.cmds as cmds import zbw_rig as rig sel = cmds.ls(sl=True, fl=True) for i in range(len(sel)): #create a cluster cluster = cmds.cluster(sel[i], relative=False, n="cluster%02d"%i) #print(cluster) #for that cluster, create a circle control at that cluster ctrl = rig.createControl("control%02d"%i, "sphere", "z", "blue") rig.groupOrient(cluster[1], ctrl) #replace the weighted node of the cluster with the circle clusHandShape = cmds.listRelatives(cluster[1], s=True) cmds.cluster(cluster[0], e=True, bs=1, wn=(ctrl, ctrl)) cmds.setAttr("%s.originX"%clusHandShape[0], 0.0) cmds.setAttr("%s.originY"%clusHandShape[0], 0.0) cmds.setAttr("%s.originZ"%clusHandShape[0], 0.0) cmds.setAttr("%s.visibility"%clusHandShape[0], 0)
import maya.cmds as cmds import zbw_rig as rig crv = cmds.ls(sl=True)[0] cvs = cmds.ls("%s.cv[*]"%crv, fl=True) orList = [] for x in range(0, len(cvs)): cv = cvs[x] pos = cmds.pointPosition(cv) clsName = "%s_%s"%(crv, x) cls = cmds.cluster(cv, n=clsName)[1] ctrl = rig.createControl(name="%sCtrl"%clsName, type="sphere", color="red") grpOrient = rig.groupOrient(cls, ctrl) orList.append(grpOrient) cmds.parent(cls, ctrl) cmds.setAttr("%s.v"%cls, 0) cmds.group(orList, n="crvCtrlsGrp")
def createRibbon(self, *args): self.name = cmds.textFieldGrp(self.widgets["ribbonNameTFG"], q=True, tx=True) self.numDiv = (cmds.intFieldGrp(self.widgets["jointsIFG"], q=True, v=True)[0]) - 1 # self.fk = cmds.checkBox(self.widgets["fkSetupCB"], q=True, v=True) self.height = cmds.floatFieldGrp(self.widgets["heightFFG"], q=True, v1=True) self.ratio = cmds.floatFieldGrp(self.widgets["ratioFFG"], q=True, v1=True) # self.axis = cmds.radioButtonGrp(self.widgets["axis"] , q=True, sl=True) # print("axis = :%s"%self.axis) self.ribbonName = "%s_ribbonGeo" % self.name self.numJoints = self.numDiv self.follicleList = [] self.follicleJntList = [] # self.own = cmds.checkBox(self.widgets["existingGeoCB"], q=True, v=True) # self.myGeo = cmds.textFieldButtonGrp(self.widgets["geoTFBG"], q=True, tx=True) # self.dir = cmds.radioButtonGrp(self.widgets["directionRBG"], q=True, sl=True ) # print("dir: %s"%self.dir) # self.centerPos = cmds.floatSliderGrp(self.widgets["centerPosFSG"], q=True, v=True ) self.follicleGrpList = [] # -----------make sure the num of divisions is at least 1 # -----------create the nurbs plane in the correct axis (just make the plane in the axis and figure out how to rotate joint local rotational axes to match it) DON'T WORRY ABOUT THIS SO MUCH (IT'S HIDDEN), WORRY ABOUT THE CONTROLS BEING ORIENTED CORRECTLY!!! # if self.own == 0: # self.dir = 2 # if self.dir == 1: # dir = "u" # uDiv = self.numDiv # vDiv = 1 # else: # dir = "v'" # uDiv = 1 # vDiv = self.numDiv # if self.axis == 1: axis = [0, 0, 1] # elif self.axis == 2: # axis = [0, 1, 0] # elif self.axis == 3: # axis = [0, 0, 1] # if self.own == 0: width = self.height / self.ratio # create the nurbsPlane cmds.nurbsPlane(ax=axis, w=width, lr=self.ratio, d=3, u=1, v=4, ch=0, n=self.ribbonName) cmds.rebuildSurface( self.ribbonName, ch=0, rpo=1, rt=0, end=1, kr=0, kcp=0, kc=0, su=1, du=1, sv=4, dv=3, tol=0.1, fr=0, dir=2 ) cmds.move(0, self.height / 2, 0, self.ribbonName) cmds.xform(self.ribbonName, ws=True, rp=[0, 0, 0]) # else: # self.ribbonName = self.myGeo # find the ratio for the uv's (one dir will be .5, the other a result of the num joints) factor = 1.0 / self.numJoints # -------keep follicle joints separate, not parente under each follicle, separate group for those # -------follicle jnts each go under a ctrl (star) that is under a group. That group gets parent constrained to the follicles # -------these joints should be aligned with the follicles??? does that make a difference? # create the follicles on the surface, joints on the follicles for x in range(self.numJoints + 1): val = x * factor folName = "%s_follicle%s" % (self.name, x) # create a follicle in the right direction # if self.dir ==1: # follicle = rig.follicle(self.ribbonName, folName, val, 0.5)[0] # else: follicle = rig.follicle(self.ribbonName, folName, 0.5, val)[0] self.follicleList.append(follicle) # create joint and parent to follicle jointName = "%s_fol%s_JNT" % (self.name, x) # ---------have to figure out how to orient this correctly (just translate and rotate the joints (or the controls they're under)) # create joint control? then move the control and the joint under it to the correct rot and pos folPos = cmds.xform(follicle, q=True, ws=True, t=True) folRot = cmds.xform(follicle, q=True, ws=True, ro=True) cmds.select(cl=True) folJoint = cmds.joint(n=jointName, p=(0, 0, 0)) folGroup = cmds.group(folJoint, n="%s_GRP" % folJoint) # this could become control for the joint cmds.xform(folGroup, a=True, ws=True, t=folPos) cmds.xform(folGroup, a=True, ws=True, ro=folRot) self.follicleJntList.append(folJoint) self.follicleGrpList.append(folGroup) cmds.parent(folGroup, follicle) # create controls here: # create a loop that runs through the cvs in v, 0 to 6 origClusterList = [ "top_CLS", "topBez_CLS", "centerTop_CLS", "center_CLS", "centerEnd_CLS", "endBez_CLS", "end_CLS", ] origControlList = [ "top_CTRL", "topBez_CTRL", "centerTop_CTRL", "center_CTRL", "centerEnd_CTRL", "endBez_CTRL", "end_CTRL", ] clusterList = [] controlList = [] constrGrpList = [] attachGrpList = [] for v in range(0, 7): cmds.select(clear=True) clusNodeName = self.name + "_" + origClusterList[v] + "Base" # select u (0 and 1) for each v and cluster them fullCls = cmds.cluster("%s.cv[0:1][%d]" % (self.ribbonName, v), relative=False, n=clusNodeName)[0] clusHandle = clusNodeName + "Handle" clusName = clusHandle.rstrip("BaseHandle") cmds.rename(clusHandle, clusName) clusterList.append(clusName) # now setup the controls and groups for the clusters # goes control,group (const), group(attach) control = self.name + "_" + origControlList[v] constrGrp = self.name + "_" + origControlList[v] + "_const_GRP" attachGrp = self.name + "_" + origControlList[v] + "_attach_GRP" rig.createControl(name=control, type="circle", axis="y", color="darkGreen", *args) oldGrp = rig.groupOrient(clusName, control) cmds.rename(oldGrp, constrGrp) # parent clus to control cmds.parent(clusName, control) # get cluster position clusPos = cmds.pointPosition(clusName + ".rotatePivot") cmds.xform(constrGrp, ws=True, piv=(clusPos[0], clusPos[1], clusPos[2])) cmds.group(constrGrp, n=attachGrp) cmds.xform(attachGrp, ws=True, piv=(clusPos[0], clusPos[1], clusPos[2])) controlList.append(control) constrGrpList.append(constrGrp) attachGrpList.append(attachGrp)