Fix #36754: animation not evaluated on object two levels down in dupligroups.

Depsgraph would only consider one level, now it works recursive.
This commit is contained in:
Brecht Van Lommel
2013-09-18 17:09:28 +00:00
parent a30a817933
commit 31acf4262d

View File

@@ -820,12 +820,26 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O
dag_add_relation(dag, scenenode, node, DAG_RL_SCENE, "Scene Relation");
}
static void build_dag_group(DagForest *dag, DagNode *scenenode, Scene *scene, Group *group, short mask)
{
GroupObject *go;
if (group->id.flag & LIB_DOIT)
return;
group->id.flag |= LIB_DOIT;
for (go = group->gobject.first; go; go = go->next) {
build_dag_object(dag, scenenode, scene, go->ob, mask);
if (go->ob->dup_group)
build_dag_group(dag, scenenode, scene, go->ob->dup_group, mask);
}
}
DagForest *build_dag(Main *bmain, Scene *sce, short mask)
{
Base *base;
Object *ob;
Group *group;
GroupObject *go;
DagNode *node;
DagNode *scenenode;
DagForest *dag;
@@ -842,6 +856,7 @@ DagForest *build_dag(Main *bmain, Scene *sce, short mask)
/* clear "LIB_DOIT" flag from all materials, to prevent infinite recursion problems later [#32017] */
tag_main_idcode(bmain, ID_MA, FALSE);
tag_main_idcode(bmain, ID_LA, FALSE);
tag_main_idcode(bmain, ID_GR, FALSE);
/* add base node for scene. scene is always the first node in DAG */
scenenode = dag_add_node(dag, sce);
@@ -853,21 +868,11 @@ DagForest *build_dag(Main *bmain, Scene *sce, short mask)
build_dag_object(dag, scenenode, sce, ob, mask);
if (ob->proxy)
build_dag_object(dag, scenenode, sce, ob->proxy, mask);
/* handled in next loop */
if (ob->dup_group)
ob->dup_group->id.flag |= LIB_DOIT;
build_dag_group(dag, scenenode, sce, ob->dup_group, mask);
}
/* add groups used in current scene objects */
for (group = bmain->group.first; group; group = group->id.next) {
if (group->id.flag & LIB_DOIT) {
for (go = group->gobject.first; go; go = go->next) {
build_dag_object(dag, scenenode, sce, go->ob, mask);
}
group->id.flag &= ~LIB_DOIT;
}
}
tag_main_idcode(bmain, ID_GR, FALSE);
/* Now all relations were built, but we need to solve 1 exceptional case;
* When objects have multiple "parents" (for example parent + constraint working on same object)
@@ -1928,6 +1933,25 @@ static void dag_object_time_update_flags(Main *bmain, Scene *scene, Object *ob)
lib_id_recalc_data_tag(bmain, &ob->id);
}
/* recursively update objects in groups, each group is done at most once */
static void dag_group_update_flags(Main *bmain, Scene *scene, Group *group, const short do_time)
{
GroupObject *go;
if (group->id.flag & LIB_DOIT)
return;
group->id.flag |= LIB_DOIT;
for (go = group->gobject.first; go; go = go->next) {
if (do_time)
dag_object_time_update_flags(bmain, scene, go->ob);
if (go->ob->dup_group)
dag_group_update_flags(bmain, scene, go->ob->dup_group, do_time);
}
}
/* flag all objects that need recalc, for changes in time for example */
/* do_time: make this optional because undo resets objects to their animated locations without this */
void DAG_scene_update_flags(Main *bmain, Scene *scene, unsigned int lay, const short do_time)
@@ -1938,6 +1962,8 @@ void DAG_scene_update_flags(Main *bmain, Scene *scene, unsigned int lay, const s
GroupObject *go;
Scene *sce_iter;
tag_main_idcode(bmain, ID_GR, FALSE);
/* set ob flags where animated systems are */
for (SETLOOPER(scene, sce_iter, base)) {
ob = base->object;
@@ -1952,20 +1978,9 @@ void DAG_scene_update_flags(Main *bmain, Scene *scene, unsigned int lay, const s
dag_object_time_update_flags(bmain, sce_iter, ob);
}
/* handled in next loop */
/* recursively tag groups with LIB_DOIT, and update flags for objects */
if (ob->dup_group)
ob->dup_group->id.flag |= LIB_DOIT;
}
if (do_time) {
/* we do groups each once */
for (group = bmain->group.first; group; group = group->id.next) {
if (group->id.flag & LIB_DOIT) {
for (go = group->gobject.first; go; go = go->next) {
dag_object_time_update_flags(bmain, scene, go->ob);
}
}
}
dag_group_update_flags(bmain, scene, ob->dup_group, do_time);
}
for (sce_iter = scene; sce_iter; sce_iter = sce_iter->set)
@@ -2049,6 +2064,26 @@ static void dag_current_scene_layers(Main *bmain, ListBase *lb)
}
}
static void dag_group_on_visible_update(Group *group)
{
GroupObject *go;
if (group->id.flag & LIB_DOIT)
return;
group->id.flag |= LIB_DOIT;
for (go = group->gobject.first; go; go = go->next) {
if (ELEM6(go->ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL, OB_LATTICE))
go->ob->recalc |= OB_RECALC_DATA;
if (go->ob->proxy_from)
go->ob->recalc |= OB_RECALC_OB;
if (go->ob->dup_group)
dag_group_on_visible_update(go->ob->dup_group);
}
}
void DAG_on_visible_update(Main *bmain, const short do_time)
{
ListBase listbase;
@@ -2062,8 +2097,6 @@ void DAG_on_visible_update(Main *bmain, const short do_time)
Scene *sce_iter;
Base *base;
Object *ob;
Group *group;
GroupObject *go;
DagNode *node;
unsigned int lay = dsl->layer, oblay;
@@ -2072,6 +2105,7 @@ void DAG_on_visible_update(Main *bmain, const short do_time)
* note armature poses or object matrices are preserved and do not
* require updates, so we skip those */
dag_scene_flush_layers(scene, lay);
tag_main_idcode(bmain, ID_GR, FALSE);
for (SETLOOPER(scene, sce_iter, base)) {
ob = base->object;
@@ -2082,22 +2116,11 @@ void DAG_on_visible_update(Main *bmain, const short do_time)
if (ELEM6(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL, OB_LATTICE))
ob->recalc |= OB_RECALC_DATA;
if (ob->dup_group)
ob->dup_group->id.flag |= LIB_DOIT;
dag_group_on_visible_update(ob->dup_group);
}
}
for (group = bmain->group.first; group; group = group->id.next) {
if (group->id.flag & LIB_DOIT) {
for (go = group->gobject.first; go; go = go->next) {
if (ELEM6(go->ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL, OB_LATTICE))
go->ob->recalc |= OB_RECALC_DATA;
if (go->ob->proxy_from)
go->ob->recalc |= OB_RECALC_OB;
}
group->id.flag &= ~LIB_DOIT;
}
}
tag_main_idcode(bmain, ID_GR, FALSE);
/* now tag update flags, to ensure deformers get calculated on redraw */
DAG_scene_update_flags(bmain, scene, lay, do_time);