From aa4cb95a5c8569704f166cfd6d8f65606502ea40 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 13 Mar 2015 11:48:04 +0500 Subject: Pass proper bmain to the updateDepgraph() of modifiers This is mainly to make physics modifiers being able to work with it. For other cases this main is not needed. --- source/blender/blenkernel/intern/depsgraph.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'source/blender/blenkernel/intern/depsgraph.c') diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index 566aa6657b9..0451c2239ac 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -484,7 +484,7 @@ static void dag_add_collision_field_relation(DagForest *dag, Scene *scene, Objec } } -static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, Object *ob, int mask) +static void build_dag_object(DagForest *dag, DagNode *scenenode, Main *bmain, Scene *scene, Object *ob, int mask) { bConstraint *con; DagNode *node; @@ -576,7 +576,7 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O for (md = ob->modifiers.first; md; md = md->next) { ModifierTypeInfo *mti = modifierType_getInfo(md->type); - if (mti->updateDepgraph) mti->updateDepgraph(md, dag, scene, ob, node); + if (mti->updateDepgraph) mti->updateDepgraph(md, dag, bmain, scene, ob, node); } } if (ob->parent) { @@ -891,7 +891,7 @@ 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) +static void build_dag_group(DagForest *dag, DagNode *scenenode, Main *bmain, Scene *scene, Group *group, short mask) { GroupObject *go; @@ -901,9 +901,9 @@ static void build_dag_group(DagForest *dag, DagNode *scenenode, Scene *scene, Gr group->id.flag |= LIB_DOIT; for (go = group->gobject.first; go; go = go->next) { - build_dag_object(dag, scenenode, scene, go->ob, mask); + build_dag_object(dag, scenenode, bmain, scene, go->ob, mask); if (go->ob->dup_group) - build_dag_group(dag, scenenode, scene, go->ob->dup_group, mask); + build_dag_group(dag, scenenode, bmain, scene, go->ob->dup_group, mask); } } @@ -936,11 +936,11 @@ DagForest *build_dag(Main *bmain, Scene *sce, short mask) for (base = sce->base.first; base; base = base->next) { ob = base->object; - build_dag_object(dag, scenenode, sce, ob, mask); + build_dag_object(dag, scenenode, bmain, sce, ob, mask); if (ob->proxy) - build_dag_object(dag, scenenode, sce, ob->proxy, mask); + build_dag_object(dag, scenenode, bmain, sce, ob->proxy, mask); if (ob->dup_group) - build_dag_group(dag, scenenode, sce, ob->dup_group, mask); + build_dag_group(dag, scenenode, bmain, sce, ob->dup_group, mask); } BKE_main_id_tag_idcode(bmain, ID_GR, false); -- cgit v1.2.3 From c2012a68b8fc4a086325add9fea8e2839a791d4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20T=C3=B6nne?= Date: Tue, 17 Mar 2015 09:36:43 +0100 Subject: Enable frame updates of duplicache through use of an invalidation flag. --- source/blender/blenkernel/intern/depsgraph.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source/blender/blenkernel/intern/depsgraph.c') diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index 1ebd34e715b..3418da73dbc 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -2141,6 +2141,10 @@ static void dag_object_time_update_flags(Main *bmain, Scene *scene, Object *ob) } } + /* invalidate dupli cache */ + if (ob->dup_cache) + ob->dup_cache->flag |= DUPCACHE_FLAG_DIRTY; + if (ob->recalc & OB_RECALC_OB) lib_id_recalc_tag(bmain, &ob->id); if (ob->recalc & OB_RECALC_DATA) -- cgit v1.2.3 From 0142bdb1ad13e7f30fd74f70017a1215f9610a0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20T=C3=B6nne?= Date: Tue, 17 Mar 2015 16:17:04 +0100 Subject: Use a new flag in duplicator objects to enable cache reading and avoid unnecessary dependencies. This flag will replace the current "read" mode on cache libraries. Beside enabling cache reading, it also disables the current "fake" dependencies between duplicators and their group objects. This is exploiting the layer visibility mechanism in depsgraph to ensure that animated group objects get evaluated when used by a visible duplicator, even when they are not themselves visible. These dependencies cause group object updates even if the duplicator is using cached results. To avoid this unnecessary overhead and make caching worthwhile we rebuild depsgraph without these relations when using the cache instead. --- source/blender/blenkernel/intern/depsgraph.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'source/blender/blenkernel/intern/depsgraph.c') diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index 3418da73dbc..4552e2bbef9 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -620,7 +620,12 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Main *bmain, Sc /* inverted relation, so addtoroot shouldn't be set to zero */ } - if (ob->transflag & OB_DUPLI) { + /* XXX Fake dependency: duplicator object becomes a child of group objects. + * This exploits the layer visibility mechanism, making the group objects update + * when the duplicator is visible (even if group objects are not visible themselves). + * It is not a true dependency, the duplicator does not in any way depend on group objects or data! + */ + if (ob->transflag & OB_DUPLI && !(ob->transflag & OB_DUPLI_USE_CACHE)) { if ((ob->transflag & OB_DUPLIGROUP) && ob->dup_group) { GroupObject *go; for (go = ob->dup_group->gobject.first; go; go = go->next) { -- cgit v1.2.3 From c053f0a53da80ecd5850d371e899eb0b62a3486d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20T=C3=B6nne?= Date: Thu, 19 Mar 2015 10:47:03 +0100 Subject: UI cleanup and a bit nicer workflow by treating read/write mode like an enum toggle. --- source/blender/blenkernel/intern/depsgraph.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender/blenkernel/intern/depsgraph.c') diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index 4552e2bbef9..0cb27ec52c5 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -625,7 +625,7 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Main *bmain, Sc * when the duplicator is visible (even if group objects are not visible themselves). * It is not a true dependency, the duplicator does not in any way depend on group objects or data! */ - if (ob->transflag & OB_DUPLI && !(ob->transflag & OB_DUPLI_USE_CACHE)) { + if (ob->transflag & OB_DUPLI && !(ob->transflag & OB_DUPLI_READ_CACHE)) { if ((ob->transflag & OB_DUPLIGROUP) && ob->dup_group) { GroupObject *go; for (go = ob->dup_group->gobject.first; go; go = go->next) { -- cgit v1.2.3 From 26b58bd1510ee0773b6373df9f160b7170e1b98c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20T=C3=B6nne?= Date: Tue, 17 Mar 2015 09:36:43 +0100 Subject: Enable frame updates of duplicache through use of an invalidation flag. --- source/blender/blenkernel/intern/depsgraph.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source/blender/blenkernel/intern/depsgraph.c') diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index 0451c2239ac..c9b906ee6a0 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -2137,6 +2137,10 @@ static void dag_object_time_update_flags(Main *bmain, Scene *scene, Object *ob) } } + /* invalidate dupli cache */ + if (ob->dup_cache) + ob->dup_cache->flag |= DUPCACHE_FLAG_DIRTY; + if (ob->recalc & OB_RECALC_OB) lib_id_recalc_tag(bmain, &ob->id); if (ob->recalc & OB_RECALC_DATA) -- cgit v1.2.3 From 0d3da1343c16e1be6a6e6b78b77cf8b3354afe07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20T=C3=B6nne?= Date: Tue, 17 Mar 2015 16:17:04 +0100 Subject: Use a new flag in duplicator objects to enable cache reading and avoid unnecessary dependencies. This flag will replace the current "read" mode on cache libraries. Beside enabling cache reading, it also disables the current "fake" dependencies between duplicators and their group objects. This is exploiting the layer visibility mechanism in depsgraph to ensure that animated group objects get evaluated when used by a visible duplicator, even when they are not themselves visible. These dependencies cause group object updates even if the duplicator is using cached results. To avoid this unnecessary overhead and make caching worthwhile we rebuild depsgraph without these relations when using the cache instead. --- source/blender/blenkernel/intern/depsgraph.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'source/blender/blenkernel/intern/depsgraph.c') diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index c9b906ee6a0..b35d070ea8c 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -620,7 +620,12 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Main *bmain, Sc /* inverted relation, so addtoroot shouldn't be set to zero */ } - if (ob->transflag & OB_DUPLI) { + /* XXX Fake dependency: duplicator object becomes a child of group objects. + * This exploits the layer visibility mechanism, making the group objects update + * when the duplicator is visible (even if group objects are not visible themselves). + * It is not a true dependency, the duplicator does not in any way depend on group objects or data! + */ + if (ob->transflag & OB_DUPLI && !(ob->transflag & OB_DUPLI_USE_CACHE)) { if ((ob->transflag & OB_DUPLIGROUP) && ob->dup_group) { GroupObject *go; for (go = ob->dup_group->gobject.first; go; go = go->next) { -- cgit v1.2.3 From f65b7c8377de664198195754abf31782cc00398f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20T=C3=B6nne?= Date: Thu, 19 Mar 2015 10:47:03 +0100 Subject: UI cleanup and a bit nicer workflow by treating read/write mode like an enum toggle. --- source/blender/blenkernel/intern/depsgraph.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender/blenkernel/intern/depsgraph.c') diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index b35d070ea8c..378663fee83 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -625,7 +625,7 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Main *bmain, Sc * when the duplicator is visible (even if group objects are not visible themselves). * It is not a true dependency, the duplicator does not in any way depend on group objects or data! */ - if (ob->transflag & OB_DUPLI && !(ob->transflag & OB_DUPLI_USE_CACHE)) { + if (ob->transflag & OB_DUPLI && !(ob->transflag & OB_DUPLI_READ_CACHE)) { if ((ob->transflag & OB_DUPLIGROUP) && ob->dup_group) { GroupObject *go; for (go = ob->dup_group->gobject.first; go; go = go->next) { -- cgit v1.2.3 From 268524c0257fe313c3c25b4c3e93913690435bea Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 30 Mar 2015 21:17:07 +1100 Subject: Cleanup: use const for typeinfo --- source/blender/blenkernel/intern/depsgraph.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source/blender/blenkernel/intern/depsgraph.c') diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index 0451c2239ac..911415621d1 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -512,7 +512,7 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Main *bmain, Sc for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { for (con = pchan->constraints.first; con; con = con->next) { - bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con); + const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con); ListBase targets = {NULL, NULL}; bConstraintTarget *ct; @@ -574,7 +574,7 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Main *bmain, Sc ModifierData *md; for (md = ob->modifiers.first; md; md = md->next) { - ModifierTypeInfo *mti = modifierType_getInfo(md->type); + const ModifierTypeInfo *mti = modifierType_getInfo(md->type); if (mti->updateDepgraph) mti->updateDepgraph(md, dag, bmain, scene, ob, node); } @@ -823,7 +823,7 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Main *bmain, Sc /* object constraints */ for (con = ob->constraints.first; con; con = con->next) { - bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con); + const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con); ListBase targets = {NULL, NULL}; bConstraintTarget *ct; @@ -2011,7 +2011,7 @@ static void dag_object_time_update_flags(Main *bmain, Scene *scene, Object *ob) if (ob->constraints.first) { bConstraint *con; for (con = ob->constraints.first; con; con = con->next) { - bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con); + const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con); ListBase targets = {NULL, NULL}; bConstraintTarget *ct; @@ -2532,7 +2532,7 @@ static void dag_id_flush_update(Main *bmain, Scene *sce, ID *id) for (obt = bmain->object.first; obt; obt = obt->id.next) { bConstraint *con; for (con = obt->constraints.first; con; con = con->next) { - bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con); + const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con); if (ELEM(cti->type, CONSTRAINT_TYPE_FOLLOWTRACK, CONSTRAINT_TYPE_CAMERASOLVER, CONSTRAINT_TYPE_OBJECTSOLVER)) { @@ -2916,7 +2916,7 @@ void DAG_pose_sort(Object *ob) addtoroot = 0; } for (con = pchan->constraints.first; con; con = con->next) { - bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con); + const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con); ListBase targets = {NULL, NULL}; bConstraintTarget *ct; -- cgit v1.2.3 From fc1d50f1e7eeeb5fbcb75d1c9c60027374effb23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20T=C3=B6nne?= Date: Tue, 31 Mar 2015 10:33:33 +0200 Subject: Reorganization of file paths and input/output workflow in cache libraries. Having a cache archive output in each modifier is not really practical. Now the cache library has at most 2 file paths. These are used based on 2 associated settings: source mode/path and display mode/path. * The SOURCE mode determines whether the original scene data is used as input or a cache archive. If the scene input is used the dupli group objects will be evaluated as usual with Mesh data, modifiers, proxy armatures, etc.. With cache input the data stored in a cache is used to override the scene data instead. * The DISPLAY mode is essentially a toggle for the whole cache modifier stack. If it is set to 'source' the respective source data is used without further modification. If set to 'result' the data from the output cache archive is used, which can be generated using the bake operator. During baking the data will be passed through the cache modifiers to create a variation of the original source data. --- source/blender/blenkernel/intern/depsgraph.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source/blender/blenkernel/intern/depsgraph.c') diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index 378663fee83..cc0da53c4ee 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -45,6 +45,7 @@ #include "BLI_threads.h" #include "DNA_anim_types.h" +#include "DNA_cache_library_types.h" #include "DNA_camera_types.h" #include "DNA_group_types.h" #include "DNA_lamp_types.h" @@ -625,8 +626,9 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Main *bmain, Sc * when the duplicator is visible (even if group objects are not visible themselves). * It is not a true dependency, the duplicator does not in any way depend on group objects or data! */ - if (ob->transflag & OB_DUPLI && !(ob->transflag & OB_DUPLI_READ_CACHE)) { - if ((ob->transflag & OB_DUPLIGROUP) && ob->dup_group) { + if (ob->transflag & OB_DUPLI) { + bool is_cached = ob->cache_library && ob->cache_library->source_mode == CACHE_LIBRARY_SOURCE_CACHE; + if (!is_cached && (ob->transflag & OB_DUPLIGROUP) && ob->dup_group) { GroupObject *go; for (go = ob->dup_group->gobject.first; go; go = go->next) { if (go->ob) { -- cgit v1.2.3 From 2d054667001602cd9b15046190e09167d7951d89 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 8 Apr 2015 20:03:35 +0500 Subject: Fix T44213: Bevel object from different scene won't update generated bezier curve geometry The issue was caused by bevel object being automatically added to the scene graph by dag_get_node() and had no incoming relations, even form the scene. This confused scene update flush logic. Now there'll be a scene relation added to such nodes, so they're always reachable from the root node. --- source/blender/blenkernel/intern/depsgraph.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source/blender/blenkernel/intern/depsgraph.c') diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index 911415621d1..869404ae4a6 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -960,6 +960,10 @@ DagForest *build_dag(Main *bmain, Scene *sce, short mask) /* also flush custom data mask */ ((Object *)node->ob)->customdata_mask = node->customdata_mask; + + if (node->parent == NULL) { + dag_add_relation(dag, scenenode, node, DAG_RL_SCENE, "Scene Relation"); + } } } /* now set relations equal, so that when only one parent changes, the correct recalcs are found */ -- cgit v1.2.3 From a6b9fc6f22754569b1413fc6f53cca1ce70eea61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20T=C3=B6nne?= Date: Fri, 10 Apr 2015 12:34:25 +0200 Subject: Use depsgraph tagging and notifiers to enforce dupli cache updates in the viewport. --- source/blender/blenkernel/intern/depsgraph.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'source/blender/blenkernel/intern/depsgraph.c') diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index 7ce49a05c53..8350525e643 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -2593,6 +2593,21 @@ static void dag_id_flush_update(Main *bmain, Scene *sce, ID *id) } } } + + /* set flags based on CacheLibrary */ + if (idtype == ID_CL) { + for (obt = bmain->object.first; obt; obt = obt->id.next) { + if (!(ob && obt == ob) && ((ID *)obt->cache_library == id)) { + obt->flag |= (OB_RECALC_OB | OB_RECALC_DATA); + lib_id_recalc_tag(bmain, &obt->id); + lib_id_recalc_data_tag(bmain, &obt->id); + + /* invalidate dupli cache */ + if (obt->dup_cache) + obt->dup_cache->flag |= DUPCACHE_FLAG_DIRTY; + } + } + } /* camera's matrix is used to orient reconstructed stuff, * so it should happen tracking-related constraints recalculation -- cgit v1.2.3 From 10df745d2195d4c1904cd141f151ad0c3726df6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20T=C3=B6nne?= Date: Mon, 20 Apr 2015 09:39:08 +0200 Subject: Revert 0d3da1343c16e1be6a6e6b78b77cf8b3354afe07 Disabling group -> duplicator dependencies would in theory make caches more attractive because the invisible objects don't have to be updated just because of the group. However, the viewport and render starts to behave unpredictably without these updates, because the dupli cache relies in many ways on the objects it is supposed to override. --- source/blender/blenkernel/intern/depsgraph.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'source/blender/blenkernel/intern/depsgraph.c') diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index 22f5effc5ac..9a5e3158234 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -627,8 +627,16 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Main *bmain, Sc * It is not a true dependency, the duplicator does not in any way depend on group objects or data! */ if (ob->transflag & OB_DUPLI) { + /* XXX In theory it would be possible to disable the visibility dependency when dupli groups are cached, + * since we use the results from the cache instead of the generated object data anyway. + * However, the caching system depends a lot on DNA objects currently and behaves unpredictably without this ... + */ +#if 0 bool is_cached = ob->cache_library && ob->cache_library->source_mode == CACHE_LIBRARY_SOURCE_CACHE; if (!is_cached && (ob->transflag & OB_DUPLIGROUP) && ob->dup_group) { +#else + if ((ob->transflag & OB_DUPLIGROUP) && ob->dup_group) { +#endif GroupObject *go; for (go = ob->dup_group->gobject.first; go; go = go->next) { if (go->ob) { -- cgit v1.2.3 From cd5ab215e339a1daa1e8fcb4470bfa55c2861c6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20T=C3=B6nne?= Date: Thu, 23 Apr 2015 09:09:06 +0200 Subject: Allow the dupli override simulation to specify layers of effector influence explicitly. The previous code would only allow using the layers of the given object. This is not useful for dupli overrides, because even finding which layers an object in a dupligroup is in is cumbersome. It makes more sense to use the layers of the duplicator instead. There is an '_ex' version of the pdInitEffectors function now, with an explicit layers argument. The simple version now also skips the 'precalc' argument, because this was true in every case except the depsgraph dependency building anyway. --- source/blender/blenkernel/intern/depsgraph.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender/blenkernel/intern/depsgraph.c') diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index 9a5e3158234..9cd978c155d 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -804,7 +804,7 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Main *bmain, Sc } } - effectors = pdInitEffectors(scene, ob, psys, part->effector_weights, false); + effectors = pdInitEffectors_ex(scene, ob, psys, ob->lay, part->effector_weights, false); if (effectors) { for (eff = effectors->first; eff; eff = eff->next) { -- cgit v1.2.3 From 5982a57f02cb2122bb509e858624f358f6433fab Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 23 Apr 2015 17:04:21 +0500 Subject: Alembic: Limit frame update to only group which we're interested in The idea is simple: make it so scene_update_for_newframe is only doing updates of the stuff which is really needed for the currently baking group. Implementation is a bit tricky since we don't have parent relations after the DAG is built, so doing some graph traversal there. This code is also now using simplified version of scene_update_for_newframe() which means in theory we can try de-duplicating some pieces of code, but that can be done later. Additionally, the same approach can be used to optimize motion path calculation. --- source/blender/blenkernel/intern/depsgraph.c | 84 ++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) (limited to 'source/blender/blenkernel/intern/depsgraph.c') diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index 9cd978c155d..5a1e11b3b50 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -2248,6 +2248,90 @@ void DAG_scene_update_flags(Main *bmain, Scene *scene, unsigned int lay, const b } } +void DAG_scene_update_group_flags(Main *bmain, + Scene *scene, + Group *group, + unsigned int lay, + const bool do_time, + const bool do_invisible_flush) +{ + DagNode *root_node = scene->theDag->DagNode.first, *node; + GroupObject *go; + DagNodeQueue *queue; + + /* Tag all possible objects for update. */ + DAG_scene_update_flags(bmain, scene, lay, do_time, do_invisible_flush); + + /* Initialize colors of nodes. */ + for (node = root_node; node != NULL; node = node->next) { + node->color = DAG_WHITE; + node->scheduled = false; + } + + /* Tag nodes which corresponds to objects which are to be updated. */ + for (go = group->gobject.first; go != NULL; go = go->next) { + if (go->ob != NULL) { + node = dag_find_node(scene->theDag, go->ob); + if (node != NULL) { + node->scheduled = true; + } + } + } + + /* Flush schedule flags to parent. */ + queue = queue_create(DAGQUEUEALLOC); + for (node = root_node; node != NULL; node = node->next) { + if (node->color == DAG_WHITE) { + push_stack(queue, node); + node->color = DAG_GRAY; + while (queue->count) { + DagNode *current_node = get_top_node_queue(queue); + DagAdjList *itA; + bool skip = false; + /* Check if all child nodes were scheduled. */ + for (itA = current_node->child; itA; itA = itA->next) { + if (itA->node->color == DAG_WHITE) { + itA->node->color = DAG_GRAY; + push_stack(queue, itA->node); + skip = true; + break; + } + } + /* Check if there are scheduled children and if so schedule + * current node as well since it's needed for chidlren. + */ + if (!skip) { + current_node = pop_queue(queue); + if (current_node->type == ID_OB) { + for (itA = current_node->child; itA; itA = itA->next) { + if (itA->node->scheduled) { + current_node->scheduled = true; + break; + } + } + } + node->color = DAG_BLACK; + } + } + } + } + queue_delete(queue); + + /* Clear recalc flags from objects which corresponds to nodes which are + * not needed for the interesting group update. + */ + for (node = root_node; node != NULL; node = node->next) { + if (node->type == ID_OB) { + Object *object = node->ob; + if (!node->scheduled) { + object->recalc &= ~OB_RECALC_ALL; + } + } + node->color = DAG_WHITE; + node->scheduled = false; + } +} + /* struct returned by DagSceneLayer */ typedef struct DagSceneLayer { struct DagSceneLayer *next, *prev; -- cgit v1.2.3 From bac735380189c63d2b8824cba8e0398bb35e9af2 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 12 May 2015 15:05:57 +0500 Subject: Depsgraph: New dependency graph integration commit This commit integrates the work done so far on the new dependency graph system, where goal was to replace legacy depsgraph with the new one, supporting loads of neat features like: - More granular dependency relation nature, which solves issues with fake cycles in the dependencies. - Move towards all-animatable, by better integration of drivers into the system. - Lay down some basis for upcoming copy-on-write, overrides and so on. The new system is living side-by-side with the previous one and disabled by default, so nothing will become suddenly broken. The way to enable new depsgraph is to pass `--new-depsgraph` command line argument. It's a bit early to consider the system production-ready, there are some TODOs and issues were discovered during the merge period, they'll be addressed ASAP. But it's important to merge, because it's the only way to attract artists to really start testing this system. There are number of assorted documents related on the design of the new system: * http://wiki.blender.org/index.php/User:Aligorith/GSoC2013_Depsgraph#Design_Documents * http://wiki.blender.org/index.php/User:Nazg-gul/DependencyGraph There are also some user-related information online: * http://code.blender.org/2015/02/blender-dependency-graph-branch-for-users/ * http://code.blender.org/2015/03/more-dependency-graph-tricks/ Kudos to everyone who was involved into the project: - Joshua "Aligorith" Leung -- design specification, initial code - Lukas "lukas_t" Toenne -- integrating code into blender, with further fixes - Sergey "Sergey" "Sharybin" -- some mocking around, trying to wrap up the project and so - Bassam "slikdigit" Kurdali -- stressing the new system, reporting all the issues and recording/writing documentation. - Everyone else who i forgot to mention here :) --- source/blender/blenkernel/intern/depsgraph.c | 405 +++++++++++++++++++++++++-- 1 file changed, 383 insertions(+), 22 deletions(-) (limited to 'source/blender/blenkernel/intern/depsgraph.c') diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index 869404ae4a6..9ee9f3d57af 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -88,16 +88,25 @@ #include "depsgraph_private.h" +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_build.h" +#include "DEG_depsgraph_debug.h" +#include "DEG_depsgraph_query.h" + +#ifdef WITH_LEGACY_DEPSGRAPH + static SpinLock threaded_update_lock; void DAG_init(void) { BLI_spin_init(&threaded_update_lock); + DEG_register_node_types(); } void DAG_exit(void) { BLI_spin_end(&threaded_update_lock); + DEG_free_node_types(); } /* Queue and stack operations for dag traversal @@ -1329,8 +1338,14 @@ static void (*EditorsUpdateSceneCb)(Main *bmain, Scene *scene, int updated) = NU void DAG_editors_update_cb(void (*id_func)(Main *bmain, ID *id), void (*scene_func)(Main *bmain, Scene *scene, int updated)) { - EditorsUpdateIDCb = id_func; - EditorsUpdateSceneCb = scene_func; + if (DEG_depsgraph_use_legacy()) { + EditorsUpdateIDCb = id_func; + EditorsUpdateSceneCb = scene_func; + } + else { + /* New dependency graph. */ + DEG_editors_set_update_cb(id_func, scene_func); + } } static void dag_editors_id_update(Main *bmain, ID *id) @@ -1529,7 +1544,7 @@ static void dag_scene_build(Main *bmain, Scene *sce) Base *base; BLI_listbase_clear(&tempbase); - + build_dag(bmain, sce, DAG_RL_ALL_BUT_DATA); dag_check_cycle(sce->theDag); @@ -1621,32 +1636,65 @@ static void dag_scene_build(Main *bmain, Scene *sce) /* clear all dependency graphs */ void DAG_relations_tag_update(Main *bmain) { - Scene *sce; - - for (sce = bmain->scene.first; sce; sce = sce->id.next) - dag_scene_free(sce); + if (DEG_depsgraph_use_legacy()) { + Scene *sce; + for (sce = bmain->scene.first; sce; sce = sce->id.next) { + dag_scene_free(sce); + } + } + else { + /* New dependency graph. */ + DEG_relations_tag_update(bmain); + } } /* rebuild dependency graph only for a given scene */ void DAG_scene_relations_rebuild(Main *bmain, Scene *sce) { - dag_scene_free(sce); - DAG_scene_relations_update(bmain, sce); + if (DEG_depsgraph_use_legacy()) { + dag_scene_free(sce); + DAG_scene_relations_update(bmain, sce); + } + else { + /* New dependency graph. */ + DEG_scene_relations_rebuild(bmain, sce); + } } /* create dependency graph if it was cleared or didn't exist yet */ void DAG_scene_relations_update(Main *bmain, Scene *sce) { - if (!sce->theDag) - dag_scene_build(bmain, sce); + if (DEG_depsgraph_use_legacy()) { + if (!sce->theDag) + dag_scene_build(bmain, sce); + } + else { + /* New dependency graph. */ + DEG_scene_relations_update(bmain, sce); + } +} + +void DAG_scene_relations_validate(Main *bmain, Scene *sce) +{ + if (!DEG_depsgraph_use_legacy()) { + DEG_debug_scene_relations_validate(bmain, sce); + } } void DAG_scene_free(Scene *sce) { - if (sce->theDag) { - free_forest(sce->theDag); - MEM_freeN(sce->theDag); - sce->theDag = NULL; + if (DEG_depsgraph_use_legacy()) { + if (sce->theDag) { + free_forest(sce->theDag); + MEM_freeN(sce->theDag); + sce->theDag = NULL; + } + } + else { + if (sce->depsgraph) { + DEG_graph_free(sce->depsgraph); + sce->depsgraph = NULL; + } } } @@ -1889,7 +1937,11 @@ void DAG_scene_flush_update(Main *bmain, Scene *sce, unsigned int lay, const sho DagAdjList *itA; Object *ob; int lasttime; - + + if (!DEG_depsgraph_use_legacy()) { + return; + } + if (sce->theDag == NULL) { printf("DAG zero... not allowed to happen!\n"); DAG_scene_relations_update(bmain, sce); @@ -2300,7 +2352,7 @@ static void dag_current_scene_layers(Main *bmain, ListBase *lb) } } -static void dag_group_on_visible_update(Group *group) +static void dag_group_on_visible_update(Scene *scene, Group *group) { GroupObject *go; @@ -2322,7 +2374,7 @@ static void dag_group_on_visible_update(Group *group) } if (go->ob->dup_group) - dag_group_on_visible_update(go->ob->dup_group); + dag_group_on_visible_update(scene, go->ob->dup_group); } } @@ -2330,7 +2382,13 @@ void DAG_on_visible_update(Main *bmain, const bool do_time) { ListBase listbase; DagSceneLayer *dsl; - + + if (!DEG_depsgraph_use_legacy()) { + /* Inform new dependnecy graphs about visibility changes. */ + DEG_on_visible_update(bmain, do_time); + return; + } + /* get list of visible scenes and layers */ dag_current_scene_layers(bmain, &listbase); @@ -2357,7 +2415,8 @@ void DAG_on_visible_update(Main *bmain, const bool do_time) oblay = (node) ? node->lay : ob->lay; if ((oblay & lay) & ~scene->lay_updated) { - if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL, OB_LATTICE)) { + /* TODO(sergey): Why do we need armature here now but didn't need before? */ + if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL, OB_LATTICE, OB_ARMATURE)) { ob->recalc |= OB_RECALC_DATA; lib_id_recalc_tag(bmain, &ob->id); } @@ -2375,7 +2434,7 @@ void DAG_on_visible_update(Main *bmain, const bool do_time) lib_id_recalc_tag(bmain, &ob->id); } if (ob->dup_group) - dag_group_on_visible_update(ob->dup_group); + dag_group_on_visible_update(scene, ob->dup_group); } } @@ -2609,7 +2668,12 @@ void DAG_ids_flush_tagged(Main *bmain) ListBase *lbarray[MAX_LIBARRAY]; int a; bool do_flush = false; - + + if (!DEG_depsgraph_use_legacy()) { + DEG_ids_flush_tagged(bmain); + return; + } + /* get list of visible scenes and layers */ dag_current_scene_layers(bmain, &listbase); @@ -2653,6 +2717,11 @@ void DAG_ids_check_recalc(Main *bmain, Scene *scene, bool time) int a; bool updated = false; + if (!DEG_depsgraph_use_legacy()) { + DEG_ids_check_recalc(bmain, scene, time); + return; + } + /* loop over all ID types */ a = set_listbasepointers(bmain, lbarray); @@ -2769,6 +2838,11 @@ void DAG_ids_clear_recalc(Main *bmain) void DAG_id_tag_update_ex(Main *bmain, ID *id, short flag) { + if (!DEG_depsgraph_use_legacy()) { + DEG_id_tag_update_ex(bmain, id, flag); + return; + } + if (id == NULL) return; if (G.debug & G_DEBUG_DEPSGRAPH) { @@ -3160,6 +3234,10 @@ short DAG_get_eval_flags_for_object(Scene *scene, void *object) { DagNode *node; + if (!DEG_depsgraph_use_legacy()) { + return DEG_get_eval_flags_for_id(scene->depsgraph, (ID*)object); + } + if (scene->theDag == NULL) { /* Happens when converting objects to mesh from a python script * after modifying scene graph. @@ -3198,3 +3276,286 @@ bool DAG_is_acyclic(Scene *scene) { return scene->theDag->is_acyclic; } + +#else + +/* ********************************************************************* + * Stubs to avoid linking issues and make sure legacy crap is not used * + * ********************************************************************* + */ + +DagNodeQueue *queue_create(int UNUSED(slots)) +{ + BLI_assert(!"Should not be used with new dependnecy graph"); + return NULL; +} + +void queue_raz(DagNodeQueue *UNUSED(queue)) +{ + BLI_assert(!"Should not be used with new dependnecy graph"); +} + +void queue_delete(DagNodeQueue *UNUSED(queue)) +{ + BLI_assert(!"Should not be used with new dependnecy graph"); +} + +void push_queue(DagNodeQueue *UNUSED(queue), DagNode *UNUSED(node)) +{ + BLI_assert(!"Should not be used with new dependnecy graph"); +} + +void push_stack(DagNodeQueue *UNUSED(queue), DagNode *UNUSED(node)) +{ + BLI_assert(!"Should not be used with new dependnecy graph"); +} + +DagNode *pop_queue(DagNodeQueue *UNUSED(queue)) +{ + BLI_assert(!"Should not be used with new dependnecy graph"); + return NULL; +} + +DagNode *get_top_node_queue(DagNodeQueue *UNUSED(queue)) +{ + BLI_assert(!"Should not be used with new dependnecy graph"); + return NULL; +} + +DagForest *dag_init(void) +{ + BLI_assert(!"Should not be used with new dependnecy graph"); + return NULL; +} + +DagForest *build_dag(Main *UNUSED(bmain), + Scene *UNUSED(sce), + short UNUSED(mask)) +{ + BLI_assert(!"Should not be used with new dependnecy graph"); + return NULL; +} + +void free_forest(DagForest *UNUSED(Dag)) +{ + BLI_assert(!"Should not be used with new dependnecy graph"); +} + +DagNode *dag_find_node(DagForest *UNUSED(forest), void *UNUSED(fob)) +{ + BLI_assert(!"Should not be used with new dependnecy graph"); + return NULL; +} + +DagNode *dag_add_node(DagForest *UNUSED(forest), void *UNUSED(fob)) +{ + BLI_assert(!"Should not be used with new dependnecy graph"); + return NULL; +} + +DagNode *dag_get_node(DagForest *UNUSED(forest), void *UNUSED(fob)) +{ + BLI_assert(!"Should not be used with new dependnecy graph"); + return NULL; +} + +DagNode *dag_get_sub_node(DagForest *UNUSED(forest), void *UNUSED(fob)) +{ + BLI_assert(!"Should not be used with new dependnecy graph"); + return NULL; +} + +void dag_add_relation(DagForest *UNUSED(forest), + DagNode *UNUSED(fob1), + DagNode *UNUSED(fob2), + short UNUSED(rel), + const char *UNUSED(name)) +{ + BLI_assert(!"Should not be used with new dependnecy graph"); +} + +/* debug test functions */ + +void graph_print_queue(DagNodeQueue *UNUSED(nqueue)) +{ + BLI_assert(!"Should not be used with new dependnecy graph"); +} + +void graph_print_queue_dist(DagNodeQueue *UNUSED(nqueue)) +{ + BLI_assert(!"Should not be used with new dependnecy graph"); +} + +void graph_print_adj_list(DagForest *UNUSED(dag)) +{ + BLI_assert(!"Should not be used with new dependnecy graph"); +} + +void DAG_scene_flush_update(Main *UNUSED(bmain), + Scene *UNUSED(sce), + unsigned int UNUSED(lay), + const short UNUSED(time)) +{ + BLI_assert(!"Should not be used with new dependnecy graph"); +} + +void DAG_scene_update_flags(Main *UNUSED(bmain), + Scene *UNUSED(scene), + unsigned int UNUSED(lay), + const bool UNUSED(do_time), + const bool UNUSED(do_invisible_flush)) +{ + BLI_assert(!"Should not be used with new dependnecy graph"); +} + +/* ******************* DAG FOR ARMATURE POSE ***************** */ + +void DAG_pose_sort(Object *UNUSED(ob)) +{ + BLI_assert(!"Should not be used with new dependnecy graph"); +} + +/* ************************ DAG FOR THREADED UPDATE ********************* */ + +void DAG_threaded_update_begin(Scene *UNUSED(scene), + void (*func)(void *node, void *user_data), + void *UNUSED(user_data)) +{ + BLI_assert(!"Should not be used with new dependnecy graph"); + (void)func; +} + +void DAG_threaded_update_handle_node_updated(void *UNUSED(node_v), + void (*func)(void *node, void *user_data), + void *UNUSED(user_data)) +{ + BLI_assert(!"Should not be used with new dependnecy graph"); + (void)func; +} + +/* ************************ DAG querying ********************* */ + +Object *DAG_get_node_object(void *UNUSED(node_v)) +{ + BLI_assert(!"Should not be used with new dependnecy graph"); + return NULL; +} + +const char *DAG_get_node_name(Scene *UNUSED(scene), void *UNUSED(node_v)) +{ + BLI_assert(!"Should not be used with new dependnecy graph"); + return "INVALID"; +} + +bool DAG_is_acyclic(Scene *UNUSED(scene)) +{ + BLI_assert(!"Should not be used with new dependnecy graph"); + return false; +} + +/* ************************************ + * This functions are to be supported * + * ************************************ + */ + +void DAG_init(void) +{ + DEG_register_node_types(); +} + +void DAG_exit(void) +{ + DEG_free_node_types(); +} + +/* ************************ API *********************** */ + +void DAG_editors_update_cb(DEG_EditorUpdateIDCb id_func, + DEG_EditorUpdateSceneCb scene_func) +{ + DEG_editors_set_update_cb(id_func, scene_func); +} + +/* Tag all relations for update. */ +void DAG_relations_tag_update(Main *bmain) +{ + DEG_relations_tag_update(bmain); +} + +/* Rebuild dependency graph only for a given scene. */ +void DAG_scene_relations_rebuild(Main *bmain, Scene *scene) +{ + DEG_scene_relations_rebuild(bmain, scene); +} + +/* Create dependency graph if it was cleared or didn't exist yet. */ +void DAG_scene_relations_update(Main *bmain, Scene *scene) +{ + DEG_scene_relations_update(bmain, scene); +} + +void DAG_scene_relations_validate(Main *bmain, Scene *scene) +{ + DEG_debug_scene_relations_validate(bmain, scene); +} + +void DAG_scene_free(Scene *scene) +{ + DEG_scene_graph_free(scene); +} + +void DAG_on_visible_update(Main *bmain, const bool do_time) +{ + DEG_on_visible_update(bmain, do_time); +} + +void DAG_ids_check_recalc(Main *bmain, Scene *scene, bool time) +{ + DEG_ids_check_recalc(bmain, scene, time); +} + +void DAG_id_tag_update(ID *id, short flag) +{ + DEG_id_tag_update_ex(G.main, id, flag); +} + +void DAG_id_tag_update_ex(Main *bmain, ID *id, short flag) +{ + DEG_id_tag_update_ex(bmain, id, flag); +} + +void DAG_id_type_tag(Main *bmain, short idtype) +{ + DEG_id_type_tag(bmain, idtype); +} + +int DAG_id_type_tagged(Main *bmain, short idtype) +{ + return DEG_id_type_tagged(bmain, idtype); +} + +void DAG_ids_clear_recalc(Main *bmain) +{ + DEG_ids_clear_recalc(bmain); +} + +short DAG_get_eval_flags_for_object(Scene *scene, void *object) +{ + return DEG_get_eval_flags_for_id(scene->depsgraph, (ID*)object); +} + +void DAG_ids_flush_tagged(Main *bmain) +{ + DEG_ids_flush_tagged(bmain); +} + +/* ************************ DAG DEBUGGING ********************* */ + +void DAG_print_dependencies(Main *UNUSED(bmain), + Scene *scene, + Object *UNUSED(ob)) +{ + DEG_debug_graphviz(scene->depsgraph, stdout, "Depsgraph", false); +} + +#endif -- cgit v1.2.3 From e4cd4c383f13eb9705d9f5d3536c0b2b72e727bd Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 13 May 2015 06:10:49 +1000 Subject: Cleanup: style --- source/blender/blenkernel/intern/depsgraph.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source/blender/blenkernel/intern/depsgraph.c') diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index 9ee9f3d57af..2fd53045e29 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -3235,7 +3235,7 @@ short DAG_get_eval_flags_for_object(Scene *scene, void *object) DagNode *node; if (!DEG_depsgraph_use_legacy()) { - return DEG_get_eval_flags_for_id(scene->depsgraph, (ID*)object); + return DEG_get_eval_flags_for_id(scene->depsgraph, (ID *)object); } if (scene->theDag == NULL) { @@ -3541,7 +3541,7 @@ void DAG_ids_clear_recalc(Main *bmain) short DAG_get_eval_flags_for_object(Scene *scene, void *object) { - return DEG_get_eval_flags_for_id(scene->depsgraph, (ID*)object); + return DEG_get_eval_flags_for_id(scene->depsgraph, (ID *)object); } void DAG_ids_flush_tagged(Main *bmain) -- cgit v1.2.3