1
$\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
$\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.

$\endgroup$
  • $\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. Nov 28 '18 at 13:53
  • $\begingroup$ as opposed to bm.verts[n]["id"] ? $\endgroup$ – batFINGER Nov 28 '18 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. Nov 28 '18 at 14:59

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.