Rigging Assignment

 Rigging Assignment

Set up for IK FK switch and automatic script that adds controllers to a skeleton and orient constrains the joints

I originally wanted to make a script that automatically set up the entire IK FK switch but I ran out of time. 

import maya.cmds as cmds
import string


def find_and_rename_joints(bodyPart, side, num_joints): # "arm", "leg", etc., "Lf" or "Rt"

    letters = list(string.ascii_uppercase)
    
    joints = []
    childJoints = []
    
    joints.append(cmds.ls(sl=1) [0])
    
    childJoints = cmds.listRelatives(ad=1, type="joint")
    childJoints.reverse()
    
    for i in range(num_joints - 1):
        joints.append(childJoints[i])
    
    armJoints = []
    
    for i,joint in enumerate(joints):
        armJoint = cmds.rename(joint, bodyPart + "J" + letters[i] + side + "_1")
        armJoints.append(armJoint)
        
    if bodyPart == "arm":
            
        shoulderJoint = armJoints[0]
        elbowJoint = armJoints[1]
        wristTwistJoint = armJoints[2]
        wristJoint = armJoints[3]
        
        return shoulderJoint, elbowJoint, wristTwistJoint, wristJoint,
        
    elif bodyPart == "leg":
            
        hipJoint = armJoints[0]
        kneeJoint = armJoints[1]
        ankleJoint = armJoints[2]
        
        return hipJoint, kneeJoint, ankleJoint
        
shoulderJoint, elbowJoint, wristTwistJoint, wristJoint = find_and_rename_joints("arm", "Lf", 4)

def make_and_rename_IKJoints(bodyPart, side):
    # make IK and FK
    cmds.select(clear=True)
    cmds.select(shoulderJoint)
    cmds.duplicate(renameChildren=True)
    
    letters = list(string.ascii_uppercase)
    
    IKjoints = []
    IKchildJoints = []
        
    IKjoints.append(cmds.ls(sl=1) [0])
        
    childJoints = cmds.listRelatives(ad=1, type="joint")
    childJoints.reverse()
        
    for i in range(3):
        IKjoints.append(childJoints[i])
        
    IKarmJoints = []
    
    for i,joint in enumerate(IKjoints):
        IKarmJoint = cmds.rename(joint, bodyPart + "J" + letters[i] + side + "_IK")
        IKarmJoints.append(IKarmJoint)
    
    shoulderIKJoint = IKarmJoints[0]    
    elbowIKJoint = IKarmJoints[1]
    wristTwistIKJoint = IKarmJoints[2]  
    wristIKJoint = IKarmJoints[3]
    wristIKChildren = cmds.listRelatives(ad = 1, type="joint")
    print(wristIKChildren)
    
    for i in range(0, ):
        cmds.delete(IKchildJoints[i])
    print(IKchildJoints)
    
    return shoulderIKJoint, elbowIKJoint, wristTwistIKJoint, wristIKJoint

shoulderIK, elbowIK, wristTwistIK, wristIK = make_and_rename_IKJoints("arm", "Lf")

def deleteWristChildren(wristJoint):
    # Replace 'wrist_joint' with the actual name of the wrist joint in your arm joint chain.
    wrist_joint_name = wristJoint

    # Check if the wrist joint exists in the scene.
    if cmds.objExists(wrist_joint_name):
        # Get the children of the wrist joint.
        children = cmds.listRelatives(wrist_joint_name, children=True, fullPath=True) or []

        if children:
            # Select and delete the children joints.
            cmds.select(children, replace=True)
            cmds.delete()
            print("Children of wrist joint deleted successfully.")
        else:
            print("No children joints found under the wrist joint.")
    else:
        print("Wrist joint not found in the scene.")

# Call the function to delete the children of the wrist joint.
deleteWristChildren(wristIK)

