iClone iK

So, I’ve been working on an addon that addon that adds IK to a iClone / Charactor Creator rig

#SELECT THE ARAMTURE AND RUN ME

import bpy
from mathutils import Vector

# RENAME BONES
def rename_bones():
    # Check if an armature is selected
    if bpy.context.active_object and bpy.context.active_object.type == 'ARMATURE':
        armature = bpy.context.active_object.data
        bpy.ops.object.mode_set(mode='EDIT')

        # Iterate through all bones in edit mode
        for bone in armature.edit_bones:
            # Check if "CC" is in the bone name
            if "CC" in bone.name:
                # Get the index of "CC" in the bone name
                index = bone.name.find("CC")
                
                # Rename the bone by keeping everything after "CC"
                new_name = bone.name[index:]
                bone.name = new_name

        bpy.ops.object.mode_set(mode='OBJECT')

def rename_bone_containing_phrase(armature, phrase, new_name):
    # Iterate through all bones in edit mode
    bpy.ops.object.mode_set(mode='EDIT')
    for bone in armature.edit_bones:
        # Check if the bone name contains the specified phrase
        if phrase in bone.name:
            # Rename the bone
            new_bone_name = bone.name.replace(phrase, new_name)
            bone.name = new_bone_name

    bpy.ops.object.mode_set(mode='OBJECT')

# Specify the phrase and the new name
phrase_to_find = "BoneRoot"
new_name = "CC_Base_BoneRoot"


# MOVE BONE HEADS
def move_bone_heads():
    # Check if an armature is selected
    if bpy.context.active_object and bpy.context.active_object.type == 'ARMATURE':
        armature = bpy.context.active_object.data

        # Ensure the armature is in Edit Mode
        bpy.ops.object.mode_set(mode='EDIT')

        move_bone_tail_to_head(armature, "CC_Base_L_Forearm", "CC_Base_L_Hand")

        move_bone_tail_to_head(armature, "CC_Base_L_Upperarm", "CC_Base_L_Forearm")

        move_bone_tail_to_head(armature, "CC_Base_R_Forearm", "CC_Base_R_Hand")

        move_bone_tail_to_head(armature, "CC_Base_R_Upperarm", "CC_Base_R_Forearm")

        # Exit Edit Mode
        bpy.ops.object.mode_set(mode='OBJECT')

def move_bone_tail_to_head(armature, source_bone_name, target_bone_name):
    # Get the bones
    source_bone = armature.edit_bones.get(source_bone_name)
    target_bone = armature.edit_bones.get(target_bone_name)

    # Check if both bones exist
    if source_bone and target_bone:
        # Move the head of the source bone to the tail of the target bone
        source_bone.tail = target_bone.head
        # source_bone.roll = target_bone.roll

#CREATE BONES
def create_bone(armature, new_bone_name):

    # Create a new bone
    bpy.ops.object.mode_set(mode='EDIT')
    bpy.ops.armature.bone_primitive_add(name=new_bone_name)
    # bpy.ops.object.mode_set(mode='OBJECT')


def move_bone_head_to_head(armature, source_bone_name, target_bone_name):
    # Get the bones
    source_bone = armature.edit_bones.get(source_bone_name)
    target_bone = armature.edit_bones.get(target_bone_name)

    # Check if both bones exist
    if source_bone and target_bone:
        # Move the head of the source bone to the tail of the target bone
        source_bone.head = target_bone.head
        # source_bone.roll = target_bone.roll


def move_bone_to_bone(armature, source_bone_name, target_bone_name):
    # Get the bones
    source_bone = armature.edit_bones.get(source_bone_name)
    target_bone = armature.edit_bones.get(target_bone_name)

    # Check if both bones exist
    if source_bone and target_bone:
        # Move the head of the source bone to the tail of the target bone
        source_bone.head = target_bone.head
        source_bone.tail = target_bone.tail
        source_bone.roll = target_bone.roll


