I made a script that allows to obtain the nearest vertex of the mouse cursor. To those interested here is:
def snap_verts(region, rv3d, obj_matrix, mouse, verts, dist):
t = time.time()
ray_origin = view3d_utils.region_2d_to_origin_3d(region, rv3d, mouse)
view_vector = view3d_utils.region_2d_to_vector_3d(region, rv3d, mouse)
matrix_inv = obj_matrix.inverted()
og = matrix_inv * ray_origin
#bpy.context.scene.cursor_location = og
vv = view_vector * obj_matrix
lvl = [] # local verts list
n1, n2 = 1,2
n3, n4 = 2,0
n5, n6 = 0,1
for vert in verts:
vert.select = False
v = vert.co
if lvl == [] or \
abs(lco.x - v.x) < dist2 and \
abs(lco.y - v.y) < dist2 and \
abs(lco.z - v.z) < dist2:
#d = vv.cross(og - v)
dx = abs(vv[n1]*(og[n2]-v[n2])-vv[n2]*(og[n1]-v[n1]))
if dx < dist:
dy = abs(vv[n3]*(og[n4]-v[n4])-vv[n4]*(og[n3]-v[n3]))
if dy < dist:
dz = abs(vv[n5]*(og[n6]-v[n6])-vv[n6]*(og[n5]-v[n5]))
if dz < dist:
dist = max([dx,dy,dz])
dist2 = 2*dist
lco = v
lvl.append(vert)
else:
n1,n2,n5,n6 = n5,n6,n1,n2
else:
n1,n2,n3,n4 = n3,n4,n1,n2
print(time.time() - t)
return lvl[-1]
One thing to note is that the default snap options in Blender are twice faster. For example:
bpy.ops.view3d.select(<i>extend=False</i>, <i>deselect=False</i>, <i>toggle=False</i>, <i>center=False</i>, <i>enumerate=False</i>, <i>object=False</i>, <i>location=(0</i>, <i>0)</i>)
How is this possible?
The ray_cast (another example) is almost instantaneous. What is the secret of ray_cast?