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.


ddge pbr

// May be best to research later.
Driver Dependancy Graph Example
Pose Bone Rotation.
File:DDGE - Pose Bone Rotation.blend
I dont know much about the DG code, so this is an attempt to document some of it.
I think the DG works by updating property in the order set by the DG nodes.
I think DG nodes are allocated and parented based on logic.
I like the driver system so im starting there.
Branches
DBO, 2.67b r58051.

Example

This is an example file which shows some of the problems with the DG.
The object/pose bone property with the problem is updated with a driver, call it Driver Property.
To see the problem, move or rotate the top pose bone in the Test row.
Trans
In this example the driver property is part of the same object.
Rotate the top pose bone to test.
Transform space works, Local space lags.
Both
In this example the driver property is part of a different object.
Rotate the top pose bone to test.
Both Trnasform and Local space work.
Local
In this example one wants to use the local rotation derived from the IK constraint.
The driver property is part of a seperate object.
Move the top pose bone up and down to test.
Only Local space works.
None
In this example one wants to use the local rotation derived from the IK constraint.
The driver property is part of the same object.
Move the top pose bone up and down to test.
Transform space doesnt work, Local space lags.
This is one of the worst case examples in 2.70a.
In one process blender needs to update the properties in the correct order.
The DG (list of nodes) controls the order, for how properties are updated.

Some Driver Code

Examples like this can work. Depends on -> X.
local rotation -> driver -> local rotation -> driver -> world location -> driver -> world rotation.
File:Driver example.blend

dag_add_driver_relation

This code loops over the driver variables, checks the target, then adds a update node, dag_add_relation.
The node type depends on the driver variable target property type.
DAG_RL_DATA_DATA : DAG_RL_DATA_OB
DAG_RL_OB_DATA : DAG_RL_OB_OB
This code gets the node for the driver target, nodel.
/* normal channel-drives-channel */
node1 = dag_get_node(dag, dtar->id);
The other node, node, comes from the argument.
// source/blender/blenkernel/intern/depsgraph.c: 316 (2.72)

/* isdata = object data... */
/* XXX this needs to be extended to be more flexible (so that not only objects are evaluated via depsgraph)... */
static void dag_add_driver_relation(AnimData *adt, DagForest *dag, DagNode *node, int isdata)
{
  FCurve *fcu;
  DagNode *node1;

  for (fcu = adt->drivers.first; fcu; fcu = fcu->next) {
    ChannelDriver *driver = fcu->driver;
    DriverVar *dvar;
    int isdata_fcu = (isdata) || (fcu->rna_path && strstr(fcu->rna_path, "modifiers["));

    /* loop over variables to get the target relationships */
    for (dvar = driver->variables.first; dvar; dvar = dvar->next) {
      /* only used targets */
      DRIVER_TARGETS_USED_LOOPER(dvar)
      {
        if (dtar->id) {
          /* FIXME: other data types need to be added here so that they can work! */
          if (GS(dtar->id->name) == ID_OB) {

            Object *ob = (Object *)dtar->id;

            /* normal channel-drives-channel */
            node1 = dag_get_node(dag, dtar->id);

            /* check if bone... */
            if ((ob->type == OB_ARMATURE) &&
            ( ((dtar->rna_path) && strstr(dtar->rna_path, "pose.bones[")) ||
            ((dtar->flag & DTAR_FLAG_STRUCT_REF) && (dtar->pchan_name[0])) ))
            {
              dag_add_relation(dag, node1, node, isdata_fcu ? DAG_RL_DATA_DATA : DAG_RL_DATA_OB, "Driver");
            }

            /* check if ob data */
            else if (dtar->rna_path && strstr(dtar->rna_path, "data."))
              dag_add_relation(dag, node1, node, isdata_fcu ? DAG_RL_DATA_DATA : DAG_RL_DATA_OB, "Driver");

            /* normal */
            else
              dag_add_relation(dag, node1, node, isdata_fcu ? DAG_RL_OB_DATA : DAG_RL_OB_OB, "Driver");
          }
        }
      }
      DRIVER_TARGETS_LOOPER_END
    }
  }
}

dag_add_relation

This code adds some dependency nodes.
nodel -> fobl. driver target.
node -> fob2. currect node.
Part of it loops some nodes with itA node pointer.
// source/blender/blenkernel/intern/depsgraph.c: 1121 (2.72)

void dag_add_relation(DagForest *forest, DagNode *fob1, DagNode *fob2, short rel, const char *name)
{
  DagAdjList *itA = fob1->child;

  /* parent relation is for cycle checking */
  dag_add_parent_relation(forest, fob1, fob2, rel, name);

  while (itA) { /* search if relation exist already */
    if (itA->node == fob2) {
      itA->type |= rel;
      itA->count += 1;
      return;
    }
    itA = itA->next;
  }

  /* create new relation and insert at head. MALLOC alert! */
  itA = MEM_mallocN(sizeof(DagAdjList), "DAG adj list");
  itA->node = fob2;
  itA->type = rel;
  itA->count = 1;
  itA->next = fob1->child;
  itA->name = name;
  fob1->child = itA;
}

Misc

...

call tree add driver relation

What calls dag_add_driver_relation and where is it called.
Search source "dag_add_driver_relation".
// depsgraph.c, 2.67b
// source/blender/blenkernel/intern/depsgraph.c, 2.72
dag_add_shader_nodetree_driver_relations	344
dag_add_material_nodetree_driver_relations	367
dag_add_material_lamp_driver_relations		394
build_dag_object				440	called a few time, 4, "XXX old anim system".
Thats it.

DG node types

// depsgraph_private.h, 2.67b
// source/blender/blenkernel/depsgraph_private.h, 2.72
/* **** DAG relation types *** */		37
#define DAG_RL_SCENE	(1 << 0)		40
A set of binary id numbers for each node type. All node types sum to 8bit.
This is also where the data structures are defined, DaGNode listbase structs.
And the prototype functions.