2
$\begingroup$

I'm trying to snap bone locations which are of a certain proximity to a vertexes of a mesh, to the difference of position based an the corresponding vertex of another mesh with the same topology.

Basically snap bone A to vertex[0] of mesh_B if vertex[0] is at the same position than vertex[0] of mesh_A.

import bpy

# Get the armature and Mesh A and Mesh B objects
armature = bpy.data.objects.get("RetopoFlow_vRig")
mesh_a = bpy.data.objects.get("RetopoFlow")
mesh_b = bpy.data.objects.get("RetopoFlowB")

# Enter Pose mode
bpy.context.view_layer.objects.active = armature
bpy.ops.object.mode_set(mode='POSE')

# Iterate through each bone in the armature
for bone in armature.pose.bones:
    # Get the bone's head position
    bone_head_pos = bone.head

    # Iterate through each vertex in Mesh A
    for vertex in mesh_a.data.vertices:
        # Get the vertex position
        vertex_pos_a = mesh_a.matrix_world @ vertex.co

        # Check if the bone's head position is close to the vertex position
        if (bone_head_pos - vertex_pos_a).length < 0.0001:
            # Find the corresponding vertex in Mesh B
            vertex_pos_b = mesh_b.matrix_world @ mesh_b.data.vertices[vertex.index].co

            # Calculate the difference in vertex position
            diff = vertex_pos_b - vertex_pos_a

            # Move the bone in the direction of the difference
            bone.location += diff
            break

While this is the right idea, it seems to only work in the X direction for some reason -

enter image description here

Any idea what I'm doing wrong?

$\endgroup$

1 Answer 1

1
$\begingroup$

There seems to be a difference between coordinates for vertices vs coordinates for bones. While I'll try and read up on that here's a working code -

import bpy

# Get the armature and Mesh A and Mesh B objects
armature = bpy.data.objects.get("RetopoFlow_vRig")
mesh_a = bpy.data.objects.get("RetopoFlow")
mesh_b = bpy.data.objects.get("RetopoFlowB")

# Enter Pose mode
bpy.context.view_layer.objects.active = armature
bpy.ops.object.mode_set(mode='POSE')

# Iterate through each bone in the armature
for bone in armature.pose.bones:
    # Get the bone's head position
    bone_head_pos = bone.head

    # Iterate through each vertex in Mesh A
    for vertex in mesh_a.data.vertices:
        # Get the vertex position
        vertex_pos_a = mesh_a.matrix_world @ vertex.co

        # Check if the bone's head position is close to the vertex position
        if (bone_head_pos - vertex_pos_a).length < 0.01:
            # Find the corresponding vertex in Mesh B
            vertex_pos_b = mesh_b.matrix_world @ mesh_b.data.vertices[vertex.index].co

            # Calculate the difference in vertex position
            diff = vertex_pos_b - vertex_pos_a

            # Move the bone in the direction of the difference
            bone.location.x += diff.x
            bone.location.z -= diff.y
            bone.location.y += diff.z
$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .