Where to put "global" properties

Scripting in Blender with Python, and working on the API

Moderators: jesterKing, stiv

Post Reply
mini3d
Posts: 0
Joined: Wed May 08, 2013 3:26 pm

Where to put "global" properties

Post by mini3d » Wed May 08, 2013 3:44 pm

Blender python docs says custom properties for objects are added like so:
bpy.types.Scenes.custom_float = bpy.props.FloatProperty(name="Test Prob")

I want to add a property that is common for all scenes but still gets saved in the .blend file. I have looked in bpy.types.* but I have not found a good class to use for this.

The property I want to save is what vertex-data (position, color, uv-coords and so on...) should be exported by an export script I am writing.

Where would be a good place to store these properties?

Any help on this would be greatly appreciated, thank you!

CoDEmanX
Posts: 0
Joined: Sun Apr 05, 2009 7:42 pm
Location: Germany

Post by CoDEmanX » Wed May 08, 2013 7:09 pm

Sounds like those properties should be properties of the export operator, and you would set them in a panel in the export dialog.

About a place for global properties: i've seen people using bpy.types.WindowManager, that's probably the best one but still not a nice solution.
I'm sitting, waiting, wishing, building Blender in superstition...

mini3d
Posts: 0
Joined: Wed May 08, 2013 3:26 pm

Post by mini3d » Wed May 08, 2013 8:10 pm

Thank you for the reply, CoDEmanX!

You confirm my suspicions... Putting the settings in the operator is what I did at first. It seems operator properties are not written to the blend file though, and that is something that I really need... I also tried the WindowManager, but the same thing there, it does not seem to get saved.

This gets saved:
bpy.context.object["test_prop"]

This does not:
bpy.context.window_manager["test_prop"]

I guess I will put these properties in bpy.types.Scene for now!

Thank again for the reply, now I know what my options are!

CoDEmanX
Posts: 0
Joined: Sun Apr 05, 2009 7:42 pm
Location: Germany

Post by CoDEmanX » Thu May 09, 2013 12:09 am

These are ID props:

bpy.context.object["test_prop"]
bpy.context.window_manager["test_prop"]

Did you also try "real" props?

bpy.types.WindowManager.test_prop = bpy.props.StringProperty()
bpy.context.window_manager.test_prop = "foobar"

I wonder what you wanna store? You could always use an export preset to re-use certain settings...
I'm sitting, waiting, wishing, building Blender in superstition...

mini3d
Posts: 0
Joined: Wed May 08, 2013 3:26 pm

Post by mini3d » Thu May 09, 2013 5:55 pm

True, I tried the real id props as well... same result. I am pretty sure I am doing it right. It works for scene, object and the like, just not for operators or window managers.

