12
$\begingroup$

I need to store additional information in a .blend file, that occurs only once per file. So, attaching it to, for example, bpy.types.Scene doesn't help.

Since bpy.data is an instance of bpy.types.BlendData, I tried attaching properties to bpy.types.BlendData. This failed:

>>> bpy.types.BlendData.testProp = bpy.props.StringProperty()
>>> bpy.data.testProp
(<built-in function StringProperty>, {})

Here, bpy.data.testProp is not a string, but some tuple, So it looks like registering properties on bpy.types.BlendData is not supported, like it is for bpy.types.Object:

>>> bpy.types.Object.testProp = bpy.props.StringProperty()
>>> bpy.data.objects['Camera'].testProp
''

Is it somehow possible to attach properties to bpy.types.BlendData?

Are there other ways to register global data in a .blend file?

$\endgroup$

2 Answers 2

11
$\begingroup$

Short answer: no, you cannot store per-file custom data.

A .blend file is basically just a collection of ID data blocks. There is no customizable data instance for "the file". All custom data must be associated to one of the ID blocks (or possibly eligible subdata that supports custom props, like bones or nodes).

Depending on what you actually want to do there are a number of other options:

  • You could make a dummy ID block (e.g. Text) to which you add custom data
  • Addon preferences can store custom properties for persistent settings of addon scripts
  • Scene data blocks can be a viable option, they are a sort of "root node" in most cases

It really depends on the actual use case.

$\endgroup$
3
  • $\begingroup$ Neither the second nor the third tips are viable in my case, since the data must be stored in the .blend file and there might be multiple scenes. The first tip is a bit of a hack, but that's fine with me :) $\endgroup$
    – Fab
    Commented Apr 3, 2014 at 14:04
  • $\begingroup$ Sorry I'm not clear how the first tip is done. How do you create that dummy ID block? $\endgroup$ Commented Jun 16, 2020 at 19:04
  • $\begingroup$ Could you provide a python command example? $\endgroup$ Commented Jun 16, 2020 at 20:39
1
$\begingroup$

Here is a hack I came up with which may be viable if the amount of data you need to store is small (a single float value in my case):

def setMyProp(self, value):
    self.my_prop = value
    for scene in bpy.data.scenes:
        scene.my_prop = value

def getMyProp(self):
    if self.my_prop != 0.0:
        return self.my_prop
    for scene in bpy.data.scenes:
        if scene.my_prop != 0.0:
            return scene.my_prop
    return 1.0

bpy.types.Scene.my_prop = bpy.props.FloatProperty(default = 0.0, options = {"HIDDEN"})
bpy.types.Scene.my_prop_proxy = bpy.props.FloatProperty(default = 1.0, options = {"HIDDEN"}, set = setMyProp, get = getMyProp, min = 0.01, max = 10.0)

Basically here I abuse scenes as a data container. I access the value through context.scene.my_prop_proxy. If there are multiple scenes, we see to copying the value around when setting the property. I also ignore the property from scenes where it is unset, i.e. set to some magic number default (0 in this case). Only problem I see is when people go deleting existing scenes. Probably shouldn't store anything too important with this technique.

$\endgroup$

You must log in to answer this question.

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