A ‘depsgraph’ (i.e. shorthand for ‘Dependency Graph’) is a type of data-structure used to represent the relationships between some ‘nodes’.
Nodes are kindof like the vertices of a mesh, in that they connected together with links, like the edges between vertices. The differences though, are that instead of representing some position in space, nodes represent some data (in Blender’s case Objects), and that the links between them have a specific direction (i.e. if ob1 is ‘used’ by ob2 in some way, then we would draw an arrow from ob1 pointing to ob2). So, referring back to the previous example I gave, the nodes would be the black boxes, and the arrows would indicate the ways these nodes relate to each other.
From these ‘arrows’ between nodes in the depsgraph, we can usually work out which nodes would need to be calculated first so that the other nodes could be sure that the values they’re getting are up to date. The other consequence is that you can determine which nodes need to be updated when one node that a few others depend on changes, which means costly full-database refreshes on every edit can be minimized.
So the despgraph acts as a way of storing what relationships between some nodes exist, and from those relationships we can determine ways of efficiently propogating changes to other nodes when one node changes.
These ways in Blender currently include: ordering the nodes in a way that the nodes earlier in the dependency chains are evaluated first, and those more dependent are ordered/evaluated later; and tagging which nodes need to updated when one node changes.
–
However, if you look carefully at this again, we can see that if several nodes have arrows between them forming a loop, i.e. A -> B -> C -> A -> …, the ordering step will fail, since we cannot figure out a way to order these so that all the nodes will have correct values at any one time. This situation here is a what is known as a ‘cyclic dependency’.
If you said, ‘let’s just evaluate them starting from one node which we’ll call the starting node, and stop when we get to this node again’, you’ve practically got Blender’s current cyclic dependency resolution strategy. That is, if we started at node ‘A’, we’d evaluate A, B, C for some timestep t0, then we’d do this again for timestep t1, and so on. However, if you’ll remember, node ‘A’ still has a dependency to node ‘C’ even though we’re ignoring this when we determine the order for evaluating them in this way. So, at timestep t1, when we evaluate node ‘A’, we’d be using the relevant values from ‘C’ which were set in timestep t0 (since ‘C’ hasn’t been updated for this timestep). But, the values for ‘C’ in timestep t0 may be drastically different.
This here is the famous ‘lagging’ problem which you will have noticed when working with some rig containing cyclic dependencies.
Due to this inability to handle cyclic dependencies, Blender’s Dependency Graph is a type of DAG (‘Directed Acyclic Graph’). ‘Directed’ simply refers to the arrows pointing between nodes, ‘Acyclic’ just means that cyclic dependencies cannot exist or be handled in a nice way, and ‘Graph’ simply means a bunch of nodes with links between them in some way.
</end short impromptu lecture on DAG’s>