diff options
Diffstat (limited to 'source/blender/depsgraph/intern/depsgraph_build.cc')
-rw-r--r-- | source/blender/depsgraph/intern/depsgraph_build.cc | 134 |
1 files changed, 72 insertions, 62 deletions
diff --git a/source/blender/depsgraph/intern/depsgraph_build.cc b/source/blender/depsgraph/intern/depsgraph_build.cc index 1b270e71d64..c39f6222a13 100644 --- a/source/blender/depsgraph/intern/depsgraph_build.cc +++ b/source/blender/depsgraph/intern/depsgraph_build.cc @@ -34,6 +34,7 @@ #include "BLI_utildefines.h" #include "BLI_ghash.h" +#include "BLI_listbase.h" #include "PIL_time.h" #include "PIL_time_utildefines.h" @@ -48,6 +49,7 @@ extern "C" { #include "BKE_collision.h" #include "BKE_effect.h" #include "BKE_modifier.h" +#include "BKE_scene.h" } /* extern "C" */ #include "DEG_depsgraph.h" @@ -188,32 +190,48 @@ void DEG_add_special_eval_flag(Depsgraph *graph, ID *id, short flag) /* ******************** */ /* Graph Building API's */ -/* Build depsgraph for the given scene, and dump results in given +/* Build depsgraph for the given scene layer, and dump results in given * graph container. */ -/* XXX: assume that this is called from outside, given the current scene as - * the "main" scene. - */ -void DEG_graph_build_from_scene(Depsgraph *graph, Main *bmain, Scene *scene) +void DEG_graph_build_from_view_layer(Depsgraph *graph, + Main *bmain, + Scene *scene, + ViewLayer *view_layer) { - double start_time; + double start_time = 0.0; if (G.debug & G_DEBUG_DEPSGRAPH_BUILD) { start_time = PIL_check_seconds_timer(); } DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(graph); + BLI_assert(BLI_findindex(&scene->view_layers, view_layer) != -1); + + BLI_assert(deg_graph->scene == scene); + BLI_assert(deg_graph->view_layer == view_layer); + + /* TODO(sergey): This is a bit tricky, but ensures that all the data + * is evaluated properly when depsgraph is becoming "visible". + * + * This now could happen for both visible scene is changed and extra + * dependency graph was created for render engine. + */ + const bool need_on_visible_update = (deg_graph->id_nodes.size() == 0); /* 1) Generate all the nodes in the graph first */ DEG::DepsgraphNodeBuilder node_builder(bmain, deg_graph); node_builder.begin_build(); - node_builder.build_scene(scene); + node_builder.build_view_layer(scene, + view_layer, + DEG::DEG_ID_LINKED_DIRECTLY); + node_builder.end_build(); /* 2) Hook up relationships between operations - to determine evaluation * order. */ DEG::DepsgraphRelationBuilder relation_builder(bmain, deg_graph); relation_builder.begin_build(); - relation_builder.build_scene(scene); + relation_builder.build_view_layer(scene, view_layer); + relation_builder.build_copy_on_write_relations(); /* Detect and solve cycles. */ DEG::deg_graph_detect_cycles(deg_graph); @@ -228,7 +246,7 @@ void DEG_graph_build_from_scene(Depsgraph *graph, Main *bmain, Scene *scene) } /* 4) Flush visibility layer and re-schedule nodes for update. */ - DEG::deg_graph_build_finalize(deg_graph); + DEG::deg_graph_build_finalize(bmain, deg_graph); #if 0 if (!DEG_debug_consistency_check(deg_graph)) { @@ -237,6 +255,16 @@ void DEG_graph_build_from_scene(Depsgraph *graph, Main *bmain, Scene *scene) } #endif + /* Relations are up to date. */ + deg_graph->need_update = false; + + /* Store pointers to commonly used valuated datablocks. */ + deg_graph->scene_cow = (Scene *)deg_graph->get_cow_id(°_graph->scene->id); + + if (need_on_visible_update) { + DEG_graph_on_visible_update(bmain, graph); + } + if (G.debug & G_DEBUG_DEPSGRAPH_BUILD) { printf("Depsgraph built in %f seconds.\n", PIL_check_seconds_timer() - start_time); @@ -246,83 +274,66 @@ void DEG_graph_build_from_scene(Depsgraph *graph, Main *bmain, Scene *scene) /* Tag graph relations for update. */ void DEG_graph_tag_relations_update(Depsgraph *graph) { + DEG_DEBUG_PRINTF(graph, TAG, "%s: Tagging relations for update.\n", __func__); DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(graph); deg_graph->need_update = true; -} - -/* Tag all relations for update. */ -void DEG_relations_tag_update(Main *bmain) -{ - for (Scene *scene = (Scene *)bmain->scene.first; - scene != NULL; - scene = (Scene *)scene->id.next) + /* NOTE: When relations are updated, it's quite possible that + * we've got new bases in the scene. This means, we need to + * re-create flat array of bases in view layer. + * + * TODO(sergey): Try to make it so we don't flush updates + * to the whole depsgraph. + */ { - if (scene->depsgraph != NULL) { - DEG_graph_tag_relations_update(scene->depsgraph); + DEG::IDDepsNode *id_node = deg_graph->find_id_node(°_graph->scene->id); + if (id_node != NULL) { + id_node->tag_update(deg_graph); } } } -/* Create new graph if didn't exist yet, - * or update relations if graph was tagged for update. - */ -void DEG_scene_relations_update(Main *bmain, Scene *scene) +/* Create or update relations in the specified graph. */ +void DEG_graph_relations_update(Depsgraph *graph, + Main *bmain, + Scene *scene, + ViewLayer *view_layer) { - if (scene->depsgraph == NULL) { - /* Rebuild graph from scratch and exit. */ - scene->depsgraph = DEG_graph_new(); - DEG_graph_build_from_scene(scene->depsgraph, bmain, scene); - return; - } - - DEG::Depsgraph *graph = reinterpret_cast<DEG::Depsgraph *>(scene->depsgraph); - if (!graph->need_update) { + DEG::Depsgraph *deg_graph = (DEG::Depsgraph *)graph; + if (!deg_graph->need_update) { /* Graph is up to date, nothing to do. */ return; } - - /* Clear all previous nodes and operations. */ - graph->clear_all_nodes(); - graph->operations.clear(); - BLI_gset_clear(graph->entry_tags, NULL); - - /* Build new nodes and relations. */ - DEG_graph_build_from_scene(reinterpret_cast< ::Depsgraph * >(graph), - bmain, - scene); - - graph->need_update = false; -} - -/* Rebuild dependency graph only for a given scene. */ -void DEG_scene_relations_rebuild(Main *bmain, Scene *scene) -{ - if (scene->depsgraph != NULL) { - DEG_graph_tag_relations_update(scene->depsgraph); - } - DEG_scene_relations_update(bmain, scene); + DEG_graph_build_from_view_layer(graph, bmain, scene, view_layer); } -void DEG_scene_graph_free(Scene *scene) +/* Tag all relations for update. */ +void DEG_relations_tag_update(Main *bmain) { - if (scene->depsgraph) { - DEG_graph_free(scene->depsgraph); - scene->depsgraph = NULL; + DEG_GLOBAL_DEBUG_PRINTF(TAG, "%s: Tagging relations for update.\n", __func__); + LISTBASE_FOREACH (Scene *, scene, &bmain->scene) { + LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) { + Depsgraph *depsgraph = + (Depsgraph *)BKE_scene_get_depsgraph(scene, + view_layer, + false); + if (depsgraph != NULL) { + DEG_graph_tag_relations_update(depsgraph); + } + } } } void DEG_add_collision_relations(DepsNodeHandle *handle, Scene *scene, Object *object, - Group *group, - int layer, + Collection *collection, unsigned int modifier_type, DEG_CollobjFilterFunction fn, bool dupli, const char *name) { unsigned int numcollobj; - Object **collobjs = get_collisionobjects_ext(scene, object, group, layer, &numcollobj, modifier_type, dupli); + Object **collobjs = get_collisionobjects_ext(scene, object, collection, &numcollobj, modifier_type, dupli); for (unsigned int i = 0; i < numcollobj; i++) { Object *ob1 = collobjs[i]; @@ -345,7 +356,7 @@ void DEG_add_forcefield_relations(DepsNodeHandle *handle, int skip_forcefield, const char *name) { - ListBase *effectors = pdInitEffectors(scene, object, NULL, effector_weights, false); + ListBase *effectors = pdInitEffectors(NULL, scene, object, NULL, effector_weights, false); if (effectors == NULL) { return; } @@ -374,7 +385,6 @@ void DEG_add_forcefield_relations(DepsNodeHandle *handle, scene, object, NULL, - eff->ob->lay, eModifierType_Collision, NULL, true, |