Small dependency debugging aid: now it also prints cycles for

the object depsgrah instead of only armatures.
This commit is contained in:
Brecht Van Lommel 2008-09-19 22:03:16 +00:00
parent 4f737bafa7
commit a15296eff6

@ -865,28 +865,6 @@ DagNode * dag_get_sub_node (DagForest *forest,void * fob)
return node;
}
void dag_add_relation(DagForest *forest, DagNode *fob1, DagNode *fob2, short rel, char *name)
{
DagAdjList *itA = fob1->child;
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;
}
static void dag_add_parent_relation(DagForest *forest, DagNode *fob1, DagNode *fob2, short rel, char *name)
{
DagAdjList *itA = fob2->parent;
@ -909,6 +887,31 @@ static void dag_add_parent_relation(DagForest *forest, DagNode *fob1, DagNode *f
fob2->parent = itA;
}
void dag_add_relation(DagForest *forest, DagNode *fob1, DagNode *fob2, short rel, 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;
}
static char *dag_node_name(DagNode *node)
{
if(node->ob == NULL)
@ -966,6 +969,63 @@ static void dag_node_print_dependency_cycle(DagForest *dag, DagNode *startnode,
printf("\n");
}
static int dag_node_recurs_level(DagNode *node, int level)
{
DagAdjList *itA;
int newlevel;
node->color= DAG_BLACK; /* done */
newlevel= ++level;
for(itA= node->parent; itA; itA= itA->next) {
if(itA->node->color==DAG_WHITE) {
itA->node->ancestor_count= dag_node_recurs_level(itA->node, level);
newlevel= MAX2(newlevel, level+itA->node->ancestor_count);
}
else
newlevel= MAX2(newlevel, level+itA->node->ancestor_count);
}
return newlevel;
}
static void dag_check_cycle(DagForest *dag)
{
DagNode *node;
DagAdjList *itA;
/* tag nodes unchecked */
for(node = dag->DagNode.first; node; node= node->next)
node->color= DAG_WHITE;
for(node = dag->DagNode.first; node; node= node->next) {
if(node->color==DAG_WHITE) {
node->ancestor_count= dag_node_recurs_level(node, 0);
}
}
/* check relations, and print errors */
for(node = dag->DagNode.first; node; node= node->next) {
for(itA= node->parent; itA; itA= itA->next) {
if(itA->node->ancestor_count > node->ancestor_count) {
if(node->ob && itA->node->ob) {
printf("Dependency cycle detected:\n");
dag_node_print_dependency_cycle(dag, itA->node, node, itA->name);
}
}
}
}
/* parent relations are only needed for cycle checking, so free now */
for(node = dag->DagNode.first; node; node= node->next) {
while (node->parent) {
itA = node->parent->next;
MEM_freeN(node->parent);
node->parent = itA;
}
}
}
/*
* MainDAG is the DAG of all objects in current scene
* used only for drawing there is one also in each scene
@ -1603,6 +1663,8 @@ void DAG_scene_sort(struct Scene *sce)
build_dag(sce, DAG_RL_ALL_BUT_DATA);
dag_check_cycle(sce->theDag);
nqueue = queue_create(DAGQUEUEALLOC);
for(node = sce->theDag->DagNode.first; node; node= node->next) {
@ -2212,57 +2274,6 @@ void DAG_object_update_flags(Scene *sce, Object *ob, unsigned int lay)
/* ******************* DAG FOR ARMATURE POSE ***************** */
static int node_recurs_level(DagNode *node, int level)
{
DagAdjList *itA;
int newlevel;
node->color= DAG_BLACK; /* done */
newlevel= ++level;
for(itA= node->parent; itA; itA= itA->next) {
if(itA->node->color==DAG_WHITE) {
itA->node->ancestor_count= node_recurs_level(itA->node, level);
newlevel= MAX2(newlevel, level+itA->node->ancestor_count);
}
else
newlevel= MAX2(newlevel, level+itA->node->ancestor_count);
}
return newlevel;
}
static void pose_check_cycle(DagForest *dag)
{
DagNode *node;
DagAdjList *itA;
/* tag nodes unchecked */
for(node = dag->DagNode.first; node; node= node->next)
node->color= DAG_WHITE;
for(node = dag->DagNode.first; node; node= node->next) {
if(node->color==DAG_WHITE) {
node->ancestor_count= node_recurs_level(node, 0);
}
}
/* check relations, and print errors */
for(node = dag->DagNode.first; node; node= node->next) {
for(itA= node->parent; itA; itA= itA->next) {
if(itA->node->ancestor_count > node->ancestor_count) {
bPoseChannel *pchan= (bPoseChannel *)node->ob;
bPoseChannel *parchan= (bPoseChannel *)itA->node->ob;
if(pchan && parchan) {
printf("Cycle detected:\n");
dag_node_print_dependency_cycle(dag, itA->node, node, itA->name);
}
}
}
}
}
/* we assume its an armature with pose */
void DAG_pose_sort(Object *ob)
{
@ -2292,7 +2303,6 @@ void DAG_pose_sort(Object *ob)
if(pchan->parent) {
node2 = dag_get_node(dag, pchan->parent);
dag_add_relation(dag, node2, node, 0, "Parent Relation");
dag_add_parent_relation(dag, node2, node, 0, "Parent Relation");
addtoroot = 0;
}
for (con = pchan->constraints.first; con; con=con->next) {
@ -2311,7 +2321,6 @@ void DAG_pose_sort(Object *ob)
if(target) {
node2 = dag_get_node(dag, target);
dag_add_relation(dag, node2, node, 0, "Ipo Driver");
dag_add_parent_relation(dag, node2, node, 0, "Ipo Driver");
/* uncommented this line, results in dependencies
* not being added properly for this constraint,
@ -2331,7 +2340,6 @@ void DAG_pose_sort(Object *ob)
if (target) {
node2= dag_get_node(dag, target);
dag_add_relation(dag, node2, node, 0, "IK Constraint");
dag_add_parent_relation(dag, node2, node, 0, "IK Constraint");
if (con->type==CONSTRAINT_TYPE_KINEMATIC) {
bKinematicConstraint *data = (bKinematicConstraint *)con->data;
@ -2348,7 +2356,6 @@ void DAG_pose_sort(Object *ob)
while (parchan) {
node3= dag_get_node(dag, parchan);
dag_add_relation(dag, node2, node3, 0, "IK Constraint");
dag_add_parent_relation(dag, node2, node3, 0, "IK Constraint");
segcount++;
if (segcount==data->rootbone || segcount>255) break; // 255 is weak
@ -2365,11 +2372,10 @@ void DAG_pose_sort(Object *ob)
}
if (addtoroot == 1 ) {
dag_add_relation(dag, rootnode, node, 0, "Root Bone Relation");
dag_add_parent_relation(dag, rootnode, node, 0, "Root Bone Relation");
}
}
pose_check_cycle(dag);
dag_check_cycle(dag);
/* now we try to sort... */
tempbase.first= tempbase.last= NULL;