def scale_bone(armature, source_bone_name, scale):
    # Get the bones
    source_bone = armature.edit_bones.get(source_bone_name)
    Head = source_bone.head
    Tail = source_bone.tail
    Tail = Head + (Tail-Head)*scale
    source_bone.tail = Tail


#ADD CONSTRAINTS
def create_ik(ik_bone_name, target_bone_name):

    # Get the selected armature object
    selected_obj = bpy.context.active_object

    # Check if the selected object is an armature
    if selected_obj and selected_obj.type == 'ARMATURE':
        # Get the pose bone by name
        pose_bone = selected_obj.pose.bones.get(ik_bone_name)
        
        # Check if the pose bone exists
        if pose_bone:
            # Add IK constraint to the pose bone
            ik_constraint = pose_bone.constraints.new(type='IK')
            ik_constraint.target = selected_obj
            ik_constraint.subtarget = target_bone_name
            ik_constraint.chain_count = 2
            ik_constraint.name = "IK_Constraint"
            
            print("IK constraint added successfully to", pose_bone.name)
        else:
            print("Pose bone 'CC_Base_L_Forearm' not found.")
    else:
        print("No armature selected.")



def create_copyr(r_bone_name, target_bone_name):

    # Get the selected armature object
    selected_obj = bpy.context.active_object

    # Check if the selected object is an armature
    if selected_obj and selected_obj.type == 'ARMATURE':
        # Get the pose bone by name
        pose_bone = selected_obj.pose.bones.get(r_bone_name)
        
        # Check if the pose bone exists
        if pose_bone:
            # Add IK constraint to the pose bone
            ik_constraint = pose_bone.constraints.new(type='COPY_ROTATION')
            ik_constraint.target = selected_obj
            ik_constraint.subtarget = target_bone_name
            ik_constraint.name = "IK_Constraint"
            
            print("IK constraint added successfully to", pose_bone.name)
        else:
            print("Pose bone 'CC_Base_L_Forearm' not found.")
    else:
        print("No armature selected.")







# RUN
# Check if an armature is selected
if bpy.context.active_object and bpy.context.active_object.type == 'ARMATURE':
    armature = bpy.context.active_object.data

    # Call the function to rename the bone
    rename_bone_containing_phrase(armature, phrase_to_find, new_name)


# RENAME BONES
rename_bones()


# MOVE BONE HEADS
move_bone_heads()


#CREATE BONES
armature = bpy.context.active_object.data
bpy.ops.object.mode_set(mode='EDIT')

#Create copies of the hand bones and sclae them for IK handles

create_bone(bpy.context.active_object, "CC_Base_L_Hand_IK")

move_bone_to_bone(armature, "CC_Base_L_Hand_IK", "CC_Base_L_Hand")
scale_bone(armature, "CC_Base_L_Hand_IK", 4)

create_bone(bpy.context.active_object, "CC_Base_R_Hand_IK")

move_bone_to_bone(armature, "CC_Base_R_Hand_IK", "CC_Base_R_Hand")
scale_bone(armature, "CC_Base_R_Hand_IK", 4)


#Scale Head and Hip Bones
scale_bone(armature, "CC_Base_Head", 4000)

scale_bone(armature, "CC_Base_Hip", 10)

#ADD CONSTRAINTS
bpy.ops.object.mode_set(mode='POSE')
create_ik("CC_Base_L_Forearm", "CC_Base_L_Hand_IK")
create_copyr("CC_Base_L_Hand", "CC_Base_L_Hand_IK")

create_ik("CC_Base_R_Forearm", "CC_Base_R_Hand_IK")
create_copyr("CC_Base_R_Hand", "CC_Base_R_Hand_IK")

This is my fisrt python script, made in colaberation with ChatGPT, but learning some phython along the way, so crits are welcome.

I hope to

  • Add bone shapes
  • Add controllers so you can phase between IK and Mocap for each limb easily
  • Make Bone Shapes
  • Make it work for legs as well
  • Make it work for feet
  • Move some bones to a hidden layer to make it easier to control

All things I’ve done within Blender, but not throuogh python.

I’d like to hear what you think of this… tell me if you’d find it useful, add sugestions, etc.