Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2013-09-18 21:09:28 +0400
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2013-09-18 21:09:28 +0400
commit31acf4262df27ee99cd4547a75bddf7a52b420cb (patch)
treea7b77edf1b164c9185f365b34abb7a6e267c7eb5 /source
parenta30a8179331d689c9e599fb9a530c0b6b155f689 (diff)
Fix #36754: animation not evaluated on object two levels down in dupligroups.
Depsgraph would only consider one level, now it works recursive.
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c107
1 files changed, 65 insertions, 42 deletions
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index cc221176994..13181662bd8 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -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);