As a side note, the documentation suggests that only the id-properties are saved anyway (the very bottom of the page under summary:
http://wiki.blender.org/index.php/Doc:2 ... Properties

I looked into the operator presets, and that could be a solution. They seem to be stored along with application configuration however and not with the .blend file. This might something that has changed recently with blender however, because I recall this working differently before...

Here is a link to a test script that I wrote for my export script. It only includes the part that creates the panel for setting the vertex attributes that get exported. The actual exporter is not done yet...

Image
https://gist.github.com/mini3d/5548092

It uses the new UI_List thing so it requires v 2.66 to run. Paste it in the blender test window and execute if you want to see what it does. The panel appears under the scene settings in the properties panel.

For the final version it will be possible to create multiple vertex layouts and set for each object in the scene which one to use when exporting.

The idea is that this mesh-data is exported into the correct format to plug straight into a custom shader program on the mini3d game engine side...

If you have any solution to the more general problem, I would be grateful to hear it!

For now, I think storing this data per scene is okay. Most people will probably only use the script to export single scenes anyway!

thanks!

CoDEmanX
Posts: 0
Joined: Sun Apr 05, 2009 7:42 pm
Location: Germany

Post by CoDEmanX » Thu May 09, 2013 11:34 pm

line 95 gives me an out of range error:

active_attribute = bpy.context.scene.test_collection[bpy.context.scene.active_collection_index]


maybe window manager and certain other types don't allow persistent props, that could be a legit limitation.

Presets are basically simple py scripts which set property values. They are stored on windows in %appdata%\Blender Foundation\Blender\2.XX\scripts\presets\ (XX=blender subversion)
So as the version changes, the presets will disappear in new blender, but you could copy them to new dir. Not sure if collectionprops are fully supported though.

You could put the attribute type dropdown directly into the template_list, also the name, but there needs a label for every entry so user can select one in list.

Is this some sort of data mapping tool? Or rather about shaders? Maybe you can export node setups in the latter case
I'm sitting, waiting, wishing, building Blender in superstition...

mini3d
Posts: 0
Joined: Wed May 08, 2013 3:26 pm

Post by mini3d » Fri May 10, 2013 11:22 pm

Thanks, CoDEmanX!

Those are great suggestions. You mentioned the shader nodes which made me realize i should store these properties with the materials instead. Then I can use the presets you pointed out instead of storing the settings in the blend files. Since blender links materials to meshes by default this will work great!

I will post some details here once I am done as a reference for others. I imagine there are more people around who are looking for solutions to similar problems!

Thanks again for all your help, It really helped improve the solution!

mini3d
Posts: 0
Joined: Wed May 08, 2013 3:26 pm

Post by mini3d » Mon May 20, 2013 2:28 pm

Ok, so here is what I ended up doing after trying a lot of different solutions...

Presets can only be used for operators. It works by adding the 'PRESETS' flag for the bl_options variable for the operator (see blender operator python documentation for details).

Some of the panels in the UI also have presets functionality (such as the subsurface scattering settings in the material properties panel)

These rely on extending the class AddPresetBase found in the blender startup scripts:
...\Blender Foundation\Blender\2.66\scripts\startup\bl_operators\presets.py
AddPresetBase works by serializing a description of the panel to an xml-file in a presets folder on the user hard drive.

This functionality can theoretically change without warning so it is probably unwise to use it by including it directly.

You can copy the presets.py to your own add-on folder and use the code from there but in my case the liberal copyright on my add-on scripts does not allow me to mix in presets.py

So what I ended up doing was creating a separate scene object for storing my "global variables".

I do this by first adding the properties to a scene object:

Code: Select all

bpy.types.Scene.my_prop = bpy.props.StringProperty()
then I use a function to get the settings scene whenever I need to read or write to the my_prop:

Code: Select all

def getSettings():
    settings = bpy.data.scenes.get("Settings")
    if settings is None:
        settings = bpy.data.scenes.new("Settings")
    
    return settings
It is then possible to access the my_prop on the settings object:

Code: Select all

getSettings().my_prop = "Hello World!"
This adds a bit of overhead, but it works well in practice...

CoDEmanX
Posts: 0
Joined: Sun Apr 05, 2009 7:42 pm
Location: Germany

Post by CoDEmanX » Mon May 20, 2013 9:29 pm

an extra scene just for settings seems like overkill yeah, but i worry there is no real good solution for this. Maybe we ask the devs to add bpy.types.GlobalProperties or something like that...
I'm sitting, waiting, wishing, building Blender in superstition...

Dairin0d
Posts: 0
Joined: Thu Jun 23, 2011 8:07 pm

Post by Dairin0d » Sun Jun 09, 2013 12:13 am

I've encountered a similar problem (storing global settings of an addon). I ended up storing the settings in the Screen, since Undo/Redo does not affect screens.

CoDEmanX
Posts: 0
Joined: Sun Apr 05, 2009 7:42 pm
Location: Germany

Post by CoDEmanX » Sun Jun 09, 2013 6:43 am

if the settings are addons-related, you should use the addon preferences

http://www.blender.org/documentation/bl ... ences.html
I'm sitting, waiting, wishing, building Blender in superstition...

Post Reply