Page MenuHome

Ability to Reset Blender to an 'empty-file'
Closed, ResolvedPublic

Description

This would allow you to ask for a new, Blend file that contains no data.
This is mainly useful to Python developers (use case from developer question)

If for example you're writing a script that loads a Blend file and renders it (or saves it to a new file).

Removing all data in a file is not very convenient.

  • Calling bpy.ops.wm.read_homefile() will load the users startup.blend, which may contain any number of data-blocks, so there is no certainty that the file can be easily cleared afterwards. Note that a custom file can be passed but this means the developer has to keep an empty file available.
  • Calling bpy.ops.wm.read_factory_settings() will give a predicable outcome, however it also re-initializes the user-prefereces, reloads fonts, all add-ons, so this is also not great either.

Here's an example of how this can be done currently.

eg:

import bpy

def reset_blend():
    bpy.ops.wm.read_factory_settings()

    for scene in bpy.data.scenes:
        for obj in scene.objects:
            scene.objects.unlink(obj)

    # only worry about data in the startup scene
    for bpy_data_iter in (
            bpy.data.objects,
            bpy.data.meshes,
            bpy.data.lamps,
            bpy.data.cameras,
            ):
        for id_data in bpy_data_iter:
            bpy_data_iter.remove(id_data)

reset_blend()

Instead, we could have an option to reset with no data. eg:

eg:

bpy.ops.wm.read_homefile(empty=True)
bpy.ops.wm.read_factory_settings(empty=True)

Internally this will likely just remove the data as the script above is doing, however it can be done in one place so developers don't have to do themselves.

Details

Type
To Do

Event Timeline

Campbell Barton (campbellbarton) changed Type from Bug to To Do.
Campbell Barton (campbellbarton) renamed this task from Ability to reset Blender to an empty file. to Ability to Reset Blender to an 'empty-file'.
Campbell Barton (campbellbarton) raised the priority of this task from to Needs Triage by Developer.
Campbell Barton (campbellbarton) triaged this task as Normal priority.
RG Dengate (rdengate) claimed this task.

Hi there,

I've attached a git diff that addresses this. This is my first time coding in Blender and so I'm sure my fix is not the most elegant solution. I'm happy to make changes based on feedback. Likewise please let me know if there are docs/tests I should update (I couldn't find any).

Hope this helps.

Thanks for checking on this, some requested change.

  • clearing the file should be made into a function.
  • the while loops - while(cam != bmain->camera.last), why keep the last camera?
  • the next variables can be in the while loops scope (no need to have them above).
  • use tabs instead of spaces.

Thanks Campbell! I will address those changes soon.

From the description I understand that this will not create completely empty blend file which would still contain user settings, space data, sculpt/texture brushes?

@Mikhail Rachinskiy (alm) User preferences are kept if using read_homefile, but not if using read_factory_settings. Either way, I believe custom sculpt brushes are removed. I'm not sure what you mean by space data, sorry (I'm still learning Blender).

@Campbell Barton (campbellbarton) In the loop in which I delete all the cameras in the scene (and the loops for meshes etc, they're all the same) I'm trying to delete every camera, and the end result is that they are all deleted, but it's very clumsy. I end up freeing the last camera in the scene after the while loop has ended which is not intuitive. What I really want to do is iterate over every camera in the scene and delete it, preferably using "for (cam = bmain->camera.first; cam; cam = cam->id.next)" but that doesn't work because id.next is read from the camera, which then can't be deleted during the loop. I've added comments in the code for this to make it clearer, but if you know how to improve this I'm happy to change it.

Here is a patch with the changes discussed:

. Please let me know if there are other changes I should make. Thanks for the code review :-)

Aha, I see what you mean! Thanks, that's much better. Updated diff here:

@RG Dengate (rdengate) So it’s just using a “factory settings” blend file with all default screen layouts, default brushes etc. This is unfortunate, I was searching for a way to create a completely empty blend file. *sigh*

@Mikhail Rachinskiy (alm) I believe it's using a factory settings blend file if using read_factory_settings, or using the user's startup.blend if using read_homefile. In both cases it's deleting data from the file after it's loaded (if empty is passed as an argument). What data did you need to delete exactly? I'm trying to understand what you're after. Since you need a completely empty file, why can't you create one and set it as the startup.blend, then use read_homefile?

