def __init__(self, prefix='new', baseObj=None): """ :param prefix: str, prefix to name new objects :param baseObj: instance of base.module.Base class :return: None """ self.topGrp = pm.group(n=prefix + 'Module_GRP', em=1) self.controlsGrp = pm.group(n=prefix + 'Controls_GRP', em=1, p=self.topGrp) self.secControlsGrp = pm.group(n=prefix + 'secondaryControls_GRP', em=1, p=self.topGrp) self.jointsGrp = pm.group(n=prefix + 'Joints_GRP', em=1, p=self.topGrp) self.partsGrp = pm.group(n=prefix + 'Parts_GRP', em=1, p=self.topGrp) self.partsNoTransGrp = pm.group(n=prefix + 'PartsNoTrans_GRP', em=1, p=self.topGrp) pm.hide(self.partsGrp, self.partsNoTransGrp) pm.setAttr(self.partsNoTransGrp + '.it', 0, l=1) if (pm.objExists('display_CTRL')): displayCtrl = pm.ls('display_CTRL')[0] levelGrp = [self.controlsGrp, self.secControlsGrp] pm.addAttr(displayCtrl, ln=prefix, at='enum', enumName='none:block:all', k=1, dv=1) pm.setAttr(displayCtrl + '.' + prefix, cb=1) common.setDrivenKey(displayCtrl + '.' + prefix, [0, 1, 2], levelGrp[0] + '.v', [0, 1, 1]) common.setDrivenKey(displayCtrl + '.' + prefix, [0, 1, 2], levelGrp[1] + '.v', [0, 0, 1]) # parent module if baseObj: pm.parent(self.topGrp, baseObj.modulesGrp)
def spaces(driverList, driverNames, destinationConstraint, destinationAttribute, name='space', maintainOffset=True): """ Add spaces :param driverList: list(str), driver object list :param driverNames: list(str), attrviute value name for each driver :param destinationConstraint: str, destination obj :param destinationAttribute: str, where attribute should appear :param name: str, name of the attribute :param maintainOffset: bool, constraint maintainOffset :return: """ pm.addAttr(destinationAttribute, longName=name, attributeType='enum', enumName=':'.join(driverNames), k=1, dv=0) constraintList = [] for driver in driverList: cnst = pm.parentConstraint(driver, destinationConstraint, mo=maintainOffset) constraintList.append(cnst) for counter, cnst in enumerate(constraintList): sourceValue = list(range(0, len(constraintList))) targetValue = [0] * len(constraintList) targetValue[counter] = 1 target = pm.listConnections(cnst.target[counter].targetWeight, source=True, plugs=True)[0] common.setDrivenKey(destinationAttribute + '.' + name, sourceValue, target, targetValue)
def makeIK(self, limbJoints, topFingerJoints, rigScale, rigmodule, useMetacarpalJoint=False, smartFootRoll=True, lSide='l_'): """ Do IK Arm/Leg, Metacarpal and Finger/Toe ctrl :param limbJoints: list(str), Arm/leg joints :param topFingerJoints: list(str), Metacarpal joints :param rigScale: float :param rigmodule: dict :return: """ metacarpalJointList = topFingerJoints topFngJntList = [] endFngJntList = [] for mtJnt in metacarpalJointList: if useMetacarpalJoint: fngJnt = pm.listRelatives(mtJnt, type='joint', children=True)[0] else: fngJnt = mtJnt fngEndJnt = joint.listHierarchy(mtJnt, withEndJoints=True)[-1] topFngJntList.append(fngJnt) endFngJntList.append(fngEndJnt) footRoolInstance = footRoll.FootRoll(limbJoints[0], limbJoints[2], topFngJntList, endFngJntList) footRollGrpList = footRoolInstance.getGroupList() pm.parent(footRollGrpList[-1], rigmodule.partsNoTransGrp) prefix = name.removeSuffix(limbJoints[2]) # make controls mainIKCtrl = control.Control(prefix=prefix + 'IK', translateTo=limbJoints[2], rotateTo=limbJoints[2], parent=rigmodule.controlsGrp, shape='circleY') midFngIKIndex = int( round(len(footRoolInstance.getIkFingerList()) / 2.0)) - 1 midFngJnt = footRoolInstance.getIkFingerList( )[midFngIKIndex].getJointList()[0] ballCtrl = control.Control(prefix=prefix + 'BallIK', translateTo=midFngJnt, rotateTo=midFngJnt, parent=mainIKCtrl.C, shape='circleZ') toeIkControls = [] for topToeJnt in topFingerJoints: toePrefix = name.removeSuffix(topToeJnt) toeEndJnt = pm.listRelatives(topToeJnt, ad=1, type='joint')[0] toeIkCtrl = control.Control(prefix=toePrefix, translateTo=toeEndJnt, scale=rigScale, parent=ballCtrl.C, shape='circleY') toeIkControls.append(toeIkCtrl) # constraint IK for i, toeIK in enumerate(footRoolInstance.getIkFingerList()): pm.parentConstraint(toeIkControls[i].C, toeIK) pm.parentConstraint(mainIKCtrl.C, footRollGrpList[-1], mo=True) pm.parentConstraint(footRollGrpList[1], ballCtrl.getOffsetGrp(), mo=True) handIKOrientContraint = pm.orientConstraint(mainIKCtrl.C, limbJoints[2], mo=True) ballRollGrp = footRollGrpList[0] toeTapGrp = footRollGrpList[1] tippyToeGrp = footRollGrpList[2] frontRollGrp, backRollGrp, innerRollGrp, outerRollGrp = footRollGrpList[ 3:-1] if smartFootRoll and frontRollGrp and ballRollGrp and innerRollGrp and outerRollGrp: rollAttr = attributes.addFloatAttribute(mainIKCtrl.getControl(), 'roll', defaultValue=0, keyable=True, minValue=-120, maxValue=120) bendLimitAttr = attributes.addFloatAttribute( mainIKCtrl.getControl(), 'bendLimitAngle', defaultValue=45, keyable=False) straightAngleAttr = attributes.addFloatAttribute( mainIKCtrl.getControl(), 'toeStraightAngle', defaultValue=70, keyable=False) heelClampNode = pm.shadingNode('clamp', asUtility=True, n=prefix + '_heelRotClamp') pm.connectAttr(rollAttr, heelClampNode.inputR) heelClampNode.minR.set(-90) pm.connectAttr(heelClampNode.outputR, backRollGrp.rotateX) ballClampNode = pm.shadingNode('clamp', asUtility=True, n=prefix + '_zeroToBendClamp') pm.connectAttr(rollAttr, ballClampNode.inputR) #heelClampNode.maxR.set(90) #pm.connectAttr(ballClampNode.outputR, ballRollGrp.rotateX) bendToStraightClampNode = pm.shadingNode('clamp', asUtility=True, n=prefix + '_bendToStraightClamp') pm.connectAttr(bendLimitAttr, bendToStraightClampNode.minR) pm.connectAttr(straightAngleAttr, bendToStraightClampNode.maxR) pm.connectAttr(rollAttr, bendToStraightClampNode.inputR) bendToStraightSetRangeNode = pm.shadingNode( 'setRange', asUtility=True, n=prefix + '_bendToStraightPercent') pm.connectAttr(bendToStraightClampNode.minR, bendToStraightSetRangeNode.oldMinX) pm.connectAttr(bendToStraightClampNode.maxR, bendToStraightSetRangeNode.oldMaxX) bendToStraightSetRangeNode.maxX.set(1) pm.connectAttr(bendToStraightClampNode.inputR, bendToStraightSetRangeNode.valueX) rollMultDivNode = pm.shadingNode('multiplyDivide', asUtility=True, n=prefix + '_rollMultDiv') pm.connectAttr(bendToStraightSetRangeNode.outValueX, rollMultDivNode.input1X) pm.connectAttr(bendToStraightClampNode.inputR, rollMultDivNode.input2X) pm.connectAttr(rollMultDivNode.outputX, tippyToeGrp.rotateX) pm.connectAttr(bendLimitAttr, ballClampNode.maxR) zeroToBendSetRangeNode = pm.shadingNode('setRange', asUtility=True, n=prefix + '_zeroToBendPercent') pm.connectAttr(ballClampNode.minR, zeroToBendSetRangeNode.oldMinX) pm.connectAttr(ballClampNode.maxR, zeroToBendSetRangeNode.oldMaxX) zeroToBendSetRangeNode.maxX.set(1) pm.connectAttr(ballClampNode.inputR, zeroToBendSetRangeNode.valueX) invertPercentNode = pm.shadingNode('plusMinusAverage', asUtility=True, n=prefix + '_invertPercent') invertPercentNode.input1D[0].set(1) invertPercentNode.input1D[1].set(1) pm.connectAttr(bendToStraightSetRangeNode.outValueX, invertPercentNode.input1D[1]) invertPercentNode.operation.set(2) ballPercentMultDivNode = pm.shadingNode('multiplyDivide', asUtility=True, n=prefix + '_ballPercentMultDiv') pm.connectAttr(zeroToBendSetRangeNode.outValueX, ballPercentMultDivNode.input1X) pm.connectAttr(invertPercentNode.output1D, ballPercentMultDivNode.input2X) ballRollMultDivNode = pm.shadingNode('multiplyDivide', asUtility=True, n=prefix + '_ballRollMultDiv') pm.connectAttr(ballPercentMultDivNode.outputX, ballRollMultDivNode.input1X) pm.connectAttr(rollAttr, ballRollMultDivNode.input2X) pm.connectAttr(ballRollMultDivNode.outputX, ballRollGrp.rotateX) # Tilt tiltAttr = attributes.addFloatAttribute(mainIKCtrl.getControl(), 'tilt', defaultValue=0, keyable=True, minValue=-90, maxValue=90) if lSide in prefix: common.setDrivenKey(tiltAttr, [-90, 0, 90], innerRollGrp.rotateZ, [90, 0, 0]) common.setDrivenKey(tiltAttr, [-90, 0, 90], outerRollGrp.rotateZ, [0, 0, -90]) else: common.setDrivenKey(tiltAttr, [-90, 0, 90], innerRollGrp.rotateZ, [-90, 0, 0]) common.setDrivenKey(tiltAttr, [-90, 0, 90], outerRollGrp.rotateZ, [0, 0, 90]) # lean leanAttr = attributes.addFloatAttribute(mainIKCtrl.getControl(), 'lean', defaultValue=0, keyable=True, minValue=-90, maxValue=90) pm.connectAttr(leanAttr, ballRollGrp.rotateZ) # toeSpin toeSpinAttr = attributes.addFloatAttribute(mainIKCtrl.getControl(), 'toeSpin', defaultValue=0, keyable=True, minValue=-90, maxValue=90) pm.connectAttr(toeSpinAttr, tippyToeGrp.rotateY) tippyToeGrp.rotateOrder.set(2) # toeWiggle toeWiggleAttr = attributes.addFloatAttribute( mainIKCtrl.getControl(), 'toeWiggle', defaultValue=0, keyable=True, minValue=-90, maxValue=90) pm.connectAttr(toeWiggleAttr, toeTapGrp.rotateX) return mainIKCtrl, footRoolInstance.getLimbIK(), [ [ballCtrl], toeIkControls ], footRoolInstance.getIkFingerList(), footRoolInstance.getIkBallList( ), handIKOrientContraint
def __init__(self, characterName='new', scale=1.0, mainCtrlAttachObj=''): """ :param characterName: str, character name :param scale: float, general scale of the rig :return: None """ # top group self.topGrp = pm.group(n=characterName + '_rig_GRP', em=1) self.rigCtrlLoc = pm.spaceLocator(n='rigCtrl_LOC') pm.rotate(self.rigCtrlLoc, [0, -90, 0], r=True, ws=True) # common.freezeTranform(self.rigCtrlLoc) pm.delete(pm.pointConstraint(mainCtrlAttachObj, self.rigCtrlLoc)) characterNameAt = 'characterName' sceneObjectTypeAt = 'sceneObjectType' for at in [characterNameAt, sceneObjectTypeAt]: pm.addAttr(self.topGrp, ln=at, dt='string') pm.setAttr(self.topGrp + '.' + characterNameAt, characterName, type='string', l=1) pm.setAttr(self.topGrp + '.' + sceneObjectTypeAt, self.sceneObjectType, type='string', l=1) # make global control self.globalCtrl = control.Control(prefix='global', scale=scale * 1, parent=self.topGrp, lockChannels=['t', 'r', 'v'], shape='circleY', doModify=False, doOffset=False) self.mainCtrl = control.Control(prefix='main', scale=scale * 1, parent=self.globalCtrl.getControl(), lockChannels=['s', 'v'], shape='move', doModify=False, doOffset=False) # model group self.modelGrp = pm.group(n='model_GRP', em=1, p=self.topGrp) self.fastModelGrp = pm.group(n='fastModel_GRP', em=1, p=self.modelGrp) self.mediumModelGrp = pm.group(n='mediumModel_GRP', em=1, p=self.modelGrp) self.mediumSlowGrp = pm.group(n='mediumSlowModel_GRP', em=1, p=self.modelGrp) self.slowModelGrp = pm.group(n='slowModel_GRP', em=1, p=self.modelGrp) self.allModelGrp = pm.group(n='allModel_GRP', em=1, p=self.modelGrp) self.rigModelGrp = pm.group(n='rigModel_GRP', em=1, p=self.modelGrp) pm.hide(self.rigModelGrp) # rig group self.rigGrp = pm.group(n='rig_GRP', em=1, p=self.mainCtrl.getControl()) # World Scale self.scaleLocator = pm.spaceLocator(n='scale_LOC') self.scaleLocator.inheritsTransform.set(0) self.scaleLocator.visibility.set(0) pm.connectAttr(self.globalCtrl.getControl().scale, self.scaleLocator.scale) pm.parent(self.scaleLocator, self.rigGrp) # make more groups self.jointsGrp = pm.group(n='skeleton_GRP', em=1, p=self.mainCtrl.getControl()) self.modulesGrp = pm.group(n='modules_GRP', em=1, p=self.mainCtrl.getControl()) self.rigCtrlGrp = pm.group(n='rigctrl_GRP', em=1, p=self.globalCtrl.getControl()) util.lock_and_hide_all(self.rigCtrlGrp) self.partGrp = pm.group(n='parts_GRP', em=1, p=self.rigGrp) pm.setAttr(self.partGrp + '.it', 0, l=1) # make halo self.haloCtrl = control.Control(prefix='halo', scale=1, parent=self.rigCtrlGrp, translateTo=mainCtrlAttachObj, rotateTo=self.rigCtrlLoc, lockChannels=['s'], shape='circleX', doOffset=True, doModify=True, objBBox=mainCtrlAttachObj) self.haloCtrl.getOffsetGrp().visibility.set(0) self.createHalo(mainCtrlAttachObj, 1) mainVisAts = ['modelVis', 'jointsVis'] mainDispAts = ['modelDisp', 'jointsDisp'] mainObjList = [self.modelGrp, self.jointsGrp] mainObjVisDvList = [1, 0] # add rig visibility connections for at, obj, dfVal in zip(mainVisAts, mainObjList, mainObjVisDvList): pm.addAttr(self.globalCtrl.getControl(), ln=at, at='enum', enumName='off:on', k=1, dv=dfVal) pm.setAttr(self.globalCtrl.getControl() + '.' + at, cb=1) pm.connectAttr(self.globalCtrl.getControl() + '.' + at, obj + '.v') # add rig display type connections for at, obj in zip(mainDispAts, mainObjList): pm.addAttr(self.globalCtrl.getControl(), ln=at, at='enum', enumName='normal:template:reference', k=1, dv=2) pm.setAttr(self.globalCtrl.getControl() + '.' + at, cb=1) pm.setAttr(obj + '.ove', 1) pm.connectAttr(self.globalCtrl.getControl() + '.' + at, obj + '.ovdt') # add rig display level connection displayLevel = 'displayLevel' levelGrp = [self.fastModelGrp, self.mediumModelGrp, self.slowModelGrp] pm.addAttr(self.globalCtrl.getControl(), ln=displayLevel, at='enum', enumName='fast:medium:slow', k=1, dv=1) pm.setAttr(self.globalCtrl.getControl() + '.' + displayLevel, cb=1) common.setDrivenKey(self.globalCtrl.getControl() + '.' + displayLevel, [0, 1, 2], levelGrp[0] + '.v', [1, 0, 0]) common.setDrivenKey(self.globalCtrl.getControl() + '.' + displayLevel, [0, 1, 2], levelGrp[1] + '.v', [0, 1, 0]) common.setDrivenKey(self.globalCtrl.getControl() + '.' + displayLevel, [0, 1, 2], levelGrp[2] + '.v', [0, 0, 1]) common.setDrivenKey(self.globalCtrl.getControl() + '.' + displayLevel, [0, 1, 2], self.mediumSlowGrp + '.v', [0, 1, 1]) # create display control self.displayCtrl = self.createDisplay(mainCtrlAttachObj, 1) self.ikfkCtrl = self.createIKFK(mainCtrlAttachObj, 1) pm.delete(self.rigCtrlLoc)