def matchIkToFk(ikControl, ikPole, offset=100.0, msgAttr='fkjoints', autoKey=True): """ Matches ikControl and ikPole Vector control to match the current pose of underlying fk duplicate joint chains Finds the fk joints using a previously created message connection to the attribute msgAttr """ fkJoints = pmc.listConnections('{0}.{1}'.format(ikControl, msgAttr), destination=False, source=True) attr = pmc.listConnections('{0}.ikfk'.format(ikControl), destination=False, source=True, plugs=True, scn=True)[0] switchControl = attr.node() switchAttr = attr.name(includeNode=False) frameBeforeCurrent = pmc.currentTime(q=True) - 1 if autoKey: pmc.setKeyframe(switchControl, attribute=switchAttr, time=frameBeforeCurrent, value=1, outTangentType='step') pmc.setKeyframe([ikControl, ikPole], time=frameBeforeCurrent, outTangentType='step') pmc.setKeyframe(switchControl, attribute=switchAttr, value=0, outTangentType='step') alignObjects(ikControl, fkJoints[-1]) loc = getPoleVectorPosition(fkJoints, offset, curveGuide=False) alignObjects(ikPole, loc, position=True, rotation=False) pmc.delete(loc) if autoKey: pmc.setKeyframe([ikControl, ikPole], time=frameBeforeCurrent) pmc.headsUpMessage('BAMF!')
def matchFkToIk(fkControls, msgAttr='ikjoints', autoKey=True): """ Matches fkControls to match the current pose of the underlying ik duplicate joint chains Finds the ik joints using a previously created message connection to the attribute msgAttr """ ikJoints = None switchControl = None switchAttr = None for ctl in fkControls: if pmc.hasAttr(ctl, msgAttr): ikJoints = pmc.listConnections('{0}.{1}'.format(ctl, msgAttr), destination=False, source=True) attr = pmc.listConnections('{0}.ikfk'.format(ctl), destination=False, source=True, plugs=True, scn=True)[0] switchControl = attr.node() switchAttr = attr.name(includeNode=False) break if autoKey: frameBeforeCurrent = pmc.currentTime(q=True) - 1 pmc.setKeyframe(switchControl, attribute=switchAttr, time=frameBeforeCurrent, value=0, outTangentType='step') pmc.setKeyframe(fkControls, attribute='rotate', time=frameBeforeCurrent, outTangentType='step') pmc.setKeyframe(switchControl, attribute=switchAttr, value=1, outTangentType='step') for ikj, ctl in izip(ikJoints, fkControls): alignObjects(ctl, ikj, position=False, rotation=True) if autoKey: pmc.setKeyframe(fkControls, attribute='rotate') pmc.headsUpMessage('BAMF!')
def squishySplineIk(startLoc, endLoc): ikJoints = list() startJoint = pmc.createNode('joint') adv.alignObjects(startJoint, startLoc) endJoint = pmc.createNode('joint') adv.alignObjects(endJoint, endLoc) pmc.parent(endJoint, startJoint) startJoint.orientJoint('xzy', secondaryAxisOrient='zup') pmc.makeIdentity(endJoint, apply=True, jointOrient=True) Splitter.doSplit(startJoint, 10) ikJoints.append(startJoint) ikJoints.extend(reversed(startJoint.getChildren(ad=True, type='joint'))) for i, ikj in enumerate(ikJoints): ikj.radius.set(2) ikj.rename('ikj_spine{0:02d}'.format(i)) # Create second set of joints rigJoints = adv.makeDuplicateJoints(joints=ikJoints, search='ikj_', replace='local_rig_', connectBone=False) # HACK I haven't figured out how to create SDK nodes procedurally, # so making some dummy locs to make the curve I need a = pmc.createNode('transform') b = pmc.createNode('transform') pmc.setKeyframe(a.ty, t=0, value=2.5, inTangentType='flat', outTangentType='flat') pmc.setKeyframe(a.ty, t=10, value=0, inTangentType='flat', outTangentType='flat') pmc.keyTangent(a.ty, index=[0], inAngle=0) pmc.keyTangent(a.ty, index=[1], inAngle=-30) pmc.keyTangent(a.ty, index=[0], outAngle=0) pmc.keyTangent(a.ty, index=[1], outAngle=-30) animSquashCurve = a.ty.listConnections()[0] animSquashCurve.output.disconnect(a.ty) animSquashCurve.rename('squash_ramp') pmc.setKeyframe(a.tx, t=0, value=0, inTangentType='flat', outTangentType='flat') pmc.setKeyframe(a.tx, t=5, value=1, inTangentType='flat', outTangentType='flat') pmc.setKeyframe(a.tx, t=10, value=0, inTangentType='flat', outTangentType='flat') animTwistCurve = a.tx.listConnections()[0] animTwistCurve.output.disconnect(a.tx) animTwistCurve.rename('twist_ramp') pmc.delete(a, b) animControls = dict() animControls['lower_spine'] = adv.makeControlNode('ctl_lower_spine', targetObject=rigJoints[2], alignRotation=False) animControls['middle_spine'] = adv.makeControlNode('ctl_middle_spine') animControls['upper_spine'] = adv.makeControlNode('ctl_upper_spine', targetObject=rigJoints[-2], alignRotation=False) animControls['lower_spine'][0].rotateOrder.set(adv.ROO_YXZ) animControls['middle_spine'][0].rotateOrder.set(adv.ROO_YXZ) animControls['upper_spine'][0].rotateOrder.set(adv.ROO_YXZ) pmc.pointConstraint(animControls['lower_spine'][0], animControls['upper_spine'][0], animControls['middle_spine'][1], mo=False) pmc.orientConstraint(animControls['lower_spine'][0], animControls['upper_spine'][0], animControls['middle_spine'][1], mo=False) splineIk = pmc.ikHandle(sj=ikJoints[0], ee=ikJoints[-1], sol='ikSplineSolver', parentCurve=False, createCurve=True, simplifyCurve=True, numSpans=2, rootOnCurve=False, n='sik_spine') splineIkHandle = splineIk[0] spline = splineIk[2] spline.rename('crv_spine') clusterJoints = list() clusterJoints.append(pmc.createNode('joint', n='clj_spine0')) pmc.parentConstraint(animControls['lower_spine'][0], clusterJoints[-1]) clusterJoints.append(pmc.createNode('joint', n='clj_spine1')) pmc.parentConstraint(animControls['middle_spine'][0], clusterJoints[-1]) clusterJoints.append(pmc.createNode('joint', n='clj_spine2')) pmc.parentConstraint(animControls['upper_spine'][0], clusterJoints[-1]) pmc.skinCluster(clusterJoints, spline, maximumInfluences=3) pmc.parentConstraint(animControls['lower_spine'][0], ikJoints[0], maintainOffset=True) for clj in clusterJoints: clj.radius.set(3) splineIkHandle.dTwistControlEnable.set(1) splineIkHandle.dWorldUpType.set(4) splineIkHandle.dWorldUpAxis.set(0) splineIkHandle.dWorldUpVector.set([0.0, 0.0, 1.0]) splineIkHandle.dWorldUpVectorEnd.set([0.0, 0.0, 1.0]) animControls['lower_spine'][0].worldMatrix[0].connect(splineIkHandle.dWorldUpMatrix) animControls['upper_spine'][0].worldMatrix[0].connect(splineIkHandle.dWorldUpMatrixEnd) normalizeNode = stretchySplineIk(splineIkHandle, useScale=True, globalScaleAttr='ctl_main.size') sqrtScale = pmc.createNode('multiplyDivide', n='sqrt_spine_scale') sqrtScale.operation.set(3) sqrtScale.input2X.set(0.5) normalizeNode.outputX.connect(sqrtScale.input1X) invScale = pmc.createNode('multiplyDivide', n='div_spine_inverse_scale') invScale.operation.set(2) invScale.input1X.set(1.0) sqrtScale.outputX.connect(invScale.input2X) jointGroups = list() for i, jnt in enumerate(rigJoints): preTransform = adv.zeroOut(jnt, 'pre') jointGroups.append(preTransform) ikNode = adv.zeroOut(jnt, 'hlp_ik') pmc.pointConstraint(ikJoints[i], ikNode) pmc.orientConstraint(ikJoints[i], ikNode) twistNode = adv.zeroOut(jnt, 'hlp_twist') twistCache = pmc.createNode('frameCache', n='frm_{0}_twist'.format(jnt)) animTwistCurve.output.connect(twistCache.stream) twistCache.varyTime.set(i) rotateMultiplier = pmc.createNode('multiplyDivide', n='mul_{0}_twist'.format(jnt.shortName())) twistCache.varying.connect(rotateMultiplier.input2X) animControls['middle_spine'][0].rotateY.connect(rotateMultiplier.input1X) rotateMultiplier.outputX.connect(twistNode.rotateX) volumeCache = pmc.createNode('frameCache', n='frm_{0}_volume'.format(jnt.shortName())) animSquashCurve.output.connect(volumeCache.stream) volumeCache.varyTime.set(i) pow_ = pmc.createNode('multiplyDivide', n='pow_{0}'.format(jnt.shortName())) pow_.operation.set(3) invScale.outputX.connect(pow_.input1X) volumeCache.varying.connect(pow_.input2X) pow_.outputX.connect(jnt.scaleY) pow_.outputX.connect(jnt.scaleZ) pmc.group(animControls['lower_spine'][1], animControls['upper_spine'][1], animControls['middle_spine'][1], n='grp_spine_anim') pmc.group(splineIkHandle, spline, n='grp_spine_rig_systems') pmc.group(clusterJoints, startJoint, n='grp_spine_system_joints') pmc.group(jointGroups, n='grp_spine_bind_joints') return rigJoints
def makeMultiConstraint(targets, source, controller, attrName='currentSpace', enumNames=None, addLocatorSpace=True, translation=True, rotation=True, maintainOffset=False): """ creates a constraint between all to the targets to the passed in source. """ targets = map(pmc.PyNode, targets) source = pmc.PyNode(source) controller = pmc.PyNode(controller) loc = None if enumNames is None: enumNames = map(str, targets) if addLocatorSpace: loc = pmc.spaceLocator(n='loc_follow_' + source.shortName()) alignObjects(loc, source) targets.append(loc) enumNames.append('locator') skipTranslate = 'none' if not translation: skipTranslate = ['x', 'y', 'z'] skipRotate = 'none' if not rotation: skipRotate = ['x', 'y', 'z'] constraints = list() for tgt, spaceName in izip(targets, enumNames): enumAttr = getAttribute(controller, attrName, at='enum', enumName=spaceName, keyable=True, longName=attrName) spaceEnums = enumAttr.getEnums().keys() if spaceName not in spaceEnums: spaceEnums.append(spaceName) enumAttr.setEnums(spaceEnums) index = enumAttr.getEnums().value(spaceName) if tgt is loc: tgtTransform = loc else: tgtTransform = pmc.createNode('transform', n='tgt_{0}_to_{1}'.format( source.shortName(), tgt.shortName())) alignObjects(tgtTransform, source) pmc.parentConstraint(tgt, tgtTransform, maintainOffset=maintainOffset) orient = pmc.orientConstraint(tgtTransform, source, skip=skipRotate, maintainOffset=maintainOffset) orient.interpType.set(2) constraints.append(orient) point = pmc.pointConstraint(tgtTransform, source, skip=skipTranslate, maintainOffset=maintainOffset) constraints.append(point) orientWeightList = orient.getWeightAliasList() orientWeightAttr = orientWeightList[-1] pointWeightList = point.getWeightAliasList() pointWeightAttr = pointWeightList[-1] nodeName = 'con_{0}_to_{1}_weight_{2:d}'.format( source.shortName(), tgt.shortName(), index) weightConditionNode = pmc.createNode('condition', n=nodeName) enumAttr.connect(weightConditionNode.firstTerm) weightConditionNode.secondTerm.set(index) weightConditionNode.colorIfTrueR.set(1) weightConditionNode.colorIfFalseR.set(0) weightConditionNode.outColorR.connect(pointWeightAttr) weightConditionNode.outColorR.connect(orientWeightAttr) return loc
def makeMultiConstraint(targets, source, controller, attrName='currentSpace', enumNames=None, addLocatorSpace=True, translation=True, rotation=True, maintainOffset=False): """ creates a constraint between all to the targets to the passed in source. """ targets = map(pmc.PyNode, targets) source = pmc.PyNode(source) controller = pmc.PyNode(controller) loc = None if enumNames is None: enumNames = map(str, targets) if addLocatorSpace: loc = pmc.spaceLocator(n='loc_follow_' + source.shortName()) alignObjects(loc, source) targets.append(loc) enumNames.append('locator') skipTranslate = 'none' if not translation: skipTranslate = ['x', 'y', 'z'] skipRotate = 'none' if not rotation: skipRotate = ['x', 'y', 'z'] constraints = list() for tgt, spaceName in izip(targets, enumNames): enumAttr = getAttribute(controller, attrName, at='enum', enumName=spaceName, keyable=True, longName=attrName) spaceEnums = enumAttr.getEnums().keys() if spaceName not in spaceEnums: spaceEnums.append(spaceName) enumAttr.setEnums(spaceEnums) index = enumAttr.getEnums().value(spaceName) if tgt is loc: tgtTransform = loc else: tgtTransform = pmc.createNode('transform', n='tgt_{0}_to_{1}'.format(source.shortName(), tgt.shortName())) alignObjects(tgtTransform, source) pmc.parentConstraint(tgt, tgtTransform, maintainOffset=maintainOffset) orient = pmc.orientConstraint(tgtTransform, source, skip=skipRotate, maintainOffset=maintainOffset) orient.interpType.set(2) constraints.append(orient) point = pmc.pointConstraint(tgtTransform, source, skip=skipTranslate, maintainOffset=maintainOffset) constraints.append(point) orientWeightList = orient.getWeightAliasList() orientWeightAttr = orientWeightList[-1] pointWeightList = point.getWeightAliasList() pointWeightAttr = pointWeightList[-1] nodeName = 'con_{0}_to_{1}_weight_{2:d}'.format(source.shortName(), tgt.shortName(), index) weightConditionNode = pmc.createNode('condition', n=nodeName) enumAttr.connect(weightConditionNode.firstTerm) weightConditionNode.secondTerm.set(index) weightConditionNode.colorIfTrueR.set(1) weightConditionNode.colorIfFalseR.set(0) weightConditionNode.outColorR.connect(pointWeightAttr) weightConditionNode.outColorR.connect(orientWeightAttr) return loc