def orient_old(joints, aimAxis=(1, 0, 0), upAxis=(0, 1, 0), upVec=(0, 1, 0)): """ Orient joints based on user defined vectors @param joints: List of joints to orient @type joints: list @param aimAxis: Axis to be aligned down the length of the joint @type aimAxis: tuple @param upAxis: Axis to be aligned withe the world vector specified by upVec @type upAxis: tuple @param upVec: World vector to align upAxis to @type upVec: tuple """ if not joints: joints = [] for joint in joints: # Get child list childList = cmds.listRelatives(joint, c=1) childJointList = cmds.listRelatives(joint, c=1, type='joint', pa=True) if not childJointList: cmds.setAttr(joint + '.jo', 0, 0, 0) continue # Unparent children childList = cmds.parent(childList, w=True) # Reset joint rotation and orientation cmds.setAttr(joint + '.r', 0, 0, 0) cmds.setAttr(joint + '.jo', 0, 0, 0) cmds.makeIdentity(joint, apply=True, t=1, r=1, s=1, n=0, jointOrient=True) # Move transform to joint parent = cmds.listRelatives(joint, p=True, pa=True) trans = cmds.group(em=True, n=joint + '_ORIENT') if parent: cmds.parent(trans, parent[0]) cmds.delete(cmds.pointConstraint(joint, trans)) # Match rotation order cmds.setAttr(trans + '.ro', cmds.getAttr(joint + '.ro')) # Derive orientation cmds.aicmdsonstraint(childJointList[0], trans, aimVector=aimAxis, upVector=upAxis, worldUpType='vector', worldUpVector=upVec) rot = cmds.getAttr(trans + '.r')[0] cmds.setAttr(joint + '.jo', rot[0], rot[1], rot[2]) cmds.delete(trans) # Reparent children cmds.parent(childList, joint)
def orient_old(joints, aimAxis=(1, 0, 0), upAxis=(0, 1, 0), upVec=(0, 1, 0)): """ Orient joints based on user defined vectors @param joints: List of joints to orient @type joints: list @param aimAxis: Axis to be aligned down the length of the joint @type aimAxis: tuple @param upAxis: Axis to be aligned withe the world vector specified by upVec @type upAxis: tuple @param upVec: World vector to align upAxis to @type upVec: tuple """ if not joints: joints = [] for joint in joints: # Get child list childList = cmds.listRelatives(joint, c=1) childJointList = cmds.listRelatives(joint, c=1, type='joint', pa=True) if not childJointList: cmds.setAttr(joint + '.jo', 0, 0, 0) continue # Unparent children childList = cmds.parent(childList, w=True) # Reset joint rotation and orientation cmds.setAttr(joint + '.r', 0, 0, 0) cmds.setAttr(joint + '.jo', 0, 0, 0) cmds.makeIdentity(joint, apply=True, t=1, r=1, s=1, n=0, jointOrient=True) # Move transform to joint parent = cmds.listRelatives(joint, p=True, pa=True) trans = cmds.group(em=True, n=joint + '_ORIENT') if parent: cmds.parent(trans, parent[0]) cmds.delete(cmds.pointConstraint(joint, trans)) # Match rotation order cmds.setAttr(trans + '.ro', cmds.getAttr(joint + '.ro')) # Derive orientation cmds.aicmdsonstraint(childJointList[0], trans, aimVector=aimAxis, upVector=upAxis, worldUpType='vector', worldUpVector=upVec) rot = cmds.getAttr(trans + '.r')[0] cmds.setAttr(joint + '.jo', rot[0], rot[1], rot[2]) cmds.delete(trans) # Reparent children cmds.parent(childList, joint)
def targetAliasList(constraint): """ Return a list of targets (drivers) attribute aliases for the specified constraint node @param constraint: The constraint node whose targets will be returned @type constraint: str """ # Check Constraint if not isConstraint(constraint): raise Exception('Constraint "' + constraint + '" does not exist!!') # Get Target List targetList = [] constraintType = cmds.objectType(constraint) if constraintType == 'aicmdsonstraint': targetList = cmds.aicmdsonstraint(constraint, q=True, weightAliasList=True) elif constraintType == 'geometryConstraint': targetList = cmds.geometryConstraint(constraint, q=True, weightAliasList=True) elif constraintType == 'normalConstraint': targetList = cmds.normalConstraint(constraint, q=True, weightAliasList=True) elif constraintType == 'orientConstraint': targetList = cmds.orientConstraint(constraint, q=True, weightAliasList=True) elif constraintType == 'parentConstraint': targetList = cmds.parentConstraint(constraint, q=True, weightAliasList=True) elif constraintType == 'pointConstraint': targetList = cmds.pointConstraint(constraint, q=True, weightAliasList=True) elif constraintType == 'poleVectorConstraint': targetList = cmds.poleVectorConstraint(constraint, q=True, weightAliasList=True) elif constraintType == 'scaleConstraint': targetList = cmds.scaleConstraint(constraint, q=True, weightAliasList=True) elif constraintType == 'tangentConstraint': targetList = cmds.tangentConstraint(constraint, q=True, weightAliasList=True) # Check Target List if not targetList: targetList = [] # Return Result return targetList
def setup_aim(lf_pivot, rt_pivot, head_ccc, aim_dist, prefix): aim_axis = [0.0, 0.0, 1.0] up_axis = [0.0, 1.0, 0.0] worldUp_axis = up_axis # LEFT eye_pos = cmds.xform(lf_pivot, q=1, ws=1, rp=1) # create eye aim transform eye_aim = cmds.group(em=1, n='lf_eye01_am01_loc') cmds.xform(eye_aim, ws=1, t=(eye_pos[0], eye_pos[1], (eye_pos[2] + aim_dist))) # create aim constraint aim_con = cmds.aicmdsonstraint(eye_aim, lf_pivot, aim=aim_axis, u=up_axis, wu=worldUp_axis, wuo=head_ccc, wut='objectrotation') # RIGHT eye_pos = cmds.xform(rt_pivot, q=1, ws=1, rp=1) # create eye aim transform eye_aim = cmds.group(em=1, n='rt_eye01_am01_loc') cmds.xform(eye_aim, ws=1, t=(eye_pos[0], eye_pos[1], (eye_pos[2] + aim_dist))) # create aim constraint aim_con = cmds.aicmdsonstraint(eye_aim, rt_pivot, aim=aim_axis, u=up_axis, wu=worldUp_axis, wuo=head_ccc, wut='objectrotation')
def setup_aim(lf_pivot, rt_pivot, head_ccc, aim_dist, prefix): aim_axis = [0.0, 0.0, 1.0] up_axis = [0.0, 1.0, 0.0] worldUp_axis = up_axis # LEFT eye_pos = cmds.xform(lf_pivot, q=1, ws=1, rp=1) # create eye aim transform eye_aim = cmds.group(em=1, n='lf_eye01_am01_loc') cmds.xform(eye_aim, ws=1, t=(eye_pos[0], eye_pos[1], (eye_pos[2] + aim_dist))) # create aim constraint aim_con = cmds.aicmdsonstraint(eye_aim, lf_pivot, aim=aim_axis, u=up_axis, wu=worldUp_axis, wuo=head_ccc, wut='objectrotation') # RIGHT eye_pos = cmds.xform(rt_pivot, q=1, ws=1, rp=1) # create eye aim transform eye_aim = cmds.group(em=1, n='rt_eye01_am01_loc') cmds.xform(eye_aim, ws=1, t=(eye_pos[0], eye_pos[1], (eye_pos[2] + aim_dist))) # create aim constraint aim_con = cmds.aicmdsonstraint(eye_aim, rt_pivot, aim=aim_axis, u=up_axis, wu=worldUp_axis, wuo=head_ccc, wut='objectrotation')
def rebuildConstraint(self, constraint): """ Rebuild single constraint using stored values. @param constraint: Constraint to rebuild from data @type constraint: str """ # Rebuild Aim Constraint constraintNode = cmds.aicmdsonstraint(self._data[constraint]['targetList'], self._data[constraint]['slave'], skip=self._data[constraint]['skipRotate'], weight=self._data[constraint]['targetWeight'], name=constraint)[0] # Return Result return constraintNode
def rebuildConstraint(self, constraint): """ Rebuild single constraint using stored values. @param constraint: Constraint to rebuild from data @type constraint: str """ # Rebuild Aim Constraint constraintNode = cmds.aicmdsonstraint( self._data[constraint]['targetList'], self._data[constraint]['slave'], skip=self._data[constraint]['skipRotate'], weight=self._data[constraint]['targetWeight'], name=constraint)[0] # Return Result return constraintNode
def targetAliasList(constraint): """ Return a list of targets (drivers) attribute aliases for the specified constraint node @param constraint: The constraint node whose targets will be returned @type constraint: str """ # Check Constraint if not isConstraint(constraint): raise Exception('Constraint "' + constraint + '" does not exist!!') # Get Target List targetList = [] constraintType = cmds.objectType(constraint) if constraintType == 'aicmdsonstraint': targetList = cmds.aicmdsonstraint(constraint, q=True, weightAliasList=True) elif constraintType == 'geometryConstraint': targetList = cmds.geometryConstraint(constraint, q=True, weightAliasList=True) elif constraintType == 'normalConstraint': targetList = cmds.normalConstraint(constraint, q=True, weightAliasList=True) elif constraintType == 'orientConstraint': targetList = cmds.orientConstraint(constraint, q=True, weightAliasList=True) elif constraintType == 'parentConstraint': targetList = cmds.parentConstraint(constraint, q=True, weightAliasList=True) elif constraintType == 'pointConstraint': targetList = cmds.pointConstraint(constraint, q=True, weightAliasList=True) elif constraintType == 'poleVectorConstraint': targetList = cmds.poleVectorConstraint(constraint, q=True, weightAliasList=True) elif constraintType == 'scaleConstraint': targetList = cmds.scaleConstraint(constraint, q=True, weightAliasList=True) elif constraintType == 'tangentConstraint': targetList = cmds.tangentConstraint(constraint, q=True, weightAliasList=True) # Check Target List if not targetList: targetList = [] # Return Result return targetList
def distanceConstrainedControl(ctrlDistPt, ctrlPt, ctrlType, ctrlScale, aimVector=[0, 0, 1], upVector=[0, 1, 0], upType='scene', upObject='', prefix=''): """ Create a control object that is distance constrained from a given position @param ctrlDistPt: Point from which the control will be distance constrained. @type ctrlDistPt: list or tuple @param ctrlPt: Control position. @type ctrlPt: list or tuple @param ctrlType: Control shape type. @type ctrlType: str @param ctrlScale: Control shape scale. @type ctrlScale: float @param aimVector: Constraint aim vector. @type aimVector: list or tuple @param upVector: Constraint upVector. @type upVector: list or tuple @param upType: Constraint upVector type. Valid types are "scene", "object", "objectrotation", "vector", or "none". @type upType: str @param upObject: Constraint upVector object. @type upObject: str @param prefix: Name prefix for control and created nodes. @type prefix: str """ # ========== # - Checks - # ========== # UpVector Object if (upType == 'object' or upType == 'objectrotation') and not cmds.objExists(upObject): raise Exception('UpVector transform "' + upObject + '" does not exist!') # ================== # - Create Control - # ================== ctrl = glTools.tools.controlBuilder.ControlBuilder().create(ctrlType, prefix + '_ctrl', scale=ctrlScale) ctrl_mvCancelGrp = cmds.group(ctrl, n=prefix + '_moveCancel_grp') ctrlGrp = cmds.group(ctrl_mvCancelGrp, n=prefix + '_ctrlGrp') ctrlGrpXform = cmds.group(em=True, n=prefix + '_ctrlGrpXform') # ======================================= # - Build Reference Transform Hierarchy - # ======================================= ctrlLocalTrans = cmds.spaceLocator(n=prefix + '_localTrans_loc')[0] ctrlLocalTransGrp = cmds.group(ctrlLocalTrans, n=prefix + '_localTrans_grp') ctrlReferenceGrp = cmds.group(ctrlLocalTransGrp, n=prefix + '_reference_grp') cmds.setAttr(ctrlLocalTrans + '.localScale', 0.05, 0.05, 0.05) # Curvature compensation addCurveComp = True if addCurveComp: cmds.addAttr(ctrlLocalTrans, ln='curvatureX', dv=0.0, k=True) cmds.addAttr(ctrlLocalTrans, ln='curvatureY', dv=0.0, k=True) curveCompNode = cmds.createNode('multiplyDivide', n=prefix + '_curvature_multiplyDivide') cmds.connectAttr(ctrlLocalTrans + '.translateX', curveCompNode + '.input1X', f=True) cmds.connectAttr(ctrlLocalTrans + '.translateY', curveCompNode + '.input1Y', f=True) cmds.connectAttr(ctrlLocalTrans + '.curvatureX', curveCompNode + '.input2X', f=True) cmds.connectAttr(ctrlLocalTrans + '.curvatureY', curveCompNode + '.input2Y', f=True) cmds.connectAttr(curveCompNode + '.outputX', ctrlLocalTransGrp + '.rotateY', f=True) cmds.connectAttr(curveCompNode + '.outputY', ctrlLocalTransGrp + '.rotateX', f=True) # ======================= # - Position Transforms - # ======================= for c in [ctrlGrp, ctrlGrpXform, ctrlReferenceGrp]: cmds.move(ctrlPt[0], ctrlPt[1], ctrlPt[2], c) # ============================= # - Build Distance Constraint - # ============================= # Aim Constraint cmds.aicmdsonstraint(ctrlLocalTrans, ctrlGrpXform, aim=aimVector, u=upVector, wut=upType, wuo=upObject, n=prefix + '_aicmdsonstraint') # Match Rotation cmds.setAttr(ctrlGrp + '.r', *cmds.getAttr(ctrlGrpXform + '.r')[0]) # ============================ # - Build Connection Network - # ============================ # CtrlXform -> CtrlLocalTrans for at in ['tx', 'ty']: cmds.connectAttr(ctrl + '.' + at, ctrlLocalTrans + '.' + at, f=True) # CtrlGrpXform -> CtrlGrp for at in ['rx', 'ry', 'rz']: cmds.connectAttr(ctrlGrpXform + '.' + at, ctrlGrp + '.' + at, f=True) # Translate Negation localTransNeg = cmds.createNode('multiplyDivide', n=prefix + '_moveCancel_multiplyDivide') cmds.connectAttr(ctrl + '.t', localTransNeg + '.input1', f=True) cmds.setAttr(localTransNeg + '.input2', -1, -1, -1) cmds.connectAttr(localTransNeg + '.outputX', ctrl_mvCancelGrp + '.tx', f=True) cmds.connectAttr(localTransNeg + '.outputY', ctrl_mvCancelGrp + '.ty', f=True) cmds.connectAttr(localTransNeg + '.outputZ', ctrl_mvCancelGrp + '.tz', f=True) # Set Pivot Positions cmds.xform(ctrlGrpXform, ws=True, rp=ctrlDistPt) cmds.xform(ctrlGrp, ws=True, rp=ctrlDistPt) # Match Rotation cmds.setAttr(ctrlReferenceGrp + '.r', *cmds.getAttr(ctrlGrpXform + '.r')[0]) # ================= # - Return Result - # ================= result = {} result['ctrl'] = ctrl result['moveCancel'] = ctrl_mvCancelGrp result['ctrlGrp'] = ctrlGrp result['ctrlGrpXform'] = ctrlGrpXform result['ctrlLocalTrans'] = ctrlLocalTrans result['ctrlLocalTransGrp'] = ctrlLocalTransGrp result['ctrlReferenceGrp'] = ctrlReferenceGrp result['localTransNeg'] = localTransNeg return result
def build(sourceJoint, targetJoint, numJoints=4, aimAxis='x', upAxis='y', baseToTip=True, enableCtrl=False, prefix=''): """ Build twist joint setup using an aicmdsonstraint to calculate rotation. @param numJoints: @param sourceJoint: Twist base joint @type sourceJoint: str @param targetJoint: Twist target or end joint @type targetJoint: str @param aimAxis: Axis along the length of the source joint @type aimAxis: list or tuple @param upAxis: Upward facing axis of the source joint @type upAxis: list or tuple @param baseToTip: Twist from the base to the tip @type baseToTip: bool @param enableCtrl: Enable the twist child joint as a control @type enableCtrl: bool @param prefix: Naming prefix for created nodes @type prefix: str """ # ========== # - Checks - # ========== # Define Axis Dictionary axisDict = {'x': (1, 0, 0), 'y': (0, 1, 0), 'z': (0, 0, 1), '-x': (-1, 0, 0), '-y': (0, -1, 0), '-z': (0, 0, -1)} if not cmds.objExists(sourceJoint): raise Exception('Source joint "' + sourceJoint + '" does not exist!') if not cmds.objExists(targetJoint): raise Exception('Target joint "' + targetJoint + '" does not exist!') if not axisDict.has_key(aimAxis): raise Exception('Invalid aim axis value! ("' + aimAxis + '")') if not axisDict.has_key(upAxis): raise Exception('Invalid up axis value! ("' + upAxis + '")') if not prefix: prefix = glTools.utils.stringUtils.stripSuffix(sourceJoint) # ====================== # - Configure Modifier - # ====================== twistCtrlScale = 0.2 ctrlBuilder = glTools.tools.controlBuilder.ControlBuilder() # ======================= # - Create Twist Joints - # ======================= twistJoints = createTwistJoints(joint=sourceJoint, numTwistJoints=numJoints, offsetAxis=aimAxis[-1], prefix=prefix) # Check baseToTip - Reverse list order if false if not baseToTip: twistJoints.reverse() # Create Joint Groups/Attributes/Tags twistJointGrps = [] twistFactor = 1.0 / (len(twistJoints) - 1) jntLen = glTools.utils.joint.length(sourceJoint) for i in range(len(twistJoints)): # Add Twist Control Attribute cmds.addAttr(twistJoints[i], ln='twist', min=-1.0, max=1.0, dv=twistFactor * i) # Add Twist Joint Group twistJointGrp = glTools.utils.joint.group(twistJoints[i], indexStr='Twist') twistJointGrps.append(twistJointGrp) # Tag Bind Joint glTools.rig.utils.tagBindJoint(twistJoints[i], True) # Create Joint Control if enableCtrl: glTools.rig.utils.tagCtrl(twistJoints[i], 'tertiary') ctrlBuilder.controlShape(transform=twistJoints[i], controlType='sphere', controlScale=twistCtrlScale) # Set Display Override if enableCtrl: glTools.utils.base.displayOverride(twistJoints[i], overrideEnable=1, overrideDisplay=0, overrideLOD=1) else: glTools.utils.base.displayOverride(twistJoints[i], overrideEnable=1, overrideDisplay=2, overrideLOD=0) # Create Twist Group twistGrp = cmds.joint(n=prefix + '_twistJoint_grp') glTools.utils.base.displayOverride(twistGrp, overrideEnable=1, overrideDisplay=2, overrideLOD=1) glTools.utils.transform.match(twistGrp, sourceJoint) cmds.setAttr(twistGrp + '.segmentScaleCompensate', 0) cmds.setAttr(twistGrp + '.drawStyle', 2) # None cmds.setAttr(twistGrp + '.radius', 0) cmds.parent(twistGrp, sourceJoint) cmds.parent(twistJointGrps, twistGrp) # Connect Inverse Scale for twistJointGrp in twistJointGrps: cmds.connectAttr(sourceJoint + '.scale', twistJointGrp + '.inverseScale', f=True) # ========================== # - Create Twist Aim Setup - # ========================== # Create Twist Aim Joint twistAimJnt = cmds.duplicate(sourceJoint, po=True, n=prefix + '_twistAim_jnt')[0] # Remove user attributes glTools.utils.attribute.deleteUserAttrs(twistAimJnt) # Parent to source joint cmds.parent(twistAimJnt, sourceJoint) # Display Overrides glTools.utils.base.displayOverride(twistAimJnt, overrideEnable=1, overrideDisplay=2, overrideLOD=0) # Create Twist Aim Locator twistAimLoc = cmds.group(em=True, n=prefix + '_twistAim_loc') cmds.delete(cmds.pointConstraint(targetJoint, twistAimLoc, mo=False)) cmds.delete(cmds.orientConstraint(sourceJoint, twistAimLoc, mo=False)) cmds.parent(twistAimLoc, targetJoint) # Display Overrides glTools.utils.base.displayOverride(twistAimLoc, overrideEnable=1, overrideDisplay=2, overrideLOD=0) # Create Twist Aim Constraint twistAicmdson = cmds.aicmdsonstraint(targetJoint, twistAimJnt, aim=axisDict[aimAxis], u=axisDict[upAxis], wu=axisDict[upAxis], wuo=twistAimLoc, wut='objectrotation')[0] # ======================== # - Connect Twist Joints - # ======================== twistMultNode = [] for i in range(len(twistJoints)): alphaInd = glTools.utils.stringUtils.alphaIndex(i, upper=True) twistMult = cmds.createNode('multDoubleLinear', n=prefix + '_twist' + alphaInd + '_multDoubleLinear') cmds.connectAttr(twistAimJnt + '.r' + aimAxis[-1], twistMult + '.input1', f=True) cmds.connectAttr(twistJoints[i] + '.twist', twistMult + '.input2', f=True) cmds.connectAttr(twistMult + '.output', twistJointGrps[i] + '.r' + aimAxis[-1], f=True) twistMultNode.append(twistMult) # ====================== # - Set Channel States - # ====================== chStateUtil = glTools.utils.channelState.ChannelState() chStateUtil.setFlags([2, 2, 2, 2, 2, 2, 2, 2, 2, 1], objectList=[twistGrp]) chStateUtil.setFlags([0, 0, 0, 0, 0, 0, 0, 0, 0, 1], objectList=twistJoints) chStateUtil.setFlags([2, 2, 2, 2, 2, 2, 2, 2, 2, 1], objectList=twistJointGrps) chStateUtil.setFlags([2, 2, 2, 1, 1, 1, 2, 2, 2, 1], objectList=[twistAimJnt]) chStateUtil.setFlags([2, 2, 2, 2, 2, 2, 2, 2, 2, 1], objectList=[twistAimLoc]) # ================= # - Return Result - # ================= result = {} result['twistGrp'] = twistGrp result['twistJoints'] = twistJoints result['twistJointGrps'] = twistJointGrps result['twistDriveJoint'] = twistAimJnt result['twistAimLocator'] = twistAimLoc result['twistConstraint'] = twistAicmdson result['twistMultNodes'] = twistMultNode return result
def aicmdsonstraint(target, slave, aim='z', up='y', worldUpType='scene', worldUpObject=None, worldUpVector='y', offset=(0, 0, 0), mo=False): """ Create an aim constraint between the specifiec master and slave transforms. Only constrains open, settable channels. @param master: Constraint master transform. @type master: str @param slave: Constraint slave transform. @type slave: str @param aim: Aim axis. @type aim: str @param aim: Up axis. @type aim: str @param worldUpType: World Up type. Options - "scene", "object", "objectrotation", "vector", or "none". @type worldUpType: str @param worldUpObject: World Up object. @type worldUpObject: str @param worldUpVector: World Up vector. @type worldUpVector: str @param mo: Maintain constraint offset @type mo: bool """ # Build Axis Dict axis = { 'x': (1, 0, 0), 'y': (0, 1, 0), 'z': (0, 0, 1), '-x': (-1, 0, 0), '-y': (0, -1, 0), '-z': (0, 0, -1) } # ========== # - Checks - # ========== # Check Master if not cmds.objExists(target): raise Exception('Constraint target "' + target + '" does not exist!') if not glTools.utils.transform.isTransform(target): raise Exception('Constraint target "' + target + '" is not a valid transform!') # Check Slave if not cmds.objExists(slave): raise Exception('Constraint slave "' + slave + '" does not exist!') if not glTools.utils.transform.isTransform(slave): raise Exception('Constraint slave "' + slave + '" is not a valid transform!') # Check Settable Channels sk = [] if not cmds.getAttr(slave + '.rx', se=True): sk.append('x') if not cmds.getAttr(slave + '.ry', se=True): sk.append('y') if not cmds.getAttr(slave + '.rz', se=True): sk.append('z') if not sk: sk = 'none' # ===================== # - Create Constraint - # ===================== constraint = '' try: if worldUpObject: constraint = cmds.aicmdsonstraint( target, slave, aim=axis[aim], u=axis[aim], worldUpType=worldUpType, worldUpObject=worldUpObject, worldUpVector=axis[worldUpVector], sk=sk, offset=offset, mo=mo)[0] else: constraint = cmds.aicmdsonstraint( target, slave, aim=axis[aim], u=axis[aim], worldUpType=worldUpType, worldUpVector=axis[worldUpVector], sk=sk, offset=offset, mo=mo)[0] except Exception, e: raise Exception('Error creating constraint from "' + target + '" to "' + slave + '"! Exception msg: ' + str(e))
def jointOrientCreateControl(): """ Create joint orient control for each selected joint """ # Check Window window = "jointOrientUI" upAxis = (0, 1, 0) if cmds.window(window, q=True, ex=1): # Build UpAxis List upAxisList = [((0, 1, 0), (0, 0, 1)), ((1, 0, 0), (0, 0, 1)), ((1, 0, 0), (0, 1, 0))] # Get Axis Selection aimAx = cmds.radioButtonGrp("jointOrientPrimAxisRBG", q=True, sl=True) upAx = cmds.radioButtonGrp("jointOrientAimAxisRBG", q=True, sl=True) # Build Axis Values upAxis = upAxisList[aimAx - 1][upAx - 1] # Create control jntList = cmds.ls(sl=True, type="joint") ctrlList = [] for jnt in jntList: # Get child joint cJnt = cmds.listRelatives(jnt, c=True, pa=True) if not cJnt: continue # Generate control prefix prefix = glTools.utils.stringUtils.stripSuffix(jnt) # Check for existing orien control if cmds.objExists(prefix + "_ori01_orientGrp"): print('Orient control already exists for joint "' + jnt + '"!!') continue # Create orient control circle = cmds.circle( c=(0, 0, 0), nr=(0, 1, 0), sw=360, r=1, d=3, ut=0, tol=0.01, s=8, ch=1, n=prefix + "_ori01_orientControl" ) for ch in ["tx", "ty", "tz", "rx", "rz", "sx", "sy", "sz"]: cmds.setAttr(circle[0] + "." + ch, l=True, k=False) # Create orient UP locator upLoc = cmds.spaceLocator(n=prefix + "_up01_orientLoc") cmds.parent(upLoc[0], circle[0]) cmds.setAttr(upLoc[0] + ".tz", 1.0) cmds.connectAttr(upLoc[0] + ".tz", circle[1] + ".radius", f=True) for ch in ["tx", "ty", "rx", "ry", "rz", "sx", "sy", "sz"]: cmds.setAttr(upLoc[0] + "." + ch, l=True, k=False) # Create orient control group ctrlGrp = cmds.group(em=True, n=prefix + "_ori01_orientGrp") cmds.parent(circle[0], ctrlGrp) # Position control group cmds.delete(cmds.pointConstraint(jnt, ctrlGrp)) cmds.delete( cmds.aicmdsonstraint( cJnt[0], ctrlGrp, aimVector=(0, 1, 0), upVector=(0, 0, 1), wu=upAxis, wuo=jnt, wut="objectrotation" ) ) # Scale control elements dist = glTools.utils.mathUtils.distanceBetween( cmds.xform(jnt, q=True, ws=True, rp=True), cmds.xform(cJnt[0], q=True, ws=True, rp=True) ) cmds.setAttr(upLoc[0] + ".tz", dist * 0.5) # Lock orient control group cmds.parent(ctrlGrp, jnt) for ch in ["tx", "ty", "tz", "rx", "ry", "rz", "sx", "sy", "sz"]: cmds.setAttr(ctrlGrp + "." + ch, l=True, k=False) # Add message connection form joint to orient control cmds.addAttr(circle[0], ln="joint", at="message") cmds.connectAttr(jnt + ".message", circle[0] + ".joint", f=True) # Append control list ctrlList.append(circle[0]) # Select controls cmds.select(ctrlList)
def aicmdsonstraint(target, slave, aim='z', up='y', worldUpType='scene', worldUpObject=None, worldUpVector='y', offset=(0, 0, 0), mo=False): """ Create an aim constraint between the specifiec master and slave transforms. Only constrains open, settable channels. @param master: Constraint master transform. @type master: str @param slave: Constraint slave transform. @type slave: str @param aim: Aim axis. @type aim: str @param aim: Up axis. @type aim: str @param worldUpType: World Up type. Options - "scene", "object", "objectrotation", "vector", or "none". @type worldUpType: str @param worldUpObject: World Up object. @type worldUpObject: str @param worldUpVector: World Up vector. @type worldUpVector: str @param mo: Maintain constraint offset @type mo: bool """ # Build Axis Dict axis = {'x': (1, 0, 0), 'y': (0, 1, 0), 'z': (0, 0, 1), '-x': (-1, 0, 0), '-y': (0, -1, 0), '-z': (0, 0, -1)} # ========== # - Checks - # ========== # Check Master if not cmds.objExists(target): raise Exception('Constraint target "' + target + '" does not exist!') if not glTools.utils.transform.isTransform(target): raise Exception('Constraint target "' + target + '" is not a valid transform!') # Check Slave if not cmds.objExists(slave): raise Exception('Constraint slave "' + slave + '" does not exist!') if not glTools.utils.transform.isTransform(slave): raise Exception('Constraint slave "' + slave + '" is not a valid transform!') # Check Settable Channels sk = [] if not cmds.getAttr(slave + '.rx', se=True): sk.append('x') if not cmds.getAttr(slave + '.ry', se=True): sk.append('y') if not cmds.getAttr(slave + '.rz', se=True): sk.append('z') if not sk: sk = 'none' # ===================== # - Create Constraint - # ===================== constraint = '' try: if worldUpObject: constraint = cmds.aicmdsonstraint(target, slave, aim=axis[aim], u=axis[aim], worldUpType=worldUpType, worldUpObject=worldUpObject, worldUpVector=axis[worldUpVector], sk=sk, offset=offset, mo=mo)[0] else: constraint = cmds.aicmdsonstraint(target, slave, aim=axis[aim], u=axis[aim], worldUpType=worldUpType, worldUpVector=axis[worldUpVector], sk=sk, offset=offset, mo=mo)[0] except Exception, e: raise Exception('Error creating constraint from "' + target + '" to "' + slave + '"! Exception msg: ' + str(e))
def jointOrientCreateControl(): """ Create joint orient control for each selected joint """ # Check Window window = 'jointOrientUI' upAxis = (0, 1, 0) if cmds.window(window, q=True, ex=1): # Build UpAxis List upAxisList = [((0, 1, 0), (0, 0, 1)), ((1, 0, 0), (0, 0, 1)), ((1, 0, 0), (0, 1, 0))] # Get Axis Selection aimAx = cmds.radioButtonGrp('jointOrientPrimAxisRBG', q=True, sl=True) upAx = cmds.radioButtonGrp('jointOrientAimAxisRBG', q=True, sl=True) # Build Axis Values upAxis = upAxisList[aimAx - 1][upAx - 1] # Create control jntList = cmds.ls(sl=True, type='joint') ctrlList = [] for jnt in jntList: # Get child joint cJnt = cmds.listRelatives(jnt, c=True, pa=True) if not cJnt: continue # Generate control prefix prefix = glTools.utils.stringUtils.stripSuffix(jnt) # Check for existing orien control if cmds.objExists(prefix + '_ori01_orientGrp'): print('Orient control already exists for joint "' + jnt + '"!!') continue # Create orient control circle = cmds.circle(c=(0, 0, 0), nr=(0, 1, 0), sw=360, r=1, d=3, ut=0, tol=0.01, s=8, ch=1, n=prefix + '_ori01_orientControl') for ch in ['tx', 'ty', 'tz', 'rx', 'rz', 'sx', 'sy', 'sz']: cmds.setAttr(circle[0] + '.' + ch, l=True, k=False) # Create orient UP locator upLoc = cmds.spaceLocator(n=prefix + '_up01_orientLoc') cmds.parent(upLoc[0], circle[0]) cmds.setAttr(upLoc[0] + '.tz', 1.0) cmds.connectAttr(upLoc[0] + '.tz', circle[1] + '.radius', f=True) for ch in ['tx', 'ty', 'rx', 'ry', 'rz', 'sx', 'sy', 'sz']: cmds.setAttr(upLoc[0] + '.' + ch, l=True, k=False) # Create orient control group ctrlGrp = cmds.group(em=True, n=prefix + '_ori01_orientGrp') cmds.parent(circle[0], ctrlGrp) # Position control group cmds.delete(cmds.pointConstraint(jnt, ctrlGrp)) cmds.delete( cmds.aicmdsonstraint(cJnt[0], ctrlGrp, aimVector=(0, 1, 0), upVector=(0, 0, 1), wu=upAxis, wuo=jnt, wut='objectrotation')) # Scale control elements dist = glTools.utils.mathUtils.distanceBetween( cmds.xform(jnt, q=True, ws=True, rp=True), cmds.xform(cJnt[0], q=True, ws=True, rp=True)) cmds.setAttr(upLoc[0] + '.tz', dist * 0.5) # Lock orient control group cmds.parent(ctrlGrp, jnt) for ch in ['tx', 'ty', 'tz', 'rx', 'ry', 'rz', 'sx', 'sy', 'sz']: cmds.setAttr(ctrlGrp + '.' + ch, l=True, k=False) # Add message connection form joint to orient control cmds.addAttr(circle[0], ln='joint', at='message') cmds.connectAttr(jnt + '.message', circle[0] + '.joint', f=True) # Append control list ctrlList.append(circle[0]) # Select controls cmds.select(ctrlList)