0
$\begingroup$

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?

$\endgroup$
3
  • $\begingroup$ What do you mean by "ID"? Is it a scripting/Python question? $\endgroup$
    – lemon
    Oct 27, 2020 at 18:31
  • $\begingroup$ Yes. I need to select a vertex based on it's index, and snap the 3D cursor to it in order to create an empty at the given location (I need to repeat it several times, hence the need for python) $\endgroup$
    – dan283
    Oct 27, 2020 at 19:19
  • $\begingroup$ Related blender.stackexchange.com/questions/6155/… $\endgroup$
    – batFINGER
    Oct 28, 2020 at 8:56

1 Answer 1

3
$\begingroup$

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 )
$\endgroup$
1
  • $\begingroup$ Thank you, I was hoping I could avoid using the 3D cursor. This is way more elegant! Appreciate it. $\endgroup$
    – dan283
    Oct 28, 2020 at 8:51

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .