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

$$$$
`