def make_and_rename_FKJoints(bodyPart, side):
    # make FK
    cmds.select(clear=True)
    cmds.select(shoulderJoint)
    cmds.duplicate(renameChildren=True)
    
    letters = list(string.ascii_uppercase)
    
    FKjoints = []
    FKchildJoints = []
        
    FKjoints.append(cmds.ls(sl=1) [0])
        
    childJoints = cmds.listRelatives(ad=1, type="joint")
    childJoints.reverse()
        
    for i in range(3):
        FKjoints.append(childJoints[i])
        
    FKarmJoints = []
    
    for i,joint in enumerate(FKjoints):
        FKarmJoint = cmds.rename(joint, bodyPart + "J" + letters[i] + side + "_FK")
        FKarmJoints.append(FKarmJoint)
    
    shoulderFKJoint = FKarmJoints[0]    
    elbowFKJoint = FKarmJoints[1]
    wristTwistFKJoint = FKarmJoints[2]  
    wristFKJoint = FKarmJoints[3]
    wristFKChildren = cmds.listRelatives(ad = 1, type="joint")
    print(wristFKChildren)
    
    for i in range(0, ):
        cmds.delete(FKchildJoints[i])
    print(FKchildJoints)
    
    return shoulderFKJoint, elbowFKJoint, wristTwistFKJoint, wristFKJoint
    
shoulderFK, elbowFK, wristTwistFK, wristFK = make_and_rename_FKJoints("arm", "Lf")

# call deleteWristChildren to delete fk wrist children joints
deleteWristChildren(wristFK)


This script when you select your shoulder joint, will rename the arm joints, duplicate the arm chain twice, delete the hand joints of the duplicates.

The script has a few functions, first is find_and_rename_joints(). This function was taken from the stretchy arm assignment. This allows use to work with the arm joints and rename them. 

The next function is make_and_rename_IKJoints(). This duplicates the arm chain and renames the joints with "_Ik" at the end.

make_and_rename_FKJoints is similar and adds "_FK" to the end of each joint name.

deleteWristChildren() is used to delete the joints after the wrist because for an IK and FK switch they are not needed in the duplicated joint chains.

Create controllers

import maya.cmds as cmds

def create_circle_controller(joint_name):
    # Create a NURBS circle controller
    controller = cmds.circle(name=joint_name + '_ctrl', normal=(1, 0, 0))[0]
    
    # Match the controller's position and orientation to the joint
    cmds.matchTransform(controller, joint_name, pos=True, rot=True)
    
    return controller

def parent_controllers_to_hierarchy(joint, parent_controller=None):
    # Create a controller for the current joint
    controller = create_circle_controller(joint)
    
    # Orient constrain the joint to the controller
    orient_constraint = cmds.orientConstraint(controller, joint)[0]
    
    # Parent the controller under the parent_controller if provided
    if parent_controller:
        cmds.parent(controller, parent_controller)
    
    # Recursively process child joints
    child_joints = cmds.listRelatives(joint, children=True, type='joint')
    if child_joints:
        for child_joint in child_joints:
            parent_controllers_to_hierarchy(child_joint, controller)

def create_nurbs_circle_controllers():
    # Select the root joint of the skeleton
    root_joint = cmds.ls(selection=True, dag=True, type='joint')
    
    if not root_joint:
        cmds.warning("Please select the root joint of the skeleton.")
        return
    
    # Start the controller hierarchy with the root joint
    parent_controllers_to_hierarchy(root_joint[0])

# Run the script to create controllers, parent them, and apply orient constraints
create_nurbs_circle_controllers()

This script automatically creates nurbs circles to act as controllers, renames the controllers to match the joint is being moved to. The script also parents the controllers together following the hierarchy of the skeleton, and then orient constrains the joints to their corresponding joint. 

This helps with the tedious task of creating controllers for every joint and renaming them and orient constraining each joint to each controller. 

This script uses a recursive function to process the joints. 


I used chatgpt for this assignment:

write a maya python script that automatically adds nurbs circle controllers to joints and names the controllers after the joint and parents the controllers in the order the joint chain is
ChatGPT

To create a Maya Python script that automatically adds NURBS circle controllers to joints and names the controllers after the joints while parenting them in the order of the joint chain, you can use the following script:

python
import maya.cmds as cmds def create_circle_controller(joint_name): # Create a NURBS circle controller controller = cmds.circle(name=joint_name + '_ctrl', normal=(1, 0, 0))[0] # Match the controller's position and orientation to the joint cmds.matchTransform(controller, joint_name, pos=True, rot=True) return controller def parent_controllers_to_joints(joint_chain, controller_chain): for i in range(len(joint_chain)): joint = joint_chain[i] controller = controller_chain[i] # Parent the controller under the joint cmds.parent(controller, joint) def create_nurbs_circle_controllers(): # Select the joint chain joint_chain = cmds.ls(selection=True, dag=True, type='joint') if not joint_chain: cmds.warning("Please select a joint chain.") return controller_chain = [] for joint in joint_chain: controller = create_circle_controller(joint) controller_chain.append(controller) # Parent the controllers in the order of the joint chain parent_controllers_to_joints(joint_chain, controller_chain) # Run the script to create controllers create_nurbs_circle_controllers()

