I've been struggling with a bmesh problem for a while now and I can't wrap my head around it. When I free my bmesh data and try to make a new bm instance with the same object, it points to the old freed data.
Simplified code snippet:
import bpy
import bmesh
obj = bpy.data.objects["Cube"]
me = obj.data
bm = bmesh.from_edit_mesh(me) #creates new bm
verts = bm.verts
for vert in verts:
vert.co[2] += 1
bmesh.update_edit_mesh(obj.data)
bm.free()
me = obj.data
bm = bmesh.from_edit_mesh(me) #points to old dead bm (memory pointer is the same)
verts = bm.verts
for vert in verts:
vert.co[2] -= 1
bmesh.update_edit_mesh(obj.data)
bm.free()
One thing that does work is switching the mode twice like this:
import bpy
import bmesh
obj = bpy.data.objects["Cube"]
me = obj.data
bm = bmesh.from_edit_mesh(me) #creates new bm
verts = bm.verts
for vert in verts:
vert.co[2] += 1
bmesh.update_edit_mesh(obj.data)
bm.free()
bpy.ops.object.editmode_toggle()
bpy.ops.object.editmode_toggle()
me = obj.data
bm = bmesh.from_edit_mesh(me) #creates new bm
verts = bm.verts
for vert in verts:
vert.co[2] -= 1
bmesh.update_edit_mesh(obj.data)
bm.free()
This is however something I really don't want to do because it's just ugly and it shouldn't be necessary.
Running the second script twice will crash unless you switch mode twice before running it again.
Turning just this part into an operator will also crash if you run it twice without switching modes twice between executions.
obj = bpy.data.objects["Cube"]
me = obj.data
bm = bmesh.from_edit_mesh(me) #creates new bm
verts = bm.verts
for vert in verts:
vert.co[2] += 1
bmesh.update_edit_mesh(obj.data)
bm.free()
How can I avoid this problem in a nicer way? I don't want people using my add-on to have to switch mode twice if they want to execute the same operator twice. But I also would like to not switch modes constantly in my code
But thank you, it did solve my problem and I learned some more about inner workings
– Singulasar Aug 23 '19 at 12:29bmesh.from_edit_meshautomatically frees the bm when edit mode is toggled. You could try usingbm.from_mesh. – BlenderEnthusiast Oct 07 '23 at 00:04