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 '20 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$ – danulrich Oct 27 '20 at 19:19
  • $\begingroup$ Related blender.stackexchange.com/questions/6155/… $\endgroup$ – batFINGER Oct 28 '20 at 8:56
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$ – danulrich Oct 28 '20 at 8:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.