# snap bone locations using python

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

# 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 -

Any idea what I'm doing wrong?

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

# 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