Page MenuHome

No-Scene-Update Property Option
Needs RevisionPublic

Authored by Jack Andersen (jackoalan) on Apr 18 2014, 10:25 PM.

Details

Summary

I've written an add-on that makes heavy use of ID properties for storing and retrieving custom game-engine metadata within .blend files. I've always been annoyed by the fact that Blender seems to reload the entire scene anytime a property is set with a new value. My scenes potentially have hundreds of materials, so the reload operation is lengthy while my graphics driver re-compiles *all* the 3D view shaders whenever I set a property.

I understand that it is a safe assumption to reload the scene anytime a property is set, but the properties in my particular add-on have absolutely no effect on the content of the scene. To mitigate the issue, I have added a new RNAProperty flag to Blender called 'NO_SCENE_UPDATE'. It's used like so:

class MyAddonProps(bpy.types.PropertyGroup):
    prop1 = bpy.props.IntProperty(name="Prop One", options={'ANIMATABLE', 'NO_SCENE_UPDATE'})

The biggest issue with this approach is I've been unable to make it backwards-compatible with non-patched Blender builds (which insist on throwing an exception for unknown option enumerations); so my add-on does this to exclude the property in vanilla Blender (I did the mod in a separate Git branch):

PROP_OPTS = {'ANIMATABLE'}
if bpy.app.build_branch == b'no_scene_update (modified)':
    PROP_OPTS = {'ANIMATABLE', 'NO_SCENE_UPDATE'}

class MyAddonProps(bpy.types.PropertyGroup):
    prop1 = bpy.props.IntProperty(name="Prop One", options=PROP_OPTS)

I realise this is a tricky proposition to implement, but it has helped my productivity tremendously.

Diff Detail

Event Timeline

One other thing: it seems that all flag bits are now used up. It might be time to make it an unsigned long long

long long is not portable across platforms, afair. int64_t is the way to go.

As for the flag -- IMO it's really up to the granular dependency graph. This patch is doing the thing which depsgraph is assumed to do..

@Lukas Tönne (lukastoenne), making sure you're summoned here, bet you've got comments here :)

I agree with @Sergey Sharybin (sergey)'s concern: this is basically a specialized workaround for the insufficient DAG. We have similar hacks in a number of places, e.g. updating meshes for particle rendering, explicit object eval for smoke/particle emitter substeps, ... These never work beyond the simplest cases (reason why it's a dependency graph) and cause major headaches sooner or later.

In this particular case you may get away with disabling all dependency updates because you know what you are doing. But adding a generic flag like that will tempt others to do the same in cases that are not so clear cut. At some point we will then have to remove it again and scripters' wrath will come upon us ...

According to a comment within rna_access.c, the update tag occurs due to the assumption that a driver is attached to the ID property. Would there be a way for the dependency graph to check whether or not there is a driver attached before tagging?

@Jack Andersen (jackoalan) I don't think think checking for drivers is feasible: This is not about whether a driver (in the same ID datablock) updates the ID property. Rather it's whether a driver in some other ID datablock reads the ID property to drive something. Detecting this would require looping over all the ID datablocks, for all such ID properties, which is prohibitively expensive. It's just the sort of thing a dependency graph is supposed to solve, but doesn't atm.

Sergey Sharybin (sergey) requested changes to this revision.Jul 18 2014, 8:50 AM