I have a bmesh holding some geometry. I store pointers to some of the vertices because I need them later.
Then I add a sphere using bmesh.ops.create_icosphere
.
Afterward, when accessing the previously stored vertices, I get:
ReferenceError: BMesh data of type BMVert has been removed
Since I am adding new geometry, I expected the old geometry to remain valid. Does the method switch to object mode and back internally?
Here's a minimal working example showing the issue. To test, select the default cube, then run the script. It will show that all original verts, stored in orig_verts, are dead.
import bpy
import bmesh
# Get the active mesh
me = bpy.context.object.data
# Get a BMesh representation
bm = bmesh.new() # create an empty BMesh
bm.from_mesh(me) # fill it in from a Mesh
# Keep a list of the original verts:
orig_verts = [v for v in bm.verts]
bmesh.ops.create_icosphere(
bm,
diameter=3,
subdivisions=2 )
for v in orig_verts:
print("orig_vert", v, v.is_valid)
for v in bm.verts:
print("new bm verts:", v, v.is_valid)
# Finish up, write the bmesh back to the mesh
bm.to_mesh(me)
bm.free()
Output for the standard cube:
orig_vert <BMVert dead at 0x7f27d6bf4db0> False
orig_vert <BMVert dead at 0x7f27d6bf4f60> False
orig_vert <BMVert dead at 0x7f27d6bf4d20> False
orig_vert <BMVert dead at 0x7f27d6bf4d50> False
orig_vert <BMVert dead at 0x7f27d6bf4cc0> False
orig_vert <BMVert dead at 0x7f27d6bf4ea0> False
orig_vert <BMVert dead at 0x7f27d6bf4de0> False
orig_vert <BMVert dead at 0x7f27d6bf4810> False
new bm verts: <BMVert(0x7f27d41f8650), index=0> True
new bm verts: <BMVert(0x7f27d41f8688), index=1> True
new bm verts: <BMVert(0x7f27d41f86c0), index=2> True
...
Using version 2.93.4.
Update: When I set subdivisons to a number lower than 2, it works! However, I'd like to have more subdivisions...
Update2: Note that my goal is to manipulate certain original vertices (let's say vertex 2) after adding a sphere. Note also that my real mesh is far more complex than what I have mentioned here, so storing vertices is really the best way to go AFAIK, however as mentioned above, the pointers point to invalid dead vertices after adding more geometry. I've also noticed similar behavior with other bmesh.ops (for example bmesh.ops.subdivide_edges).
A possible workaround might be to find the new vertex at the position of the original vertex. Ugly, though...