#☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺ # # Script: createControllersAtJoints.py # Author: Audrey Paransky & Simon Burdick # Last Updated: 06/07/2024 # Created: 06/07/2024 # Description: This script creates curves on selected joints and stacks the curves in the same hierarchical order as # the selected joints. Last, it parents the joints under the curves. # #☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺ import maya.cmds as cmds selectionList = cmds.ls( selection=True, type='joint' ) if (len(selectionList) > 0): controlCurveList = [] for jnt in selectionList: ## Joint Information # Get parent of current joint jntParent = cmds.listRelatives( jnt, parent=True ) if( jntParent ): jntParentName = jntParent[0] else: jntParentName = "GARBAGE" #this is for the first joint in the heirarchy since it has no parent. there needs to be something # Get Radius of current joint jntRadius = cmds.getAttr( jnt + '.radius' ) # Get translation and rotation of current joint jntTranslation = cmds.xform( jnt, query=True, translation=True, worldSpace=True ) jntRotation = cmds.xform( jnt, query=True, rotation=True, worldSpace=True ) ## Controller Manipulation # Create new controller newControl = cmds.circle( c=(0, 0, 0), name=(jnt + '_ctrl') ) #c changes the shape of the cirlce, 0,0,0 ensures that it's a full circle controlCurveList.append( newControl[0] ) #newControl will return a dictionary containing the transform and the shape node, you just want the name, hence [0] cmds.move( jntTranslation[0], jntTranslation[1], jntTranslation[2], newControl ) cmds.rotate( 90, 0, 90, newControl ) cmds.scale( ( 1*jntRadius ), ( 1*jntRadius ), ( 1*jntRadius ), newControl ) cmds.makeIdentity( newControl, apply=True ) # Create the offset group for our new controller newGroup = cmds.group( empty=True, name=(jnt + '_offset') ) cmds.move( jntTranslation[0], jntTranslation[1], jntTranslation[2], newGroup ) #the group and the cntrl are at the same place cmds.makeIdentity( newGroup, apply=True ) #freeze transformations # Make new control a child of new group cmds.parent( newControl, newGroup ) # Rotate offset group to match the rotations of the joint cmds.rotate( jntRotation[0], jntRotation[1], jntRotation[2], newGroup ) ## Place group in the right hierarchy if ( jntParentName + '_ctrl' ) in controlCurveList: cmds.parent( newGroup, (jntParentName + '_ctrl') ) print( newGroup + ' parented under ' + jntParentName + '_ctrl' ) else: print( 'No parent found' ) print( jntParentName ) print( controlCurveList ) ## Parent constrain joint under control cmds.parentConstraint( newControl, jnt ) else: print("no joints selected")