How do I find the closest point on another mesh to a vertex with Python?

I know that the closest_point_on_mesh function in BPY can be used to find the closest point on any mesh to an arbitrary point in space. However, I am working on a project for which I need to take a vertex on a mesh object, and find the closest point on any other mesh object. Is there a method that can be used to do that? Thanks.

Using closest point on mesh.

Similarly to the answer here https://blender.stackexchange.com/a/40979/15543 code hacked together to find the closest point on mesh of all other mesh objects in the scene to vertex[0] of the active mesh object. Adds an Empty on the hit point.

import bpy
import bmesh
context = bpy.context
scene = context.scene

edit_obj = context.active_object
me = edit_obj.data
mesh_objects = [o for o in scene.objects if o.type == 'MESH']
bm = bmesh.new()
for sphere in mesh_objects:
if sphere == edit_obj:
continue
smwi = sphere.matrix_world.inverted()

bm.from_mesh(me)
bm.verts.ensure_lookup_table()
vert = bm.verts[0]
v1 = edit_obj.matrix_world * vert.co # global face median
local_pos = smwi * v1  # face cent in sphere local space

(hit, loc, norm, face_index) = sphere.closest_point_on_mesh(local_pos)
if hit:
v2 = sphere.matrix_world * loc
print(sphere.name, (v2 - v1).length)
bm.clear()


A base to do that by simply going through all objects vertices (so not really optimized if many vertices/objects) :

The result is a list of tuples [object, nearest vertice, distance].

import bpy
from mathutils import Vector

max = 100000 #max distance

point = Vector([0, 0, 0]) #reference point from which we seek the distances (set your reference vertex in global coordinates here)

result = [] #stores the results

for obj in bpy.data.objects:
pos = obj.matrix_world.inverted() * point #converts the reference to local space

shortest = None
shortestDist = max

for v in obj.data.vertices: #go throught all vertices
dist = (Vector( v.co ) - pos).length  #calculate the distance
if dist < shortestDist : #test if better so far
shortest = v
shortestDist = dist

result.append( [obj, shortest, shortestDist] ) #append the result

print( result )


mathutils supports KDTrees, which can also be helpful in this scenario: https://docs.blender.org/api/current/mathutils.kdtree.html

from mathutils.kdtree import KDTree

def createKdTreeForObject(blenderObject):
mesh = blenderObject.data
size = len(mesh.vertices)
kd = KDTree(size)

for i, v in enumerate(mesh.vertices):
kd.insert(v.co, i)

kd.balance()
return kd

vertex = (1,0,1)
blenderObject = D.objects['Cube']
kdTree = createKdTreeForObject(blenderObject)
matrixWorld = blenderObject.matrix_world
invertedMatrixWorld = matrixWorld.inverted()

vertexInverted = invertedMatrixWorld @ Vector(vertex)

print("Closest 10 points")
for (co, index, dist) in kdTree.find_n(vertexInverted, 10):
print("    ", co, index, dist)

$$$$
`