From 2145c35e12331af0e2693a092a116ad5a830ba8d Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Wed, 1 Nov 2006 11:26:16 +0000 Subject: [PATCH] Bugfix #5038 The "Copy Size" constraint was calling a where_is_object(), this caused the depsgraph to mess up in very weird ways and rare occasions. In the sample file it showed strange lags in bones for using the "Stride bone" option. While trying to locate the bug I've revisited the Pose depsgraph in detail, trying to figure out how it can print possible cycle errors in dependency. That has been added now too (in console). Unfortunately the bugreport example had no cycle errors. :) --- source/blender/blenkernel/depsgraph_private.h | 1 + source/blender/blenkernel/intern/constraint.c | 5 +- source/blender/blenkernel/intern/depsgraph.c | 82 ++++++++++++++++++- 3 files changed, 83 insertions(+), 5 deletions(-) diff --git a/source/blender/blenkernel/depsgraph_private.h b/source/blender/blenkernel/depsgraph_private.h index 527b78bcbe3..15c06b8ae79 100644 --- a/source/blender/blenkernel/depsgraph_private.h +++ b/source/blender/blenkernel/depsgraph_private.h @@ -73,6 +73,7 @@ typedef struct DagNode int DFS_dvtm; // DFS discovery time int DFS_fntm; // DFS Finishing time struct DagAdjList *child; + struct DagAdjList *parent; struct DagNode *next; } DagNode; diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 7f6ea1b5a6a..2c2e529ca4d 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -1000,8 +1000,6 @@ short get_constraint_target_matrix (bConstraint *con, short ownertype, void* own data = (bSizeLikeConstraint*)con->data; if (data->tar){ - /* Update the location of the target object */ - where_is_object_time (data->tar, ctime); constraint_target_to_mat4(data->tar, data->subtarget, mat, size); valid=1; } @@ -1151,7 +1149,7 @@ void evaluate_constraint (bConstraint *constraint, Object *ob, short ownertype, if (!constraint || !ob) return; - + return; Mat4One (M_identity); switch (constraint->type){ @@ -1380,7 +1378,6 @@ void evaluate_constraint (bConstraint *constraint, Object *ob, short ownertype, data=(bLockTrackConstraint*)constraint->data; - if (data->tar){ diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index c65e9363274..03398eced05 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -650,6 +650,14 @@ void free_forest(DagForest *Dag) itA = itA->next; MEM_freeN(tempA); } + + itA = itN->parent; + while (itA) { + tempA = itA; + itA = itA->next; + MEM_freeN(tempA); + } + tempN = itN; itN = itN->next; MEM_freeN(tempN); @@ -759,6 +767,27 @@ void dag_add_relation(DagForest *forest, DagNode *fob1, DagNode *fob2, short rel fob1->child = itA; } +static void dag_add_parent_relation(DagForest *forest, DagNode *fob1, DagNode *fob2, short rel) +{ + DagAdjList *itA = fob2->parent; + + while (itA) { /* search if relation exist already */ + if (itA->node == fob1) { + 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 = fob1; + itA->type = rel; + itA->count = 1; + itA->next = fob2->parent; + fob2->parent = itA; +} + /* * MainDAG is the DAG of all objects in current scene @@ -1925,6 +1954,50 @@ 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; + + node->color= DAG_BLACK; /* done */ + 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); + } + + return level; +} + +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 in %s to %s\n", pchan->name, parchan->name); + } + } + } +} + /* we assume its an armature with pose */ void DAG_pose_sort(Object *ob) { @@ -1954,6 +2027,7 @@ void DAG_pose_sort(Object *ob) if(pchan->parent) { node2 = dag_get_node(dag, pchan->parent); dag_add_relation(dag, node2, node, 0); + dag_add_parent_relation(dag, node2, node, 0); addtoroot = 0; } for (con = pchan->constraints.first; con; con=con->next){ @@ -1966,6 +2040,7 @@ void DAG_pose_sort(Object *ob) if(target) { node2= dag_get_node(dag, target); dag_add_relation(dag, node2, node, 0); + dag_add_parent_relation(dag, node2, node, 0); if(con->type==CONSTRAINT_TYPE_KINEMATIC) { bKinematicConstraint *data = (bKinematicConstraint*)con->data; @@ -1982,6 +2057,7 @@ void DAG_pose_sort(Object *ob) while (parchan){ node3= dag_get_node(dag, parchan); dag_add_relation(dag, node2, node3, 0); + dag_add_parent_relation(dag, node2, node3, 0); segcount++; if(segcount==data->rootbone || segcount>255) break; // 255 is weak @@ -1992,10 +2068,14 @@ void DAG_pose_sort(Object *ob) } } } - if (addtoroot == 1 ) + if (addtoroot == 1 ) { dag_add_relation(dag, rootnode, node, 0); + dag_add_parent_relation(dag, rootnode, node, 0); + } } + pose_check_cycle(dag); + /* now we try to sort... */ tempbase.first= tempbase.last= NULL;