What data did you need to delete exactly?

  • All objects and object data: Objects, Meshes, Materials, Textures, Lamps
  • Default data: Brushes, Line styles, Worlds
  • Scene ID properties (if the are any)
  • Screens (except one)
  • Space data (with “Clean-up Space-data” operator)

I need this for an asset blend file.

Since you need a completely empty file, why can't you create one

That is what I am doing at the moment, very tedious, and even if I make special script for that, I would still need to track additional default data in new Blender versions.

Well my use case (or my requirements rather) quite specific, I guess factory settings blend file would do just fine for general purpose.

That makes sense. Thanks for the info. It does sound like a very specific use case.

@Mikhail Rachinskiy (alm), its now possible to save individual data blocks - https://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.78/Add-ons#New_APIs

However think your suggestion is reasonable for an 'empty' file.

@Campbell Barton (campbellbarton) its now possible to save individual data blocks

May I say that it is super duper cool and exactly what I was searching for! But why there is no option to save compressed?

As for the topic, I read the use case on stackexchange and I do not understand why do we need to read_homefile or read_factory_settings if we could just use bpy.ops.wm.open_mainfile(filepath=bpy.data.filepath) instead?
That way we are not limited to startup.blend and default factory settings blend files.

@Campbell Barton (campbellbarton) Should empty=True for read_homefile and read_factory_settings delete more data than in my implementation, i.e. to get the file to the stage Mikhail is talking about (a completely empty file)?

@RG Dengate (rdengate), yes, I think it should give something as close to an empty file as possible.

@Mikhail Rachinskiy (alm), added support for writing compressed blend files rB57d98a80

@RG Dengate (rdengate) @Campbell Barton (campbellbarton), what’s the use case of this feature? For a given use case open_mainfile is a much better fit.

Thanks for “save compressed” option Campbell.

@Mikhail Rachinskiy (alm), not sure how open_mainfile relates? - making an empty file is mainly useful when you want to create a file from scratch and save it without having to manually clear the data.

not sure how open_mainfile relates?

In the description to this task this stackexchange question is specified as a use case for this feature, where open_mainfile is a much better solution.

empty file is mainly useful when you want to create a file from scratch and save it without having to manually clear the data.

Isn't libraries.write were created specifically for this purpose?

My point is: if we want to clear newly loaded data we can use open_mainfile, if we want to write to an empty blend file we can use libraries.write. Where is the use case for read_factory_settings(empty=True)?

Perhaps I should suspend work on this until a clear use case emerges. Do you agree @Campbell Barton (campbellbarton)?

@Campbell Barton (campbellbarton) What's the current status of this task? I'm interested in contributing to this hack.

@Mikhail Rachinskiy (alm) however you managed to solve your particular use-case, the ability to reset Blender to a blank state is quite reasonable.

We have automated tests for example, where it would be useful to be able to start with a blank Blender state for each test.


@Alvis (wongalvis) - nobody is working on this currently.

@Campbell Barton (campbellbarton) as I understand this option performing data cleanup after Factory Settings file is loaded. Which means as soon as Factory Settings would receive new default data—this feature will become obsolete and need to be updated.

Isn't it better to leave this task to automated tests?

Which means as soon as Factory Settings would receive new default data—this feature will become obsolete and need to be updated.

Factory settings are changed very rarely, its possible this function will need updating when they do, this doesn't make it obsolete.

As for tests doing this, yes - they do this already, its quite awkward IMHO.

./tests/python/batch_import.py:59:
./tests/python/bl_mesh_modifiers.py:128:
./tests/python/bl_run_operators.py:320:

All duplicate similar logic, which is good enough reason IMHO for Blender to have the functionality built-in.

Then what are criteria for an empty file?
I think we all can agree that a file with objects, object data, materials and textures cannot be empty.

But what about brushes? Freestyle linestyles? Screens? Render layers? Worlds?

@Mikhail Rachinskiy (alm), right - all of this would be removed (or not created in the first place). Except a single empty scene.

nobody picked this up and maybe wasn't that simple.
committed rBdf7f6a3e2e91a7ad27f8ca2b2b43a6c51da8c2c9 for 2.79