Best way to store data at the blend-file level?

Hey guys,

I feel like the best way to describe this is to first start with the why, so I’ll do that first.

I have a module which has a few classes, called distinguishers. The main purpose of these distinguishers is to provide their own implementation for the function is_fulfilled(obj), which takes in a mesh object and returns a boolean based on what that particular distinguisher is designed to distinguish. For example, the distinguisher, MeshDistinguisher_UVSets, has an is_fulfilled(obj) function which simply returns true if the input object has a UV map.

I will then store these distinguishers in a list, which can be manipulated by the end user through my addon panel. The user can add/remove distinguishers, as well as change their order. Doing it this way lets me automate tasks (ex. moving meshes to a collection) based on a list of conditions, rather than locking my addon to my specific use cases. Fortunately, most of this has worked so far.

Because these distinguisher objects are designed to be user-configurable, it would be critical that they sync properly with the .blend file, which is where my problem lies.

The problem

I have stored my list of active distinguisher objects in a dict, which I can then use to “re-create” new distinguisher objects. (ideally this would happen every time the dict is updated or the blend file is reloaded). I am able to serialize this dict as a json object, which seems to behave correctly. However, I can’t seem to figure out the most “best-practice” way to store this dictionary as part of the blend file.

Since what I’m trying to store is a dict, it would be most convenient if I could just store it as a dict object directly. I tried for a while to see if this was possible, but in hindsight I’m not sure if this makes sense.

I looked at EnumProperties for a little bit, but it became obvious pretty quickly that they aren’t what I’m looking for. I suppose I could store the entire serialized dict as a StringProperty, but this just feels wrong I guess? It seems like there must be a better solution to this problem.

The closest feature to what I’m looking for seems to be within bpy.types.BlendDataTexts, but I’m having trouble understanding exactly what this does or how to use it, as I can’t find any examples of this in practice. I simply don’t understand enough about Python to figure this out.

Any help/guidance/recommendations would be greatly appreciated!

The best practice is to add a custom property to bpy.types.Scene
https://docs.blender.org/api/current/bpy.props.html

1 Like

It only works if your file only contains one scene though. Unfortunately there is AFAIK currently no way to store data at a blend file level. You might want to store your settings in a json file together within the file’s directory.

There is no built-in dictionary structure using blender props. You can create a custom sructure through CollectionProperty or EnumProperty though. You can also serialize data as a json in a StringProperty.

1 Like

yes that’s true. A majority of users probably don’t utilize multiple scenes so it’s generally safe, but if you are targeting users who do you can serialize data into an external file as suggested. At my studio the artists didn’t want to deal with additional meta check-ins into perforce so I usually just tack a property onto a rarely used data block like a palette type. Some suggest using a text data block and prefixing the name with a period to ‘hide’ it from the text editor, but this only works if you already have a text data block in the file- if it’s the only one it will show up in the editor so a user could accidentally delete it.