ishandutta2007
ishandutta2007

Reputation: 18244

Parent the BaseMesh to the rig with automatic weights is not working

I am on blender 3.6.

Goal is to simulate a running/walking animation of a loaded BaseMesh as obj file via python.

Here is my python code:

import bpy
import math

def import_basemesh(filepath):
    # Import the BaseMesh OBJ file
    bpy.ops.import_scene.obj(filepath=filepath)
    basemesh = bpy.context.selected_objects[0]
    basemesh.name = "BaseMesh"
    return basemesh

def create_rig():
    # Create an armature
    bpy.ops.object.armature_add(enter_editmode=True, location=(0, 0, 0))
    armature = bpy.context.object
    armature.name = "Rig"
    armature.show_in_front = True

    # Add bones in Edit Mode
    bones = armature.data.edit_bones

    # Rename default bone to "Spine"
    bones["Bone"].head = (0, 0, 18)
    bones["Bone"].tail =(0, 0, 11)
    bones["Bone"].name = "Spine"

    # Add head bone
    head_bone = bones.new("Head")
    head_bone.head = (0, 0, 20)
    head_bone.tail = (0, 0, 18)
    head_bone.parent = bones["Spine"]

    # Add left leg bone
    left_leg_bone = bones.new("Left_Leg")
    left_leg_bone.head = (0, 0, 11)
    left_leg_bone.tail = (0, -2, 1)
    left_leg_bone.parent = bones["Spine"]

    # Add right leg bone
    right_leg_bone = bones.new("Right_Leg")
    right_leg_bone.head = (0, 0, 11)
    right_leg_bone.tail = (0, 2, 1)
    right_leg_bone.parent = bones["Spine"]

    # Add left arm bone
    left_arm_bone = bones.new("Left_Arm")
    left_arm_bone.head = (0, 0, 18)
    left_arm_bone.tail = (0, -6, 9)
    left_arm_bone.parent = bones["Spine"]

    # Add right arm bone
    right_arm_bone = bones.new("Right_Arm")
    right_arm_bone.head = (0, 0, 18)
    right_arm_bone.tail = (0, 6, 9)
    right_arm_bone.parent = bones["Spine"]

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

def rig_basemesh(basemesh, armature):
    """
    Parent the BaseMesh to the rig with automatic weights.
    """
    # Select the BaseMesh and the Armature
    bpy.ops.object.mode_set(mode='OBJECT')
    bpy.context.view_layer.objects.active = armature
    bpy.ops.object.select_all(action='DESELECT')
    basemesh.select_set(True)
    armature.select_set(True)

    # Set Parent to Armature with Automatic Weights
    bpy.ops.object.parent_set(type='ARMATURE_AUTO')

    print(f"Parented '{basemesh.name}' to '{armature.name}' with Automatic Weights.")

def rotate_basemesh(basemesh, angle_degrees):
    """
    Rotates the BaseMesh around the Z-axis by a given angle (in degrees).
    """
    import math

    # Convert degrees to radians
    angle_radians = math.radians(angle_degrees)

    # Apply rotation
    basemesh.rotation_euler[2] += angle_radians  # Z-axis rotation (XY plane)

    print(f"Rotated '{basemesh.name}' by {angle_degrees} degrees counterclockwise on the XY plane.")