Make sure you have the joint chain selected in Maya before running this script. It will create NURBS circle controllers for each joint in the chain, name them after the joints, and parent them in the order of the joint chain.

Please note that this script assumes that the joint chain is continuous and correctly ordered. It also assumes that the joint orientation matches the desired controller orientation. You may need to adjust it to fit your specific rigging needs.

User
i dont want the controllers to be parented to the joints, i want them to be parented to each other in the same order the joints are
ChatGPT

I see, you want the controllers to be parented to each other in the same order as the joints, creating a hierarchy of controllers. Here's the modified script:

python
import maya.cmds as cmds def create_circle_controller(joint_name): # Create a NURBS circle controller controller = cmds.circle(name=joint_name + '_ctrl', normal=(1, 0, 0))[0] # Match the controller's position and orientation to the joint cmds.matchTransform(controller, joint_name, pos=True, rot=True) return controller def create_nurbs_circle_controllers(): # Select the joint chain joint_chain = cmds.ls(selection=True, dag=True, type='joint') if not joint_chain: cmds.warning("Please select a joint chain.") return controller_chain = [] for joint in joint_chain: controller = create_circle_controller(joint) controller_chain.append(controller) # Parent the controllers in the order of the joint chain for i in range(1, len(controller_chain)): cmds.parent(controller_chain[i], controller_chain[i - 1]) # Run the script to create controllers create_nurbs_circle_controllers()

With this modified script, the controllers will be created and parented to each other in the same order as the joints in the chain, creating a hierarchy of controllers. Select the joint chain in Maya before running the script.

User
sepereate the hierarchy so that the left controllers are together and seperate from the right controllers
ChatGPT

To separate the hierarchy so that the left controllers are together and separate from the right controllers, you can modify the script as follows:

python
import maya.cmds as cmds def create_circle_controller(joint_name): # Create a NURBS circle controller controller = cmds.circle(name=joint_name + '_ctrl', normal=(1, 0, 0))[0] # Match the controller's position and orientation to the joint cmds.matchTransform(controller, joint_name, pos=True, rot=True) return controller def create_nurbs_circle_controllers(): # Select the joint chain joint_chain = cmds.ls(selection=True, dag=True, type='joint') if not joint_chain: cmds.warning("Please select a joint chain.") return left_controllers = [] right_controllers = [] for joint in joint_chain: controller = create_circle_controller(joint) # Check if the joint name contains "left" or "right" and categorize accordingly if "left" in joint.lower(): left_controllers.append(controller) elif "right" in joint.lower(): right_controllers.append(controller) # Parent the left controllers to each other if left_controllers: for i in range(1, len(left_controllers)): cmds.parent(left_controllers[i], left_controllers[i - 1]) # Parent the right controllers to each other if right_controllers: for i in range(1, len(right_controllers)): cmds.parent(right_controllers[i], right_controllers[i - 1]) # Run the script to create controllers create_nurbs_circle_controllers()

With this script, it categorizes controllers as "left" or "right" based on the joint names and then parents them separately within their respective groups. Make sure to select the entire joint chain in Maya before running the script.

User
parent the separate groups of the controllers
ChatGPT

To parent the separate groups of controllers (left controllers and right controllers) in the order they were created, you can modify the script as follows:

python
import maya.cmds as cmds def create_circle_controller(joint_name): # Create a NURBS circle controller controller = cmds.circle(name=joint_name + '_ctrl', normal=(1, 0, 0))[0] # Match the controller's position and orientation to the joint cmds.matchTransform(controller, joint_name, pos=True, rot=True) return controller def create_nurbs_circle_controllers(): # Select the joint chain joint_chain = cmds.ls(selection=True, dag=True, type='joint') if not joint_chain: cmds.warning("Please select a joint chain.") return left_controllers = [] right_controllers = [] for joint in joint_chain: controller = create_circle_controller(joint) # Check if the joint name contains "left" or "right" and categorize accordingly if "left" in joint.lower(): left_controllers.append(controller) elif "right" in joint.lower(): right_controllers.append(controller) # Parent the left controllers to each other if left_controllers: for i in range(1, len(left_controllers)): cmds.parent(left_controllers[i], left_controllers[i - 1]) # Parent the right controllers to each other if right_controllers: for i in range(1, len(right_controllers)): cmds.parent(right_controllers[i], right_controllers[i - 1]) # Create groups for left and right controllers if left_controllers: left_group = cmds.group(left_controllers[0], name="left_controllers_grp") if right_controllers: right_group = cmds.group(right_controllers[0], name="right_controllers_grp") # Parent the groups to maintain the hierarchy if left_controllers and right_controllers: cmds.parent(left_group, right_group) # Run the script to create controllers and parent them into groups create_nurbs_circle_controllers()

