If the indices no longer correspond, you can:
- use a brute-force proximity check
- use spatial search structure (K-dimensional-Tree).
Template for getting a bmesh in Object or Edit mode can be found in:
TextEditor > Templates > Python > Simple Bmesh (EditMode)
Brute Force
For each coordinate listed in coords_to_find
it will select the first vertex which has a similar 3d location. Due to numeric imprecision of 32bit floats we might use an Epsilon as a fuzzyness factor, and say "Any vertex coordinate found within linear distance Epsilon of a given coordinate is the one we want", then skip on to the remaining verts and coords.
Below is a slight modification of the Bmesh template, it assumes we have a mesh object in edit-mode, i happened to use a Suzanne model.
import bpy
import bmesh
from mathutils import Vector
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)
Epsilon = 0.00001
"""
Here we iterate over the lists of verts and coords. We remove
the coordinate from the 'coords_to_find' once it's found. this
decreases the number of comparisons on the remaining vertices.
-- it might also make sense to _break_ when 'coords_to_find' is empty.
"""
for v in bm.verts:
for idx, coord in enumerate(coords_to_find):
if (v.co-Vector(coord)).length < Epsilon:
v.select = True
print(v.co)
coords_to_find.pop(idx)
break
# Show the updates in the viewport
# and recalculate n-gon tessellation.
bmesh.update_edit_mesh(me, True)
KDTree
An alternative, which might be faster (especially noticable on larger objects) uses the built in KDTree module. There are 3 search functions find
, find_n
and find_range
.
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)