Object manipulation and removal during animation

I want to make animation in blender 2.8 by using premade stl files. I do that by importing the stls frame by frame. See code below.

In order to save memory I delete the old object before I load a new stl. This goes well for a few frames. Then a EXCEPTION_ACCESS_VIOLATION error is thrown during the Dependency Graph evaluation.

I guess I’m not deleting objects at the best time. Any ideas when to delete the old objects in my usecase? Maybe I should delete objects using another of the bpy.app.handlers?

def doatnewframe(scene):
surfacename=‘isoSurfaceTopo’

# delete old object created at previous frame
for o in bpy.data.objects:
	if surfacename in o.name:
		o.parent = None
		bpy.data.objects.remove(o, do_unlink=True,do_ui_user=True)

# import new object from stl for current frame
timedir = scene.frame_current
stlfilename=os.path.join(bpy.context.scene["datadir"],timedir,surfacename+'.stl')
bpy.ops.import_mesh.stl(filepath=stlfilename)

# get object with newly loaded stl
obnew=[o for o in bpy.context.scene.objects if o.select_get()][0] 

# adjust position of newly imported stl
origo=bpy.data.objects['rocketparent']
obnew.parent = origo
obnew.matrix_world = mathutils.Matrix.Translation([0,0,1.5]) @ origo.matrix_world

# link newly loaded object to scene
bpy.context.scene.collection.objects.link(obnew)

head,tail = os.path.split(bpy.data.filepath)
bpy.context.scene[“datadir”] = os.path.join(head,‘isoSurface’)
bpy.context.scene[“timedirs”] = next(os.walk(bpy.context.scene[“datadir”]))[1]

bpy.app.handlers.frame_change_pre.clear()
bpy.app.handlers.frame_change_pre.append(doatnewframe)

I think handlers are a bad choice for modifying the scene’s data- it’s really best to avoid using them altogether if you can.

Here’s an addon that does something similar to what you’re doing, but with OBJs. https://github.com/neverhood311/Stop-motion-OBJ

Maybe you can adapt the code to do what you need?

Thanks for the suggestion. The Stop-motion code is somewhat similar to what I want to do. Unfortunately the code doesn’t deal with removing objects. It seems to load all stl frames into memory. I can easily to the same with my current method but would run out of memory.

Handlers work fine.
I think the problem is that you are only deleting the object but not the mesh.

bpy.data.meshes.remove(YourOldMesh)

should do the trick.

Hi Lumpengnom,
Good suggestion, but I did include mesh removal. Still same problem.
Code snippet is:

for o in bpy.data.objects:
if surfacename in o.name:
o.parent = None
bpy.data.objects.remove(o, do_unlink=True,do_ui_user=True)

for m in bpy.data.meshes:
if surfacename in m.name:
bpy.data.meshes.remove(m)

BR
Jens

You might be getting in trouble due to removing an object from bpy.data.objects while also iterating over the same list. Try doing it in two phases: 1) go through bpy.data.objects to make a separate list R of objects to remove, 2) iterate over R and delete each of the objects.

Yes, or just slice like this:

for o in bpy.data.objects[::]:

1 Like