bmesh data "dead" when class ends

as soon as a class is done executing, the bmesh data “dies”. I still need to use that data.

this is part of a larger script, so there are unused variables. just ignore them.

import bpy
import math
import mathutils
from mathutils import Vector
import bmesh


pi = math.pi   

class Tetrahedron:
    
    def __init__(self, randomlist, index, parentprimitive = None, attachmentface = None):
        
        self.parentprimitive = parentprimitive      # the object lower down the chain to which this object is attached
        self.attachmentface = attachmentface        # the face of the parent object to which this object is attached
        self.randomlist = randomlist
        self.index = index
        
    # creates the center "head" shape
    def create(self):        
                
        origin = Vector((0,0,0))
            
        # Create mesh and object
        mesh = bpy.data.meshes.new("alien head")
        ob = bpy.data.objects.new("alien head", mesh)
        ob.location = origin
        
        # Link object to scene and make active
        scn = bpy.context.scene
        scn.objects.link(ob)
        scn.objects.active = ob

        ob.select = True
        bpy.ops.object.mode_set(mode='EDIT')
        bm = bmesh.from_edit_mesh(ob.data)
    
        a = (pi*2) / 3
        
        self.vert = []
        self.vert.append(bm.verts.new((0, 0, 2)))
        self.vert.append(bm.verts.new((math.sin(a*1) * math.sqrt(2), math.cos(a*1) * math.sqrt(2), 0)))
        self.vert.append(bm.verts.new((math.sin(a*2) * math.sqrt(2), math.cos(a*2) * math.sqrt(2), 0)))
        self.vert.append(bm.verts.new((math.sin(a*3) * math.sqrt(2), math.cos(a*3) * math.sqrt(2), 0)))

        bm.verts.ensure_lookup_table()
        bm.edges.new(( self.vert[0], self.vert[1]))
        bm.edges.new(( self.vert[0], self.vert[2]))
        bm.edges.new(( self.vert[0], self.vert[3]))
        bm.edges.new(( self.vert[1], self.vert[2]))
        bm.edges.new(( self.vert[1], self.vert[3]))
        bm.edges.new(( self.vert[2], self.vert[3]))

        self.face = []
        self.face.append(bm.faces.new(( self.vert[0], self.vert[1], self.vert[2])))
        self.face.append(bm.faces.new(( self.vert[0], self.vert[2], self.vert[3])))
        self.face.append(bm.faces.new(( self.vert[0], self.vert[3], self.vert[1])))
        self.face.append(bm.faces.new(( self.vert[1], self.vert[2], self.vert[3])))
        
        bmesh.update_edit_mesh(mesh)
        
        bpy.ops.mesh.normals_make_consistent()
        
        print(self.face[0])    # the bmesh is still alive here
        
        
t = Tetrahedron(0, 0)
t.create()
print(t.face[0])    # the bmesh dies here

console output:

<BMFace(0x000002361EA79D40), index=0, totverts=3>
<BMFace dead at 0x000002361956CD00>

this is how it works

if you need var to be pass on then use global vars !
but the Bmesh data in class itself is temporary

after the class you might need to re open a new Bmesh data in edit mode

happy bl

I don’t think global variables would work in my code, and all I’ve ever heard or been told is “DON’T USE GLOBAL VARIABLES.”

wouldn’t it be useless to open up a new bmesh. I need the data from the old one.

EDIT: I tried using a global variable, and even that doesn’t work.

EDIT2: it seems that opening a new bmesh worked, thank you.

I was able to get the face data to work, but all the verts “die” and I can’t seem to get them back.

I just quickly tried this:
Saving the bmesh in the class seems to keep it alive.
Maybe that is enough for you?

import bpy
import math
import mathutils
from mathutils import Vector
import bmesh


pi = math.pi   

class Tetrahedron:
    
    def __init__(self, randomlist, index, parentprimitive = None, attachmentface = None):
        
        self.parentprimitive = parentprimitive      # the object lower down the chain to which this object is attached
        self.attachmentface = attachmentface        # the face of the parent object to which this object is attached
        self.randomlist = randomlist
        self.index = index
        
    # creates the center "head" shape
    def create(self):        
                
        origin = Vector((0,0,0))
            
        # Create mesh and object
        mesh = bpy.data.meshes.new("alien head")
        ob = bpy.data.objects.new("alien head", mesh)
        ob.location = origin
        
        # Link object to scene and make active
        scn = bpy.context.scene
        scn.objects.link(ob)
        scn.objects.active = ob

        ob.select = True
        bpy.ops.object.mode_set(mode='EDIT')
        bm = bmesh.from_edit_mesh(ob.data)
        
        #SAVE BM
        self.bm = bm

        a = (pi*2) / 3
        
        self.vert = []
        self.vert.append(bm.verts.new((0, 0, 2)))
        self.vert.append(bm.verts.new((math.sin(a*1) * math.sqrt(2), math.cos(a*1) * math.sqrt(2), 0)))
        self.vert.append(bm.verts.new((math.sin(a*2) * math.sqrt(2), math.cos(a*2) * math.sqrt(2), 0)))
        self.vert.append(bm.verts.new((math.sin(a*3) * math.sqrt(2), math.cos(a*3) * math.sqrt(2), 0)))

        bm.verts.ensure_lookup_table()
        bm.edges.new(( self.vert[0], self.vert[1]))
        bm.edges.new(( self.vert[0], self.vert[2]))
        bm.edges.new(( self.vert[0], self.vert[3]))
        bm.edges.new(( self.vert[1], self.vert[2]))
        bm.edges.new(( self.vert[1], self.vert[3]))
        bm.edges.new(( self.vert[2], self.vert[3]))

        self.face = []
        self.face.append(bm.faces.new(( self.vert[0], self.vert[1], self.vert[2])))
        self.face.append(bm.faces.new(( self.vert[0], self.vert[2], self.vert[3])))
        self.face.append(bm.faces.new(( self.vert[0], self.vert[3], self.vert[1])))
        self.face.append(bm.faces.new(( self.vert[1], self.vert[2], self.vert[3])))
        
        bmesh.update_edit_mesh(mesh)
        
        bpy.ops.mesh.normals_make_consistent()
        
        print(self.face[0])    # the bmesh is still alive here
        
        
t = Tetrahedron(0, 0)
t.create()
print(t.face[0])    # the bmesh dies here

cannot print from bmesh after it has been created like that
it is gone
and again you should erase the instantiated data with free… for bmesh

use bpy.data instead
to access data or use polygon bmesh

happy bl

Thank’s, that was the issue.