def rig_jointCopyChain(rootJoint, replaceName=('', '')): jointChain = rig_chain(rootJoint).chain #print 'rootJoint = '+rootJoint parent = pm.listRelatives(rootJoint, p=True) #print 'parent = '+parent if len(parent) == 0: parent = '' print 'No parent found' else: parent = parent[0] i = 0 firstJoint = '' for joint in jointChain: newJnt = rig_transform(0, name=joint.replace(replaceName[0], replaceName[1]), type='joint', target=joint, parent=parent).object parent = newJnt if i == 0: firstJoint = newJnt i += 1 return rig_chain(firstJoint).chain
def poleVector(self, name='', mid='', posMultiplier=1): if name == '': name = self.name poleVector = rig_transform(0, name=name + 'PoleVector', type='locator').object pm.delete(pm.parentConstraint(self.start, self.end, poleVector)) pm.delete(pm.aimConstraint(mid, poleVector, mo=False)) startPos = pm.xform(self.start, translation=True, query=True, ws=True) midPos = pm.xform(self.end, translation=True, query=True, ws=True) poleVectorPos = pm.xform(poleVector, translation=True, query=True, ws=True) pvDistance = lengthVector(midPos, poleVectorPos) pm.xform(poleVector, translation=[pvDistance * posMultiplier, 0, 0], os=True, r=True) pm.poleVectorConstraint(poleVector, self.handle) # create pv return poleVector
def connectShapesToLoc(locName='flexShapes', refGeo='skin_C_body_GS'): blendShapes = mm.eval('rig_returnDeformers("' + refGeo + '", "blendShape")') if len(blendShapes) == 1: bs = blendShapes[0] shapeList = pm.listAttr(bs + '.weight', m=True) loc = locName + '_LOC' if not cmds.objExists(loc): loc = rig_transform(0, name=locName, type='locator').object for shape in shapeList: attr = pm.addAttr(loc, longName=shape, attributeType="double", min=0, max=1, defaultValue=0, keyable=True) print bs print shape pm.connectAttr(loc + '.' + shape, bs + '.' + shape, f=True)
def rig_autoFlexControl(name, shapeDriverLoc, startEnd=(), shapeDriven='', flexLoc='flexShapes_LOC', module=None, **kwds): scale = defaultReturn(5, 'scale', param=kwds) shape = defaultReturn('sphere', 'shape', param=kwds) colour = defaultReturn('red', 'colour', param=kwds) if not cmds.objExists(flexLoc + '.' + shapeDriven): pm.warning(flexLoc + '.' + shapeDriven + ' = does not exist ! Not making auto flex control') return if module == None: parent = rig_transform(0, name=name + '_measureSetup').object else: parent = module.parts distNode = rig_measure(name=name + 'FlexDistance', start=startEnd[0], end=startEnd[1], parent=parent) flexCenter = rig_control( name=name + 'FlexCenter', shape='box', scale=(scale, scale, scale), colour='white', lockHideAttrs=['tx', 'ty', 'tz', 'rx', 'ry', 'rz'], parentOffset=module.controls) pm.delete(pm.parentConstraint(shapeDriverLoc, flexCenter.offset)) flexCtrl = rig_control(name=name + 'Flex', shape=shape, scale=(scale / 2, scale / 2, scale / 2), parentOffset=flexCenter.con, colour=colour, lockHideAttrs=['tx', 'tz', 'rx', 'ry', 'rz']) pm.delete(pm.parentConstraint(flexCenter.con, flexCtrl.offset)) rig_curveBetweenTwoPoints(flexCenter.con, flexCtrl.con, name=name + '_curveBetween', degree=1, colour=colour, parent=flexCenter.offset) pm.addAttr(flexCtrl.ctrl, longName='autoFlex', attributeType="long", min=0, max=1, defaultValue=1, keyable=True) mdNode = multiplyDivideNode( name + '_flexMD', 'multiply', input1=[distNode.distance + '.globalOriginalPercent', 0, 0], input2=[1, 1, 1], output=[]) pmNode = plusMinusNode(name + '_flexPM', 'sum', distNode.distance, 'globalOriginalPercent', mdNode, 'outputX') conNode = conditionNode(name + '_flexCondition', 'equal', (pmNode, 'output1D'), ('', 0), ('', 1), (pmNode, 'output1D')) remapNode = remapValueNode(conNode + '.outColorR', 1, 0, 0, 1, name=name, valueinterp=2) rig_animDrivenKey(flexCtrl.ctrl.autoFlex, (0, 1), mdNode + '.input2X', (-1, 0)) rig_animDrivenKey(flexCtrl.ctrl.translateY, (0, -10), remapNode + '.inputMin', (1, 0.8)) rig_animDrivenKey(flexCtrl.ctrl.translateY, (0, 10), remapNode + '.outputMin', (0, 1)) pm.setAttr(remapNode + '.inputMax', 0.8) pm.connectAttr(remapNode + '.outValue', flexLoc + '.' + shapeDriven, f=True) pm.transformLimits(flexCtrl.ctrl, ty=(-10, 10), ety=(1, 1)) mdNode = multiplyDivideNode(name + '_flexOffsetMD', 'multiply', input1=[remapNode + '.outValue', 0, 0], input2=[10, 1, 1], output=[flexCtrl.offset + '.translateY']) pm.setAttr(flexCenter.ctrl.overrideDisplayType, 1) pm.select(flexCtrl.ctrl.cv[1], flexCtrl.ctrl.cv[27], flexCtrl.ctrl.cv[36], flexCtrl.ctrl.cv[46], flexCtrl.ctrl.cv[54], r=True) pm.move(0, 3, 0, r=True, os=True, wd=True) pm.select(flexCtrl.ctrl.cv[22], flexCtrl.ctrl.cv[32], flexCtrl.ctrl.cv[41], flexCtrl.ctrl.cv[50], flexCtrl.ctrl.cv[61], r=True) pm.move(0, -1, 0, r=True, os=True, wd=True) return (flexCenter, flexCtrl)
def rig_ikChainSpline(name, rootJnt, ctrlSize=1.0, **kwds): numIkControls = defaultReturn(5, 'numIkControls', param=kwds) numFkControls = defaultReturn(5, 'numFkControls', param=kwds) dWorldUpAxis = defaultReturn(6, 'dWorldUpAxis', param=kwds) parentRoot = defaultReturn('spineJA_JNT', 'parent', param=kwds) lockBase = defaultReturn(1, 'lockBase', param=kwds) module = rig_module(name) ctrlSizeHalf = [ctrlSize / 2.0, ctrlSize / 2.0, ctrlSize / 2.0] ctrlSizeQuarter = [ctrlSize / 4.0, ctrlSize / 4.0, ctrlSize / 4.0] ctrlSize = [ctrlSize, ctrlSize, ctrlSize] chainList = rig_chain(rootJnt).chain numJoints = len(chainList) ''' ctrlPos = [] for i in range(0, numJoints): if i % numFkControls == 0: ctrlPos.append(chainList[i]) ''' endJnt = defaultReturn(rootJnt.replace('JA_JNT', 'JEnd_JNT'), 'endJnt', param=kwds) ctrlPos = mm.eval('rig_chainBetweenTwoPoints("' + name + 'Pos", "' + rootJnt + '", "' + endJnt + '",' + str(numIkControls) + ');') #for jnt in ctrlPos: pm.parent(ctrlPos, w=True) for jnt in ctrlPos: pm.delete(pm.orientConstraint(rootJnt, jnt)) # make ik driver controls/joints fkControls = [] ikControls = [] driverJntList = [] fkScale = 1.5 for i in range(0, len(ctrlPos)): driverJnt = rig_transform(0, name=name + 'DriverJ' + ABC[i], type='joint', target=ctrlPos[i], parent=module.parts, rotateOrder=2).object driverJntList.append(driverJnt) driverCtrl = rig_control(name=name + 'Driver' + ABC[i], shape='box', modify=1, scale=ctrlSizeHalf, colour='green', parentOffset=module.controlsSec, rotateOrder=2) ikControls.append(driverCtrl) pm.delete(pm.parentConstraint(driverJnt, driverCtrl.offset)) pm.parentConstraint(driverCtrl.con, driverJnt, mo=True) lockTranslate = [] ctrlShape = 'circle' if i == 0: lockTranslate = ['tx', 'ty', 'tz'] ctrlShape = 'pyramid' else: lockTranslate = [] fkCtrl = rig_control(name=name + 'FK' + ABC[i], shape=ctrlShape, modify=2, targetOffset=ctrlPos[i], parentOffset=module.controls, lockHideAttrs=lockTranslate, scale=((ctrlSize[0]) * fkScale, (ctrlSize[1]) * fkScale, (ctrlSize[2]) * fkScale)) if i == 0: if pm.objExists(parentRoot): pm.parentConstraint(parentRoot, fkCtrl.offset, mo=True) if pm.objExists(parentRoot) and pm.objExists('worldSpace_GRP'): constrainObject(fkCtrl.modify[0], [fkCtrl.offset, 'worldSpace_GRP'], fkCtrl.ctrl, ['parent', 'world'], type='orientConstraint') pm.parentConstraint(fkCtrl.con, driverCtrl.offset, mo=True) if i > 0: parentOffset = fkControls[i - 1].con pm.parent(fkCtrl.offset, parentOffset) fkControls.append(fkCtrl) fkScale = fkScale - 0.1 pm.delete(ctrlPos) # shape controls rootCtrl = fkControls[0] pm.addAttr(rootCtrl.ctrl, ln='SHAPE', at='enum', enumName='___________', k=True) rootCtrl.ctrl.SHAPE.setLocked(True) pm.addAttr(rootCtrl.ctrl, longName='curl', at='float', k=True, min=-10, max=10, dv=0) pm.addAttr(rootCtrl.ctrl, longName='curlSide', at='float', k=True, min=-10, max=10, dv=0) for i in range(1, numIkControls): rig_animDrivenKey(rootCtrl.ctrl.curl, (-10, 0, 10), fkControls[i].modify[0] + '.rotateX', (-90, 0, 90)) rig_animDrivenKey(rootCtrl.ctrl.curlSide, (-10, 0, 10), fkControls[i].modify[0] + '.rotateZ', (-90, 0, 90)) ik = rig_ik(name, rootJnt, chainList[-1], 'ikSplineSolver', numSpans=numIkControls) pm.parent(ik.handle, ik.curve, module.parts) lowerAim = rig_transform(0, name=name + 'LowerAim', type='locator', parent=module.parts, target=ikControls[1].con).object upperAim = rig_transform(0, name=name + 'UpperAim', type='locator', parent=module.parts, target=ikControls[-2].con).object pm.rotate(lowerAim, 0, 0, -90, r=True, os=True) pm.rotate(upperAim, 0, 0, -90, r=True, os=True) pm.parentConstraint(ikControls[1].con, lowerAim, mo=True) pm.parentConstraint(ikControls[-2].con, upperAim, mo=True) aimTop = mm.eval('rig_makePiston("' + lowerAim + '", "' + upperAim + '", "' + name + 'Aim");') pm.move(upperAim + 'Up', 0, 30 * ctrlSize[0], 0, r=True, os=True) pm.move(lowerAim + 'Up', 0, 20 * ctrlSize[0], 0, r=True, os=True) # advanced twist pm.setAttr(ik.handle + '.dTwistControlEnable', 1) pm.setAttr(ik.handle + '.dWorldUpType', 2) # object up start and end pm.setAttr(ik.handle + '.dForwardAxis', 2) # positive y pm.setAttr(ik.handle + '.dWorldUpAxis', dWorldUpAxis) # positive x pm.connectAttr(upperAim + 'Up.worldMatrix[0]', ik.handle.dWorldUpMatrixEnd, f=True) pm.connectAttr(lowerAim + 'Up.worldMatrix[0]', ik.handle.dWorldUpMatrix, f=True) pm.parent(aimTop, module.parts) pm.select(ik.curve) curveShape = pm.pickWalk(direction='down') curveInfoNode = pm.arclen(curveShape[0], ch=True) curveInfo = pm.rename(curveInfoNode, name + '_splineIk_curveInfo') globalCurve = pm.duplicate(ik.curve) globalCurve = pm.rename(globalCurve, name + 'global_splineIk_curve') pm.select(globalCurve) globalCurveShape = pm.pickWalk(direction='down') globalCurveInfoNode = pm.arclen(globalCurveShape[0], ch=True) globalCurveInfo = pm.rename(globalCurveInfoNode, name + 'global_splineIk_curveInfo') pm.parent(globalCurve, module.parts) pm.setAttr(globalCurve + '.inheritsTransform', 1) distanceToStretch_PM = plusMinusNode(name + '_distanceToStretch', 'subtract', curveInfo, 'arcLength', globalCurveInfo, 'arcLength') correctAdd_Minus_MD = multiplyDivideNode( name + '_correctAdd_Minus', 'multiply', input1=[-1, 0, 0], input2=[distanceToStretch_PM + '.output1D', 0, 0], output=[]) toggleStretch_ctrl_MD = multiplyDivideNode( name + '_toggleStretch_ctrl', 'multiply', input1=[0, 0, 0], input2=[correctAdd_Minus_MD + '.outputX', 0, 0], output=[]) distanceStretchCurve_PM = plusMinusNode(name + '_distanceStretchCurve', 'sum', curveInfo, 'arcLength', toggleStretch_ctrl_MD, 'outputX') globalCurveStretchyFix_MD = multiplyDivideNode( name + '_globalCurveStretchyFix', 'divide', input1=[distanceStretchCurve_PM + '.output1D', 0, 0], input2=[globalCurveInfo + '.arcLength', 1, 1], output=[]) pm.addAttr(fkControls[0].ctrl, longName='stretch', shortName='ts', attributeType="double", min=0, max=1, defaultValue=0, keyable=True) connectReverse(input=(fkControls[0].ctrl + '.stretch', 0, 0), output=(toggleStretch_ctrl_MD + '.input1X', 0, 0)) for i in range(0, len(chainList) - 1): pm.connectAttr(globalCurveStretchyFix_MD + '.outputX', chainList[i] + '.scaleY', f=True) pm.skinCluster(driverJntList, ik.curve, tsb=True) return module
def rig_ikStretchySoftPop(side, name, chainIK, module, ikCtrl, ctrlSize, topGrp): # assign appropriate names startJnt = chainIK[0] midJnt = chainIK[1] endJnt = chainIK[2] nme = name if name.startswith('l_'): nme = name.replace('l_', '') if name.startswith('r_'): nme = name.replace('r_', '') midPinControl = rig_control(side=side, name=nme + 'MidPin', shape='sphere', modify=1, parentOffset=module.controlsSec, scale=ctrlSize, rotateOrder=2, lockHideAttrs=['rx', 'ry', 'rz']) pm.delete(pm.parentConstraint(midJnt, midPinControl.offset)) pm.parentConstraint(topGrp, midPinControl.offset, mo=True) startMeasure = rig_transform(0, name=name + '_startMeasure', type='locator', parent=module.parts, target=topGrp).object pm.pointConstraint(topGrp, startMeasure) pm.aimConstraint(ikCtrl.con, startMeasure) endMeasure = rig_transform(0, name=name + '_endMeasure', type='locator', parent=module.parts, target=ikCtrl.gimbal.ctrl).object pm.pointConstraint(ikCtrl.con, endMeasure) measureGrp = rig_transform(0, name=name + '_measureSetup', parent=module.parts).object upperDist = rig_measure(name=name + 'Upper', start=startMeasure, end=midPinControl.con, parent=measureGrp) lowerDist = rig_measure(name=name + 'Lower', start=midPinControl.con, end=endMeasure, parent=measureGrp) totalDist = rig_measure(name=name + 'Total', start=startMeasure, end=endMeasure, parent=measureGrp) endBlendLoc = rig_transform(0, name=name + '_endBlend', type='locator', parent=module.parts, target=endJnt).object endSoftOffset = rig_transform(0, name=name + '_endSoftOffset', parent=module.parts, target=endJnt).object pm.parentConstraint(startMeasure, endSoftOffset) endSoftLoc = rig_transform(0, name=name + '_endSoft', type='locator', parent=endSoftOffset, target=ikCtrl.gimbal.ctrl).object #wristPC = pm.pointConstraint(endSoftLoc, endBlendLoc, mo=True, w=0) #stretchPC = pm.pointConstraint(endMeasure, endBlendLoc, mo=True, w=1) stretchPC = pm.pointConstraint(endMeasure, endSoftLoc, endBlendLoc, mo=True) stretchTargets = stretchPC.getWeightAliasList() pm.setAttr(stretchTargets[1], 0) #pm.pointConstraint( endBlendLoc, ikCtrl.con, mo=True) endBlendDist = rig_measure(name=name + 'EndBlend', start=startMeasure, end=endBlendLoc, parent=measureGrp) endSoftBlendDist = rig_measure(name=name + 'SoftEndBlend', start=endSoftLoc, end=endBlendLoc, parent=measureGrp) pm.addAttr(ikCtrl.ctrl, ln='ikSettings', at='enum', enumName='___________', k=True) ikCtrl.ctrl.ikSettings.setLocked(True) blendAttrNodes_and_checkStretchCond = addStretchyIKJoints( name, chainIK, (upperDist.distance, lowerDist.distance, totalDist.distance), ikCtrl.ctrl, (endBlendDist.distance, endSoftBlendDist.distance)) # create sdk for elbow pin upperBlendNode = blendAttrNodes_and_checkStretchCond[0] lowerBlendNode = blendAttrNodes_and_checkStretchCond[1] checkStretch_condition = blendAttrNodes_and_checkStretchCond[2] cmds.connectAttr(checkStretch_condition + '.outColorR', endSoftLoc + '.translateX', f=True) pm.addAttr(midPinControl.ctrl, longName='pin', attributeType="double", min=0, max=10, defaultValue=0, keyable=True) rig_animDrivenKey(midPinControl.ctrl.pin, (0, 10), upperBlendNode + '.attributesBlender', (0, 1)) rig_animDrivenKey(midPinControl.ctrl.pin, (0, 10), lowerBlendNode + '.attributesBlender', (0, 1)) rig_animDrivenKey(ikCtrl.ctrl.ikStretch, (0, 1), stretchTargets[1], (1, 0)) rig_animDrivenKey(ikCtrl.ctrl.ikStretch, (1, 0), stretchTargets[0], (1, 0)) return endBlendLoc
def __init__(self, name, start, end, up, **kwds): rigGrp = '' if cmds.objExists('rig_GRP'): rigGrp = 'rig_GRP' parent = 'stretchyJoints_GRP' if not cmds.objExists(parent): parent = rig_transform(0, name='stretchyJoints', parent=rigGrp).object self.topGrp = rig_transform(0, name=name + 'Stretchy', parent=parent).object jntStart = rig_transform(0, name=name + 'JntStartTmp', type='joint', target=start).object jntEnd = rig_transform(0, name=name + 'JntEndTmp', type='joint', target=end, parent=jntStart).object cmds.joint(jntStart, e=True, oj='xzy', sao='zup', ch=True, zso=True) pm.setAttr(jntEnd + '.jointOrientX', 0) pm.setAttr(jntEnd + '.jointOrientY', 0) pm.setAttr(jntEnd + '.jointOrientZ', 0) self.startOffset = rig_transform(0, name=name + 'DrvStartOffset', parent=self.topGrp, target=jntStart).object self.start = rig_transform(0, name=name + 'DrvStart', type='locator', parent=self.startOffset, target=self.startOffset).object startLoc = rig_transform(0, name=name + 'StartStretchy', type='locator', parent=self.topGrp, target=jntStart).object self.endOffset = rig_transform(0, name=name + 'DrvEndOffset', parent=self.topGrp, target=jntEnd).object self.end = rig_transform(0, name=name + 'DrvEnd', type='locator', parent=self.endOffset, target=self.endOffset).object endLoc = rig_transform(0, name=name + 'EndStretchy', type='locator', parent=self.topGrp, target=jntEnd).object self.upOffset = rig_transform(0, name=name + 'DrvUpOffset', parent=self.topGrp, target=up).object pm.delete(jntStart, jntEnd) partsGrp = mm.eval('rig_makePiston("' + startLoc + '", "' + endLoc + '", "' + name + 'StretchyParts");') pm.hide(partsGrp) pm.delete(pm.parentConstraint(self.upOffset, endLoc + 'Up')) pm.parent(endLoc + 'Up', self.upOffset) self.up = name + 'DrvUp_LOC' pm.rename(endLoc + 'Up', name + 'DrvUp_LOC') self.startJnt = startLoc.replace('_LOC', '_JNT') endJnt = endLoc.replace('_LOC', '_JNT') pm.parent(endJnt, self.startJnt) pm.parent(self.startJnt, self.topGrp) pm.parentConstraint(startLoc + 'Aim', self.startJnt, mo=True) pm.delete(startLoc + 'Up', endLoc, startLoc) pm.parentConstraint(self.start, startLoc + 'AimOffset', mo=True) pm.parentConstraint(self.end, endLoc + 'AimOffset', mo=True) pm.parentConstraint(self.start, self.upOffset, mo=True) pm.parent(partsGrp, self.topGrp) measure = rig_measure(name=name + 'Dist', start=self.start, end=self.end, parent=partsGrp) # make pin feature #pm.connectAttr( measure.distance.globalOriginalPercent, self.startJnt+'.scaleX' ) self.startJnt = pm.PyNode(self.startJnt) pm.addAttr(self.startJnt, longName='stretch', at='float', k=True, dv=1, min=0, max=1) #self.startJnt.stretch.set(cb=True) bldColor = pm.shadingNode('blendColors', asUtility=True, name=name + '_blendStretch') pm.connectAttr(measure.distance.globalOriginalPercent, bldColor + '.color1R', f=True) # connect ik jnt to color pm.setAttr(bldColor + '.color2R', 1) pm.connectAttr(bldColor + '.outputR', self.startJnt + '.scaleX', f=True) # connect bldColor output to bind jnt pm.connectAttr(self.startJnt.stretch, bldColor.blender) # bulge pm.addAttr(self.startJnt, longName='bulge', at='float', k=True, dv=1) bulge_PM = plusMinusNode(name + 'Bulge_plusMinus', 'subtract', '', 2, self.startJnt, 'scaleX') bldColorBulge = pm.shadingNode('blendColors', asUtility=True, name=name + '_blendBulge') pm.connectAttr(bulge_PM + '.output1D', bldColorBulge + '.color1R', f=True) pm.setAttr(bldColorBulge + '.color2R', 1) pm.connectAttr(bldColorBulge + '.outputR', self.startJnt + '.scaleY', f=True) pm.connectAttr(bldColorBulge + '.outputR', self.startJnt + '.scaleZ', f=True) pm.connectAttr(self.startJnt.bulge, bldColorBulge.blender)
def rig_stretchyMirror(topGroup): listParts = cmds.listRelatives(topGroup) nameBase = topGroup.replace('Stretchy_GRP', '') tokens = nameBase.split('_') side = tokens[0] mirrorSide = rig_nameGetMirror(nameBase) name = mirrorSide + '_' + tokens[1] mirrorGrp = rig_transform(0, name='mirrorTmp').object start = '' end = '' up = '' startCons = {} endCons = {} upCons = {} for part in listParts: if 'DrvStart' in part: start = rig_transform(0, name='startTmp', type='locator', target=part, parent=mirrorGrp).object try: offsetCon = pm.listRelatives(part, type='constraint')[0] targets = [] for o in offsetCon.getTargetList(): print 'side targets = ' + o print rig_nameMirror(o.stripNamespace()) targets.append(rig_nameMirror(o.stripNamespace())) startCons['offset'] = targets startCons['offsetCon'] = offsetCon.type() except IndexError: print 'no constraints' loc = cmds.listRelatives(part, type='transform')[0] try: locCon = pm.listRelatives(loc, type='constraint')[0] targets = [] for o in locCon.getTargetList(): targets.append(rig_nameMirror(o.stripNamespace())) startCons['loc'] = targets startCons['locCon'] = locCon.type() except IndexError: print 'no constraints' if 'DrvEnd' in part: end = rig_transform(0, name='endTmp', type='locator', target=part, parent=mirrorGrp).object try: offsetCon = pm.listRelatives(part, type='constraint')[0] targets = [] for o in offsetCon.getTargetList(): print 'side targets = ' + o print rig_nameMirror(o.stripNamespace()) targets.append(rig_nameMirror(o.stripNamespace())) endCons['offset'] = targets endCons['offsetCon'] = offsetCon.type() except IndexError: print 'no constraints' loc = cmds.listRelatives(part, type='transform')[0] try: locCon = pm.listRelatives(loc, type='constraint')[0] targets = [] for o in locCon.getTargetList(): targets.append(rig_nameMirror(o.stripNamespace())) endCons['loc'] = targets endCons['locCon'] = locCon.type() except IndexError: print 'no constraints' if 'DrvUp' in part: up = rig_transform(0, name='upTmp', type='locator', target=part, parent=mirrorGrp).object try: offsetCon = pm.listRelatives(part, type='constraint')[0] targets = [] for o in offsetCon.getTargetList(): targets.append(rig_nameMirror(o.stripNamespace())) upCons['offset'] = targets upCons['offsetCon'] = offsetCon.type() except IndexError: print 'no constraints' loc = cmds.listRelatives(part, type='transform')[0] try: locCon = pm.listRelatives(loc, type='constraint')[0] targets = [] for o in locCon.getTargetList(): targets.append(rig_nameMirror(o.stripNamespace())) upCons['loc'] = targets upCons['locCon'] = locCon.type() except IndexError: print 'no constraints' pm.setAttr(mirrorGrp + '.scaleX', -1) stretchy = rig_makeStretchy(name, start, end, up) try: print startCons['offset'] rig_constrainByType(startCons['offsetCon'], startCons['offset'], stretchy.startOffset) except KeyError: print 'no key' try: rig_constrainByType(startCons['locCon'], startCons['loc'], stretchy.start) except KeyError: print 'no key' try: rig_constrainByType(endCons['offsetCon'], endCons['offset'], stretchy.endOffset) except KeyError: print 'no key' try: rig_constrainByType(endCons['locCon'], endCons['loc'], stretchy.end) except KeyError: print 'no key' try: rig_constrainByType(upCons['offsetCon'], upCons['offset'], stretchy.upOffset) except KeyError: print 'no key' try: rig_constrainByType(upCons['locCon'], upCons['loc'], stretchy.up) except KeyError: print 'no key' pm.delete(mirrorGrp)