# Select multiple vertices using a list of coordinates with KDTree

I want to select (or to put into active selection) some vertices using their coordinates so I've seen an answer there : Automatic select vertices by given coordinates

But it only works when I'm in edit mode, how could I use it this way :
Object mode : select an object, put it in edit mode and then select the vertices, go out of edit mode (back to object)
And when I use this at the beggining of the code : bpy.ops.object.editmode_toggle() it sends me an error.

Because I'd like to use this code with other objects in my scene not just one. I guess the problem is in bmesh but I don't quite understand it... Thank you for your help.

The answer given by zeffii :

import bpy
import bmesh
from mathutils import Vector, kdtree

coords_to_find = [
(0.3203125, -0.734375, 0.7578125),
(0.0, -0.2890625, 0.8984375),
(0.453125, -0.234375, 0.8515625),
(-0.6328125, -0.28125, 0.453125),
(-0.796875, -0.125, 0.5625)
]

# Get the active mesh
obj = bpy.context.edit_object
me = obj.data
bm = bmesh.from_edit_mesh(me)

size = len(bm.verts)
kd = kdtree.KDTree(size)

for i, vtx in enumerate(bm.verts):
kd.insert(vtx.co, i)
kd.balance()

for idx, vtx in enumerate(coords_to_find):
co, index, dist = kd.find(vtx)  # dist is the distance
print(idx, vtx, index, co)
bm.verts[index].select = True

# Show the updates in the viewport
# and recalculate n-gon tessellation.
bmesh.update_edit_mesh(me, True)

• See the bmesh docs docs.blender.org/api/blender2.8/bmesh.html#mesh-access The example script is object mode docs.blender.org/api/blender2.8/bmesh.html#example-script May 29, 2019 at 13:36
• Okay thanks, so I guess that I don't have to use this : bm = bmesh.from_edit_mesh(me) but I have to create a new mesh so I've used this : # Get the active mesh me = bpy.context.object.data # Get a BMesh representation bm = bmesh.new() # create an empty BMesh bm.from_mesh(me) # fill it in from a Mesh But it still don't work... May 29, 2019 at 14:58

Object mode non-bmesh version

Run script in object mode. Selects vertices in each object based on being closest to points in list.

import bpy
import bmesh
from mathutils import Vector, kdtree

context = bpy.context

coords_to_find = [
(0.3203125, -0.734375, 0.7578125),
(0.0, -0.2890625, 0.8984375),
(0.453125, -0.234375, 0.8515625),
(-0.6328125, -0.28125, 0.453125),
(-0.796875, -0.125, 0.5625)
]

# Get the active meshes
meshes = set(o.data for o in context.selected_objects
if o.type == 'MESH')

for me in meshes:
size = len(me.vertices)
kd = kdtree.KDTree(size)
select = [False] * size

# deselect all edges and faces
me.edges.foreach_set("select", [False] * len(me.edges))
me.polygons.foreach_set("select", [False] * len(me.polygons))

for v in me.vertices:
kd.insert(v.co, v.index)
kd.balance()

for co in coords_to_find:
loc, index, dist = kd.find(co)
select[index] = True

me.vertices.foreach_set("select", select)
print(me.name, [v.index for v in me.vertices if v.select])
#me.update_tag()
#context.view_layer.update()


which if run on default scene, returns

Cube [5, 6]


Note this assumes the given coordinates are in local space.

For global coordinates would have to decide how to handle objects sharing the same mesh, since a different vert may be chosen based on object transform for each object that shares the mesh.