This script will create groups for left and right controllers and then parent these groups to maintain the hierarchy. Make sure to select the entire joint chain in Maya before running the script.

User
modify this script so that the controllers are parented following the hierarchy of the joints and the branches of the skeleton, for example the left wrist joint should be parented under the left elbow joint
ChatGPT

To modify the script so that the controllers are parented following the hierarchy of the joints and branches of the skeleton, you can use a recursive function to traverse the joint hierarchy and create controllers accordingly. Here's the modified script:

python
import maya.cmds as cmds def create_circle_controller(joint_name): # Create a NURBS circle controller controller = cmds.circle(name=joint_name + '_ctrl', normal=(1, 0, 0))[0] # Match the controller's position and orientation to the joint cmds.matchTransform(controller, joint_name, pos=True, rot=True) return controller def parent_controllers_to_hierarchy(joint, parent_controller=None): # Create a controller for the current joint controller = create_circle_controller(joint) # Parent the controller under the parent_controller if provided if parent_controller: cmds.parent(controller, parent_controller) # Recursively process child joints child_joints = cmds.listRelatives(joint, children=True, type='joint') if child_joints: for child_joint in child_joints: parent_controllers_to_hierarchy(child_joint, controller) def create_nurbs_circle_controllers(): # Select the root joint of the skeleton root_joint = cmds.ls(selection=True, dag=True, type='joint') if not root_joint: cmds.warning("Please select the root joint of the skeleton.") return # Start the controller hierarchy with the root joint parent_controllers_to_hierarchy(root_joint[0]) # Run the script to create controllers and parent them following the joint hierarchy create_nurbs_circle_controllers()

With this script, the controllers will be created and parented according to the joint hierarchy, ensuring that they follow the branching structure of the skeleton. Select the root joint of the skeleton in Maya before running the script.

User
write an addition to this code that orient constrains the joints to their corresponding controllers
ChatGPT

To orient constrain the joints to their corresponding controllers, you can add an orient constraint to each joint-controller pair within the parent_controllers_to_hierarchy function. Here's the modified script:

python
import maya.cmds as cmds def create_circle_controller(joint_name): # Create a NURBS circle controller controller = cmds.circle(name=joint_name + '_ctrl', normal=(1, 0, 0))[0] # Match the controller's position and orientation to the joint cmds.matchTransform(controller, joint_name, pos=True, rot=True) return controller def parent_controllers_to_hierarchy(joint, parent_controller=None): # Create a controller for the current joint controller = create_circle_controller(joint) # Orient constrain the joint to the controller orient_constraint = cmds.orientConstraint(controller, joint)[0] # Parent the controller under the parent_controller if provided if parent_controller: cmds.parent(controller, parent_controller) # Recursively process child joints child_joints = cmds.listRelatives(joint, children=True, type='joint') if child_joints: for child_joint in child_joints: parent_controllers_to_hierarchy(child_joint, controller) def create_nurbs_circle_controllers(): # Select the root joint of the skeleton root_joint = cmds.ls(selection=True, dag=True, type='joint') if not root_joint: cmds.warning("Please select the root joint of the skeleton.") return # Start the controller hierarchy with the root joint parent_controllers_to_hierarchy(root_joint[0]) # Run the script to create controllers, parent them, and apply orient constraints create_nurbs_circle_controllers()

Now, the script will create controllers, parent them following the joint hierarchy, and apply orient constraints between the joints and their corresponding controllers. Select the root joint of the skeleton in Maya before running the script.

Comments

Popular posts from this blog

Scripting for Animation and VFX: Week3

Final: Auto three point lighting set up

Scripting For Animation and VFX: Week 2