I need to snap the 3D cursor to a specific vertex based on it's ID (to create an empty at that location) and I'm having trouble finding a simple way to achieve that.
Anyone got some pointers?
I need to snap the 3D cursor to a specific vertex based on it's ID (to create an empty at that location) and I'm having trouble finding a simple way to achieve that.
Anyone got some pointers?
I think you want to move the 3D cursor in order to use bpy.ops to create the empties.
You should avoid using it because it involves updates at each usage and is slow.
In your case you can use directly objects data.
The code is commented below but ask in comments if anything is not clear:
import bpy
import bmesh
def empties_from_indices( context, obj, vertex_indices ):
#Get the current collection
collection = context.collection
#Access to obj vertices
vertices = obj.data.vertices
#Get its world matrix
matrix = obj.matrix_world
#Loop over indices to get vertex locations
for location in [vertices[index].co for index in vertex_indices]:
#Create an empty
empty = bpy.data.objects.new("empty", None)
#Set its location converted in world space
empty.location = matrix @ location
#Add it to the current collection
collection.objects.link(empty)
#Get current context and object
context = bpy.context
obj = context.object
vertex_indices = [1, 4, 6]
empties_from_indices( context, obj, vertex_indices )
If you need to access vertex location when the object is deformed by a modifier or has an armature for instance, you can use the following (same principle, only the way vertices are accessed changes):
import bpy
import bmesh
def empties_from_indices_with_deform( context, obj, vertex_indices ):
#Get the current collection
collection = context.collection
#Access to obj vertices
dg = context.evaluated_depsgraph_get() #Get the dependency graph
bm = bmesh.new() #Create a bmesh
bm.from_object(obj, dg) #Get object data
bm.verts.ensure_lookup_table() #So that can access verts with indices
vertices = bm.verts
#Get its world matrix
matrix = obj.matrix_world
#Loop over indices to get vertex locations
for location in [vertices[index].co for index in vertex_indices]:
#Create an empty
empty = bpy.data.objects.new("empty", None)
#Set its location converted in world space
empty.location = matrix @ location
#Add it to the current collection
collection.objects.link(empty)
#Get current context and object
context = bpy.context
obj = context.object
vertex_indices = [1, 4, 6]
empties_from_indices_with_deform( context, obj, vertex_indices )