3
$\begingroup$

I have a Blender Python script that uses a loop to sequentially load and render viewpoints of multiple OBJ files that I generally try to run from the command line. However, if I have Blender open, eventually it starts using up more and more memory and things will crash for processing a large amount of OBJ files. I've gone through several Stack Overflow answers to figure out how to delete the OBJ files I'm importing as well as the camera settings and such that I set for each viewpoint render, but none of them seem to delete everything. I've tried the following answers:

https://blender.stackexchange.com/a/101319/103462 and https://blender.stackexchange.com/a/27235/103462

However, each time I hit run on my script, the stats under "Current File" keep going up, thus progressively increasing memory usage:

enter image description here

How do I clear out those camera, material, mesh, objects, etc. for each iteration of processing loop?

My code is located here: https://pastebin.com/HDxQKByY

$\endgroup$
1
  • 1
    $\begingroup$ bpy.ops.outliner.orphans_purge() ? $\endgroup$
    – Ron Jensen
    Aug 30, 2020 at 20:07

2 Answers 2

2
$\begingroup$

So I used this trick a while back when working on the following script for an addon: https://github.com/torrinworx/Blend_My_NFTs/blob/main/src/Main_Generators/Exporter.py

Every time you import an object to your scene run this function after the render method is complete:

def deleteAllObjects():
    """
    Deletes all objects in the current scene
    """
    deleteListObjects = ['MESH', 'CURVE', 'SURFACE', 'META', 'FONT', 'HAIR', 'POINTCLOUD', 'VOLUME', 'GPENCIL',
                     'ARMATURE', 'LATTICE', 'EMPTY', 'LIGHT', 'LIGHT_PROBE', 'CAMERA', 'SPEAKER']

    # Select all objects in the scene to be deleted:

    for o in bpy.context.scene.objects:
        for i in deleteListObjects:
            if o.type == i:
                o.select_set(False)
            else:
                o.select_set(True)
    # Deletes all selected objects in the scene:

    bpy.ops.object.delete() 

deleteAllObjects()

Here is the doc where I sourced the object type list deleteListObjects: https://docs.blender.org/api/current/bpy.types.Object.html?highlight=mesh%20curve%20surface%20meta%20font%20hair%20pointcloud%20volume%20gpencil%20armature%20lattice%20empty%20light%20light_probe%20camera%20speaker#bpy.types.Object.type

Here is the doc for the op bpy.ops.object.delete(): https://docs.blender.org/api/current/bpy.ops.object.html?highlight=bpy%20ops%20object%20delete#bpy.ops.object.delete

$\endgroup$
1
$\begingroup$

Here is a function that can do for you. Note, the passage on the group node is multi-pass, as the group nodes can contain other group nodes in turn, so a single pass is not sufficient in that case

import bpy

def mega_purge():
    orphan_ob = [o for o in bpy.data.objects if not o.users]
    while orphan_ob:
        bpy.data.objects.remove(orphan_ob.pop())
        
    orphan_mesh = [m for m in bpy.data.meshes if not m.users]
    while orphan_mesh:
        bpy.data.meshes.remove(orphan_mesh.pop())
        
    orphan_mat = [m for m in bpy.data.materials if not m.users]
    while orphan_mat:
        bpy.data.materials.remove(orphan_mat.pop())

    def purge_node_groups():   
        orphan_node_group = [g for g in bpy.data.node_groups if not g.users]
        while orphan_node_group:
            bpy.data.node_groups.remove(orphan_node_group.pop())
        if [g for g in bpy.data.node_groups if not g.users]: purge_node_groups()
    purge_node_groups()
        
    orphan_texture = [t for t in bpy.data.textures if not t.users]
    while orphan_texture:
        bpy.data.textures.remove(orphan_texture.pop())

    orphan_images = [i for i in bpy.data.images if not i.users]
    while orphan_images:
        bpy.data.images.remove(orphan_images.pop())

    orphan_cameras = [c for c in bpy.data.cameras if not c.users]
    while orphan_cameras :
        bpy.data.cameras.remove(orphan_cameras.pop())
        
mega_purge() #call the function

Note: You can put many other things into this function for example bpy.data.scenes, bpy.data.lights etc. in the same way you see this function structured.

Another important thing is the hierarchy of this cleanup, if we started with deleting a Material, it wouldn't work. Even worse if starting from an image.

This is because the image can be linked to a material or texture, and as long as the material or texture is not deleted, it will turn out that that image is still linked to something so it will not be deleted.

$\endgroup$
1
  • $\begingroup$ This answer deserves it's own question about cleaning up unowned/orphan objects in script, and it'd be great to dig into how it differs from bpy.ops.outliner.orphans_purge. $\endgroup$
    – mghicks
    Jan 7 at 16:18

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .