From BlenderWiki

Jump to: navigation, search
Note: This is an archived version of the Blender Developer Wiki. The current and active wiki is available on wiki.blender.org.

About

The depsgraph (dependency graph) and evaluation system in Blender, while sufficient for a number of important use cases, is severely limited for more advanced usage, and/or is a source of continual pain for riggers hoping to set up more advanced procedural setups and abstractions.

This page aims to document some of the failings of the current system, including use cases which commonly fail, acting as a both a springboard of ideas to incorporate, but also for validating that we haven't built another dud that will need to be rectified sooner rather than later.

Main Problem Areas

"Depsgraph" Specific:

  1. Only Objects and Object.Data are handled by Depsgraph - All other dependencies between other ID datablocks are ignored.
  2. Granularity of relationships represented too coarse - Only Object-level dependency representation and evaluation (forced by "tagging" approach) means that users end up creating "cyclic dependencies" far too often.
  3. Layers - When layers change (either by UI actions, or by animation), updates are often not properly flushed to newly visible layers

"Evaluation" Specific (partly as result of Depsgraph implementation, but also vica versa):

  1. Non thread-safe - where data is used by multiple users (i.e. material shared by multiple objects), any animation on the users which animates the data will edit the original, causing conflicts (last writer wins)
  2. Single-threaded only - see previous point. Main problem here is that we loose possibility of speedups, and/or being able to just evaluate some stuff off to the side (i.e. baking tools)
  3. Dealing with instances is dodgy - nested groups, group duplicators/instances, proxies, etc.
  4. Update Handling - how relevant updates get performed and/or when this takes place

"Library linking?" related:

  1. Only single instance of proxified character from a rig file possible per scene

"Physics Sim" Integration:

  1. Cache management - dodgy management of when caches get cleared, how much gets cleared
  2. Modifiers, etc. - how physics sims fit within the overall workflow, and their representation as modifiers...

Non-Object Datablocks Ignored

Some common examples (many more variations on this theme possible):

  • Material settings (i.e. diffuse colour) driving location of object
  • Lamp settings (i.e. distance) driving location of object
  • Scene setting (commonly frame number) driving anything (e.g. object location) not working. Arguably in this particular case, that's exactly what standard keyframe animation is (but without the possibility of using NLA), but somehow, in "TD" mode, users suddenly like to start doing everything themselves ;)
  • Material settings (perhaps even a custom property) driving lamp settings
  • Custom properties on world/scene being used to drive stuff (i.e. object layer membership)

Granularity of Relationships

Most of these bugs either manisfest themselves as "lag" bugs (as in, "visible lagging" in viewport while playing with these things, or "delayed refresh" after cancelling a transform).

Some common problems riggers run into:

  • For Spline IK, need to have "deformation" armature and "control" armature, with curve deform wedged in the middle (i.e. control deforms curve, and curve then affects some bones in armature)
  • We have two bones, a and b. a has CopyLoc to b, while b has CopyRot to a. (NOTE: this is not a real setup, but there have been many real setups which have had an element of this, just perhaps a bit more indirect)
  • Rig setting/bone drives some setting on another bone in same rig
    • ... driven property is constraint influence on another bone
    • ... driven property is bbone blending, but those settings are located on armature data, NOT pose data; armature data gets evaluated first by default
    • ... trying to use drivers to do what constraints do (most of the time completely unwarranted and a braindead idiotic fallacy, but yet, some people still do it)

Layers

The layers system serves several purposes:

  1. Organisational - grouping objects by purpose (e.g. geometry vs rigs, characters vs props)
  2. Controlling visibility - a coarse method for showing/hiding groups of related objects with a single click (e.g. show/hide rig controls, show/hide character geometry, show/hide underlying rig mechanics)
  3. Hiding unused objects (e.g. widget shapes, metarigs, etc.) - these shouldn't and/or don't need updating when the view changes
  4. Optimising view playback speed - by only evaluating stuff that's visible. For instance, heavy geometry that's hidden on a hidden layer doesn't get updated while doing viewport playback with low-res proxies.

However, the have the following problems:

  • Enabling a previously hidden layer doesn't force a recalc/flush, which would get the newly visible stuff up to date with the current state of its dependencies (i.e. deforms from rig onto highres geometry previously hidden)
  • Animating layer changes not updating newly visible objects (related to previous)

Need to keep in mind (AFAIK, these are all working ok now?):

  • Visible objects depending on hidden objects (e.g. via drivers)

Lib Linking

... Todo...

Physics Sims / Modifiers

Cache Issues

  • Correctly tagging when caches need rebuilding, and/or what parts of caches need rebuilding is dodgy at best currently. Currently, it either feels overly complicated or out of the control of the user, which is something that needs to be brought under control, perhaps with a single centralised point of command.
  • Need to support a "point cache" modifier which can bake all the vertex locations of a mesh with all physics and deforms applied, then disable the original data sources but without inducing a depsgraph recalc which subsequently clears the caches again

Update Handling

RNA Updates

The whole mechanism for how RNA results in data updates needs reviewing.

There are currently several ways in which changing a property via RNA results in updates either occurring or being scheduled to occur. These are:

  1. prop.update() - callbacks defined for the property. From experience, these appear to fall into several use cases:
    • Depsgraph Tagging - Only the ID-block from the the PointerRNA is actually used
    • Performing actual update actions - Some nodes (see bug 28754), and also Game Engine properties
  2. prop.noteflag - a bitflag of notifiers to send (for UI refresh)
  3. ID-tagging - this happens at the end of

Assorted Issues

Delayed Relationships, etc.

In 2.4x and earlier versions of Blender, there were a plethora of "time offset", "time ipo", "slow parent", etc. etc. things were all the various heads of the multi-headed "time" beast. Data was getting calculated, and recalculated multiple times as a result of this, and really, it meant that it was never clear exactly what time each piece of data was displaying its state for.

To resolve these problems, we've basically eliminated all of these in 2.5, so that there is only one time shown across the scene. For time rescaling and similar effects on a per AnimData unit basis, the intention is that the NLA should play the primary role in this process.

Implementation Considerations

Mistakes we shouldn't make

  • Under no circumstance unrepresented dependencies be shoe-horned in at evaluation time, via manual ID-tagging in updates. This can result in infinite recursion, as some dependencies are updated and others are not, resulting in some dependencies getting flushed on when other dependencies get run.

Building Depsgraph

  • We currently have three places defining need for dependency updates: hardcoded in depsgraph.c, RNA update calls, and tools?

Further Reading

Ton's notes:

Brecht's notes:

Papers: