def makeFK(self, limbJoints, topFingerJoints, rigScale, rigmodule): """ Do FK 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: """ limbCtrlInstanceList = [] handFeetCtrlInstanceList = [] limbCtrlConstraintList = [] handFeetCtrlConstraintList = [] # Arm/Leg for jnt in limbJoints: prefix = name.removeSuffix(jnt) parent = rigmodule.controlsGrp if len(limbCtrlInstanceList) > 0: parent = limbCtrlInstanceList[-1].C ctrl = control.Control(prefix=prefix, translateTo=jnt, rotateTo=jnt, parent=parent, shape='circleX') orientCnst = pm.orientConstraint(ctrl.getControl(), jnt, mo=True) limbCtrlConstraintList.append(orientCnst) limbCtrlInstanceList.append(ctrl) # Hand/Foot for topJntList in topFingerJoints: fnjJntList = joint.listHierarchy(topJntList, withEndJoints=False) fingerJointList = [] for jnt in fnjJntList: prefix = name.removeSuffix(jnt) parent = limbCtrlInstanceList[-1].C if len(fingerJointList) > 0: parent = fingerJointList[-1].C ctrl = control.Control(prefix=prefix, translateTo=jnt, rotateTo=jnt, parent=parent, shape='circleX') orientCnst = pm.orientConstraint(ctrl.getControl(), jnt) fingerJointList.append(ctrl) handFeetCtrlConstraintList.append(orientCnst) handFeetCtrlInstanceList.extend(fingerJointList) return limbCtrlInstanceList, limbCtrlConstraintList, handFeetCtrlInstanceList, handFeetCtrlConstraintList
def rollGroups(self, frontRollLoc, backRollLoc, innerRollLoc, outerRollLoc): frontRollGrp, backRollGrp, innerRollGrp, outerRollGrp = [ None, None, None, None ] if pm.objExists(frontRollLoc) and pm.objExists( backRollLoc) and pm.objExists(innerRollLoc) and pm.objExists( outerRollLoc): frontLoc = pm.ls(frontRollLoc)[0] backLoc = pm.ls(backRollLoc)[0] innerLoc = pm.ls(innerRollLoc)[0] outerLoc = pm.ls(outerRollLoc)[0] frontRollGrp = pm.group(self.tippyToeGrp, n=name.removeSuffix(frontLoc) + '_GRP') backRollGrp = pm.group(frontRollGrp, n=name.removeSuffix(backLoc) + '_GRP') innerRollGrp = pm.group(backRollGrp, n=name.removeSuffix(innerLoc) + '_GRP') outerRollGrp = pm.group(innerRollGrp, n=name.removeSuffix(outerLoc) + '_GRP') common.centerPivot(frontRollGrp, frontLoc) common.centerPivot(backRollGrp, backLoc) common.centerPivot(innerRollGrp, innerLoc) common.centerPivot(outerRollGrp, outerLoc) return frontRollGrp, backRollGrp, innerRollGrp, outerRollGrp
def __init__(self, hipJnt, ankleJnt, ballJntList, toeEndJntList, doSmartFootRoll=True): """ Build footRoll on selected joints :param hipJnt: str :param ankleJnt: str :param ballJntList: list :param toeEndJntList: list :param doSmartFootRoll: bool """ self.side = name.getSide(hipJnt) self.ballIkHandleList = [] self.toeIkHandleList= [] self.prefixJnt1 = name.removeSuffix(hipJnt) self.prefixJnt2 = name.removeSuffix(ankleJnt) self.ankleIkHandle = pm.ikHandle( n=self.prefixJnt1+'_IKH', sj=hipJnt, ee=ankleJnt)[0] for ballJnt in ballJntList: ballJntParent = pm.ls(ballJnt)[0].getParent() prefix = name.removeSuffix(ballJnt) tmpBallIkHandle = pm.ikHandle( n=prefix+'Ball_IKH', sj=ballJntParent, ee=ballJnt)[0] self.ballIkHandleList.append(tmpBallIkHandle) for toeJnt, ballJnt in zip(toeEndJntList, ballJntList): prefix = name.removeSuffix(toeJnt) tmpToeIkHandle = pm.ikHandle(n=prefix+'Fng_IKH', sj=ballJnt, ee=toeJnt)[0] self.toeIkHandleList.append(tmpToeIkHandle) # set temporarily ON Sticky self.setSticky(1) self.peelHeel() self.toeTap() self.tippyToe() if doSmartFootRoll: frontRollLoc = self.prefixJnt2 + '_frontRoll_LOC' backRollLoc = self.prefixJnt2 + '_backRoll_LOC' innerRollLoc = self.prefixJnt2 + '_innerRoll_LOC' outerRollLoc = self.prefixJnt2 + '_outerRoll_LOC' self.frontRollGrp, self.backRollGrp, self.innerRollGrp, self.outerRollGrp = self.rollGroups(frontRollLoc, backRollLoc, innerRollLoc, outerRollLoc) else: self.frontRollGrp, self.backRollGrp, self.innerRollGrp, self.outerRollGrp = [None, None, None, None] self.moveGrp() # set OFF Sticky self.setSticky(0)
def makeModifyGrp(object, prefix=''): """ make modify group for given object @param object: transform object to get modify group @param prefix: str, prefix to name new objects @return: str, name of new modify group """ if not prefix: prefix = name.removeSuffix(object) modifyGrp = pm.group(n=prefix + 'Modify_GRP', em=1) objectParents = pm.listRelatives(object, p=1) if objectParents: pm.parent(modifyGrp, objectParents[0]) # match object transform pm.delete(pm.parentConstraint(object, modifyGrp)) pm.delete(pm.scaleConstraint(object, modifyGrp)) # parent object under offset group pm.parent(object, modifyGrp) return modifyGrp
def makeControlFollowSkin(geo, ctrl, drivenObj): geo = pm.ls(geo)[0] ctrl = pm.ls(ctrl)[0] drivenObj = pm.ls(drivenObj)[0] uv = findClosestUVCoordinate(geo, ctrl) prefix = name.removeSuffix(ctrl.name()) follicle = createFollicle(geo, uv[0], uv[1], prefix) followGrp = pm.group(em=True, n=prefix + 'Follow_GRP', w=True) compensateGrp = pm.group(em=True, n=prefix + 'Compensate_GRP', w=True) common.centerPivot(compensateGrp, ctrl) common.centerPivot(followGrp, ctrl) pm.parent(compensateGrp, followGrp) pm.parent(followGrp, ctrl.getParent()) pm.parent(ctrl, compensateGrp) # pm.pointConstraint(follicle, followGrp, mo=True) util.matrixConstrain(follicle, followGrp, rotate=False) multDivideNode = pm.createNode('multiplyDivide', n=prefix + 'CompensateNode') pm.connectAttr(ctrl.translate, multDivideNode.input1) pm.connectAttr(multDivideNode.output, compensateGrp.translate) multDivideNode.input2X.set(-1) multDivideNode.input2Y.set(-1) multDivideNode.input2Z.set(-1) ctrl.translate.set(0, 0, 0) pm.connectAttr(ctrl.translate, drivenObj.translate, f=True) return ctrl, follicle
def calculateScale(self, scale, translateTo='', objBBox='', useBBox=False, useMean=False): """ Calculate scale value :param scale: float :param objBBox: str, object where to calculate bounding box :param autoBBox: bool, auto find proxy geo for bbox :param translateTo: str, object where to search proxy geo :return: float, scale """ if scale == 1: if useBBox and pm.objExists(objBBox): # customGeo objBBox = pm.ls(objBBox)[0] scale = util.getPlanarRadiusBBOXFromTransform(objBBox, radiusFactor=3)['3D'] elif pm.objExists(translateTo): translateTo = pm.ls(translateTo)[0] proxyGeoName = name.removeSuffix(translateTo.name()) + '_PRX' if useBBox and pm.objExists(proxyGeoName): objBBox = pm.ls(proxyGeoName)[0] scale = util.getPlanarRadiusBBOXFromTransform(objBBox, radiusFactor=3)['3D'] elif useMean and pm.objExists(proxyGeoName): objBBox = pm.ls(proxyGeoName)[0] bboxValues = util.getPlanarRadiusBBOXFromTransform(objBBox, radiusFactor=3) scale = (bboxValues['planarX'] + bboxValues['planarY'] + bboxValues['planarZ']) / 3 elif isinstance(translateTo, pm.nodetypes.Joint): scale = self.ctrlRadiusFromJoint(translateTo) if scale < 1 or (scale / 3) < 0.01: scale = 1 else: scale = scale / 3 return scale
def __init__(self, spine_jnt, shoulder_jnt, scapulaShoulder_jnt): """ Create scapula IK :param spine_jnt: str :param shoulder_jnt: str :param scapulaShoulder_jnt: str """ # get side and name side = name.getSide(scapulaShoulder_jnt) # get childern of shoulder scapula_jnt = pm.listRelatives(scapulaShoulder_jnt, type='joint')[0] # create ik ikhandle = pm.ikHandle(n=side + 'scapula_IKH', sj=scapulaShoulder_jnt, ee=scapula_jnt) effector = pm.listConnections(ikhandle[0].endEffector, source=True) # group ik grpName = name.removeSuffix(side + 'scapula_GRP') self.scapulaGrp = pm.group(ikhandle, n=grpName) # parent constraint group pm.parentConstraint(spine_jnt, self.scapulaGrp, mo=True) # parent constraint only transform pm.parentConstraint(shoulder_jnt, scapulaShoulder_jnt, skipRotate=['x', 'y', 'z'], mo=True) # parent effector pm.parent(effector, scapulaShoulder_jnt)
def createLimbFootRollLocatorsReference(ankleJnt): prefix = name.removeSuffix(ankleJnt) frontLoc = pm.spaceLocator(n=prefix + '_frontRoll_LOC') backLoc = pm.spaceLocator(n=prefix + '_backRoll_LOC') innerLoc = pm.spaceLocator(n=prefix + '_innerRoll_LOC') outerLoc = pm.spaceLocator(n=prefix + '_outerRoll_LOC') locGrp = pm.group(frontLoc, backLoc, innerLoc, outerLoc, n=prefix+'FootRollLocators_GRP') return locGrp
def duplicateSourceMesh(self, obj, joint): """ :param obj: :param ctrl: :return: Mesh Shape for the Control """ dupliObj = pm.duplicate(obj) pm.rename(dupliObj, name.removeSuffix(joint) + '_PRX') return dupliObj[0], dupliObj[0].getShape()
def __init__(self, ikHandle, ikCtrl, doFlexyplane=True): ikHandle = pm.ls(ikHandle)[0] ikCtrl = pm.ls(ikCtrl)[0] prefix = name.removeSuffix(ikHandle.name()) jointList = pm.ikHandle(ikHandle, jointList=True, q=True) endJoint = pm.listRelatives(jointList[-1], c=True, type='joint')[0] jointList.append(endJoint) distanceDimensionShape = pm.distanceDimension(sp=jointList[0].getTranslation(space='world'), ep=jointList[-1].getTranslation(space='world')) locators = pm.listConnections(distanceDimensionShape, s=True) startLoc = pm.rename(locators[0], prefix + 'DistanceStart_LOC') endLoc = pm.rename(locators[1], prefix + 'DistanceEnd_LOC') pm.pointConstraint(jointList[0], startLoc) pm.pointConstraint(ikCtrl, endLoc) # multiplyDivide Node multiplyDivideNode = pm.shadingNode('multiplyDivide', asUtility=True, n=prefix + '_multiplyDivide') multiplyDivideNode.input2X.set(1) multiplyDivideNode.operation.set(2) pm.connectAttr(distanceDimensionShape.distance, multiplyDivideNode.input1X, f=True) distance = 0 for i in range(0, len(jointList[:-1])): distance = distance + util.get_distance(jointList[i], jointList[i + 1]) multiplyDivideNode.input2X.set(distance) # condition Node conditionNode = pm.shadingNode('condition', asUtility=True, n=prefix + '_condition') conditionNode.operation.set(2) pm.connectAttr(distanceDimensionShape.distance, conditionNode.firstTerm, f=True) pm.connectAttr(multiplyDivideNode.input2X, conditionNode.secondTerm, f=True) pm.connectAttr(multiplyDivideNode.outputX, conditionNode.colorIfTrueR, f=True) for jnt in jointList[:-1]: pm.connectAttr(conditionNode.outColorR, jnt.scaleX, f=True) self.stretchyGrp = pm.group(startLoc, endLoc, distanceDimensionShape.getParent(), n=prefix+'Stretchy_GRP') self.stretchyGrp.visibility.set(0) # save attributes self.prefix = prefix self.jointList = jointList if doFlexyplane: self.doFlexyPlane(prefix)
def findClosestUVCoordinate(geo, obj): closestPointOnMesh = pm.createNode("closestPointOnMesh") geoShape = geo.getShape() pm.connectAttr(geoShape.worldMesh, closestPointOnMesh.inMesh) pm.connectAttr(geoShape.worldMatrix, closestPointOnMesh.inputMatrix) loc = pm.spaceLocator(n=name.removeSuffix(geo.name()) + '_LOC') pm.matchTransform(loc, obj) pm.connectAttr(loc.translate, closestPointOnMesh.inPosition) u = closestPointOnMesh.result.parameterU.get() v = closestPointOnMesh.result.parameterV.get() pm.delete(closestPointOnMesh, loc) return u, v
def makeDynamic(self, prefix, baserig, basemodule, chainControls, chainCurveClusters): # duplicate ikChain curve and make dynamic dynamicCurveName = name.removeSuffix( pm.ls(self.chainCurve)[0].shortName()) + '_CRV' dynCurvebase = pm.duplicate(self.chainCurve, n=dynamicCurveName) pm.parent(dynCurvebase, w=True) dynCurve = dynamic.DynamicCurve(dynCurvebase, prefix=prefix, baseRig=baserig) # reparent pm.parent(dynCurve.getSystemGrp(), basemodule.partsNoTransGrp) return dynCurve
def maketwistJoints(self, parentJnt, nTwistJoint, rotAxis): prefix = name.removeSuffix(parentJnt) parentJntChild = pm.listRelatives(parentJnt, c=1, type='joint')[0] # make twist joints twistJntGrp = pm.group(n=prefix + 'TwistJoint_GRP', p=self.twistJointsMainGrp, em=1) twistParentJnt = pm.duplicate(parentJnt, n=prefix + 'TwistStart_JNT', parentOnly=True)[0] twistChildJnt = pm.duplicate(parentJntChild, n=prefix + 'TwistEnd_JNT', parentOnly=True)[0] # adjust twist joints origJntRadius = pm.getAttr(parentJnt + '.radius') for j in [twistParentJnt, twistChildJnt]: pm.setAttr(j + '.radius', origJntRadius * 2) pm.color(j, ud=1) pm.parent(twistChildJnt, twistParentJnt) pm.parent(twistParentJnt, twistJntGrp) # attach twist joints pm.pointConstraint(parentJnt, twistParentJnt) # make IK handle twistIk = pm.ikHandle(n=prefix + 'TwistJoint_IKH', sol='ikSCsolver', sj=twistParentJnt, ee=twistChildJnt)[0] pm.hide(twistIk) pm.parent(twistIk, twistJntGrp) pm.parentConstraint(parentJntChild, twistIk) pm.hide(twistParentJnt) innerJointList = self.makeInnerTwistJoints(prefix, twistParentJnt, twistChildJnt, nTwistJoint, rotAxis) pm.parent(innerJointList, twistJntGrp) # Constriant twistJoint group to main Joint pm.parentConstraint(parentJnt, twistJntGrp, mo=True)
def makeControlFollowSkin(geo, ctrlTop): uv = findClosestUVCoordinate(geo, ctrlTop) prefix = name.removeSuffix(ctrlTop.name()) follicle = createFollicle(geo, uv[0], uv[1], prefix) followGrp = pm.group(ctrlTop, n=prefix + 'Follow_GRP') compensateGrp = pm.group(ctrlTop, n=prefix + 'Compensate_GRP') pm.pointConstraint(follicle, followGrp, mo=True) multDivideNode = pm.createNode('multiplyDivide', n=prefix + 'CompensateNode') pm.connectAttr(followGrp.translate, multDivideNode.input1) pm.connectAttr(multDivideNode.output, compensateGrp.translate) multDivideNode.input2X.set(-1) multDivideNode.input2Y.set(-1) multDivideNode.input2Z.set(-1) return followGrp, follicle
def makePoleVector(self, ikHandle, autoElbowCtrl, rigScale, rigmodule): prefix = name.removeSuffix(ikHandle) pvInstance = poleVector.PoleVector(ikHandle) poleVectorLoc, poleVectorGrp = pvInstance.getPoleVector() pm.parent(poleVectorGrp, rigmodule.partsNoTransGrp) poleVectorCtrl = control.Control(prefix=prefix + 'PV', translateTo=poleVectorLoc, scale=rigScale, parent=rigmodule.controlsGrp, shape='sphere') #pm.parentConstraint(self.bodyAttachGrp, poleVectorCtrl.Off, mo=1) spaces.spaces([self.bodyAttachGrp, autoElbowCtrl], ['body', 'control'], poleVectorCtrl.Off, poleVectorCtrl.getControl()) poleVectorCtrl.getControl().space.set(1) pm.parentConstraint(poleVectorCtrl.getControl(), poleVectorLoc) # make pole vector connection line elbowJnt = ikHandle.getJointList()[1] pvLinePos1 = pm.xform(elbowJnt, q=1, t=1, ws=1) pvLinePos2 = pm.xform(poleVectorLoc, q=1, t=1, ws=1) poleVectorCrv = pm.curve(n=prefix + 'Pv_CRV', d=1, p=[pvLinePos1, pvLinePos2]) pm.cluster(poleVectorCrv + '.cv[0]', n=prefix + 'Pv1_CLS', wn=[elbowJnt, elbowJnt], bs=True) pm.cluster(poleVectorCrv + '.cv[1]', n=prefix + 'Pv2_CLS', wn=[poleVectorCtrl.C, poleVectorCtrl.C], bs=True) pm.parent(poleVectorCrv, rigmodule.controlsGrp) pm.setAttr(poleVectorCrv + '.template', 1) pm.setAttr(poleVectorCrv + '.it', 0) return poleVectorCtrl, poleVectorLoc
def makeProxyGeo(self, geo, percentage=50): proxyName = name.removeSuffix(geo.name()) + 'Proxy_GEO' proxyGeo = pm.duplicate(geo, n=proxyName)[0] pm.polyReduce(proxyGeo, p=percentage, ver=1, trm=0, shp=0, keepBorder=1, keepMapBorder=1, keepColorBorder=1, keepFaceGroupBorder=1, keepHardEdge=1, keepCreaseEdge=1, keepBorderWeight=0.5, keepMapBorderWeight=0.5, keepColorBorderWeight=0.5, keepFaceGroupBorderWeight=0.5, keepHardEdgeWeight=0.5, keepCreaseEdgeWeight=0.5, useVirtualSymmetry=0, symmetryTolerance=0.01, sx=0, sy=1, sz=0, sw=0, preserveTopology=1, keepQuadsWeight=1, vertexMapName='', cachingReduce=1, ch=1, vct=0, tct=0, replaceOriginal=1) common.deleteHistory(proxyGeo) return proxyGeo
def __init__(self, mainSkinGeo, mainClothGeo, proxySkinGeo='', proxyClothGeo='', rigModelGrp=None): """ Setup Sliding Cloth deformation :param mainSkinGeo: str :param mainClothGeo: str :param proxySkinGeo: str :param proxyClothGeo: str """ if mainSkinGeo and mainClothGeo: self.mainSkinGeo = pm.ls(mainSkinGeo)[0] self.mainClothGeo = pm.ls(mainClothGeo)[0] else: print 'No valid Geo!' if proxySkinGeo: self.proxySkinGeo = pm.ls(proxySkinGeo)[0] else: self.proxySkinGeo = self.makeProxyGeo(self.mainSkinGeo) if proxyClothGeo: self.proxyClothGeo = pm.ls(proxyClothGeo)[0] else: self.proxyClothGeo = self.makeProxyGeo(self.mainClothGeo) # setup skin proxy geo skin.copyBind(self.mainSkinGeo, self.proxySkinGeo) # setup cloth proxy geo skin.copyBind(self.mainSkinGeo, self.proxyClothGeo) cMuscleDeformer = deform.cMuscleSystemDeformer(self.proxyClothGeo) cMuscleDeformer.enableRelax.set(1) cMuscleDeformer.relaxCompress.set(10) cMuscleDeformer.enableSmooth.set(1) shrinkWrapDeformer = deform.shrinkWrapDeformer(self.proxyClothGeo, self.proxySkinGeo) shrinkWrapDeformer.shapePreservationEnable.set(1) shrinkWrapDeformer.projection.set(4) shrinkWrapDeformer.targetInflation.set(0.01) polySmoothDeformer = pm.polySmooth(self.proxyClothGeo)[0] # wrap main Cloth Geo wrapDeformer = deform.wrapDeformer(self.mainClothGeo, self.proxyClothGeo) baseObj = pm.listConnections(wrapDeformer.basePoints, source=True)[0] # regroup grpName = name.removeSuffix(self.mainClothGeo.name()) + 'Cloth_GRP' clothGrp = pm.group(self.proxySkinGeo, self.proxyClothGeo, baseObj, n=grpName) if rigModelGrp: pm.parent(clothGrp, rigModelGrp) # save attribute self.baseObj = baseObj self.wrapDeformer = wrapDeformer self.shrinkWrapDeformer = shrinkWrapDeformer self.cMuscleDeformer = cMuscleDeformer
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, limbJoints, topFingerJoints, clavicleJoint='', scapulaJnt='', visibilityIKFKCtrl='ikfk_CTRL', doFK=True, doIK=True, useMetacarpalJoint=False, doSmartFootRool=True, prefix=None, rigScale=1.0, baseRig=None): """ :param limbJoints: list( str ), shoulder - elbow - hand - toe - end toe :param topFingerJoints: list( str ), top metacarpal toe joints :param scapulaJnt: str, optional, scapula joint, parent of top leg joint :param doFK: bool, do FK controls :param doIK: bool, do IK controls :param prefix: str, prefix to name new objects :param rigScale: float, scale factor for size of controls :param baseRig: baseRig: instance of base.module.Base class :return: dictionary with rig module objects """ # :param pvLocator: str, reference locator for position of Pole Vector control # prefix if not prefix: prefix = name.removeSuffix(limbJoints[0]) # make rig module rigmodule = module.Module(prefix=prefix, baseObj=baseRig) # make attach groups bodyAttachGrp = pm.group(n=prefix + 'BodyAttach_GRP', em=1, p=rigmodule.partsGrp) baseAttachGrp = pm.group(n=prefix + 'BaseAttach_GRP', em=1, p=rigmodule.partsGrp) self.rigmodule = rigmodule self.baseAttachGrp = baseAttachGrp self.bodyAttachGrp = bodyAttachGrp if doFK: fkLimbCtrls, fkLimbCnst, fkHandsFeetCtrls, fkHandsFeetCnst = self.makeFK( limbJoints, topFingerJoints, rigScale, rigmodule) if doIK: mainIKCtrl, ikHandle, fngCtrls, fngIKs, ballIKs, handIKOrientCnst = self.makeIK( limbJoints, topFingerJoints, rigScale, rigmodule, useMetacarpalJoint) poleVectorCtrl, poleVectorLoc = self.makePoleVector( ikHandle, mainIKCtrl.getControl(), rigScale, rigmodule) if doFK and doIK: # IK/FK switch if visibilityIKFKCtrl: IKFKCtrl = pm.ls(visibilityIKFKCtrl)[0] self.switchIKFK(prefix, IKFKCtrl, fkLimbCtrls, fkLimbCnst, fkHandsFeetCtrls, fkHandsFeetCnst, mainIKCtrl, ikHandle, fngCtrls, fngIKs, ballIKs, poleVectorCtrl, handIKOrientCnst) # clavicle if clavicleJoint != '' and pm.objExists(clavicleJoint): clavicleCtrl = self.makeClavicle(prefix, limbJoints, clavicleJoint, rigScale, rigmodule) pm.parentConstraint(clavicleCtrl.getControl(), fkLimbCtrls[0].getTop(), mo=1) else: pm.parentConstraint(self.baseAttachGrp, fkLimbCtrls[0].getTop(), mo=1) # scapula if scapulaJnt != '' and pm.objExists(scapulaJnt): scpJnt = pm.ls(limbJoints)[0].getParent() scapulaCtrl = None if scpJnt.name() == pm.ls(scapulaJnt)[0].name(): # simple scapula scapulaCtrl = self.makeSimpleScapula(prefix, limbJoints, scapulaJnt, rigScale, rigmodule) else: # dynamic scapula self.makeDynamicScapula(limbJoints, rigmodule) # constriant FK limb if scapulaCtrl: pm.parentConstraint(scapulaCtrl.getControl(), fkLimbCtrls[0].getTop(), mo=1) self.limbIK = ikHandle self.mainIKControl = mainIKCtrl
def __init__(self, clavicleJoint, shoulderJoint, forearmJoint, wristJoint, scapulaJnt='', visibilityIKFKCtrl='ikfk_CTRL', doFK=True, doIK=True, prefix=None, rigScale=1.0, baseRig=None): """ :param clavicleJoint: pynode :param shoulderJoint: pynode :param forearmJoint: pynode :param scapulaJnt: pynode :param wristJoint: pynode :param doFK: bool, do FK controls :param doIK: bool, do IK controls :param prefix: str, prefix to name new objects :param rigScale: float, scale factor for size of controls :param baseRig: baseRig: instance of base.module.Base class :return: dictionary with rig module objects """ # :param pvLocator: str, reference locator for position of Pole Vector control # prefix if not prefix: prefix = name.removeSuffix( pm.ls(clavicleJoint, shoulderJoint, forearmJoint, wristJoint, scapulaJnt)) # make rig module rigmodule = module.Module(prefix=prefix, baseObj=baseRig) # make attach groups bodyAttachGrp = pm.group(n=prefix + 'BodyAttach_GRP', em=1, p=rigmodule.partsGrp) baseAttachGrp = pm.group(n=prefix + 'BaseAttach_GRP', em=1, p=rigmodule.partsGrp) self.rigmodule = rigmodule self.baseAttachGrp = baseAttachGrp self.bodyAttachGrp = bodyAttachGrp def makeFK(self, limbJoints, topFingerJoints, rigScale, rigmodule): """ Do FK 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: """ limbCtrlInstanceList = [] handFeetCtrlInstanceList = [] limbCtrlConstraintList = [] handFeetCtrlConstraintList = [] # Arm/Leg for jnt in limbJoints: prefix = name.removeSuffix(jnt) parent = rigmodule.controlsGrp if len(limbCtrlInstanceList) > 0: parent = limbCtrlInstanceList[-1].C ctrl = control.Control(prefix=prefix, translateTo=jnt, rotateTo=jnt, parent=parent, shape='circleX') orientCnst = pm.orientConstraint(ctrl.getControl(), jnt, mo=True) limbCtrlConstraintList.append(orientCnst) limbCtrlInstanceList.append(ctrl)
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=rigmodule.controlsGrp, shape='circleZ') # pm.parentConstraint(mainIKCtrl.C, ballCtrl.getTop(), mo=True) 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)