0

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?

brockmann
  • 12,613
  • 4
  • 50
  • 93
dan283
  • 259
  • 1
  • 8
  • What do you mean by "ID"? Is it a scripting/Python question? – lemon Oct 27 '20 at 18:31
  • 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) – dan283 Oct 27 '20 at 19:19
  • Related https://blender.stackexchange.com/questions/6155/how-to-convert-coordinates-from-vertex-to-world-space – batFINGER Oct 28 '20 at 08:56

1 Answers1

3

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 )

lemon
  • 60,295
  • 3
  • 66
  • 136
  • Thank you, I was hoping I could avoid using the 3D cursor. This is way more elegant! Appreciate it. – dan283 Oct 28 '20 at 08:51