diff options
Diffstat (limited to 'source/blender/blenkernel/intern/depsgraph.c')
-rw-r--r-- | source/blender/blenkernel/intern/depsgraph.c | 35 |
1 files changed, 33 insertions, 2 deletions
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index 0582d07d99c..30dcba66c5e 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -834,6 +834,8 @@ DagForest *build_dag(Main *bmain, Scene *sce, short mask) } dag->need_update = false; + BKE_main_id_tag_idcode(bmain, ID_OB, LIB_TAG_DOIT, false); + /* clear "LIB_TAG_DOIT" flag from all materials, to prevent infinite recursion problems later [#32017] */ BKE_main_id_tag_idcode(bmain, ID_MA, LIB_TAG_DOIT, false); BKE_main_id_tag_idcode(bmain, ID_LA, LIB_TAG_DOIT, false); @@ -845,14 +847,43 @@ DagForest *build_dag(Main *bmain, Scene *sce, short mask) /* add current scene objects */ for (base = sce->base.first; base; base = base->next) { ob = base->object; - + ob->id.tag |= LIB_TAG_DOIT; build_dag_object(dag, scenenode, bmain, sce, ob, mask); if (ob->proxy) build_dag_object(dag, scenenode, bmain, sce, ob->proxy, mask); if (ob->dup_group) build_dag_group(dag, scenenode, bmain, sce, ob->dup_group, mask); } - + + /* There might be situations when object from current scene depends on + * objects form other scene AND objects from other scene has own + * dependencies on objects from other scene. + * + * This is really important to include such indirect dependencies in order + * to keep threaded update safe but since we don't really know if object is + * coming from current scene or another scene we do rather stupid tag-based + * check here: all the objects for which build_dag_object() was called are + * getting tagged with LIB_TAG_DOIT. This way if some node has untagged + * object we know it's an object from other scene. + * + * It should be enough to to it once, because if there's longer chain of + * indirect dependencies, all the new nodes will be added to the end of the + * list, meaning we'll keep covering them in this for loop. + */ + for (node = sce->theDag->DagNode.first; node != NULL; node = node->next) { + if (node->type == ID_OB) { + ob = node->ob; + if ((ob->id.tag & LIB_TAG_DOIT) == 0) { + ob->id.tag |= LIB_TAG_DOIT; + build_dag_object(dag, scenenode, bmain, sce, ob, mask); + if (ob->proxy) + build_dag_object(dag, scenenode, bmain, sce, ob->proxy, mask); + if (ob->dup_group) + build_dag_group(dag, scenenode, bmain, sce, ob->dup_group, mask); + } + } + } + BKE_main_id_tag_idcode(bmain, ID_GR, LIB_TAG_DOIT, false); /* Now all relations were built, but we need to solve 1 exceptional case; |