5
$\begingroup$

How can I completely remove a objects (e.g. particle system or groups used in particle systems) in blender using python?

The problem is this: I have a script, with which I create a scene (e.g. adding some normal objects and some group of objects with a particle system). For a research study I would like to repeat that that several times, without restarting blender. So I can create a scene, delete everything, e.g. with a script like this:

import bpy
scn = bpy.context.scene
for obj in scn.objects:
    obj.select = True
bpy.ops.object.delete()

If I rerun the script to recreate the scene with objects using particle system, the latter is not shown in the scene anymore (only the placeholders of the particle system). Now I'm not sure where exactly the problem lies, but I guess not everything is immediately deleted, running the script above. Only the startup of blender helps (but that's not what I want) or pushing the purge button. The purge button seems to start the command:

bpy.ops.outliner.orphans_purge()

But I can't get this piece of code to run in the console. It says that "the context is incorrect". Is there a way to purge the unused data by python script? Thanks a lot for any help.

$\endgroup$
4
  • 1
    $\begingroup$ Possibly useful: How do I completely remove an image from my .blend file? $\endgroup$
    – David
    Mar 14, 2016 at 17:09
  • $\begingroup$ For the second part, bpy.ops.outliner... operators expect to be run from the outliner, running them from the text editor or console with give you a "context is incorrect" error. blender.stackexchange.com/a/6105/15543 $\endgroup$
    – batFINGER
    Mar 16, 2016 at 5:05
  • $\begingroup$ @batFINGER: I checked that link as well, but was not successful with implementing it, my blender crashed without any error message. The author of that post gives a hint to that problem "...which require scene bases - if you don't provide a reference to them...". Unfortunately I don't know how to provide the required reference in bpy.ops.outliner.orphans_purge(), so blender crashes. $\endgroup$
    – corbofix
    Mar 18, 2016 at 9:02
  • $\begingroup$ @David: That worked fine. Saving the scene and reopening it removes all the "orphan data". Thanks. $\endgroup$
    – corbofix
    Mar 18, 2016 at 9:17

3 Answers 3

7
$\begingroup$

To permanently delete curve data blocks that have no users without reloading the project file (which can be bit problematic at times), you can use this python code:

import bpy
from bpy import data as D

for block in D.curves:
    if block.users == 0:
        D.curves.remove(block)

It'll iterate through all data blocks of type "Curve" and delete them if they have no users.

$\endgroup$
1
  • $\begingroup$ This also works in 2.80. To remove objects linking to the block bevore removing the block itself: bpy.data.objects.remove(obj, do_unlink=True) does the trick. $\endgroup$ Jan 6, 2019 at 14:05
4
$\begingroup$

You can remove all unlinked data blocks with the following solution. This way you can make sure there will never be any memory leakage what so ever and you will not need to save a .blend file and reopen it.

First remove the meshes/objects with the following code:

for obj in bpy.context.scene.objects:
     if obj.type == 'MESH':
         obj.select = True
     else:
         obj.select = False
 bpy.ops.object.delete()

where you can check type against any of the following values according to [this documentation][1]:

[‘MESH’, ‘CURVE’, ‘SURFACE’, ‘META’, ‘FONT’, ‘ARMATURE’, ‘LATTICE’, ‘EMPTY’, ‘CAMERA’, ‘LAMP’, ‘SPEAKER’]

Then you can execute the following code snippet to remove all the unused blocks. This way you don't have to close/open Blender or save/open a .blend file:

for block in bpy.data.meshes:
    if block.users == 0:
        bpy.data.meshes.remove(block)

for block in bpy.data.materials:
    if block.users == 0:
        bpy.data.materials.remove(block)

for block in bpy.data.textures:
    if block.users == 0:
        bpy.data.textures.remove(block)

for block in bpy.data.images:
    if block.users == 0:
        bpy.data.images.remove(block)

IMPORTANT NOTE: It looks like that there is some dependencies between some data blocks such as mesh, texture, image and materials. If you do not remove the data blocks on the highest level of the hierarchy, you will not be able to remove other data blocks or you have to take the risk and remove data blocks with users more than 0. So make sure you use the code above in the following order to remove data blocks. This way you can remove all unlinked (users == 0) data blocks:

remove meshes --> remove materials --> remove textures --> remove images

The followings also have data blocks:

bpy.data.curves
bpy.data.lamps
bpy.data.cameras
$\endgroup$
5
  • $\begingroup$ This is more relevant to how you can prevent memory leakage in Blender $\endgroup$
    – Amir
    Mar 1, 2018 at 4:35
  • 1
    $\begingroup$ How this answer is different to unfa's answer 2 years ago? Better suggest an edit. Also: if not block.users: is more pythonic. $\endgroup$
    – brockmann
    Mar 1, 2018 at 12:53
  • 1
    $\begingroup$ @brockmann My answer is more comprehensive and is an extension to his answer :) $\endgroup$
    – Amir
    Mar 1, 2018 at 15:03
  • 1
    $\begingroup$ If it's just an extension (which is obvious), it's better practice suggesting an edit @Amir $\endgroup$
    – brockmann
    Mar 1, 2018 at 15:36
  • 1
    $\begingroup$ @brockmann There is also a subtle point in my newly-updated answer :) I totally believe that my answer is completely distinct from unfa's answer in the sense that it provides information that he never did :) $\endgroup$
    – Amir
    Mar 3, 2018 at 1:54
2
$\begingroup$

The following python script solved the problem in that case (all the orphaned data was removed). After that, the objects with particle system can be rebuilt and the particle system is displayed properly.

import bpy
scn = bpy.context.scene  
for obj in scn.objects:
    obj.select = True
bpy.ops.object.delete()

bpy.ops.wm.save_mainfile(filepath="/...../test.blend")
bpy.ops.wm.open_mainfile(filepath="/...../test.blend")
$\endgroup$

You must log in to answer this question.

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