def rigModule(self, *args): Base.StartClass.rigModule(self) # verify if the guide exists: if cmds.objExists(self.moduleGrp): try: hideJoints = cmds.checkBox("hideJointsCB", query=True, value=True) except: hideJoints = 1 # declare lists to store names and attributes: self.worldRefList, self.headCtrlList = [], [] # start as no having mirror: sideList = [""] # analisys the mirror module: self.mirrorAxis = cmds.getAttr(self.moduleGrp + ".mirrorAxis") if self.mirrorAxis != "off": # get rigs names: self.mirrorNames = cmds.getAttr(self.moduleGrp + ".mirrorName") # get first and last letters to use as side initials (prefix): sideList = [self.mirrorNames[0] + "_", self.mirrorNames[len(self.mirrorNames) - 1] + "_"] for s, side in enumerate(sideList): duplicated = cmds.duplicate(self.moduleGrp, name=side + self.userGuideName + "_Guide_Base")[0] allGuideList = cmds.listRelatives(duplicated, allDescendents=True) for item in allGuideList: cmds.rename(item, side + self.userGuideName + "_" + item) self.mirrorGrp = cmds.group(name="Guide_Base_Grp", empty=True) cmds.parent(side + self.userGuideName + "_Guide_Base", self.mirrorGrp, absolute=True) # re-rename grp: cmds.rename(self.mirrorGrp, side + self.userGuideName + "_" + self.mirrorGrp) # do a group mirror with negative scaling: if s == 1: for axis in self.mirrorAxis: cmds.setAttr(side + self.userGuideName + "_" + self.mirrorGrp + ".scale" + axis, -1) else: # if not mirror: duplicated = cmds.duplicate(self.moduleGrp, name=self.userGuideName + "_Guide_Base")[0] allGuideList = cmds.listRelatives(duplicated, allDescendents=True) for item in allGuideList: cmds.rename(item, self.userGuideName + "_" + item) self.mirrorGrp = cmds.group(self.userGuideName + "_Guide_Base", name="Guide_Base_Grp", relative=True) # re-rename grp: cmds.rename(self.mirrorGrp, self.userGuideName + "_" + self.mirrorGrp) # store the number of this guide by module type dpAR_count = utils.findModuleLastNumber(CLASS_NAME, "dpAR_type") + 1 # run for all sides for s, side in enumerate(sideList): # redeclaring variables: self.base = side + self.userGuideName + "_Guide_Base" self.cvNeckLoc = side + self.userGuideName + "_Guide_neck" self.cvHeadLoc = side + self.userGuideName + "_Guide_head" self.cvJawLoc = side + self.userGuideName + "_Guide_jaw" self.cvChinLoc = side + self.userGuideName + "_Guide_chin" self.cvLLipLoc = side + self.userGuideName + "_Guide_lLip" self.cvRLipLoc = side + self.userGuideName + "_Guide_rLip" self.cvEndJoint = side + self.userGuideName + "_Guide_JointEnd" # creating joints: self.neckJnt = cmds.joint( name=side + self.userGuideName + "_" + self.langDic[self.langName]["c_neck"] + "_Jnt" ) self.headJxt = cmds.joint( name=side + self.userGuideName + "_" + self.langDic[self.langName]["c_head"] + "_Jxt" ) cmds.select(clear=True) self.headJnt = cmds.joint( name=side + self.userGuideName + "_" + self.langDic[self.langName]["c_head"] + "_Jnt", scaleCompensate=False, ) self.jawJnt = cmds.joint( name=side + self.userGuideName + "_" + self.langDic[self.langName]["c_jaw"] + "_Jnt", scaleCompensate=False, ) self.chinJnt = cmds.joint( name=side + self.userGuideName + "_" + self.langDic[self.langName]["c_chin"] + "_Jnt", scaleCompensate=False, ) self.endJnt = cmds.joint(name=side + self.userGuideName + "_JEnd", scaleCompensate=False) cmds.select(clear=True) self.lLipJnt = cmds.joint( name=side + self.userGuideName + "_" + self.langDic[self.langName]["p002_left"] + "_" + self.langDic[self.langName]["c_lip"] + "_Jnt", scaleCompensate=False, ) cmds.select(clear=True) self.rLipJnt = cmds.joint( name=side + self.userGuideName + "_" + self.langDic[self.langName]["p003_right"] + "_" + self.langDic[self.langName]["c_lip"] + "_Jnt", scaleCompensate=False, ) dpARJointList = [self.neckJnt, self.headJnt, self.jawJnt, self.chinJnt, self.lLipJnt, self.rLipJnt] for dpARJoint in dpARJointList: cmds.addAttr(dpARJoint, longName="dpAR_joint", attributeType="float", keyable=False) # creating controls: self.neckCtrl = ctrls.cvNeck( ctrlName=side + self.userGuideName + "_" + self.langDic[self.langName]["c_neck"] + "_Ctrl", r=self.ctrlRadius / 2.0, ) self.headCtrl = ctrls.cvHead( ctrlName=side + self.userGuideName + "_" + self.langDic[self.langName]["c_head"] + "_Ctrl", r=self.ctrlRadius / 2.0, ) self.jawCtrl = ctrls.cvJaw( ctrlName=side + self.userGuideName + "_" + self.langDic[self.langName]["c_jaw"] + "_Ctrl", r=self.ctrlRadius / 2.0, ) self.chinCtrl = ctrls.cvChin( ctrlName=side + self.userGuideName + "_" + self.langDic[self.langName]["c_chin"] + "_Ctrl", r=self.ctrlRadius / 2.0, ) self.lLipCtrl = cmds.circle( name=side + self.userGuideName + "_" + self.langDic[self.langName]["p002_left"] + "_" + self.langDic[self.langName]["c_lip"] + "_Ctrl", ch=False, o=True, nr=(0, 0, 1), d=3, s=8, radius=(self.ctrlRadius * 0.25), )[0] self.rLipCtrl = cmds.circle( name=side + self.userGuideName + "_" + self.langDic[self.langName]["p003_right"] + "_" + self.langDic[self.langName]["c_lip"] + "_Ctrl", ch=False, o=True, nr=(0, 0, 1), d=3, s=8, radius=(self.ctrlRadius * 0.25), )[0] self.headCtrlList.append(self.headCtrl) # creating the originedFrom attributes (in order to permit integrated parents in the future): utils.originedFrom(objName=self.neckCtrl, attrString=self.base + ";" + self.cvNeckLoc) utils.originedFrom(objName=self.headCtrl, attrString=self.cvHeadLoc) utils.originedFrom(objName=self.jawCtrl, attrString=self.cvJawLoc) utils.originedFrom(objName=self.chinCtrl, attrString=self.cvChinLoc + ";" + self.cvEndJoint) # orientation of controls: ctrls.setAndFreeze(nodeName=self.neckCtrl, rx=90, rz=-90) ctrls.setAndFreeze(nodeName=self.headCtrl, rx=90, rz=-90) ctrls.setAndFreeze(nodeName=self.jawCtrl, rz=-90) ctrls.setAndFreeze(nodeName=self.chinCtrl, rz=-90) # edit the mirror shape to a good direction of controls: ctrlList = [self.neckCtrl, self.headCtrl, self.jawCtrl, self.chinCtrl] if s == 1: for ctrl in ctrlList: if self.mirrorAxis == "X": cmds.setAttr(ctrl + ".rotateY", 180) elif self.mirrorAxis == "Y": cmds.setAttr(ctrl + ".rotateY", 180) elif self.mirrorAxis == "Z": cmds.setAttr(ctrl + ".rotateX", 180) cmds.setAttr(ctrl + ".rotateZ", 180) elif self.mirrorAxis == "XYZ": cmds.setAttr(ctrl + ".rotateX", 180) cmds.setAttr(ctrl + ".rotateZ", 180) cmds.makeIdentity(ctrlList, apply=True, translate=False, rotate=True, scale=False) # temporary parentConstraints: tempDelNeck = cmds.parentConstraint(self.cvNeckLoc, self.neckCtrl, maintainOffset=False) tempDelHead = cmds.parentConstraint(self.cvHeadLoc, self.headCtrl, maintainOffset=False) tempDelJaw = cmds.parentConstraint(self.cvJawLoc, self.jawCtrl, maintainOffset=False) tempDelChin = cmds.parentConstraint(self.cvChinLoc, self.chinCtrl, maintainOffset=False) tempDelLLip = cmds.parentConstraint(self.cvLLipLoc, self.lLipCtrl, maintainOffset=False) tempDelRLip = cmds.parentConstraint(self.cvRLipLoc, self.rLipCtrl, maintainOffset=False) cmds.delete(tempDelNeck, tempDelHead, tempDelJaw, tempDelChin, tempDelLLip, tempDelRLip) # zeroOut controls: self.zeroLipCtrlList = utils.zeroOut([self.lLipCtrl, self.rLipCtrl]) self.lLipGrp = cmds.group(self.lLipCtrl, name=self.lLipCtrl + "_Grp") self.rLipGrp = cmds.group(self.rLipCtrl, name=self.rLipCtrl + "_Grp") self.zeroCtrlList = utils.zeroOut( [ self.neckCtrl, self.headCtrl, self.jawCtrl, self.chinCtrl, self.zeroLipCtrlList[0], self.zeroLipCtrlList[1], ] ) # make joints be ride by controls: cmds.makeIdentity( self.neckJnt, self.headJxt, self.headJnt, self.jawJnt, self.chinJnt, self.endJnt, rotate=True, apply=True, ) cmds.parentConstraint( self.neckCtrl, self.neckJnt, maintainOffset=False, name=self.neckJnt + "_ParentConstraint" ) cmds.scaleConstraint( self.neckCtrl, self.neckJnt, maintainOffset=False, name=self.neckJnt + "_ScaleConstraint" ) cmds.delete(cmds.parentConstraint(self.headCtrl, self.headJxt, maintainOffset=False)) cmds.parentConstraint( self.headCtrl, self.headJnt, maintainOffset=False, name=self.headJnt + "_ParentConstraint" ) cmds.parentConstraint( self.jawCtrl, self.jawJnt, maintainOffset=False, name=self.jawJnt + "_ParentConstraint" ) cmds.parentConstraint( self.chinCtrl, self.chinJnt, maintainOffset=False, name=self.chinJnt + "_ParentConstraint" ) cmds.parentConstraint( self.lLipCtrl, self.lLipJnt, maintainOffset=False, name=self.lLipJnt + "_ParentConstraint" ) cmds.parentConstraint( self.rLipCtrl, self.rLipJnt, maintainOffset=False, name=self.rLipJnt + "_ParentConstraint" ) cmds.scaleConstraint( self.headCtrl, self.headJnt, maintainOffset=False, name=self.headJnt + "_ScaleConstraint" ) cmds.scaleConstraint( self.jawCtrl, self.jawJnt, maintainOffset=False, name=self.jawJnt + "_ScaleConstraint" ) cmds.scaleConstraint( self.chinCtrl, self.chinJnt, maintainOffset=False, name=self.chinJnt + "_ScaleConstraint" ) cmds.scaleConstraint( self.lLipCtrl, self.lLipJnt, maintainOffset=False, name=self.lLipJnt + "_ScaleConstraint" ) cmds.scaleConstraint( self.rLipCtrl, self.rLipJnt, maintainOffset=False, name=self.rLipJnt + "_ScaleConstraint" ) cmds.delete(cmds.parentConstraint(self.cvEndJoint, self.endJnt, maintainOffset=False)) # create interations between neck and head: self.grpNeck = cmds.group(self.zeroCtrlList[0], name=self.neckCtrl + "_Grp") self.grpHeadA = cmds.group(empty=True, name=self.headCtrl + "_A_Grp") self.grpHead = cmds.group(self.grpHeadA, name=self.headCtrl + "_Grp") # arrange pivots: self.neckPivot = cmds.xform(self.neckCtrl, query=True, worldSpace=True, translation=True) self.headPivot = cmds.xform(self.headCtrl, query=True, worldSpace=True, translation=True) cmds.xform(self.grpNeck, pivots=(self.neckPivot[0], self.neckPivot[1], self.neckPivot[2])) cmds.xform( self.grpHead, self.grpHeadA, pivots=(self.headPivot[0], self.headPivot[1], self.headPivot[2]) ) self.worldRef = cmds.group(empty=True, name=side + self.userGuideName + "_WorldRef") self.worldRefList.append(self.worldRef) cmds.delete(cmds.parentConstraint(self.neckCtrl, self.worldRef, maintainOffset=False)) cmds.parentConstraint( self.neckCtrl, self.grpHeadA, maintainOffset=True, skipRotate=["x", "y", "z"], name=self.grpHeadA + "_ParentConstraint", ) orientConst = cmds.orientConstraint( self.neckCtrl, self.worldRef, self.grpHeadA, maintainOffset=False, name=self.grpHeadA + "_OrientConstraint", )[0] cmds.parent(self.zeroCtrlList[1], self.grpHeadA, absolute=True) # connect reverseNode: cmds.addAttr( self.headCtrl, longName=self.langDic[self.langName]["c_Follow"], attributeType="float", minValue=0, maxValue=1, keyable=True, ) cmds.connectAttr( self.headCtrl + "." + self.langDic[self.langName]["c_Follow"], orientConst + "." + self.neckCtrl + "W0", force=True, ) self.headRevNode = cmds.createNode("reverse", name=side + self.userGuideName + "_Rev") cmds.connectAttr( self.headCtrl + "." + self.langDic[self.langName]["c_Follow"], self.headRevNode + ".inputX", force=True, ) cmds.connectAttr(self.headRevNode + ".outputX", orientConst + "." + self.worldRef + "W1", force=True) # mount controls hierarchy: cmds.parent(self.zeroCtrlList[3], self.jawCtrl, absolute=True) # jaw follow head or root ctrl (using worldRef) jawParentConst = cmds.parentConstraint( self.headCtrl, self.worldRef, self.zeroCtrlList[2], maintainOffset=True, name=self.zeroCtrlList[2] + "_ParentConstraint", )[0] cmds.setAttr(jawParentConst + ".interpType", 0) # no flip cmds.addAttr( self.jawCtrl, longName=self.langDic[self.langName]["c_Follow"], attributeType="float", minValue=0, maxValue=1, defaultValue=1, keyable=True, ) cmds.connectAttr( self.jawCtrl + "." + self.langDic[self.langName]["c_Follow"], jawParentConst + "." + self.headCtrl + "W0", force=True, ) jawFollowRev = cmds.createNode("reverse", name=self.jawCtrl + "_Rev") cmds.connectAttr( self.jawCtrl + "." + self.langDic[self.langName]["c_Follow"], jawFollowRev + ".inputX", force=True ) cmds.connectAttr(jawFollowRev + ".outputX", jawParentConst + "." + self.worldRef + "W1", force=True) # setup jaw auto translation self.jawSdkGrp = cmds.group(self.jawCtrl, name=self.jawCtrl + "_SDK_Grp") cmds.addAttr( self.jawCtrl, longName=self.langDic[self.langName]["c_moveIntensity"] + "Y", attributeType="float", keyable=True, ) cmds.addAttr( self.jawCtrl, longName=self.langDic[self.langName]["c_moveIntensity"] + "Z", attributeType="float", keyable=True, ) cmds.addAttr( self.jawCtrl, longName=self.langDic[self.langName]["c_moveStartRotation"], attributeType="float", keyable=True, ) cmds.setAttr( self.jawCtrl + "." + self.langDic[self.langName]["c_moveIntensity"] + "Y", keyable=False, channelBox=True, ) cmds.setAttr( self.jawCtrl + "." + self.langDic[self.langName]["c_moveIntensity"] + "Z", keyable=False, channelBox=True, ) cmds.setAttr( self.jawCtrl + "." + self.langDic[self.langName]["c_moveStartRotation"], keyable=False, channelBox=True, ) cmds.setAttr(self.jawCtrl + "." + self.langDic[self.langName]["c_moveIntensity"] + "Y", 0.01) cmds.setAttr(self.jawCtrl + "." + self.langDic[self.langName]["c_moveIntensity"] + "Z", -0.02) cmds.setAttr(self.jawCtrl + "." + self.langDic[self.langName]["c_moveStartRotation"], -10) self.jawIntensityMD = cmds.createNode("multiplyDivide", name="JawMoveIntensity_MD") self.jawIntensityZMD = cmds.createNode("multiplyDivide", name="JawMoveIntensityZ_MD") self.jawStartIntensityMD = cmds.createNode("multiplyDivide", name="JawMoveIntensityStart_MD") self.jawIntensityPMA = cmds.createNode("plusMinusAverage", name="JawMoveIntensity_PMA") self.jawIntensityCnd = cmds.createNode("condition", name="JawMoveIntensity_Cnd") cmds.connectAttr(self.jawCtrl + ".rotateY", self.jawIntensityMD + ".input1Y", force=True) cmds.connectAttr( self.jawCtrl + "." + self.langDic[self.langName]["c_moveIntensity"] + "Y", self.jawIntensityMD + ".input2Y", force=True, ) cmds.connectAttr( self.jawCtrl + "." + self.langDic[self.langName]["c_moveIntensity"] + "Y", self.jawStartIntensityMD + ".input1X", force=True, ) cmds.connectAttr( self.jawCtrl + "." + self.langDic[self.langName]["c_moveStartRotation"], self.jawStartIntensityMD + ".input2X", force=True, ) cmds.setAttr(self.jawIntensityPMA + ".operation", 2) cmds.connectAttr(self.jawIntensityMD + ".outputY", self.jawIntensityPMA + ".input1D[0]", force=True) cmds.connectAttr( self.jawStartIntensityMD + ".outputX", self.jawIntensityPMA + ".input1D[1]", force=True ) cmds.connectAttr(self.jawIntensityPMA + ".output1D", self.jawIntensityCnd + ".colorIfTrueG", force=True) cmds.connectAttr(self.jawCtrl + ".rotateY", self.jawIntensityCnd + ".firstTerm", force=True) cmds.connectAttr( self.jawCtrl + "." + self.langDic[self.langName]["c_moveStartRotation"], self.jawIntensityCnd + ".secondTerm", force=True, ) cmds.setAttr(self.jawIntensityCnd + ".operation", 4) cmds.setAttr(self.jawIntensityCnd + ".colorIfFalseG", 0) cmds.connectAttr(self.jawIntensityCnd + ".outColorG", self.jawSdkGrp + ".translateX", force=True) cmds.connectAttr(self.jawIntensityCnd + ".outColorG", self.jawIntensityZMD + ".input1Z", force=True) cmds.connectAttr( self.jawCtrl + "." + self.langDic[self.langName]["c_moveIntensity"] + "Z", self.jawIntensityZMD + ".input2Z", force=True, ) cmds.connectAttr(self.jawIntensityZMD + ".outputZ", self.jawSdkGrp + ".translateZ", force=True) # create lip setup: # left side lip: lLipParentConst = cmds.parentConstraint( self.jawCtrl, self.headCtrl, self.lLipGrp, maintainOffset=True, name=self.lLipGrp + "_ParentConstraint", )[0] cmds.setAttr(lLipParentConst + ".interpType", 0) cmds.addAttr( self.lLipCtrl, longName=self.langDic[self.langName]["c_Follow"], attributeType="float", minValue=0, maxValue=1, defaultValue=0.5, keyable=True, ) cmds.connectAttr( self.lLipCtrl + "." + self.langDic[self.langName]["c_Follow"], lLipParentConst + "." + self.jawCtrl + "W0", force=True, ) self.lLipRevNode = cmds.createNode( "reverse", name=side + self.userGuideName + "_" + self.langDic[self.langName]["p002_left"] + "_" + self.langDic[self.langName]["c_lip"] + "_Rev", ) cmds.connectAttr( self.lLipCtrl + "." + self.langDic[self.langName]["c_Follow"], self.lLipRevNode + ".inputX", force=True, ) cmds.connectAttr( self.lLipRevNode + ".outputX", lLipParentConst + "." + self.headCtrl + "W1", force=True ) # right side lip: rLipParentConst = cmds.parentConstraint( self.jawCtrl, self.headCtrl, self.rLipGrp, maintainOffset=True, name=self.rLipGrp + "_ParentConstraint", )[0] cmds.setAttr(rLipParentConst + ".interpType", 0) cmds.addAttr( self.rLipCtrl, longName=self.langDic[self.langName]["c_Follow"], attributeType="float", minValue=0, maxValue=1, defaultValue=0.5, keyable=True, ) cmds.connectAttr( self.rLipCtrl + "." + self.langDic[self.langName]["c_Follow"], rLipParentConst + "." + self.jawCtrl + "W0", force=True, ) self.rLipRevNode = cmds.createNode( "reverse", name=side + self.userGuideName + "_" + self.langDic[self.langName]["p003_right"] + "_" + self.langDic[self.langName]["c_lip"] + "_Rev", ) cmds.connectAttr( self.rLipCtrl + "." + self.langDic[self.langName]["c_Follow"], self.rLipRevNode + ".inputX", force=True, ) cmds.connectAttr( self.rLipRevNode + ".outputX", rLipParentConst + "." + self.headCtrl + "W1", force=True ) # create a locator in order to avoid delete static group loc = cmds.spaceLocator(name=side + self.userGuideName + "_DO_NOT_DELETE")[0] cmds.parent(loc, self.worldRef, absolute=True) cmds.setAttr(loc + ".visibility", 0) ctrls.setLockHide([loc], ["tx", "ty", "tz", "rx", "ry", "rz", "sx", "sy", "sz", "v"]) # hiding visibility attributes: ctrls.setLockHide([self.headCtrl, self.neckCtrl, self.jawCtrl, self.chinCtrl], ["v"], l=False) # create a masterModuleGrp to be checked if this rig exists: self.toCtrlHookGrp = cmds.group( self.grpNeck, self.grpHead, self.zeroCtrlList[2], self.zeroCtrlList[4], self.zeroCtrlList[5], name=side + self.userGuideName + "_Control_Grp", ) self.toScalableHookGrp = cmds.group( self.neckJnt, self.headJnt, self.lLipJnt, self.rLipJnt, name=side + self.userGuideName + "_Joint_Grp", ) self.toStaticHookGrp = cmds.group( self.toCtrlHookGrp, self.toScalableHookGrp, self.grpHead, self.worldRef, name=side + self.userGuideName + "_Grp", ) cmds.addAttr(self.toStaticHookGrp, longName="dpAR_name", dataType="string") cmds.addAttr(self.toStaticHookGrp, longName="dpAR_type", dataType="string") cmds.setAttr(self.toStaticHookGrp + ".dpAR_name", self.userGuideName, type="string") cmds.setAttr(self.toStaticHookGrp + ".dpAR_type", CLASS_NAME, type="string") # add module type counter value cmds.addAttr(self.toStaticHookGrp, longName="dpAR_count", attributeType="long", keyable=False) cmds.setAttr(self.toStaticHookGrp + ".dpAR_count", dpAR_count) # add hook attributes to be read when rigging integrated modules: utils.addHook(objName=self.toCtrlHookGrp, hookType="ctrlHook") utils.addHook(objName=self.grpHead, hookType="rootHook") utils.addHook(objName=self.toScalableHookGrp, hookType="scalableHook") utils.addHook(objName=self.toStaticHookGrp, hookType="staticHook") if hideJoints: cmds.setAttr(self.toScalableHookGrp + ".visibility", 0) # delete duplicated group for side (mirror): cmds.delete(side + self.userGuideName + "_" + self.mirrorGrp) # finalize this rig: self.integratingInfo() cmds.select(clear=True) # delete UI (moduleLayout), GUIDE and moduleInstance namespace: self.deleteModule()
def createRibbon(axis=(0, 0, 1), name='xxxx', horizontal=False, numJoints=3, guias=None, v=True, s=0, firstLimb=True, upCtrl=None, ctrlRadius=1, worldRef="worldRef"): retDict = {} #define variables top_Loc = [] mid_Loc = [] bttm_Loc = [] rb_Jnt = [] drv_Jnt =[] fols = [] aux_Jnt = [] ribbon = '' extraCtrlList = [] #define attributes limbManualVVAttr = "limbManualVolume" limbVVAttr = "limbVolumeVariation" limbMinVVAttr = "limbMinVolume" #create a nurbsPlane based in the choose orientation option if horizontal: ribbon =cmds.nurbsPlane(ax=axis, w=numJoints, lr=(1/float(numJoints)), d=3, u=numJoints, v=1, ch=0, name=name+'_Plane')[0] cmds.rebuildSurface(ribbon, ch=0, rpo=1, rt=0, end=1, kr=0, kcp=0, kc=0, sv=1, du=3, dv=1, tol=0.01, fr=0, dir=1) else: ribbon =cmds.nurbsPlane(ax=axis, w=1, lr=numJoints, d=3, u=1, v=numJoints, ch=0, name=name+'_Plane')[0] cmds.rebuildSurface(ribbon, ch=0, rpo=1, rt=0, end=1, kr=0, kcp=0, kc=0, su=1, du=1, dv=3, tol=0.01, fr=0, dir=0) # make this ribbonNurbsPlane as not skinable from dpAR_UI: cmds.addAttr(ribbon, longName="doNotSkinIt", attributeType="bool", keyable=True) cmds.setAttr(ribbon+".doNotSkinIt", 1) #call the function to create follicles and joint in the nurbsPlane results = createFollicles(rib=ribbon, num=numJoints, name=name, horizontal=horizontal) rb_Jnt = results[0] fols = results[1] #create locator controls for the middle of the ribbon mid_Loc.append(cmds.spaceLocator(name=name+'_Mid_Pos_Loc')[0]) mid_Loc.append(cmds.spaceLocator(name=name+'_Mid_Aim_Loc')[0]) mid_Loc.append(cmds.spaceLocator(name=name+'_Mid_Off_Loc')[0]) mid_Loc.append(cmds.spaceLocator(name=name+'_Mid_Up_Loc')[0]) #parent correctly the middle locators cmds.parent(mid_Loc[2], mid_Loc[1], relative=True) cmds.parent(mid_Loc[1], mid_Loc[0], relative=True) cmds.parent(mid_Loc[3], mid_Loc[0], relative=True) #create the locators controls for the top of the ribbon top_Loc.append(cmds.spaceLocator(name=name+'_Top_Pos_Loc')[0]) top_Loc.append(cmds.spaceLocator(name=name+'_Top_Aim_Loc')[0]) top_Loc.append(cmds.spaceLocator(name=name+'_Top_Up_Loc')[0]) #parent correctly the top locators cmds.parent(top_Loc[1], top_Loc[0], relative=True) cmds.parent(top_Loc[2], top_Loc[0], relative=True) #create the locators for the end of the ribbon bttm_Loc.append(cmds.spaceLocator(name=name+'_Bttm_Pos_Loc')[0]) bttm_Loc.append(cmds.spaceLocator(name=name+'_Bttm_Aim_Loc')[0]) bttm_Loc.append(cmds.spaceLocator(name=name+'_Bttm_Up_Loc')[0]) #parent correctly the bottom locators cmds.parent(bttm_Loc[1], bttm_Loc[0], relative=True) cmds.parent(bttm_Loc[2], bttm_Loc[0], relative=True) #put the top locators in the same place of the top joint cmds.parent(top_Loc[0], fols[len(fols)-1], relative=True) cmds.parent(top_Loc[0], w=True) #put the bottom locators in the same place of the bottom joint cmds.parent(bttm_Loc[0], fols[0], relative=True) cmds.parent(bttm_Loc[0], w=True) cmds.select(clear=True) #create the joints that will be used to control the ribbon drv_Jnt = cmds.duplicate([rb_Jnt[0], rb_Jnt[(len(rb_Jnt)-1)/2], rb_Jnt[len(rb_Jnt)-1]]) dup = cmds.duplicate([drv_Jnt[0], drv_Jnt[2]]) drv_Jnt.append(dup[0]) drv_Jnt.append(dup[1]) #cmds.parent(drv_Jnt, w=True) for jnt in drv_Jnt: cmds.joint(jnt, e=True, oj='none', ch=True, zso=True); cmds.setAttr(jnt+'.radius', cmds.getAttr(jnt+'.radius')+0.5) #rename created joints drv_Jnt[0] = cmds.rename(drv_Jnt[0], name+'_Drv_Bttm_Jxt') drv_Jnt[1] = cmds.rename(drv_Jnt[1], name+'_Drv_Mid_Jxt') drv_Jnt[2] = cmds.rename(drv_Jnt[2], name+'_Drv_Top_Jxt') drv_Jnt[3] = cmds.rename(drv_Jnt[3], name+'_Drv_Bttm_End') drv_Jnt[4] = cmds.rename(drv_Jnt[4], name+'_Drv_Top_End') #place joints correctly accordaly with the user options choose if (horizontal and axis==(1, 0, 0)) or (horizontal and axis==(0, 0, 1)): cmds.setAttr(bttm_Loc[2]+'.translateY', 2) cmds.setAttr(top_Loc[2]+'.translateY', 2) cmds.setAttr(mid_Loc[3]+'.translateY', 2) elif (horizontal and axis==(0, 1, 0)) or (not horizontal and axis==(1, 0, 0)): cmds.setAttr(bttm_Loc[2]+'.translateZ', 2) cmds.setAttr(top_Loc[2]+'.translateZ', 2) cmds.setAttr(mid_Loc[3]+'.translateZ', 2) elif not horizontal and axis==(0, 1, 0) or (not horizontal and axis==(0, 0, 1)): cmds.setAttr(bttm_Loc[2]+'.translateX', 2) cmds.setAttr(top_Loc[2]+'.translateX', 2) cmds.setAttr(mid_Loc[3]+'.translateX', 2) elif horizontal and axis==(0, 0, -1): if firstLimb: cmds.setAttr(bttm_Loc[2]+'.translateY', 2) cmds.setAttr(top_Loc[2]+'.translateX', -2) cmds.setAttr(mid_Loc[3]+'.translateX', -2) cmds.setAttr(mid_Loc[3]+'.translateY', 2) else: if s == 0: cmds.setAttr(bttm_Loc[2]+'.translateX', -2) cmds.setAttr(top_Loc[2]+'.translateY', -2) cmds.setAttr(mid_Loc[3]+'.translateX', -2) cmds.setAttr(mid_Loc[3]+'.translateY', 2) else: cmds.setAttr(bttm_Loc[2]+'.translateX', -2) cmds.setAttr(top_Loc[2]+'.translateY', -2) cmds.setAttr(mid_Loc[3]+'.translateX', -2) cmds.setAttr(mid_Loc[3]+'.translateY', 2) #create auxiliary joints that will be used to control the ribbon aux_Jnt.append(cmds.duplicate(drv_Jnt[1], name=name+'_Jxt_Rot')[0]) cmds.setAttr(aux_Jnt[0]+'.jointOrient', 0, 0, 0) aux_Jnt.append(cmds.duplicate(aux_Jnt[0], name=name+'_Jxt_Rot_End')[0]) cmds.parent(aux_Jnt[1], mid_Loc[3]) cmds.setAttr(aux_Jnt[1]+'.translate', 0, 0, 0) cmds.parent(aux_Jnt[1], aux_Jnt[0]) cmds.parent(mid_Loc[3], aux_Jnt[1]) #calculate the adjust for the new chain position dist = float(numJoints)/2.0 end_dist = (1/float(numJoints)) cmds.parent(drv_Jnt[3], drv_Jnt[0]) cmds.parent(drv_Jnt[4], drv_Jnt[2]) #adjust the joints orientation and position based in the options choose from user if horizontal and axis==(1, 0, 0): cmds.setAttr(drv_Jnt[0]+'.jointOrient', 0, 90, 0) cmds.setAttr(drv_Jnt[2]+'.jointOrient', 0, 90, 0) cmds.setAttr(drv_Jnt[0]+'.tz', -dist) cmds.setAttr(drv_Jnt[3]+'.tz', end_dist*dist) cmds.setAttr(drv_Jnt[2]+'.tz', dist) cmds.setAttr(drv_Jnt[4]+'.tz', -end_dist*dist) elif horizontal and axis==(0, 1, 0): cmds.setAttr(drv_Jnt[0]+'.jointOrient', 0, 0, 0) cmds.setAttr(drv_Jnt[2]+'.jointOrient', 0, 0, 0) cmds.setAttr(drv_Jnt[0]+'.tx', -dist) cmds.setAttr(drv_Jnt[3]+'.tx', end_dist*dist) cmds.setAttr(drv_Jnt[2]+'.tx', dist) cmds.setAttr(drv_Jnt[4]+'.tx', -end_dist*dist) elif horizontal and axis==(0, 0, 1): cmds.setAttr(drv_Jnt[0]+'.jointOrient', 0, 0, 0) cmds.setAttr(drv_Jnt[2]+'.jointOrient', 0, 0, 0) cmds.setAttr(drv_Jnt[0]+'.tx', -dist) cmds.setAttr(drv_Jnt[3]+'.tx', end_dist*dist) cmds.setAttr(drv_Jnt[2]+'.tx', dist) cmds.setAttr(drv_Jnt[4]+'.tx', -end_dist*dist) elif horizontal and axis==(0, 0, -1): cmds.setAttr(drv_Jnt[0]+'.jointOrient', 0, 0, 0) cmds.setAttr(drv_Jnt[2]+'.jointOrient', 0, 0, 0) cmds.setAttr(drv_Jnt[0]+'.tx', -dist) cmds.setAttr(drv_Jnt[3]+'.tx', end_dist*dist) cmds.setAttr(drv_Jnt[2]+'.tx', dist) cmds.setAttr(drv_Jnt[4]+'.tx', -end_dist*dist) elif not horizontal and axis==(1, 0, 0): cmds.setAttr(drv_Jnt[0]+'.jointOrient', 0, 0, -90) cmds.setAttr(drv_Jnt[2]+'.jointOrient', 0, 0, -90) cmds.setAttr(drv_Jnt[0]+'.ty', -dist) cmds.setAttr(drv_Jnt[3]+'.ty', end_dist*dist) cmds.setAttr(drv_Jnt[2]+'.ty', dist) cmds.setAttr(drv_Jnt[4]+'.ty', -end_dist*dist) elif not horizontal and axis==(0, 1, 0): cmds.setAttr(drv_Jnt[0]+'.jointOrient', 0, 90, 0) cmds.setAttr(drv_Jnt[2]+'.jointOrient', 0, 90, 0) cmds.setAttr(drv_Jnt[0]+'.tz', -dist) cmds.setAttr(drv_Jnt[3]+'.tz', end_dist*dist) cmds.setAttr(drv_Jnt[2]+'.tz', dist) cmds.setAttr(drv_Jnt[4]+'.tz', -end_dist*dist) elif not horizontal and axis==(0, 0, 1): cmds.setAttr(drv_Jnt[0]+'.jointOrient', 0, 0, -90) cmds.setAttr(drv_Jnt[2]+'.jointOrient', 0, 0, -90) cmds.setAttr(drv_Jnt[0]+'.ty', -dist) cmds.setAttr(drv_Jnt[3]+'.ty', end_dist*dist) cmds.setAttr(drv_Jnt[2]+'.ty', dist) cmds.setAttr(drv_Jnt[4]+'.ty', -end_dist*dist) #fix the control locators position and orientation cmds.parent(top_Loc[0], drv_Jnt[2]) cmds.setAttr(top_Loc[0]+'.translate', 0, 0, 0) cmds.parent(top_Loc[0], w=True) cmds.setAttr(top_Loc[0]+'.rotate', 0, 0, 0) cmds.parent(bttm_Loc[0], drv_Jnt[0]) cmds.setAttr(bttm_Loc[0]+'.translate', 0, 0, 0) cmds.parent(bttm_Loc[0], w=True) cmds.setAttr(bttm_Loc[0]+'.rotate', 0, 0, 0) cmds.parent(drv_Jnt[2], top_Loc[1]) cmds.parent(drv_Jnt[1], mid_Loc[2]) cmds.parent(drv_Jnt[0], bttm_Loc[1]) cmds.parent(aux_Jnt[0], mid_Loc[0]) #create a nurbs control in order to be used in the ribbon offset mid_Ctrl = cmds.circle (c=(0, 0, 0), nr=(1, 0, 0), ch=0, name=name+'_MidCtrl')[0] ctrls.renameShape([mid_Ctrl]) midCtrl = mid_Ctrl mid_Ctrl = cmds.group(n=mid_Ctrl+'_Grp', em=True) cmds.delete(cmds.parentConstraint(midCtrl, mid_Ctrl, mo=0)) cmds.parent(midCtrl, mid_Ctrl) #adjust the realtionship between the locators cmds.parent(mid_Ctrl, mid_Loc[2], r=True) cmds.parent(drv_Jnt[1], midCtrl) cmds.parent([top_Loc[2], mid_Loc[3], bttm_Loc[2]], w=True) cmds.makeIdentity(top_Loc[0], apply=True) cmds.makeIdentity(mid_Loc[0], apply=True) cmds.makeIdentity(bttm_Loc[0], apply=True) cmds.parent(top_Loc[2], top_Loc[0]) cmds.parent(bttm_Loc[2], bttm_Loc[0]) cmds.parent(mid_Loc[3], aux_Jnt[1]) #create needed constraints in the locators in order to set the top always follow, to the base always aim the middle, to the middle always aim the top if firstLimb: cmds.aimConstraint(drv_Jnt[1], bttm_Loc[1], offset=(0, 0, 0), weight=1, aimVector=(1, 0, 0), upVector=(0, 0, 1), worldUpType='object', worldUpObject=bttm_Loc[2], name=bttm_Loc[1]+"_AimConstraint") cmds.aimConstraint(top_Loc[0], mid_Loc[1], offset=(0, 0, 0), weight=1, aimVector=(1, 0, 0), upVector=(0, 0, 1), worldUpType='object', worldUpObject=mid_Loc[3], name=mid_Loc[1]+"_AimConstraint") cmds.aimConstraint(drv_Jnt[1], top_Loc[1], offset=(0, 0, 0), weight=1, aimVector=(-1, 0, 0), upVector=(0, 1, 0), worldUpType='object', worldUpObject=top_Loc[2], name=top_Loc[1]+"_AimConstraint") else: # bug fix to plane twist cmds.aimConstraint(drv_Jnt[1], bttm_Loc[1], offset=(0, 0, 0), weight=1, aimVector=(1, 0, 0), upVector=(0, 1, 0), worldUpType='object', worldUpObject=bttm_Loc[2], name=bttm_Loc[1]+"_AimConstraint") cmds.aimConstraint(top_Loc[0], mid_Loc[1], offset=(0, 0, 0), weight=1, aimVector=(-1, 0, 0), upVector=(0, 0, 1), worldUpType='object', worldUpObject=mid_Loc[3], name=mid_Loc[1]+"_AimConstraint") cmds.aimConstraint(drv_Jnt[1], top_Loc[1], offset=(0, 0, 0), weight=1, aimVector=(-1, 0, 0), upVector=(0, 0, 1), worldUpType='object', worldUpObject=top_Loc[2], name=top_Loc[1]+"_AimConstraint") #create a point and orient constraint for the middel control cmds.pointConstraint(top_Loc[0], bttm_Loc[0], mid_Loc[0], offset=(0, 0, 0), weight=1, name=mid_Loc[0]+"_PointConstraint") ori = cmds.orientConstraint(top_Loc[0], bttm_Loc[0], aux_Jnt[0], offset=(0, 0, 0), weight=1, name=aux_Jnt[0]+"_OrientConstraint") #ribbon scale (volume variation) if numJoints == 3: proportionList = [0.5, 1, 0.5] elif numJoints == 5: proportionList = [0.4, 0.8, 1, 0.8, 0.4] elif numJoints == 7: proportionList = [0.25, 0.5, 0.75, 1, 0.75, 0.5, 0.25] curveInfoNode = cmds.arclen(ribbon+".v[0.5]", constructionHistory=True) curveInfoNode = cmds.rename(curveInfoNode, ribbon+"_CurveInfo") rbScaleMD = cmds.createNode("multiplyDivide", name=ribbon+"_ScaleCompensate_MD") rbNormalizeMD = cmds.createNode("multiplyDivide", name=ribbon+"_Normalize_MD") cmds.setAttr(rbNormalizeMD+".operation", 2) cmds.connectAttr(curveInfoNode+".arcLength", rbNormalizeMD+".input2X", force=True) cmds.connectAttr(rbScaleMD+".outputX", rbNormalizeMD+".input1X", force=True) if cmds.objExists(worldRef): if not cmds.objExists(worldRef+"."+limbManualVVAttr): cmds.addAttr(worldRef, longName=limbVVAttr, attributeType="float", minValue=0, maxValue=1, defaultValue=1, keyable=True) cmds.addAttr(worldRef, longName=limbManualVVAttr, attributeType="float", defaultValue=1, keyable=True) cmds.addAttr(worldRef, longName=limbMinVVAttr, attributeType="float", defaultValue=0.01, keyable=True) cmds.connectAttr(worldRef+".scaleX", rbScaleMD+".input1X", force=True) #fix group hierarchy extraCtrlGrp = cmds.group(empty=True, name=name+"_ExtraBendyCtrl_Grp") i = 0 for jnt in rb_Jnt: cmds.makeIdentity(jnt, a=True) # create extra control extraCtrlName = jnt.replace("_Jnt", "_Ctrl") extraCtrl = ctrls.cvSquare(ctrlName=extraCtrlName, r=ctrlRadius) extraCtrlList.append(extraCtrl) cmds.rotate(0, 0, 90, extraCtrl) cmds.makeIdentity(extraCtrl, a=True) extraCtrlZero = utils.zeroOut([extraCtrl])[0] cmds.parent(extraCtrlZero, extraCtrlGrp) cmds.parentConstraint(fols[i], extraCtrlZero, w=1, name=extraCtrlZero+"_ParentConstraint") cmds.parentConstraint(extraCtrl, jnt, w=1, name=jnt+"_ParentConstraint") cmds.scaleConstraint(extraCtrl, jnt, w=1, name=jnt+"_ScaleConstraint") # work with volume variation rbProportionMD = cmds.createNode("multiplyDivide", name=extraCtrlName.replace("_Ctrl", "_Proportion_MD")) rbIntensityMD = cmds.createNode("multiplyDivide", name=extraCtrlName.replace("_Ctrl", "_Intensity_MD")) rbAddScalePMA = cmds.createNode("plusMinusAverage", name=extraCtrlName.replace("_Ctrl", "_AddScale_PMA")) rbScaleClp = cmds.createNode("clamp", name=extraCtrlName.replace("_Ctrl", "_Scale_Clp")) rbBlendCB = cmds.createNode("blendColors", name=extraCtrlName.replace("_Ctrl", "_Blend_BC")) cmds.connectAttr(worldRef+"."+limbVVAttr, rbBlendCB+".blender", force=True) cmds.setAttr(rbBlendCB+".color2", 1, 1, 1, type="double3") cmds.connectAttr(rbNormalizeMD+".outputX", rbProportionMD+".input1X", force=True) cmds.setAttr(rbProportionMD+".input2X", proportionList[i]) cmds.connectAttr(rbProportionMD+".outputX", rbIntensityMD+".input1X", force=True) cmds.connectAttr(worldRef+"."+limbManualVVAttr, rbIntensityMD+".input2X", force=True) cmds.connectAttr(rbIntensityMD+".outputX", rbAddScalePMA+".input1D[1]", force=True) cmds.connectAttr(rbAddScalePMA+".output1D", rbScaleClp+".inputR", force=True) cmds.connectAttr(worldRef+"."+limbMinVVAttr, rbScaleClp+".minR") cmds.setAttr(rbScaleClp+".maxR", 1000000) cmds.connectAttr(rbScaleClp+".outputR", rbBlendCB+".color1.color1R", force=True) cmds.connectAttr(rbBlendCB+".output.outputR", extraCtrlZero+".scaleY", force=True) cmds.connectAttr(rbBlendCB+".output.outputR", extraCtrlZero+".scaleZ", force=True) # update i i = i + 1 locatorsGrp = cmds.group(bttm_Loc[0], top_Loc[0], mid_Loc[0], n=name+'_Loc_Grp') skinJntGrp = cmds.group(rb_Jnt, n=name+'_Jnt_Grp') finalSystemGrp = cmds.group(ribbon, locatorsGrp, skinJntGrp, n=name+'_RibbonSystem_Grp') #do the controller joints skin and the ribbon ribbonShape = cmds.listRelatives(ribbon, shapes=True) skin = cmds.skinCluster(drv_Jnt[0:3], ribbonShape, tsb=True, mi=2, dr=1) #skin presets for the ribbon (that's amazing!) if not horizontal: if numJoints == 3: cmds.skinPercent(skin[0], ribbon + '.cv[0:1][5]', tv=(drv_Jnt[2], 1)) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][4]', tv=[(drv_Jnt[2], 0.6), (drv_Jnt[1], 0.4)]) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][3]', tv=[(drv_Jnt[2], 0.2), (drv_Jnt[1], 0.8)]) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][2]', tv=[(drv_Jnt[0], 0.2), (drv_Jnt[1], 0.8)]) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][1]', tv=[(drv_Jnt[0], 0.6), (drv_Jnt[1], 0.4)]) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][0]', tv=(drv_Jnt[0], 1)) elif numJoints == 5: cmds.skinPercent(skin[0], ribbon + '.cv[0:1][7]', tv=(drv_Jnt[2], 1)) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][6]', tv=[(drv_Jnt[2], 0.80), (drv_Jnt[1], 0.2)]) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][5]', tv=[(drv_Jnt[2], 0.5), (drv_Jnt[1], 0.5)]) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][4]', tv=[(drv_Jnt[2], 0.25), (drv_Jnt[1], 0.75)]) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][3]', tv=[(drv_Jnt[0], 0.25), (drv_Jnt[1], 0.75)]) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][2]', tv=[(drv_Jnt[0], 0.5), (drv_Jnt[1], 0.5)]) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][1]', tv=[(drv_Jnt[0], 0.8), (drv_Jnt[1], 0.2)]) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][0]', tv=(drv_Jnt[0], 1)) elif numJoints == 7: cmds.skinPercent(skin[0], ribbon + '.cv[0:1][9]', tv=(drv_Jnt[2], 1)) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][8]', tv=[(drv_Jnt[2], 0.85), (drv_Jnt[1], 0.15)]) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][7]', tv=[(drv_Jnt[2], 0.6), (drv_Jnt[1], 0.4)]) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][6]', tv=[(drv_Jnt[2], 0.35), (drv_Jnt[1], 0.65)]) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][5]', tv=[(drv_Jnt[2], 0.25), (drv_Jnt[1], 0.75)]) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][4]', tv=[(drv_Jnt[0], 0.25), (drv_Jnt[1], 0.75)]) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][3]', tv=[(drv_Jnt[0], 0.35), (drv_Jnt[1], 0.65)]) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][2]', tv=[(drv_Jnt[0], 0.6), (drv_Jnt[1], 0.4)]) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][1]', tv=[(drv_Jnt[0], 0.85), (drv_Jnt[1], 0.15)]) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][0]', tv=(drv_Jnt[0], 1)) else: if numJoints == 3: cmds.skinPercent(skin[0], ribbon + '.cv[5][0:1]', tv=(drv_Jnt[2], 1)) cmds.skinPercent(skin[0], ribbon + '.cv[4][0:1]', tv=[(drv_Jnt[2], 0.6), (drv_Jnt[1], 0.4)]) cmds.skinPercent(skin[0], ribbon + '.cv[3][0:1]', tv=[(drv_Jnt[2], 0.2), (drv_Jnt[1], 0.8)]) cmds.skinPercent(skin[0], ribbon + '.cv[2][0:1]', tv=[(drv_Jnt[0], 0.2), (drv_Jnt[1], 0.8)]) cmds.skinPercent(skin[0], ribbon + '.cv[1][0:1]', tv=[(drv_Jnt[0], 0.6), (drv_Jnt[1], 0.4)]) cmds.skinPercent(skin[0], ribbon + '.cv[0][0:1]', tv=(drv_Jnt[0], 1)) elif numJoints == 5: cmds.skinPercent(skin[0], ribbon + '.cv[7][0:1]', tv=(drv_Jnt[2], 1)) cmds.skinPercent(skin[0], ribbon + '.cv[6][0:1]', tv=[(drv_Jnt[2], 0.80), (drv_Jnt[1], 0.2)]) cmds.skinPercent(skin[0], ribbon + '.cv[5][0:1]', tv=[(drv_Jnt[2], 0.5), (drv_Jnt[1], 0.5)]) cmds.skinPercent(skin[0], ribbon + '.cv[4][0:1]', tv=[(drv_Jnt[2], 0.25), (drv_Jnt[1], 0.75)]) cmds.skinPercent(skin[0], ribbon + '.cv[3][0:1]', tv=[(drv_Jnt[0], 0.25), (drv_Jnt[1], 0.75)]) cmds.skinPercent(skin[0], ribbon + '.cv[2][0:1]', tv=[(drv_Jnt[0], 0.5), (drv_Jnt[1], 0.5)]) cmds.skinPercent(skin[0], ribbon + '.cv[1][0:1]', tv=[(drv_Jnt[0], 0.8), (drv_Jnt[1], 0.2)]) cmds.skinPercent(skin[0], ribbon + '.cv[0][0:1]', tv=(drv_Jnt[0], 1)) elif numJoints == 7: cmds.skinPercent(skin[0], ribbon + '.cv[9][0:1]', tv=(drv_Jnt[2], 1)) cmds.skinPercent(skin[0], ribbon + '.cv[8][0:1]', tv=[(drv_Jnt[2], 0.85), (drv_Jnt[1], 0.15)]) cmds.skinPercent(skin[0], ribbon + '.cv[7][0:1]', tv=[(drv_Jnt[2], 0.6), (drv_Jnt[1], 0.4)]) cmds.skinPercent(skin[0], ribbon + '.cv[6][0:1]', tv=[(drv_Jnt[2], 0.35), (drv_Jnt[1], 0.65)]) cmds.skinPercent(skin[0], ribbon + '.cv[5][0:1]', tv=[(drv_Jnt[2], 0.25), (drv_Jnt[1], 0.75)]) cmds.skinPercent(skin[0], ribbon + '.cv[4][0:1]', tv=[(drv_Jnt[0], 0.25), (drv_Jnt[1], 0.75)]) cmds.skinPercent(skin[0], ribbon + '.cv[3][0:1]', tv=[(drv_Jnt[0], 0.35), (drv_Jnt[1], 0.65)]) cmds.skinPercent(skin[0], ribbon + '.cv[2][0:1]', tv=[(drv_Jnt[0], 0.6), (drv_Jnt[1], 0.4)]) cmds.skinPercent(skin[0], ribbon + '.cv[1][0:1]', tv=[(drv_Jnt[0], 0.85), (drv_Jnt[1], 0.15)]) cmds.skinPercent(skin[0], ribbon + '.cv[0][0:1]', tv=(drv_Jnt[0], 1)) constr = [] if guias: top = guias[0] bottom = guias[1] constr.append(cmds.parentConstraint(top, bttm_Loc[0], mo=False, name=bttm_Loc[0]+"_ParentConstraint")) constr.append(cmds.parentConstraint(bottom, top_Loc[0], mo=False, name=top_Loc[0]+"_ParentConstraint")) #fix orientation issues cmds.delete(ori) cmds.orientConstraint(bttm_Loc[0], aux_Jnt[0], weight=0.5, mo=True, name=aux_Jnt[0]+"_OrientConstraint") #fix loc_Grp scale if guias: from math import sqrt, pow auxLoc1 = cmds.spaceLocator(name='auxLoc1')[0] auxLoc2 = cmds.spaceLocator(name='auxLoc2')[0] cmds.delete(cmds.parentConstraint(top, auxLoc1, mo=False, w=1)) cmds.delete(cmds.parentConstraint(bottom, auxLoc2, mo=False, w=1)) a = cmds.xform(auxLoc1, ws=True, translation=True, q=True) b = cmds.xform(auxLoc2, ws=True, translation=True, q=True) dist = sqrt(pow(a[0]-b[0], 2.0)+pow(a[1]-b[1], 2.0)+pow(a[2]-b[2], 2.0)) scale = dist/float(numJoints) cmds.setAttr(locatorsGrp+'.s', scale, scale, scale) cmds.delete(auxLoc1, auxLoc2) # baseTwist: if not upCtrl == None: bttm_LocGrp = cmds.group(bttm_Loc[2], name=bttm_Loc[2]+"_Grp") bttm_LocPos = cmds.xform(bttm_Loc[0], query=True, worldSpace=True, translation=True) cmds.move(bttm_LocPos[0], bttm_LocPos[1], bttm_LocPos[2], bttm_LocGrp+".scalePivot", bttm_LocGrp+".rotatePivot", absolute=True) cmds.connectAttr(upCtrl+".baseTwist", bttm_LocGrp+".rotateZ", force=True) #updating values cmds.setAttr(rbScaleMD+".input2X", cmds.getAttr(curveInfoNode+".arcLength")) for jnt in rb_Jnt: rbAddScalePMA = jnt.replace("_Jnt", "_AddScale_PMA") cmds.setAttr(rbAddScalePMA+".input1D[0]", 1-cmds.getAttr(rbAddScalePMA+".input1D[1]")) #change renderStats ribbonShape = cmds.listRelatives(ribbon, s=True, f=True)[0] cmds.setAttr(ribbonShape+'.castsShadows', 0) cmds.setAttr(ribbonShape+'.receiveShadows', 0) cmds.setAttr(ribbonShape+'.motionBlur', 0) cmds.setAttr(ribbonShape+'.primaryVisibility', 0) cmds.setAttr(ribbonShape+'.smoothShading', 0) cmds.setAttr(ribbonShape+'.visibleInReflections', 0) cmds.setAttr(ribbonShape+'.visibleInRefractions', 0) cmds.setAttr(ribbonShape+'.doubleSided', 1) retDict['name'] = name retDict['locsList'] = [top_Loc[0], mid_Loc[0], bttm_Loc[0]] retDict['skinJointsList'] = rb_Jnt retDict['scaleGrp'] = locatorsGrp retDict['finalGrp'] = finalSystemGrp retDict['middleCtrl'] = mid_Ctrl retDict['constraints'] = constr retDict['bendGrpList'] = [top_Loc[0], bttm_Loc[0]] retDict['extraCtrlGrp'] = extraCtrlGrp retDict['extraCtrlList'] = extraCtrlList retDict['rbScaleMD'] = rbScaleMD retDict['rbNormalizeMD'] = rbNormalizeMD cmds.setAttr(finalSystemGrp+'.v', v) return retDict
def createRibbon(axis=(0, 0, 1), name='xxxx', horizontal=False, numJoints=3, guias=None, v=True, s=0, firstLimb=True, upCtrl=None, ctrlRadius=1, worldRef="worldRef"): retDict = {} #define variables top_Loc = [] mid_Loc = [] bttm_Loc = [] rb_Jnt = [] drv_Jnt = [] fols = [] aux_Jnt = [] ribbon = '' extraCtrlList = [] #define attributes limbManualVVAttr = "limbManualVolume" limbVVAttr = "limbVolumeVariation" limbMinVVAttr = "limbMinVolume" #create a nurbsPlane based in the choose orientation option if horizontal: ribbon = cmds.nurbsPlane(ax=axis, w=numJoints, lr=(1 / float(numJoints)), d=3, u=numJoints, v=1, ch=0, name=name + '_Plane')[0] cmds.rebuildSurface(ribbon, ch=0, rpo=1, rt=0, end=1, kr=0, kcp=0, kc=0, sv=1, du=3, dv=1, tol=0.01, fr=0, dir=1) else: ribbon = cmds.nurbsPlane(ax=axis, w=1, lr=numJoints, d=3, u=1, v=numJoints, ch=0, name=name + '_Plane')[0] cmds.rebuildSurface(ribbon, ch=0, rpo=1, rt=0, end=1, kr=0, kcp=0, kc=0, su=1, du=1, dv=3, tol=0.01, fr=0, dir=0) # make this ribbonNurbsPlane as not skinable from dpAR_UI: cmds.addAttr(ribbon, longName="doNotSkinIt", attributeType="bool", keyable=True) cmds.setAttr(ribbon + ".doNotSkinIt", 1) #call the function to create follicles and joint in the nurbsPlane results = createFollicles(rib=ribbon, num=numJoints, name=name, horizontal=horizontal) rb_Jnt = results[0] fols = results[1] #create locator controls for the middle of the ribbon mid_Loc.append(cmds.spaceLocator(name=name + '_Mid_Pos_Loc')[0]) mid_Loc.append(cmds.spaceLocator(name=name + '_Mid_Aim_Loc')[0]) mid_Loc.append(cmds.spaceLocator(name=name + '_Mid_Off_Loc')[0]) mid_Loc.append(cmds.spaceLocator(name=name + '_Mid_Up_Loc')[0]) #parent correctly the middle locators cmds.parent(mid_Loc[2], mid_Loc[1], relative=True) cmds.parent(mid_Loc[1], mid_Loc[0], relative=True) cmds.parent(mid_Loc[3], mid_Loc[0], relative=True) #create the locators controls for the top of the ribbon top_Loc.append(cmds.spaceLocator(name=name + '_Top_Pos_Loc')[0]) top_Loc.append(cmds.spaceLocator(name=name + '_Top_Aim_Loc')[0]) top_Loc.append(cmds.spaceLocator(name=name + '_Top_Up_Loc')[0]) #parent correctly the top locators cmds.parent(top_Loc[1], top_Loc[0], relative=True) cmds.parent(top_Loc[2], top_Loc[0], relative=True) #create the locators for the end of the ribbon bttm_Loc.append(cmds.spaceLocator(name=name + '_Bttm_Pos_Loc')[0]) bttm_Loc.append(cmds.spaceLocator(name=name + '_Bttm_Aim_Loc')[0]) bttm_Loc.append(cmds.spaceLocator(name=name + '_Bttm_Up_Loc')[0]) #parent correctly the bottom locators cmds.parent(bttm_Loc[1], bttm_Loc[0], relative=True) cmds.parent(bttm_Loc[2], bttm_Loc[0], relative=True) #put the top locators in the same place of the top joint cmds.parent(top_Loc[0], fols[len(fols) - 1], relative=True) cmds.parent(top_Loc[0], w=True) #put the bottom locators in the same place of the bottom joint cmds.parent(bttm_Loc[0], fols[0], relative=True) cmds.parent(bttm_Loc[0], w=True) cmds.select(clear=True) #create the joints that will be used to control the ribbon drv_Jnt = cmds.duplicate( [rb_Jnt[0], rb_Jnt[(len(rb_Jnt) - 1) / 2], rb_Jnt[len(rb_Jnt) - 1]]) dup = cmds.duplicate([drv_Jnt[0], drv_Jnt[2]]) drv_Jnt.append(dup[0]) drv_Jnt.append(dup[1]) #cmds.parent(drv_Jnt, w=True) for jnt in drv_Jnt: cmds.joint(jnt, e=True, oj='none', ch=True, zso=True) cmds.setAttr(jnt + '.radius', cmds.getAttr(jnt + '.radius') + 0.5) #rename created joints drv_Jnt[0] = cmds.rename(drv_Jnt[0], name + '_Drv_Bttm_Jxt') drv_Jnt[1] = cmds.rename(drv_Jnt[1], name + '_Drv_Mid_Jxt') drv_Jnt[2] = cmds.rename(drv_Jnt[2], name + '_Drv_Top_Jxt') drv_Jnt[3] = cmds.rename(drv_Jnt[3], name + '_Drv_Bttm_End') drv_Jnt[4] = cmds.rename(drv_Jnt[4], name + '_Drv_Top_End') #place joints correctly accordaly with the user options choose if (horizontal and axis == (1, 0, 0)) or (horizontal and axis == (0, 0, 1)): cmds.setAttr(bttm_Loc[2] + '.translateY', 2) cmds.setAttr(top_Loc[2] + '.translateY', 2) cmds.setAttr(mid_Loc[3] + '.translateY', 2) elif (horizontal and axis == (0, 1, 0)) or (not horizontal and axis == (1, 0, 0)): cmds.setAttr(bttm_Loc[2] + '.translateZ', 2) cmds.setAttr(top_Loc[2] + '.translateZ', 2) cmds.setAttr(mid_Loc[3] + '.translateZ', 2) elif not horizontal and axis == (0, 1, 0) or (not horizontal and axis == (0, 0, 1)): cmds.setAttr(bttm_Loc[2] + '.translateX', 2) cmds.setAttr(top_Loc[2] + '.translateX', 2) cmds.setAttr(mid_Loc[3] + '.translateX', 2) elif horizontal and axis == (0, 0, -1): if firstLimb: cmds.setAttr(bttm_Loc[2] + '.translateY', 2) cmds.setAttr(top_Loc[2] + '.translateX', -2) cmds.setAttr(mid_Loc[3] + '.translateX', -2) cmds.setAttr(mid_Loc[3] + '.translateY', 2) else: if s == 0: cmds.setAttr(bttm_Loc[2] + '.translateX', -2) cmds.setAttr(top_Loc[2] + '.translateY', -2) cmds.setAttr(mid_Loc[3] + '.translateX', -2) cmds.setAttr(mid_Loc[3] + '.translateY', 2) else: cmds.setAttr(bttm_Loc[2] + '.translateX', -2) cmds.setAttr(top_Loc[2] + '.translateY', -2) cmds.setAttr(mid_Loc[3] + '.translateX', -2) cmds.setAttr(mid_Loc[3] + '.translateY', 2) #create auxiliary joints that will be used to control the ribbon aux_Jnt.append(cmds.duplicate(drv_Jnt[1], name=name + '_Jxt_Rot')[0]) cmds.setAttr(aux_Jnt[0] + '.jointOrient', 0, 0, 0) aux_Jnt.append(cmds.duplicate(aux_Jnt[0], name=name + '_Jxt_Rot_End')[0]) cmds.parent(aux_Jnt[1], mid_Loc[3]) cmds.setAttr(aux_Jnt[1] + '.translate', 0, 0, 0) cmds.parent(aux_Jnt[1], aux_Jnt[0]) cmds.parent(mid_Loc[3], aux_Jnt[1]) #calculate the adjust for the new chain position dist = float(numJoints) / 2.0 end_dist = (1 / float(numJoints)) cmds.parent(drv_Jnt[3], drv_Jnt[0]) cmds.parent(drv_Jnt[4], drv_Jnt[2]) #adjust the joints orientation and position based in the options choose from user if horizontal and axis == (1, 0, 0): cmds.setAttr(drv_Jnt[0] + '.jointOrient', 0, 90, 0) cmds.setAttr(drv_Jnt[2] + '.jointOrient', 0, 90, 0) cmds.setAttr(drv_Jnt[0] + '.tz', -dist) cmds.setAttr(drv_Jnt[3] + '.tz', end_dist * dist) cmds.setAttr(drv_Jnt[2] + '.tz', dist) cmds.setAttr(drv_Jnt[4] + '.tz', -end_dist * dist) elif horizontal and axis == (0, 1, 0): cmds.setAttr(drv_Jnt[0] + '.jointOrient', 0, 0, 0) cmds.setAttr(drv_Jnt[2] + '.jointOrient', 0, 0, 0) cmds.setAttr(drv_Jnt[0] + '.tx', -dist) cmds.setAttr(drv_Jnt[3] + '.tx', end_dist * dist) cmds.setAttr(drv_Jnt[2] + '.tx', dist) cmds.setAttr(drv_Jnt[4] + '.tx', -end_dist * dist) elif horizontal and axis == (0, 0, 1): cmds.setAttr(drv_Jnt[0] + '.jointOrient', 0, 0, 0) cmds.setAttr(drv_Jnt[2] + '.jointOrient', 0, 0, 0) cmds.setAttr(drv_Jnt[0] + '.tx', -dist) cmds.setAttr(drv_Jnt[3] + '.tx', end_dist * dist) cmds.setAttr(drv_Jnt[2] + '.tx', dist) cmds.setAttr(drv_Jnt[4] + '.tx', -end_dist * dist) elif horizontal and axis == (0, 0, -1): cmds.setAttr(drv_Jnt[0] + '.jointOrient', 0, 0, 0) cmds.setAttr(drv_Jnt[2] + '.jointOrient', 0, 0, 0) cmds.setAttr(drv_Jnt[0] + '.tx', -dist) cmds.setAttr(drv_Jnt[3] + '.tx', end_dist * dist) cmds.setAttr(drv_Jnt[2] + '.tx', dist) cmds.setAttr(drv_Jnt[4] + '.tx', -end_dist * dist) elif not horizontal and axis == (1, 0, 0): cmds.setAttr(drv_Jnt[0] + '.jointOrient', 0, 0, -90) cmds.setAttr(drv_Jnt[2] + '.jointOrient', 0, 0, -90) cmds.setAttr(drv_Jnt[0] + '.ty', -dist) cmds.setAttr(drv_Jnt[3] + '.ty', end_dist * dist) cmds.setAttr(drv_Jnt[2] + '.ty', dist) cmds.setAttr(drv_Jnt[4] + '.ty', -end_dist * dist) elif not horizontal and axis == (0, 1, 0): cmds.setAttr(drv_Jnt[0] + '.jointOrient', 0, 90, 0) cmds.setAttr(drv_Jnt[2] + '.jointOrient', 0, 90, 0) cmds.setAttr(drv_Jnt[0] + '.tz', -dist) cmds.setAttr(drv_Jnt[3] + '.tz', end_dist * dist) cmds.setAttr(drv_Jnt[2] + '.tz', dist) cmds.setAttr(drv_Jnt[4] + '.tz', -end_dist * dist) elif not horizontal and axis == (0, 0, 1): cmds.setAttr(drv_Jnt[0] + '.jointOrient', 0, 0, -90) cmds.setAttr(drv_Jnt[2] + '.jointOrient', 0, 0, -90) cmds.setAttr(drv_Jnt[0] + '.ty', -dist) cmds.setAttr(drv_Jnt[3] + '.ty', end_dist * dist) cmds.setAttr(drv_Jnt[2] + '.ty', dist) cmds.setAttr(drv_Jnt[4] + '.ty', -end_dist * dist) #fix the control locators position and orientation cmds.parent(top_Loc[0], drv_Jnt[2]) cmds.setAttr(top_Loc[0] + '.translate', 0, 0, 0) cmds.parent(top_Loc[0], w=True) cmds.setAttr(top_Loc[0] + '.rotate', 0, 0, 0) cmds.parent(bttm_Loc[0], drv_Jnt[0]) cmds.setAttr(bttm_Loc[0] + '.translate', 0, 0, 0) cmds.parent(bttm_Loc[0], w=True) cmds.setAttr(bttm_Loc[0] + '.rotate', 0, 0, 0) cmds.parent(drv_Jnt[2], top_Loc[1]) cmds.parent(drv_Jnt[1], mid_Loc[2]) cmds.parent(drv_Jnt[0], bttm_Loc[1]) cmds.parent(aux_Jnt[0], mid_Loc[0]) #create a nurbs control in order to be used in the ribbon offset mid_Ctrl = cmds.circle(c=(0, 0, 0), nr=(1, 0, 0), ch=0, name=name + '_MidCtrl')[0] ctrls.renameShape([mid_Ctrl]) midCtrl = mid_Ctrl mid_Ctrl = cmds.group(n=mid_Ctrl + '_Grp', em=True) cmds.delete(cmds.parentConstraint(midCtrl, mid_Ctrl, mo=0)) cmds.parent(midCtrl, mid_Ctrl) #adjust the realtionship between the locators cmds.parent(mid_Ctrl, mid_Loc[2], r=True) cmds.parent(drv_Jnt[1], midCtrl) cmds.parent([top_Loc[2], mid_Loc[3], bttm_Loc[2]], w=True) cmds.makeIdentity(top_Loc[0], apply=True) cmds.makeIdentity(mid_Loc[0], apply=True) cmds.makeIdentity(bttm_Loc[0], apply=True) cmds.parent(top_Loc[2], top_Loc[0]) cmds.parent(bttm_Loc[2], bttm_Loc[0]) cmds.parent(mid_Loc[3], aux_Jnt[1]) #create needed constraints in the locators in order to set the top always follow, to the base always aim the middle, to the middle always aim the top if firstLimb: cmds.aimConstraint(drv_Jnt[1], bttm_Loc[1], offset=(0, 0, 0), weight=1, aimVector=(1, 0, 0), upVector=(0, 0, 1), worldUpType='object', worldUpObject=bttm_Loc[2], name=bttm_Loc[1] + "_AimConstraint") cmds.aimConstraint(top_Loc[0], mid_Loc[1], offset=(0, 0, 0), weight=1, aimVector=(1, 0, 0), upVector=(0, 0, 1), worldUpType='object', worldUpObject=mid_Loc[3], name=mid_Loc[1] + "_AimConstraint") cmds.aimConstraint(drv_Jnt[1], top_Loc[1], offset=(0, 0, 0), weight=1, aimVector=(-1, 0, 0), upVector=(0, 1, 0), worldUpType='object', worldUpObject=top_Loc[2], name=top_Loc[1] + "_AimConstraint") else: # bug fix to plane twist cmds.aimConstraint(drv_Jnt[1], bttm_Loc[1], offset=(0, 0, 0), weight=1, aimVector=(1, 0, 0), upVector=(0, 1, 0), worldUpType='object', worldUpObject=bttm_Loc[2], name=bttm_Loc[1] + "_AimConstraint") cmds.aimConstraint(top_Loc[0], mid_Loc[1], offset=(0, 0, 0), weight=1, aimVector=(-1, 0, 0), upVector=(0, 0, 1), worldUpType='object', worldUpObject=mid_Loc[3], name=mid_Loc[1] + "_AimConstraint") cmds.aimConstraint(drv_Jnt[1], top_Loc[1], offset=(0, 0, 0), weight=1, aimVector=(-1, 0, 0), upVector=(0, 0, 1), worldUpType='object', worldUpObject=top_Loc[2], name=top_Loc[1] + "_AimConstraint") #create a point and orient constraint for the middel control cmds.pointConstraint(top_Loc[0], bttm_Loc[0], mid_Loc[0], offset=(0, 0, 0), weight=1, name=mid_Loc[0] + "_PointConstraint") ori = cmds.orientConstraint(top_Loc[0], bttm_Loc[0], aux_Jnt[0], offset=(0, 0, 0), weight=1, name=aux_Jnt[0] + "_OrientConstraint") #ribbon scale (volume variation) if numJoints == 3: proportionList = [0.5, 1, 0.5] elif numJoints == 5: proportionList = [0.4, 0.8, 1, 0.8, 0.4] elif numJoints == 7: proportionList = [0.25, 0.5, 0.75, 1, 0.75, 0.5, 0.25] curveInfoNode = cmds.arclen(ribbon + ".v[0.5]", constructionHistory=True) curveInfoNode = cmds.rename(curveInfoNode, ribbon + "_CurveInfo") rbScaleMD = cmds.createNode("multiplyDivide", name=ribbon + "_ScaleCompensate_MD") rbNormalizeMD = cmds.createNode("multiplyDivide", name=ribbon + "_Normalize_MD") cmds.setAttr(rbNormalizeMD + ".operation", 2) cmds.connectAttr(curveInfoNode + ".arcLength", rbNormalizeMD + ".input2X", force=True) cmds.connectAttr(rbScaleMD + ".outputX", rbNormalizeMD + ".input1X", force=True) if cmds.objExists(worldRef): if not cmds.objExists(worldRef + "." + limbManualVVAttr): cmds.addAttr(worldRef, longName=limbVVAttr, attributeType="float", minValue=0, maxValue=1, defaultValue=1, keyable=True) cmds.addAttr(worldRef, longName=limbManualVVAttr, attributeType="float", defaultValue=1, keyable=True) cmds.addAttr(worldRef, longName=limbMinVVAttr, attributeType="float", defaultValue=0.01, keyable=True) cmds.connectAttr(worldRef + ".scaleX", rbScaleMD + ".input1X", force=True) #fix group hierarchy extraCtrlGrp = cmds.group(empty=True, name=name + "_ExtraBendyCtrl_Grp") i = 0 for jnt in rb_Jnt: cmds.makeIdentity(jnt, a=True) # create extra control extraCtrlName = jnt.replace("_Jnt", "_Ctrl") extraCtrl = ctrls.cvSquare(ctrlName=extraCtrlName, r=ctrlRadius) extraCtrlList.append(extraCtrl) cmds.rotate(0, 0, 90, extraCtrl) cmds.makeIdentity(extraCtrl, a=True) extraCtrlZero = utils.zeroOut([extraCtrl])[0] cmds.parent(extraCtrlZero, extraCtrlGrp) cmds.parentConstraint(fols[i], extraCtrlZero, w=1, name=extraCtrlZero + "_ParentConstraint") cmds.parentConstraint(extraCtrl, jnt, w=1, name=jnt + "_ParentConstraint") cmds.scaleConstraint(extraCtrl, jnt, w=1, name=jnt + "_ScaleConstraint") # work with volume variation rbProportionMD = cmds.createNode("multiplyDivide", name=extraCtrlName.replace( "_Ctrl", "_Proportion_MD")) rbIntensityMD = cmds.createNode("multiplyDivide", name=extraCtrlName.replace( "_Ctrl", "_Intensity_MD")) rbAddScalePMA = cmds.createNode("plusMinusAverage", name=extraCtrlName.replace( "_Ctrl", "_AddScale_PMA")) rbScaleClp = cmds.createNode("clamp", name=extraCtrlName.replace( "_Ctrl", "_Scale_Clp")) rbBlendCB = cmds.createNode("blendColors", name=extraCtrlName.replace( "_Ctrl", "_Blend_BC")) cmds.connectAttr(worldRef + "." + limbVVAttr, rbBlendCB + ".blender", force=True) cmds.setAttr(rbBlendCB + ".color2", 1, 1, 1, type="double3") cmds.connectAttr(rbNormalizeMD + ".outputX", rbProportionMD + ".input1X", force=True) cmds.setAttr(rbProportionMD + ".input2X", proportionList[i]) cmds.connectAttr(rbProportionMD + ".outputX", rbIntensityMD + ".input1X", force=True) cmds.connectAttr(worldRef + "." + limbManualVVAttr, rbIntensityMD + ".input2X", force=True) cmds.connectAttr(rbIntensityMD + ".outputX", rbAddScalePMA + ".input1D[1]", force=True) cmds.connectAttr(rbAddScalePMA + ".output1D", rbScaleClp + ".inputR", force=True) cmds.connectAttr(worldRef + "." + limbMinVVAttr, rbScaleClp + ".minR") cmds.setAttr(rbScaleClp + ".maxR", 1000000) cmds.connectAttr(rbScaleClp + ".outputR", rbBlendCB + ".color1.color1R", force=True) cmds.connectAttr(rbBlendCB + ".output.outputR", extraCtrlZero + ".scaleY", force=True) cmds.connectAttr(rbBlendCB + ".output.outputR", extraCtrlZero + ".scaleZ", force=True) # update i i = i + 1 locatorsGrp = cmds.group(bttm_Loc[0], top_Loc[0], mid_Loc[0], n=name + '_Loc_Grp') skinJntGrp = cmds.group(rb_Jnt, n=name + '_Jnt_Grp') finalSystemGrp = cmds.group(ribbon, locatorsGrp, skinJntGrp, n=name + '_RibbonSystem_Grp') #do the controller joints skin and the ribbon ribbonShape = cmds.listRelatives(ribbon, shapes=True) skin = cmds.skinCluster(drv_Jnt[0:3], ribbonShape, tsb=True, mi=2, dr=1) #skin presets for the ribbon (that's amazing!) if not horizontal: if numJoints == 3: cmds.skinPercent(skin[0], ribbon + '.cv[0:1][5]', tv=(drv_Jnt[2], 1)) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][4]', tv=[(drv_Jnt[2], 0.6), (drv_Jnt[1], 0.4)]) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][3]', tv=[(drv_Jnt[2], 0.2), (drv_Jnt[1], 0.8)]) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][2]', tv=[(drv_Jnt[0], 0.2), (drv_Jnt[1], 0.8)]) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][1]', tv=[(drv_Jnt[0], 0.6), (drv_Jnt[1], 0.4)]) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][0]', tv=(drv_Jnt[0], 1)) elif numJoints == 5: cmds.skinPercent(skin[0], ribbon + '.cv[0:1][7]', tv=(drv_Jnt[2], 1)) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][6]', tv=[(drv_Jnt[2], 0.80), (drv_Jnt[1], 0.2)]) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][5]', tv=[(drv_Jnt[2], 0.5), (drv_Jnt[1], 0.5)]) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][4]', tv=[(drv_Jnt[2], 0.25), (drv_Jnt[1], 0.75)]) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][3]', tv=[(drv_Jnt[0], 0.25), (drv_Jnt[1], 0.75)]) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][2]', tv=[(drv_Jnt[0], 0.5), (drv_Jnt[1], 0.5)]) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][1]', tv=[(drv_Jnt[0], 0.8), (drv_Jnt[1], 0.2)]) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][0]', tv=(drv_Jnt[0], 1)) elif numJoints == 7: cmds.skinPercent(skin[0], ribbon + '.cv[0:1][9]', tv=(drv_Jnt[2], 1)) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][8]', tv=[(drv_Jnt[2], 0.85), (drv_Jnt[1], 0.15)]) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][7]', tv=[(drv_Jnt[2], 0.6), (drv_Jnt[1], 0.4)]) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][6]', tv=[(drv_Jnt[2], 0.35), (drv_Jnt[1], 0.65)]) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][5]', tv=[(drv_Jnt[2], 0.25), (drv_Jnt[1], 0.75)]) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][4]', tv=[(drv_Jnt[0], 0.25), (drv_Jnt[1], 0.75)]) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][3]', tv=[(drv_Jnt[0], 0.35), (drv_Jnt[1], 0.65)]) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][2]', tv=[(drv_Jnt[0], 0.6), (drv_Jnt[1], 0.4)]) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][1]', tv=[(drv_Jnt[0], 0.85), (drv_Jnt[1], 0.15)]) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][0]', tv=(drv_Jnt[0], 1)) else: if numJoints == 3: cmds.skinPercent(skin[0], ribbon + '.cv[5][0:1]', tv=(drv_Jnt[2], 1)) cmds.skinPercent(skin[0], ribbon + '.cv[4][0:1]', tv=[(drv_Jnt[2], 0.6), (drv_Jnt[1], 0.4)]) cmds.skinPercent(skin[0], ribbon + '.cv[3][0:1]', tv=[(drv_Jnt[2], 0.2), (drv_Jnt[1], 0.8)]) cmds.skinPercent(skin[0], ribbon + '.cv[2][0:1]', tv=[(drv_Jnt[0], 0.2), (drv_Jnt[1], 0.8)]) cmds.skinPercent(skin[0], ribbon + '.cv[1][0:1]', tv=[(drv_Jnt[0], 0.6), (drv_Jnt[1], 0.4)]) cmds.skinPercent(skin[0], ribbon + '.cv[0][0:1]', tv=(drv_Jnt[0], 1)) elif numJoints == 5: cmds.skinPercent(skin[0], ribbon + '.cv[7][0:1]', tv=(drv_Jnt[2], 1)) cmds.skinPercent(skin[0], ribbon + '.cv[6][0:1]', tv=[(drv_Jnt[2], 0.80), (drv_Jnt[1], 0.2)]) cmds.skinPercent(skin[0], ribbon + '.cv[5][0:1]', tv=[(drv_Jnt[2], 0.5), (drv_Jnt[1], 0.5)]) cmds.skinPercent(skin[0], ribbon + '.cv[4][0:1]', tv=[(drv_Jnt[2], 0.25), (drv_Jnt[1], 0.75)]) cmds.skinPercent(skin[0], ribbon + '.cv[3][0:1]', tv=[(drv_Jnt[0], 0.25), (drv_Jnt[1], 0.75)]) cmds.skinPercent(skin[0], ribbon + '.cv[2][0:1]', tv=[(drv_Jnt[0], 0.5), (drv_Jnt[1], 0.5)]) cmds.skinPercent(skin[0], ribbon + '.cv[1][0:1]', tv=[(drv_Jnt[0], 0.8), (drv_Jnt[1], 0.2)]) cmds.skinPercent(skin[0], ribbon + '.cv[0][0:1]', tv=(drv_Jnt[0], 1)) elif numJoints == 7: cmds.skinPercent(skin[0], ribbon + '.cv[9][0:1]', tv=(drv_Jnt[2], 1)) cmds.skinPercent(skin[0], ribbon + '.cv[8][0:1]', tv=[(drv_Jnt[2], 0.85), (drv_Jnt[1], 0.15)]) cmds.skinPercent(skin[0], ribbon + '.cv[7][0:1]', tv=[(drv_Jnt[2], 0.6), (drv_Jnt[1], 0.4)]) cmds.skinPercent(skin[0], ribbon + '.cv[6][0:1]', tv=[(drv_Jnt[2], 0.35), (drv_Jnt[1], 0.65)]) cmds.skinPercent(skin[0], ribbon + '.cv[5][0:1]', tv=[(drv_Jnt[2], 0.25), (drv_Jnt[1], 0.75)]) cmds.skinPercent(skin[0], ribbon + '.cv[4][0:1]', tv=[(drv_Jnt[0], 0.25), (drv_Jnt[1], 0.75)]) cmds.skinPercent(skin[0], ribbon + '.cv[3][0:1]', tv=[(drv_Jnt[0], 0.35), (drv_Jnt[1], 0.65)]) cmds.skinPercent(skin[0], ribbon + '.cv[2][0:1]', tv=[(drv_Jnt[0], 0.6), (drv_Jnt[1], 0.4)]) cmds.skinPercent(skin[0], ribbon + '.cv[1][0:1]', tv=[(drv_Jnt[0], 0.85), (drv_Jnt[1], 0.15)]) cmds.skinPercent(skin[0], ribbon + '.cv[0][0:1]', tv=(drv_Jnt[0], 1)) constr = [] if guias: top = guias[0] bottom = guias[1] constr.append( cmds.parentConstraint(top, bttm_Loc[0], mo=False, name=bttm_Loc[0] + "_ParentConstraint")) constr.append( cmds.parentConstraint(bottom, top_Loc[0], mo=False, name=top_Loc[0] + "_ParentConstraint")) #fix orientation issues cmds.delete(ori) cmds.orientConstraint(bttm_Loc[0], aux_Jnt[0], weight=0.5, mo=True, name=aux_Jnt[0] + "_OrientConstraint") #fix loc_Grp scale if guias: from math import sqrt, pow auxLoc1 = cmds.spaceLocator(name='auxLoc1')[0] auxLoc2 = cmds.spaceLocator(name='auxLoc2')[0] cmds.delete(cmds.parentConstraint(top, auxLoc1, mo=False, w=1)) cmds.delete(cmds.parentConstraint(bottom, auxLoc2, mo=False, w=1)) a = cmds.xform(auxLoc1, ws=True, translation=True, q=True) b = cmds.xform(auxLoc2, ws=True, translation=True, q=True) dist = sqrt( pow(a[0] - b[0], 2.0) + pow(a[1] - b[1], 2.0) + pow(a[2] - b[2], 2.0)) scale = dist / float(numJoints) cmds.setAttr(locatorsGrp + '.s', scale, scale, scale) cmds.delete(auxLoc1, auxLoc2) # baseTwist: if not upCtrl == None: bttm_LocGrp = cmds.group(bttm_Loc[2], name=bttm_Loc[2] + "_Grp") bttm_LocPos = cmds.xform(bttm_Loc[0], query=True, worldSpace=True, translation=True) cmds.move(bttm_LocPos[0], bttm_LocPos[1], bttm_LocPos[2], bttm_LocGrp + ".scalePivot", bttm_LocGrp + ".rotatePivot", absolute=True) cmds.connectAttr(upCtrl + ".baseTwist", bttm_LocGrp + ".rotateZ", force=True) #updating values cmds.setAttr(rbScaleMD + ".input2X", cmds.getAttr(curveInfoNode + ".arcLength")) for jnt in rb_Jnt: rbAddScalePMA = jnt.replace("_Jnt", "_AddScale_PMA") cmds.setAttr(rbAddScalePMA + ".input1D[0]", 1 - cmds.getAttr(rbAddScalePMA + ".input1D[1]")) #change renderStats ribbonShape = cmds.listRelatives(ribbon, s=True, f=True)[0] cmds.setAttr(ribbonShape + '.castsShadows', 0) cmds.setAttr(ribbonShape + '.receiveShadows', 0) cmds.setAttr(ribbonShape + '.motionBlur', 0) cmds.setAttr(ribbonShape + '.primaryVisibility', 0) cmds.setAttr(ribbonShape + '.smoothShading', 0) cmds.setAttr(ribbonShape + '.visibleInReflections', 0) cmds.setAttr(ribbonShape + '.visibleInRefractions', 0) cmds.setAttr(ribbonShape + '.doubleSided', 1) retDict['name'] = name retDict['locsList'] = [top_Loc[0], mid_Loc[0], bttm_Loc[0]] retDict['skinJointsList'] = rb_Jnt retDict['scaleGrp'] = locatorsGrp retDict['finalGrp'] = finalSystemGrp retDict['middleCtrl'] = mid_Ctrl retDict['constraints'] = constr retDict['bendGrpList'] = [top_Loc[0], bttm_Loc[0]] retDict['extraCtrlGrp'] = extraCtrlGrp retDict['extraCtrlList'] = extraCtrlList retDict['rbScaleMD'] = rbScaleMD retDict['rbNormalizeMD'] = rbNormalizeMD cmds.setAttr(finalSystemGrp + '.v', v) return retDict
def rigModule(self, *args): Base.StartClass.rigModule(self) # verify if the guide exists: if cmds.objExists(self.moduleGrp): try: hideJoints = cmds.checkBox("hideJointsCB", query=True, value=True) except: hideJoints = 1 # declare lists to store names and attributes: self.hipsAList, self.chestAList, self.volumeVariationAttrList = [], [], [] # start as no having mirror: sideList = [""] # analisys the mirror module: self.mirrorAxis = cmds.getAttr(self.moduleGrp + ".mirrorAxis") if self.mirrorAxis != "off": # get rigs names: self.mirrorNames = cmds.getAttr(self.moduleGrp + ".mirrorName") # get first and last letters to use as side initials (prefix): sideList = [self.mirrorNames[0] + "_", self.mirrorNames[len(self.mirrorNames) - 1] + "_"] for s, side in enumerate(sideList): duplicated = cmds.duplicate(self.moduleGrp, name=side + self.userGuideName + "_Guide_Base")[0] allGuideList = cmds.listRelatives(duplicated, allDescendents=True) for item in allGuideList: cmds.rename(item, side + self.userGuideName + "_" + item) self.mirrorGrp = cmds.group(name="Guide_Base_Grp", empty=True) cmds.parent(side + self.userGuideName + "_Guide_Base", self.mirrorGrp, absolute=True) # re-rename grp: cmds.rename(self.mirrorGrp, side + self.userGuideName + "_" + self.mirrorGrp) # do a group mirror with negative scaling: if s == 1: for axis in self.mirrorAxis: cmds.setAttr(side + self.userGuideName + "_" + self.mirrorGrp + ".scale" + axis, -1) else: # if not mirror: duplicated = cmds.duplicate(self.moduleGrp, name=self.userGuideName + "_Guide_Base")[0] allGuideList = cmds.listRelatives(duplicated, allDescendents=True) for item in allGuideList: cmds.rename(item, self.userGuideName + "_" + item) self.mirrorGrp = cmds.group(self.userGuideName + "_Guide_Base", name="Guide_Base_Grp", relative=True) # re-rename grp: cmds.rename(self.mirrorGrp, self.userGuideName + "_" + self.mirrorGrp) # store the number of this guide by module type dpAR_count = utils.findModuleLastNumber(CLASS_NAME, "dpAR_type") + 1 # run for all sides for s, side in enumerate(sideList): self.base = side + self.userGuideName + "_Guide_Base" # get the number of joints to be created: self.nJoints = cmds.getAttr(self.base + ".nJoints") # create controls: self.hipsA = ctrls.cvBox( ctrlName=side + self.userGuideName + "_" + self.langDic[self.langName]["c_hips"] + "A_Ctrl", r=self.ctrlRadius, h=(self.ctrlRadius * 0.25), ) self.hipsB = cmds.circle( name=side + self.userGuideName + "_" + self.langDic[self.langName]["c_hips"] + "B_Ctrl", ch=False, o=True, nr=(0, 1, 0), d=1, s=8, radius=self.ctrlRadius, )[0] self.chestA = ctrls.cvBox( ctrlName=side + self.userGuideName + "_" + self.langDic[self.langName]["c_chest"] + "A_Ctrl", r=self.ctrlRadius, h=(self.ctrlRadius * 0.25), ) self.chestB = cmds.circle( name=side + self.userGuideName + "_" + self.langDic[self.langName]["c_chest"] + "B_Ctrl", ch=False, o=True, nr=(0, 1, 0), d=1, s=8, radius=self.ctrlRadius, )[0] cmds.addAttr( self.hipsA, longName=side + self.userGuideName + "_" + self.langDic[self.langName]["c_volumeVariation"], attributeType="float", defaultValue=1, keyable=True, ) ctrls.setLockHide([self.hipsA, self.hipsB, self.chestA, self.chestB], ["v"], l=False) self.hipsAList.append(self.hipsA) self.chestAList.append(self.chestA) self.volumeVariationAttrList.append( side + self.userGuideName + "_" + self.langDic[self.langName]["c_volumeVariation"] ) # organize hierarchy: cmds.parent(self.hipsB, self.hipsA) cmds.parent(self.chestB, self.chestA) cmds.parent(self.chestA, self.hipsA) cmds.rotate(-90, 0, 0, self.hipsA) cmds.makeIdentity(self.hipsA, apply=True, rotate=True) # position of controls: bottomLocGuide = side + self.userGuideName + "_Guide_JointLoc1" topLocGuide = side + self.userGuideName + "_Guide_JointLoc" + str(self.nJoints) # snap controls to guideLocators: tempDel = cmds.parentConstraint(bottomLocGuide, self.hipsA, maintainOffset=False) cmds.delete(tempDel) tempDel = cmds.parentConstraint(topLocGuide, self.chestA, maintainOffset=False) cmds.delete(tempDel) # zeroOut transformations: utils.zeroOut([self.hipsA, self.chestA]) # modify the pivots of chest controls: upPivotPos = cmds.xform( side + self.userGuideName + "_Guide_JointLoc" + str(self.nJoints - 1), query=True, worldSpace=True, translation=True, ) cmds.move( upPivotPos[0], upPivotPos[1], upPivotPos[2], self.chestA + ".scalePivot", self.chestA + ".rotatePivot", ) # , self.chestB+".scalePivot", self.chestB+".rotatePivot") # add originedFrom attributes to hipsA, hipsB and chestB: utils.originedFrom(objName=self.hipsA, attrString=self.base) utils.originedFrom(objName=self.hipsB, attrString=bottomLocGuide) utils.originedFrom(objName=self.chestB, attrString=topLocGuide) # create a simple spine ribbon: returnedRibbonList = ctrls.createSimpleRibbon( name=side + self.userGuideName + "_Rbn", totalJoints=(self.nJoints - 1) ) rbnNurbsPlane = returnedRibbonList[0] rbnNurbsPlaneShape = returnedRibbonList[1] rbnJointGrpList = returnedRibbonList[2] rbnJointList = returnedRibbonList[3] # position of ribbon nurbs plane: cmds.setAttr(rbnNurbsPlane + ".tz", -4) cmds.move(0, 0, 0, rbnNurbsPlane + ".scalePivot", rbnNurbsPlane + ".rotatePivot") cmds.rotate(90, 90, 0, rbnNurbsPlane) cmds.makeIdentity(rbnNurbsPlane, apply=True, translate=True, rotate=True) downLocPos = cmds.xform( side + self.userGuideName + "_Guide_JointLoc1", query=True, worldSpace=True, translation=True ) upLocPos = cmds.xform( side + self.userGuideName + "_Guide_JointLoc" + str(self.nJoints), query=True, worldSpace=True, translation=True, ) cmds.move(downLocPos[0], downLocPos[1], downLocPos[2], rbnNurbsPlane) # create up and down clusters: downCluster = cmds.cluster( rbnNurbsPlane + ".cv[0:3][0:1]", name=side + self.userGuideName + "_Down_Cls" )[1] upCluster = cmds.cluster( rbnNurbsPlane + ".cv[0:3][" + str(self.nJoints) + ":" + str(self.nJoints + 1) + "]", name=side + self.userGuideName + "_Up_Cls", )[1] # get positions of joints from ribbon nurbs plane: startRbnJointPos = cmds.xform( side + self.userGuideName + "_Rbn0_Jnt", query=True, worldSpace=True, translation=True ) endRbnJointPos = cmds.xform( side + self.userGuideName + "_Rbn" + str(self.nJoints - 1) + "_Jnt", query=True, worldSpace=True, translation=True, ) # move pivots of clusters to start and end positions: cmds.move( startRbnJointPos[0], startRbnJointPos[1], startRbnJointPos[2], downCluster + ".scalePivot", downCluster + ".rotatePivot", ) cmds.move( endRbnJointPos[0], endRbnJointPos[1], endRbnJointPos[2], upCluster + ".scalePivot", upCluster + ".rotatePivot", ) # snap clusters to guideLocators: tempDel = cmds.parentConstraint(bottomLocGuide, downCluster, maintainOffset=False) cmds.delete(tempDel) tempDel = cmds.parentConstraint(topLocGuide, upCluster, maintainOffset=False) cmds.delete(tempDel) # rotate clusters to compensate guide: upClusterRot = cmds.xform(upCluster, query=True, worldSpace=True, rotation=True) downClusterRot = cmds.xform(downCluster, query=True, worldSpace=True, rotation=True) cmds.xform( upCluster, worldSpace=True, rotation=(upClusterRot[0] + 90, upClusterRot[1], upClusterRot[2]) ) cmds.xform( downCluster, worldSpace=True, rotation=(downClusterRot[0] + 90, downClusterRot[1], downClusterRot[2]), ) # scaleY of the clusters in order to avoid great extremity deforms: rbnHeight = ctrls.distanceBet( side + self.userGuideName + "_Guide_JointLoc" + str(self.nJoints), side + self.userGuideName + "_Guide_JointLoc1", keep=False, )[0] cmds.setAttr(upCluster + ".sy", rbnHeight / 10) cmds.setAttr(downCluster + ".sy", rbnHeight / 10) # parent clusters in controls (up and down): cmds.parentConstraint( self.hipsB, downCluster, maintainOffset=True, name=downCluster + "_ParentConstraint" ) cmds.parentConstraint(self.chestB, upCluster, maintainOffset=True, name=upCluster + "_ParentConstraint") # organize a group of clusters: self.clustersGrp = cmds.group(name=side + self.userGuideName + "_Rbn_Clusters_Grp", empty=True) if hideJoints: cmds.setAttr(self.clustersGrp + ".visibility", 0) cmds.parent(downCluster, upCluster, self.clustersGrp, relative=True) # make ribbon joints groups scalable: for r, rbnJntGrp in enumerate(rbnJointGrpList): if (r > 0) and (r < (len(rbnJointGrpList) - 1)): scaleGrp = cmds.group(rbnJntGrp, name=rbnJntGrp.replace("_Grp", "_Scale_Grp")) ctrls.directConnect(scaleGrp, rbnJntGrp, ["sx", "sz"]) cmds.scaleConstraint(self.clustersGrp, scaleGrp, maintainOffset=True, name=rbnJntGrp + "_Scale") else: cmds.scaleConstraint( self.clustersGrp, rbnJntGrp, maintainOffset=True, name=rbnJntGrp + "_Scale" ) # calculate the distance to volumeVariation: arcLenShape = cmds.createNode("arcLengthDimension", name=side + self.userGuideName + "_Rbn_ArcLenShape") arcLenFather = cmds.listRelatives(arcLenShape, parent=True)[0] arcLen = cmds.rename(arcLenFather, side + self.userGuideName + "_Rbn_ArcLen") arcLenShape = cmds.listRelatives(arcLen, children=True, shapes=True)[0] cmds.setAttr(arcLen + ".visibility", 0) # connect nurbsPlaneShape to arcLength node: cmds.connectAttr(rbnNurbsPlaneShape + ".worldSpace[0]", arcLenShape + ".nurbsGeometry") cmds.setAttr(arcLenShape + ".vParamValue", 1) # avoid undesired squash if rotateZ the nurbsPlane: cmds.setAttr(arcLenShape + ".uParamValue", 0.5) arcLenValue = cmds.getAttr(arcLenShape + ".arcLengthInV") # create a multiplyDivide to output the squashStretch values: rbnMD = cmds.createNode("multiplyDivide", name=side + self.userGuideName + "_Rbn_MD") cmds.connectAttr(arcLenShape + ".arcLengthInV", rbnMD + ".input2X") cmds.setAttr(rbnMD + ".input1X", arcLenValue) cmds.setAttr(rbnMD + ".operation", 2) # create a blendColor in order to get the correct result value of volumeVariation: rbnBlendColors = cmds.createNode("blendColors", name=side + self.userGuideName + "_Rbn_BlendColor") cmds.connectAttr( self.hipsA + "." + side + self.userGuideName + "_" + self.langDic[self.langName]["c_volumeVariation"], rbnBlendColors + ".blender", ) cmds.connectAttr(rbnMD + ".outputX", rbnBlendColors + ".color1R") cmds.setAttr(rbnBlendColors + ".color2R", 1) # middle ribbon setup: for n in range(1, self.nJoints - 1): self.middle = cmds.circle( name=side + self.userGuideName + "_" + self.langDic[self.langName]["c_middle"] + str(n) + "_Ctrl", ch=False, o=True, nr=(0, 0, 1), d=3, s=8, radius=self.ctrlRadius, )[0] ctrls.setLockHide([self.middle], ["sx", "sy", "sz"]) cmds.setAttr(self.middle + ".visibility", keyable=False) cmds.parent(self.middle, self.hipsA) middleLocGuide = side + self.userGuideName + "_Guide_JointLoc" + str(n + 1) tempDel = cmds.parentConstraint(middleLocGuide, self.middle, maintainOffset=False) cmds.delete(tempDel) utils.zeroOut([self.middle]) middleCluster = cmds.cluster( rbnNurbsPlane + ".cv[0:3][" + str(n + 1) + "]", name=side + self.userGuideName + "_Middle_Cls" )[1] middleLocPos = cmds.xform( side + self.userGuideName + "_Guide_JointLoc" + str(n), query=True, worldSpace=True, translation=True, ) tempDel = cmds.parentConstraint(middleLocGuide, middleCluster, maintainOffset=False) cmds.delete(tempDel) middleClusterRot = cmds.xform(middleCluster, query=True, worldSpace=True, rotation=True) cmds.xform( middleCluster, worldSpace=True, rotation=(middleClusterRot[0] + 90, middleClusterRot[1], middleClusterRot[2]), ) cmds.parentConstraint( self.middle, middleCluster, maintainOffset=True, name=middleCluster + "_ParentConstraint" ) # parenting constraints like guide locators: self.parentConst = cmds.parentConstraint( self.hipsB, self.chestB, self.middle + "_Zero", name=self.middle + "_ParentConstraint", maintainOffset=True, )[0] nParentValue = (n) / float(self.nJoints - 1) cmds.setAttr(self.parentConst + "." + self.hipsB + "W0", 1 - nParentValue) cmds.setAttr(self.parentConst + "." + self.chestB + "W1", nParentValue) cmds.parent(middleCluster, self.clustersGrp, relative=True) # add originedFrom attribute to this middle ctrl: utils.originedFrom(objName=self.middle, attrString=middleLocGuide) # apply volumeVariation to joints in the middle ribbon setup: cmds.connectAttr(rbnBlendColors + ".outputR", rbnJointList[n] + ".scaleX") cmds.connectAttr(rbnBlendColors + ".outputR", rbnJointList[n] + ".scaleZ") # organize groups: self.rbnRigGrp = cmds.group(name=side + self.userGuideName + "_Grp", empty=True) self.rbnControlGrp = cmds.group(name=side + self.userGuideName + "_Control_Grp", empty=True) cmds.parent(self.hipsA + "_Zero", self.rbnControlGrp, relative=True) cmds.parent( self.clustersGrp, side + self.userGuideName + "_Rbn_RibbonJoint_Grp", self.rbnControlGrp, arcLen, self.rbnRigGrp, relative=True, ) if hideJoints: cmds.setAttr(side + self.userGuideName + "_Rbn_RibbonJoint_Grp.visibility", 0) # add hook attributes to be read when rigging integrated modules: utils.addHook(objName=self.rbnControlGrp, hookType="ctrlHook") utils.addHook(objName=self.clustersGrp, hookType="scalableHook") utils.addHook(objName=self.rbnRigGrp, hookType="staticHook") cmds.addAttr(self.rbnRigGrp, longName="dpAR_name", dataType="string") cmds.addAttr(self.rbnRigGrp, longName="dpAR_type", dataType="string") cmds.setAttr(self.rbnRigGrp + ".dpAR_name", self.userGuideName, type="string") cmds.setAttr(self.rbnRigGrp + ".dpAR_type", CLASS_NAME, type="string") # add module type counter value cmds.addAttr(self.rbnRigGrp, longName="dpAR_count", attributeType="long", keyable=False) cmds.setAttr(self.rbnRigGrp + ".dpAR_count", dpAR_count) # lockHide scale of up and down controls: ctrls.setLockHide([self.hipsA, self.hipsB, self.chestA, self.chestB], ["sx", "sy", "sz"]) # delete duplicated group for side (mirror): cmds.delete(side + self.userGuideName + "_" + self.mirrorGrp) # finalize this rig: self.integratingInfo() cmds.select(clear=True) # delete UI (moduleLayout), GUIDE and moduleInstance namespace: self.deleteModule()
def rigModule(self, *args): Base.StartClass.rigModule(self) # verify if the guide exists: if cmds.objExists(self.moduleGrp): try: hideJoints = cmds.checkBox('hideJointsCB', query=True, value=True) except: hideJoints = 1 # start as no having mirror: sideList = [""] # analisys the mirror module: self.mirrorAxis = cmds.getAttr(self.moduleGrp+".mirrorAxis") if self.mirrorAxis != 'off': # get rigs names: self.mirrorNames = cmds.getAttr(self.moduleGrp+".mirrorName") # get first and last letters to use as side initials (prefix): sideList = [ self.mirrorNames[0]+'_', self.mirrorNames[len(self.mirrorNames)-1]+'_' ] for s, side in enumerate(sideList): duplicated = cmds.duplicate(self.moduleGrp, name=side+self.userGuideName+'_Guide_Base')[0] allGuideList = cmds.listRelatives(duplicated, allDescendents=True) for item in allGuideList: cmds.rename(item, side+self.userGuideName+"_"+item) self.mirrorGrp = cmds.group(name="Guide_Base_Grp", empty=True) cmds.parent(side+self.userGuideName+'_Guide_Base', self.mirrorGrp, absolute=True) # re-rename grp: cmds.rename(self.mirrorGrp, side+self.userGuideName+'_'+self.mirrorGrp) # do a group mirror with negative scaling: if s == 1: if cmds.getAttr(self.moduleGrp+".flip") == 0: for axis in self.mirrorAxis: gotValue = cmds.getAttr(side+self.userGuideName+"_Guide_Base.translate"+axis) flipedValue = gotValue*(-2) cmds.setAttr(side+self.userGuideName+'_'+self.mirrorGrp+'.translate'+axis, flipedValue) else: for axis in self.mirrorAxis: cmds.setAttr(side+self.userGuideName+'_'+self.mirrorGrp+'.scale'+axis, -1) else: # if not mirror: duplicated = cmds.duplicate(self.moduleGrp, name=self.userGuideName+'_Guide_Base')[0] allGuideList = cmds.listRelatives(duplicated, allDescendents=True) for item in allGuideList: cmds.rename(item, self.userGuideName+"_"+item) self.mirrorGrp = cmds.group(self.userGuideName+'_Guide_Base', name="Guide_Base_Grp", relative=True) #for Maya2012: self.userGuideName+'_'+self.moduleGrp+"_Grp" # re-rename grp: cmds.rename(self.mirrorGrp, self.userGuideName+'_'+self.mirrorGrp) # store the number of this guide by module type: dpAR_count = utils.findModuleLastNumber(CLASS_NAME, "dpAR_type") + 1 # create a list to export: self.eyeScaleGrpList = [] # create the main control: self.eyeCtrl = cmds.circle(name=self.userGuideName+"_A_Ctrl", radius=(2.25*self.ctrlRadius), normal=(0,0,1), degree=3, constructionHistory=False)[0] cmds.addAttr(self.eyeCtrl, longName=self.langDic[self.langName]['c_Follow'], attributeType='float', keyable=True, minValue=0, maxValue=1) cmds.setAttr(self.eyeCtrl+"."+self.langDic[self.langName]['c_Follow'], 1) cmds.move(0,-1,0, self.eyeCtrl+".cv[1]", relative=True) cmds.move(0,1,0, self.eyeCtrl+".cv[5]", relative=True) cmds.delete(cmds.parentConstraint(sideList[0]+self.userGuideName+"_Guide_JointEnd", self.eyeCtrl, maintainOffset=False)) cmds.setAttr(self.eyeCtrl+".translateX", 0) self.eyeGrp = cmds.group(self.eyeCtrl, name=self.userGuideName+"_A_Grp") utils.zeroOut([self.eyeCtrl]) self.upLocGrp = cmds.group(name=self.userGuideName+"_UpLoc_Grp", empty=True) # run for all sides: for s, side in enumerate(sideList): cmds.select(clear=True) self.base = side+self.userGuideName+'_Guide_Base' # declare guide: self.guide = side+self.userGuideName+"_Guide_JointLoc1" # create a joint: self.jxt = cmds.joint(name=side+self.userGuideName+"_1_Jxt", scaleCompensate=False) self.jnt = cmds.joint(name=side+self.userGuideName+"_1_Jnt", scaleCompensate=False) cmds.addAttr(self.jnt, longName='dpAR_joint', attributeType='float', keyable=False) self.fkEyeCtrl = cmds.circle(name=side+self.userGuideName+"_Fk_Ctrl", radius=self.ctrlRadius, normal=(0,0,1), degree=1, sections=6, constructionHistory=False)[0] utils.originedFrom(objName=self.fkEyeCtrl, attrString=self.base+";"+self.guide) self.baseEyeCtrl = ctrls.cvBox(ctrlName=side+self.userGuideName+"_Base_Ctrl", r=self.ctrlRadius) utils.originedFrom(objName=self.baseEyeCtrl, attrString=self.base+";"+self.guide) # position and orientation of joint and control: cmds.delete(cmds.parentConstraint(self.guide, self.jxt, maintainOffset=False)) cmds.delete(cmds.parentConstraint(self.guide, self.fkEyeCtrl, maintainOffset=False)) cmds.delete(cmds.parentConstraint(self.guide, self.baseEyeCtrl, maintainOffset=False)) cmds.makeIdentity(self.baseEyeCtrl, self.fkEyeCtrl, apply=True) # zeroOut controls: eyeZeroList = utils.zeroOut([self.baseEyeCtrl, self.fkEyeCtrl]) cmds.parent(eyeZeroList[1], self.baseEyeCtrl) # hide visibility attribute: cmds.setAttr(self.fkEyeCtrl+'.visibility', keyable=False) ctrls.setLockHide([self.fkEyeCtrl], ['tx', 'ty', 'tz']) # create end joint: self.cvEndJoint = side+self.userGuideName+"_Guide_JointEnd" self.endJoint = cmds.joint(name=side+self.userGuideName+"_JEnd") cmds.delete(cmds.parentConstraint(self.cvEndJoint, self.endJoint, maintainOffset=False)) cmds.parent(self.endJoint, self.jnt, absolute=True) # create parentConstraint from ctrl to jxt: cmds.parentConstraint(self.fkEyeCtrl, self.jxt, maintainOffset=False, name=self.jnt+"_ParentConstraint") # create scaleConstraint from ctrl to jnt: cmds.scaleConstraint(self.fkEyeCtrl, self.jxt, maintainOffset=True, name=self.jnt+"_ScaleConstraint") # lookAt control: self.lookAtCtrl = cmds.circle(name=side+self.userGuideName+"_LookAt_Ctrl", radius=self.ctrlRadius, normal=(0,0,1), degree=3, constructionHistory=False)[0] cmds.delete(cmds.parentConstraint(self.cvEndJoint, self.lookAtCtrl, maintainOffset=False)) cmds.parent(self.lookAtCtrl, self.eyeCtrl, relative=False) cmds.makeIdentity(self.lookAtCtrl, apply=True) cmds.addAttr(self.lookAtCtrl, longName="active", attributeType="bool", defaultValue=1, keyable=True) # up locator: self.lUpGrpLoc = cmds.group(name=side+self.userGuideName+"_Up_Loc_Grp", empty=True) cmds.delete(cmds.parentConstraint(self.jnt, self.lUpGrpLoc, maintainOffset=False)) self.lUpLoc = cmds.spaceLocator(name=side+self.userGuideName+"_Up_Loc")[0] cmds.delete(cmds.parentConstraint(self.jnt, self.lUpLoc, maintainOffset=False)) cmds.move(cmds.getAttr(self.guideName+"_JointEnd.translateZ"), self.lUpLoc, moveY=True, relative=True) cmds.parent(self.lUpLoc, self.lUpGrpLoc, relative=False) cmds.parent(self.lUpGrpLoc, self.upLocGrp, relative=False) # look at aim constraint: aimConst = cmds.aimConstraint(self.lookAtCtrl, self.fkEyeCtrl+"_Zero", worldUpType="object", worldUpObject=self.upLocGrp+"|"+self.lUpGrpLoc+"|"+self.lUpLoc, maintainOffset=True)[0] cmds.connectAttr(self.lookAtCtrl+".active", aimConst+"."+self.lookAtCtrl+"W0", force=True) # eye aim rotation cmds.addAttr(self.fkEyeCtrl, longName="aimRotation", attributeType="float", keyable=True) cmds.connectAttr(self.fkEyeCtrl+".aimRotation", self.jnt+".rotateZ", force=True) cmds.pointConstraint(self.baseEyeCtrl, self.lUpGrpLoc, maintainOffset=True, name=self.lUpGrpLoc+"_PointConstraint") # create eyeScale setup: cmds.select(clear=True) self.eyeScaleJnt = cmds.joint(name=side+self.userGuideName+"Scale_1_Jnt", scaleCompensate=False) cmds.addAttr(self.eyeScaleJnt, longName='dpAR_joint', attributeType='float', keyable=False) # jointScale position: cmds.delete(cmds.parentConstraint(self.guide, self.eyeScaleJnt, maintainOffset=False)) # create endScale joint: self.endScaleJoint = cmds.joint(name=side+self.userGuideName+"Scale_JEnd") cmds.delete(cmds.parentConstraint(self.eyeScaleJnt, self.endScaleJoint, maintainOffset=False)) cmds.setAttr(self.endScaleJoint+".translateZ", 1) # create constraints to eyeScale: cmds.pointConstraint(self.jnt, self.eyeScaleJnt, maintainOffset=False, name=self.eyeScaleJnt+"_PointConstraint") cmds.scaleConstraint(self.jnt, self.eyeScaleJnt, maintainOffset=True, name=self.eyeScaleJnt+"_ScaleConstraint") self.eyeScaleGrp = cmds.group(self.eyeScaleJnt, name=self.eyeScaleJnt+"_Grp") self.eyeScaleGrpList.append(self.eyeScaleGrp) # create a masterModuleGrp to be checked if this rig exists: self.toCtrlHookGrp = cmds.group(eyeZeroList[0], name=side+self.userGuideName+"_Control_Grp") self.toScalableHookGrp = cmds.group(self.jxt, self.eyeScaleGrp, name=side+self.userGuideName+"_Joint_Grp") self.toStaticHookGrp = cmds.group(self.toCtrlHookGrp, self.toScalableHookGrp, name=side+self.userGuideName+"_Grp") if s == 0: cmds.parent(self.eyeGrp, self.toCtrlHookGrp) cmds.parent(self.upLocGrp, self.toScalableHookGrp) # create a locator in order to avoid delete static group: loc = cmds.spaceLocator(name=side+self.userGuideName+"_DO_NOT_DELETE")[0] cmds.parent(loc, self.toStaticHookGrp, absolute=True) cmds.setAttr(loc+".visibility", 0) ctrls.setLockHide([loc], ['tx', 'ty', 'tz', 'rx', 'ry', 'rz', 'sx', 'sy', 'sz', 'v']) # add hook attributes to be read when rigging integrated modules: utils.addHook(objName=self.toCtrlHookGrp, hookType='ctrlHook') utils.addHook(objName=self.toScalableHookGrp, hookType='scalableHook') utils.addHook(objName=self.toStaticHookGrp, hookType='staticHook') cmds.addAttr(self.toStaticHookGrp, longName="dpAR_name", dataType="string") cmds.addAttr(self.toStaticHookGrp, longName="dpAR_type", dataType="string") cmds.setAttr(self.toStaticHookGrp+".dpAR_name", self.userGuideName, type="string") cmds.setAttr(self.toStaticHookGrp+".dpAR_type", CLASS_NAME, type="string") # add module type counter value cmds.addAttr(self.toStaticHookGrp, longName='dpAR_count', attributeType='long', keyable=False) cmds.setAttr(self.toStaticHookGrp+'.dpAR_count', dpAR_count) if hideJoints: cmds.setAttr(self.toScalableHookGrp+".visibility", 0) # delete duplicated group for side (mirror): cmds.delete(side+self.userGuideName+'_'+self.mirrorGrp) # finalize this rig: self.integratingInfo() cmds.select(clear=True) # delete UI (moduleLayout), GUIDE and moduleInstance namespace: self.deleteModule()
def rigModule(self, *args): Base.StartClass.rigModule(self) # verify if the guide exists: if cmds.objExists(self.moduleGrp): try: hideJoints = cmds.checkBox('hideJointsCB', query=True, value=True) except: hideJoints = 1 # create lists to be integrated: self.footCtrlList, self.revFootCtrlZeroFinalList, self.revFootCtrlShapeList, self.toLimbIkHandleGrpList, self.parentConstList, self.footJntList, self.ballRFList, self.middleFootCtrlList, self.reverseFootAttrList = [], [], [], [], [], [], [], [], [] # start as no having mirror: sideList = [""] # analisys the mirror module: self.mirrorAxis = cmds.getAttr(self.moduleGrp+".mirrorAxis") if self.mirrorAxis != 'off': # get rigs names: self.mirrorNames = cmds.getAttr(self.moduleGrp+".mirrorName") # get first and last letters to use as side initials (prefix): sideList = [ self.mirrorNames[0]+'_', self.mirrorNames[len(self.mirrorNames)-1]+'_' ] for s, side in enumerate(sideList): duplicated = cmds.duplicate(self.moduleGrp, name=side+self.userGuideName+'_Guide_Base')[0] allGuideList = cmds.listRelatives(duplicated, allDescendents=True) for item in allGuideList: cmds.rename(item, side+self.userGuideName+"_"+item) self.mirrorGrp = cmds.group(name="Guide_Base_Grp", empty=True) cmds.parent(side+self.userGuideName+'_Guide_Base', self.mirrorGrp, absolute=True) # re-rename grp: cmds.rename(self.mirrorGrp, side+self.userGuideName+'_'+self.mirrorGrp) # do a group mirror with negative scaling: if s == 1: for axis in self.mirrorAxis: cmds.setAttr(side+self.userGuideName+'_'+self.mirrorGrp+'.scale'+axis, -1) else: # if not mirror: duplicated = cmds.duplicate(self.moduleGrp, name=self.userGuideName+'_Guide_Base')[0] allGuideList = cmds.listRelatives(duplicated, allDescendents=True) for item in allGuideList: cmds.rename(item, self.userGuideName+"_"+item) self.mirrorGrp = cmds.group(self.userGuideName+'_Guide_Base', name="Guide_Base_Grp", relative=True) # re-rename grp: cmds.rename(self.mirrorGrp, self.userGuideName+'_'+self.mirrorGrp) # store the number of this guide by module type dpAR_count = utils.findModuleLastNumber(CLASS_NAME, "dpAR_type") + 1 # run for all sides for s, side in enumerate(sideList): # redeclaring variables: self.base = side+self.userGuideName+"_Guide_Base" self.cvFootLoc = side+self.userGuideName+"_Guide_foot" self.cvRFALoc = side+self.userGuideName+"_Guide_RfA" self.cvRFBLoc = side+self.userGuideName+"_Guide_RfB" self.cvRFCLoc = side+self.userGuideName+"_Guide_RfC" self.cvRFDLoc = side+self.userGuideName+"_Guide_RfD" self.cvRFELoc = side+self.userGuideName+"_Guide_RfE" self.cvEndJoint = side+self.userGuideName+"_Guide_JointEnd" # declaring attributes reading from dictionary: ankleRFAttr = self.langDic[self.langName]['c_leg_extrem'] middleRFAttr = self.langDic[self.langName]['c_RevFoot_middle'] outsideRFAttr = self.langDic[self.langName]['c_RevFoot_A'] insideRFAttr = self.langDic[self.langName]['c_RevFoot_B'] heelRFAttr = self.langDic[self.langName]['c_RevFoot_C'] toeRFAttr = self.langDic[self.langName]['c_RevFoot_D'] ballRFAttr = self.langDic[self.langName]['c_RevFoot_E'] footRFAttr = self.langDic[self.langName]['c_RevFoot_F'] sideRFAttr = self.langDic[self.langName]['c_RevFoot_G'] rfRoll = self.langDic[self.langName]['c_RevFoot_roll'] rfSpin = self.langDic[self.langName]['c_RevFoot_spin'] rfTurn = self.langDic[self.langName]['c_RevFoot_turn'] # creating joints: cmds.select(clear=True) self.footJnt = cmds.joint(name=side+self.userGuideName+"_"+ankleRFAttr.capitalize()+"_Jnt") self.middleFootJxt = cmds.joint(name=side+self.userGuideName+"_"+middleRFAttr.capitalize()+"_Jxt") self.endJnt = cmds.joint(name=side+self.userGuideName+"_JEnd") cmds.select(clear=True) self.middleFootJnt = cmds.joint(name=side+self.userGuideName+"_"+middleRFAttr.capitalize()+"_Jnt") self.endBJnt = cmds.joint(name=side+self.userGuideName+"B_JEnd") cmds.parent(self.middleFootJnt, self.middleFootJxt) cmds.addAttr(self.footJnt, longName='dpAR_joint', attributeType='float', keyable=False) cmds.addAttr(self.middleFootJnt, longName='dpAR_joint', attributeType='float', keyable=False) cmds.select(clear=True) # reverse foot joints: self.RFAJxt = cmds.joint(name=side+self.userGuideName+"_"+outsideRFAttr.capitalize()+"_Jxt") self.RFBJxt = cmds.joint(name=side+self.userGuideName+"_"+insideRFAttr.capitalize()+"_Jxt") self.RFCJxt = cmds.joint(name=side+self.userGuideName+"_"+heelRFAttr.capitalize()+"_Jxt") self.RFDJxt = cmds.joint(name=side+self.userGuideName+"_"+toeRFAttr.capitalize()+"_Jxt") self.RFEJxt = cmds.joint(name=side+self.userGuideName+"_"+ballRFAttr.capitalize()+"_Jxt") self.RFEndJxt = cmds.joint(name=side+self.userGuideName+"_RFEnd_Jxt") rfJointList = [self.RFAJxt, self.RFBJxt, self.RFCJxt, self.RFDJxt, self.RFEJxt] self.ballRFList.append(self.RFEJxt) # set as template using overrides in order to permit no template children: for rfJoint in rfJointList: cmds.setAttr(rfJoint+'.overrideEnabled', 1) cmds.setAttr(rfJoint+'.overrideDisplayType', 1) cmds.setAttr(self.footJnt+'.overrideEnabled', 1) cmds.setAttr(self.middleFootJnt+'.overrideEnabled', 1) # reverse foot zero out joints: self.RFEJzt = utils.zeroOutJoints([self.RFEJxt])[0] self.RFDJzt = utils.zeroOutJoints([self.RFDJxt])[0] self.RFCJzt = utils.zeroOutJoints([self.RFCJxt])[0] self.RFBJzt = utils.zeroOutJoints([self.RFBJxt])[0] self.RFAJzt = utils.zeroOutJoints([self.RFAJxt])[0] rfJointZeroList = [self.RFAJzt, self.RFBJzt, self.RFCJzt, self.RFDJzt, self.RFEJzt] # putting joints in the correct place: tempToDelA = cmds.parentConstraint(self.cvFootLoc, self.footJnt, maintainOffset=False) tempToDelB = cmds.parentConstraint(self.cvRFELoc, self.middleFootJxt, maintainOffset=False) tempToDelC = cmds.parentConstraint(self.cvEndJoint, self.endJnt, maintainOffset=False) tempToDelD = cmds.parentConstraint(self.cvEndJoint, self.endBJnt, maintainOffset=False) tempToDelE = cmds.parentConstraint(self.cvRFALoc, self.RFAJzt, maintainOffset=False) tempToDelF = cmds.parentConstraint(self.cvRFBLoc, self.RFBJzt, maintainOffset=False) tempToDelG = cmds.parentConstraint(self.cvRFCLoc, self.RFCJzt, maintainOffset=False) tempToDelH = cmds.parentConstraint(self.cvRFDLoc, self.RFDJzt, maintainOffset=False) tempToDelI = cmds.parentConstraint(self.cvRFELoc, self.RFEJzt, maintainOffset=False) tempToDelJ = cmds.parentConstraint(self.cvEndJoint, self.RFEndJxt, maintainOffset=False) cmds.delete(tempToDelA, tempToDelB, tempToDelC, tempToDelD, tempToDelE, tempToDelF, tempToDelG, tempToDelH, tempToDelI, tempToDelJ) cmds.makeIdentity(rfJointZeroList, apply=True, translate=True, rotate=True, scale=True) # creating ikHandles: ikHandleAnkleList = cmds.ikHandle(name=side+self.userGuideName+"_"+ankleRFAttr.capitalize()+"_IkHandle", startJoint=self.footJnt, endEffector=self.middleFootJxt, solver='ikSCsolver') ikHandleMiddleList = cmds.ikHandle(name=side+self.userGuideName+"_"+middleRFAttr.capitalize()+"_IkHandle", startJoint=self.middleFootJxt, endEffector=self.endJnt, solver='ikSCsolver') cmds.rename(ikHandleAnkleList[1], ikHandleAnkleList[0]+"_Effector") cmds.rename(ikHandleMiddleList[1], ikHandleMiddleList[0]+"_Effector") cmds.setAttr(ikHandleAnkleList[0]+'.visibility', 0) cmds.setAttr(ikHandleMiddleList[0]+'.visibility', 0) # creating Fk controls: self.footCtrl = cmds.circle(name=side+self.userGuideName+"_"+self.langDic[self.langName]['c_leg_extrem']+"_Ctrl", ch=False, o=True, nr=(1, 0, 0), d=3, s=8, radius=self.ctrlRadius/2.0)[0] self.footCtrlList.append(self.footCtrl) self.revFootCtrlShapeList.append(cmds.listRelatives(self.footCtrl, children=True, type='nurbsCurve')[0]) self.middleFootCtrl = cmds.circle(name=side+self.userGuideName+"_"+self.langDic[self.langName]['c_RevFoot_middle'].capitalize()+"_Ctrl", ch=False, o=True, nr=(0, 0, 1), d=1, s=8, radius=self.ctrlRadius/2.0)[0] cmds.setAttr(self.middleFootCtrl+'.overrideEnabled', 1) tempToDelA = cmds.parentConstraint(self.cvFootLoc, self.footCtrl, maintainOffset=False) tempToDelB = cmds.parentConstraint(self.cvRFELoc, self.middleFootCtrl, maintainOffset=False) cmds.delete(tempToDelA, tempToDelB) self.footCtrlZeroList = utils.zeroOut([self.footCtrl, self.middleFootCtrl]) self.revFootCtrlZeroFinalList.append(self.footCtrlZeroList[0]) self.middleFootCtrlList.append(self.middleFootCtrl) # mount hierarchy: cmds.parent(self.footCtrlZeroList[1], self.RFDJxt, absolute=True) cmds.parent(ikHandleMiddleList[0], self.middleFootCtrl, absolute=True) self.toLimbIkHandleGrp = cmds.group(empty=True, name=side+self.userGuideName+"_"+self.langDic[self.langName]['c_leg_extrem']+"_Grp") self.toLimbIkHandleGrpList.append(self.toLimbIkHandleGrp) cmds.parent(ikHandleAnkleList[0], self.toLimbIkHandleGrp, self.RFEJxt, absolute=True) cmds.makeIdentity(self.toLimbIkHandleGrp, apply=True, translate=True, rotate=True, scale=True) parentConst = cmds.parentConstraint(self.RFEJxt, self.footJnt, maintainOffset=True, name=self.footJnt+"_ParentConstraint")[0] self.parentConstList.append(parentConst) self.footJntList.append(self.footJnt) cmds.parent(self.RFAJzt, self.footCtrl, absolute=True) cmds.scaleConstraint(self.footCtrl, self.footJnt, maintainOffset=True, name=self.footJnt+"_ScaleConstraint") cmds.parentConstraint(self.middleFootCtrl, self.middleFootJnt, maintainOffset=True, name=self.middleFootJnt+"_ParentConstraint") cmds.scaleConstraint(self.middleFootCtrl, self.middleFootJnt, maintainOffset=True, name=self.middleFootJnt+"_ScaleConstraint") # add attributes to footCtrl and connect them to joint rotation: rfAttrList = [outsideRFAttr, insideRFAttr, heelRFAttr, toeRFAttr, ballRFAttr] rfTypeAttrList = [rfRoll, rfSpin] for j, rfAttr in enumerate(rfAttrList): for t, rfType in enumerate(rfTypeAttrList): if t == 1 and j == (len(rfAttrList)-1): # create turn attr to ball cmds.addAttr(self.footCtrl, longName=rfAttr+"_"+rfTurn, attributeType='float', keyable=True) cmds.connectAttr(self.footCtrl+"."+rfAttr+"_"+rfTurn, rfJointList[j]+".rotateX", force=True) self.reverseFootAttrList.append(rfAttr+"_"+rfTurn) cmds.addAttr(self.footCtrl, longName=rfAttr+"_"+rfType, attributeType='float', keyable=True) self.reverseFootAttrList.append(rfAttr+"_"+rfType) if t == 0: if j > 1: cmds.connectAttr(self.footCtrl+"."+rfAttr+"_"+rfType, rfJointList[j]+".rotateY", force=True) else: cmds.connectAttr(self.footCtrl+"."+rfAttr+"_"+rfType, rfJointList[j]+".rotateX", force=True) else: cmds.connectAttr(self.footCtrl+"."+rfAttr+"_"+rfType, rfJointList[j]+".rotateZ", force=True) # creating the originedFrom attributes (in order to permit integrated parents in the future): utils.originedFrom(objName=self.footCtrl, attrString=self.base+";"+self.cvFootLoc+";"+self.cvRFALoc+";"+self.cvRFBLoc+";"+self.cvRFCLoc+";"+self.cvRFDLoc) utils.originedFrom(objName=self.middleFootCtrl, attrString=self.cvRFELoc+";"+self.cvEndJoint) # creating pre-defined attributes for footRoll and sideRoll attributes: cmds.addAttr(self.footCtrl, longName=footRFAttr+"_"+rfRoll, attributeType='float', keyable=True) cmds.addAttr(self.footCtrl, longName=sideRFAttr+"_"+rfRoll, attributeType='float', keyable=True) # create clampNodes in order to limit the side rotations: sideClamp = cmds.createNode("clamp", name=side+self.userGuideName+"_Side_Clp") # outside values in R cmds.setAttr(sideClamp+".maxR", 360) # inside values in G cmds.setAttr(sideClamp+".minG", -360) # connections: cmds.connectAttr(self.footCtrl+"."+sideRFAttr+"_"+rfRoll, sideClamp+".inputR", force=True) cmds.connectAttr(self.footCtrl+"."+sideRFAttr+"_"+rfRoll, sideClamp+".inputG", force=True) cmds.connectAttr(sideClamp+".outputR", self.RFAJzt+".rotateX", force=True) cmds.connectAttr(sideClamp+".outputG", self.RFBJzt+".rotateX", force=True) # for footRoll: footClamp = cmds.createNode("clamp", name=side+self.userGuideName+"_Foot_Clp") # heel values in R cmds.setAttr(footClamp+".maxR", 360) cmds.connectAttr(self.footCtrl+"."+footRFAttr+"_"+rfRoll, footClamp+".inputR", force=True) cmds.connectAttr(footClamp+".outputR", self.RFCJzt+".rotateY", force=True) # set driven keys cmds.setDrivenKeyframe(self.RFEJzt+".rotateY", currentDriver=self.footCtrl+"."+footRFAttr+"_"+rfRoll, driverValue=0, value=0, inTangentType="flat", outTangentType="flat") cmds.setDrivenKeyframe(self.RFEJzt+".rotateY", currentDriver=self.footCtrl+"."+footRFAttr+"_"+rfRoll, driverValue=-45, value=-45, inTangentType="spline", outTangentType="spline") cmds.setDrivenKeyframe(self.RFEJzt+".rotateY", currentDriver=self.footCtrl+"."+footRFAttr+"_"+rfRoll, driverValue=-200, value=0, inTangentType="flat", outTangentType="flat") cmds.setDrivenKeyframe(self.RFDJzt+".rotateY", currentDriver=self.footCtrl+"."+footRFAttr+"_"+rfRoll, driverValue=-30, value=0, inTangentType="flat", outTangentType="flat") cmds.setDrivenKeyframe(self.RFDJzt+".rotateY", currentDriver=self.footCtrl+"."+footRFAttr+"_"+rfRoll, driverValue=-60, value=-30, inTangentType="spline", outTangentType="spline") cmds.setDrivenKeyframe(self.RFDJzt+".rotateY", currentDriver=self.footCtrl+"."+footRFAttr+"_"+rfRoll, driverValue=-360, value=-180, inTangentType="flat", outTangentType="flat") # organizing keyable attributes: ctrls.setLockHide([self.middleFootCtrl, self.footCtrl], ['v'], l=False) # create a masterModuleGrp to be checked if this rig exists: self.toCtrlHookGrp = cmds.group(self.footCtrlZeroList[0], name=side+self.userGuideName+"_Control_Grp") self.toScalableHookGrp = cmds.group(self.footJnt, name=side+self.userGuideName+"_Joint_Grp") self.toStaticHookGrp = cmds.group(self.toCtrlHookGrp, self.toScalableHookGrp, name=side+self.userGuideName+"_Grp") cmds.addAttr(self.toStaticHookGrp, longName="dpAR_name", dataType="string") cmds.addAttr(self.toStaticHookGrp, longName="dpAR_type", dataType="string") cmds.setAttr(self.toStaticHookGrp+".dpAR_name", self.userGuideName, type="string") cmds.setAttr(self.toStaticHookGrp+".dpAR_type", CLASS_NAME, type="string") # add module type counter value cmds.addAttr(self.toStaticHookGrp, longName='dpAR_count', attributeType='long', keyable=False) cmds.setAttr(self.toStaticHookGrp+'.dpAR_count', dpAR_count) # create a locator in order to avoid delete static group loc = cmds.spaceLocator(name=side+self.userGuideName+"_DO_NOT_DELETE")[0] cmds.parent(loc, self.toStaticHookGrp, absolute=True) cmds.setAttr(loc+".visibility", 0) ctrls.setLockHide([loc], ['tx', 'ty', 'tz', 'rx', 'ry', 'rz', 'sx', 'sy', 'sz', 'v']) # add hook attributes to be read when rigging integrated modules: utils.addHook(objName=self.toCtrlHookGrp, hookType='ctrlHook') utils.addHook(objName=self.toScalableHookGrp, hookType='scalableHook') utils.addHook(objName=self.toStaticHookGrp, hookType='staticHook') if hideJoints: cmds.setAttr(self.toScalableHookGrp+".visibility", 0) # delete duplicated group for side (mirror): cmds.delete(side+self.userGuideName+'_'+self.mirrorGrp) # finalize this rig: self.integratingInfo() cmds.select(clear=True) # delete UI (moduleLayout), GUIDE and moduleInstance namespace: self.deleteModule()
def rigModule(self, *args): Base.StartClass.rigModule(self) # verify if the guide exists: if cmds.objExists(self.moduleGrp): try: hideJoints = cmds.checkBox('hideJointsCB', query=True, value=True) except: hideJoints = 1 # start as no having mirror: sideList = [""] # analisys the mirror module: self.mirrorAxis = cmds.getAttr(self.moduleGrp+".mirrorAxis") if self.mirrorAxis != 'off': # get rigs names: self.mirrorNames = cmds.getAttr(self.moduleGrp+".mirrorName") # get first and last letters to use as side initials (prefix): sideList = [ self.mirrorNames[0]+'_', self.mirrorNames[len(self.mirrorNames)-1]+'_' ] for s, side in enumerate(sideList): duplicated = cmds.duplicate(self.moduleGrp, name=side+self.userGuideName+'_Guide_Base')[0] allGuideList = cmds.listRelatives(duplicated, allDescendents=True) for item in allGuideList: cmds.rename(item, side+self.userGuideName+"_"+item) self.mirrorGrp = cmds.group(name="Guide_Base_Grp", empty=True) cmds.parent(side+self.userGuideName+'_Guide_Base', self.mirrorGrp, absolute=True) # re-rename grp: cmds.rename(self.mirrorGrp, side+self.userGuideName+'_'+self.mirrorGrp) # do a group mirror with negative scaling: if s == 1: if cmds.getAttr(self.moduleGrp+".flip") == 0: for axis in self.mirrorAxis: gotValue = cmds.getAttr(side+self.userGuideName+"_Guide_Base.translate"+axis) flipedValue = gotValue*(-2) cmds.setAttr(side+self.userGuideName+'_'+self.mirrorGrp+'.translate'+axis, flipedValue) else: for axis in self.mirrorAxis: cmds.setAttr(side+self.userGuideName+'_'+self.mirrorGrp+'.scale'+axis, -1) else: # if not mirror: duplicated = cmds.duplicate(self.moduleGrp, name=self.userGuideName+'_Guide_Base')[0] allGuideList = cmds.listRelatives(duplicated, allDescendents=True) for item in allGuideList: cmds.rename(item, self.userGuideName+"_"+item) self.mirrorGrp = cmds.group(self.userGuideName+'_Guide_Base', name="Guide_Base_Grp", relative=True) #for Maya2012: self.userGuideName+'_'+self.moduleGrp+"_Grp" # re-rename grp: cmds.rename(self.mirrorGrp, self.userGuideName+'_'+self.mirrorGrp) # store the number of this guide by module type dpAR_count = utils.findModuleLastNumber(CLASS_NAME, "dpAR_type") + 1 # run for all sides for s, side in enumerate(sideList): self.base = side+self.userGuideName+'_Guide_Base' # get the number of joints to be created: self.nJoints = cmds.getAttr(self.base+".nJoints") for n in range(1, self.nJoints+1): cmds.select(clear=True) # declare guide: self.guide = side+self.userGuideName+"_Guide_JointLoc"+str(n) # create a joint: self.jnt = cmds.joint(name=side+self.userGuideName+"_"+str(n)+"_Jnt", scaleCompensate=False) cmds.addAttr(self.jnt, longName='dpAR_joint', attributeType='float', keyable=False) # create a control: self.ctrl = cmds.circle(name=side+self.userGuideName+"_"+str(n)+"_Ctrl", degree=1, normal=(0, 0, 1), r=self.ctrlRadius, s=6, ch=False)[0] if n == 1: utils.originedFrom(objName=self.ctrl, attrString=self.base+";"+self.guide) else: utils.originedFrom(objName=self.ctrl, attrString=self.guide) # position and orientation of joint and control: cmds.delete(cmds.parentConstraint(self.guide, self.jnt, maintainOffset=False)) cmds.delete(cmds.parentConstraint(self.guide, self.ctrl, maintainOffset=False)) # zeroOut controls: zeroOutCtrlGrp = utils.zeroOut([self.ctrl])[0] # hide visibility attribute: cmds.setAttr(self.ctrl+'.visibility', keyable=False) # fixing flip mirror: if s == 1: if cmds.getAttr(self.moduleGrp+".flip") == 1: cmds.setAttr(zeroOutCtrlGrp+".scaleX", -1) cmds.setAttr(zeroOutCtrlGrp+".scaleY", -1) cmds.setAttr(zeroOutCtrlGrp+".scaleZ", -1) cmds.addAttr(self.ctrl, longName='scaleCompensate', attributeType="bool", keyable=True) cmds.setAttr(self.ctrl+".scaleCompensate", 1) cmds.connectAttr(self.ctrl+".scaleCompensate", self.jnt+".segmentScaleCompensate", force=True) if n == self.nJoints: # create end joint: cmds.select(self.jnt) self.cvEndJoint = side+self.userGuideName+"_Guide_JointEnd" self.endJoint = cmds.joint(name=side+self.userGuideName+"_JEnd") cmds.delete(cmds.parentConstraint(self.cvEndJoint, self.endJoint, maintainOffset=False)) # grouping: for n in range(1, self.nJoints+1): self.jnt = side+self.userGuideName+"_"+str(n)+"_Jnt" self.ctrl = side+self.userGuideName+"_"+str(n)+"_Ctrl" self.zeroCtrl = side+self.userGuideName+"_"+str(n)+"_Ctrl_Zero" if n > 1: # parent joints as a simple chain (line) self.fatherJnt = side+self.userGuideName+"_"+str(n-1)+"_Jnt" cmds.parent(self.jnt, self.fatherJnt, absolute=True) # parent zeroCtrl Group to the before ctrl: self.fatherCtrl = side+self.userGuideName+"_"+str(n-1)+"_Ctrl" cmds.parent(self.zeroCtrl, self.fatherCtrl, absolute=True) # create parentConstraint from ctrl to jnt: cmds.parentConstraint(self.ctrl, self.jnt, maintainOffset=False, name=self.jnt+"_ParentConstraint") # create scaleConstraint from ctrl to jnt: cmds.scaleConstraint(self.ctrl, self.jnt, maintainOffset=True, name=self.jnt+"_ScaleConstraint") # create a masterModuleGrp to be checked if this rig exists: self.toCtrlHookGrp = cmds.group(side+self.userGuideName+"_1_Ctrl_Zero", name=side+self.userGuideName+"_Control_Grp") self.toScalableHookGrp = cmds.group(side+self.userGuideName+"_1_Jnt", name=side+self.userGuideName+"_Joint_Grp") self.toStaticHookGrp = cmds.group(self.toCtrlHookGrp, self.toScalableHookGrp, name=side+self.userGuideName+"_Grp") # create a locator in order to avoid delete static group loc = cmds.spaceLocator(name=side+self.userGuideName+"_DO_NOT_DELETE")[0] cmds.parent(loc, self.toStaticHookGrp, absolute=True) cmds.setAttr(loc+".visibility", 0) ctrls.setLockHide([loc], ['tx', 'ty', 'tz', 'rx', 'ry', 'rz', 'sx', 'sy', 'sz', 'v']) # add hook attributes to be read when rigging integrated modules: utils.addHook(objName=self.toCtrlHookGrp, hookType='ctrlHook') utils.addHook(objName=self.toScalableHookGrp, hookType='scalableHook') utils.addHook(objName=self.toStaticHookGrp, hookType='staticHook') cmds.addAttr(self.toStaticHookGrp, longName="dpAR_name", dataType="string") cmds.addAttr(self.toStaticHookGrp, longName="dpAR_type", dataType="string") cmds.setAttr(self.toStaticHookGrp+".dpAR_name", self.userGuideName, type="string") cmds.setAttr(self.toStaticHookGrp+".dpAR_type", CLASS_NAME, type="string") # add module type counter value cmds.addAttr(self.toStaticHookGrp, longName='dpAR_count', attributeType='long', keyable=False) cmds.setAttr(self.toStaticHookGrp+'.dpAR_count', dpAR_count) if hideJoints: cmds.setAttr(self.toScalableHookGrp+".visibility", 0) # delete duplicated group for side (mirror): cmds.delete(side+self.userGuideName+'_'+self.mirrorGrp) # finalize this rig: self.integratingInfo() cmds.select(clear=True) # delete UI (moduleLayout), GUIDE and moduleInstance namespace: self.deleteModule()