3
$\begingroup$

This has been driving me crazy for some time, because it seems so simple, but I just cannot find a way to do it despite exhaustive searching. Say I'm in bmesh, and I create a vertex, and I add it to the mesh. For whatever reason, this vertex is special. I need to be able to access this vertex again. Not just later in the same script, but between sessions.

Things I've tried and why I can't make them work:

  • Obviously, I can just go for the index of the BMVert, but those change all the time when other vertices get deleted, so this value isn't useful to me.
  • I thought of storing the actual reference to the BMVert Python object, but I don't really understand how this could really persist between sessions, because besides the fact in new sessions those same objects (from Python's perspective) no longer exist, the only storage place I know of that persists on an object is custom properties, and in there you can only store basic types like strings and numbers.

So, I need a way, ideally in text or numerical form, to permanently and uniquely address a vertex, and it should be one I can access in an indexed way, because the shapes I'm dealing with have too many vertices to do this by search. It just feels so viscerally simple to me, and it's been a major stumbling block for me for a while now that I just can't figure out how to do it.

Any help would be immensely appreciated.

$\endgroup$

1 Answer 1

6
$\begingroup$

Custom Layer Access

Suggest adding a custom layer. Example of adding an int layer.

id_int_layer = bm.verts.layers.int.new("id")

Vertex groups could also be considered a custom layer, it's the deform layer.

>>> bm.verts.layers.
                bevel_weight
                deform
                float
                int
                paint_mask
                shape
                skin
                string

Example of adding an int layer with values assigned to vertex index.

import bpy
import bmesh
obj = bpy.context.object

bm = bmesh.new()
bm.from_mesh(obj.data)

#get or create custom verts int layer
my_id = bm.verts.layers.int.get("id") or bm.verts.layers.int.new("id")

for v in bm.verts:
    v[my_id] = v.index  # assign value
    #print(v.index, v[my_id])
  
bm.to_mesh(obj.data)

Also see examples here, for tagging specific vertex using this method. Custom data of vertices, Vertex Layers

After setting the layer on default cube, extruding one face, saving then reopening and printing v.index, v[my_id]

0 0
1 1
...
7 7
8 0
9 1
10 4
11 5

New verts 8 to 11 have the layer value of the original they were extruded from.

NOTE. In hindsight would set to vert.index + 1 so as not to confuse original vert 0 with all new verts. (or via another layer that is given a non default value when setting indices)

Via the mesh API.

>>> me = C.object.data
>>> me
bpy.data.meshes['Cube']

Vert layers

>>> me.vertex_layers_
                     float
                     int
                     string

Add a new int layer, & populate it with values. Using foreach_set will be very quick. All set to vert index + 1.

>>> il = me.vertex_layers_int.new(name="ID")
>>> il.data.foreach_set("value", range(1, len(me.vertices) + 1))

Test result

>>> il.data[3]
bpy.data.meshes['Cube'].vertex_layers_int["ID"].data[3]

>>> il.data[3].value
4
$\endgroup$
3
  • $\begingroup$ This is one avenue I explored, but it isn't ideal for my situation, because afaik, custom data layers aren't indexed (if they are, that would solve my problem, though). I have a ton of vertices to deal with, so accessing specific vertices by doing [x for x in bm.verts where x["id"] == n] is just too slow. What I would need ideally (if this is even possible) is something like bm.verts["id"][n]. $\endgroup$
    – Tim M.
    Commented Nov 28, 2018 at 13:53
  • $\begingroup$ as opposed to bm.verts[n]["id"] ? $\endgroup$
    – batFINGER
    Commented Nov 28, 2018 at 14:24
  • $\begingroup$ Exactly. I'm already basically using this technique in that direction, i.e. to identify which vertex I have when I grab a vert from a user selection, but what I really need to figure out is how to obtain the vertex in the other direction, like maybe a user enters some information that identifies particular vertices that I need to manipulate, and from there I need to obtain a reference to those vertices. $\endgroup$
    – Tim M.
    Commented Nov 28, 2018 at 14:59

You must log in to answer this question.

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