def animate_running(armature):
    """
    Create a running animation for the rig's bones.
    """
    # Ensure animation data exists
    if not armature.animation_data:
        armature.animation_data_create()

    # Switch to Pose Mode
    bpy.context.view_layer.objects.active = armature
    bpy.ops.object.mode_set(mode='POSE')
    pose_bones = armature.pose.bones

    # Verify the bones exist
    required_bones = ["Left_Leg", "Right_Leg", "Left_Arm", "Right_Arm"]
    missing_bones = [bone for bone in required_bones if bone not in pose_bones]
    if missing_bones:
        print(f"ERROR: Missing bones: {missing_bones}")
        return

    print("Available bones in armature:")
    for bone in pose_bones:
        print(bone.name)

    # Set animation frame range
    frame_start = 1
    frame_end = 200
    bpy.context.scene.frame_start = frame_start
    bpy.context.scene.frame_end = frame_end

    # Insert keyframes for each bone
    print("Inserting keyframes for running animation...")
    try:
        while frame_start<frame_end:
            # Animate the Right Leg's location (opposite phase)
            # Set the starting rotation
            pose_bones["Left_Leg"].rotation_quaternion = (1, 0, 0, math.sin(math.radians(45/2)))
            pose_bones["Left_Leg"].keyframe_insert(data_path="rotation_quaternion", frame=frame_start)

            pose_bones["Left_Leg"].rotation_quaternion = (1, 0, 0, 0)
            pose_bones["Left_Leg"].keyframe_insert(data_path="rotation_quaternion", frame=frame_start + 5)

            pose_bones["Left_Leg"].rotation_quaternion = (1, 0, 0, -math.sin(math.radians(45/2)))
            pose_bones["Left_Leg"].keyframe_insert(data_path="rotation_quaternion", frame=frame_start + 10)

            pose_bones["Left_Leg"].rotation_quaternion = (1, 0, 0, 0)
            pose_bones["Left_Leg"].keyframe_insert(data_path="rotation_quaternion", frame=frame_start + 15)

            # Animate the Right Leg's location (opposite phase)
            pose_bones["Right_Leg"].rotation_quaternion = (1, 0, 0, -math.sin(math.radians(45/2)))
            pose_bones["Right_Leg"].keyframe_insert(data_path="rotation_quaternion", frame=frame_start)

            pose_bones["Right_Leg"].rotation_quaternion = (1, 0, 0, 0)
            pose_bones["Right_Leg"].keyframe_insert(data_path="rotation_quaternion", frame=frame_start + 5)

            pose_bones["Right_Leg"].rotation_quaternion = (1, 0, 0, math.sin(math.radians(45/2)))
            pose_bones["Right_Leg"].keyframe_insert(data_path="rotation_quaternion", frame=frame_start + 10)

            pose_bones["Right_Leg"].rotation_quaternion = (1, 0, 0, 0)
            pose_bones["Right_Leg"].keyframe_insert(data_path="rotation_quaternion", frame=frame_start + 15)

            # Animate the Left Arm's location (opposite to legs)
            pose_bones["Left_Arm"].rotation_quaternion = (1, 0, 0, math.sin(math.radians(45/2)))
            pose_bones["Left_Arm"].keyframe_insert(data_path="rotation_quaternion", frame=frame_start)

            pose_bones["Left_Arm"].rotation_quaternion = (1, 0, 0, 0)
            pose_bones["Left_Arm"].keyframe_insert(data_path="rotation_quaternion", frame=frame_start + 5)

            pose_bones["Left_Arm"].rotation_quaternion = (1, 0, 0, -math.sin(math.radians(45/2)))
            pose_bones["Left_Arm"].keyframe_insert(data_path="rotation_quaternion", frame=frame_start + 10)

            pose_bones["Left_Arm"].rotation_quaternion = (1, 0, 0, 0)
            pose_bones["Left_Arm"].keyframe_insert(data_path="rotation_quaternion", frame=frame_start + 15)

            # Animate the Right Arm's location (opposite phase to Left Arm)
            pose_bones["Right_Arm"].rotation_quaternion = (1, 0, 0, -math.sin(math.radians(45/2)))
            pose_bones["Right_Arm"].keyframe_insert(data_path="rotation_quaternion", frame=frame_start)

            pose_bones["Right_Arm"].rotation_quaternion = (1, 0, 0, 0)
            pose_bones["Right_Arm"].keyframe_insert(data_path="rotation_quaternion", frame=frame_start + 5)

            pose_bones["Right_Arm"].rotation_quaternion = (1, 0, 0, math.sin(math.radians(45/2)))
            pose_bones["Right_Arm"].keyframe_insert(data_path="rotation_quaternion", frame=frame_start + 10)

            pose_bones["Right_Arm"].rotation_quaternion = (1, 0, 0, 0)
            pose_bones["Right_Arm"].keyframe_insert(data_path="rotation_quaternion", frame=frame_start + 15)

            print("Location keyframes successfully inserted.")
            frame_start += 20
    except Exception as e:
        print(f"ERROR: Failed to insert keyframes: {e}")

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

def main(filepath):
    basemesh = import_basemesh(filepath)

    armature = create_rig()

    rig_basemesh(basemesh, armature)

    basemesh = bpy.data.objects["BaseMesh"]
    rotate_basemesh(basemesh, 90)

    animate_running(armature)

obj_filepath = "C:/Users/hp/Downloads/fdx54mtvuz28-FinalBaseMesh/FinalBaseMesh.obj"
main(obj_filepath)

Expectation is the rig bones to attach to corresponding body parts , instead it seems like they are attached randomly as the entire body sways back and forth instead of running animation. Here is the obj file of the basemesh

https://sketchfab.com/3d-models/fdx54mtvuz28-final-base-mesh-bfa060fcbce64195be4fe5098b88b1a7

Upvotes: 0

Views: 25

Answers (0)

Related Questions