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
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/depsgraph/intern/depsgraph_build.cc')
-rw-r--r--source/blender/depsgraph/intern/depsgraph_build.cc161
1 files changed, 85 insertions, 76 deletions
diff --git a/source/blender/depsgraph/intern/depsgraph_build.cc b/source/blender/depsgraph/intern/depsgraph_build.cc
index 1b270e71d64..da64478404b 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(&deg_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(&deg_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;
+ DEG_graph_build_from_view_layer(graph, bmain, scene, view_layer);
}
-/* 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);
-}
-
-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,36 +356,35 @@ void DEG_add_forcefield_relations(DepsNodeHandle *handle,
int skip_forcefield,
const char *name)
{
- ListBase *effectors = pdInitEffectors(scene, object, NULL, effector_weights, false);
- if (effectors == NULL) {
- return;
- }
- for (EffectorCache *eff = (EffectorCache*)effectors->first; eff; eff = eff->next) {
- if (eff->ob != object && eff->pd->forcefield != skip_forcefield) {
- DEG_add_object_relation(handle, eff->ob, DEG_OB_COMP_TRANSFORM, name);
- if (eff->psys) {
- DEG_add_object_relation(handle, eff->ob, DEG_OB_COMP_EVAL_PARTICLES, name);
+ Depsgraph *depsgraph = DEG_get_graph_from_handle(handle);
+ DEG::Depsgraph *deg_graph = (DEG::Depsgraph *)depsgraph;
+ ListBase *relations = deg_build_effector_relations(deg_graph, effector_weights->group);
+
+ LISTBASE_FOREACH (EffectorRelation *, relation, relations) {
+ if (relation->ob != object && relation->pd->forcefield != skip_forcefield) {
+ DEG_add_object_relation(handle, relation->ob, DEG_OB_COMP_TRANSFORM, name);
+ if (relation->psys) {
+ DEG_add_object_relation(handle, relation->ob, DEG_OB_COMP_EVAL_PARTICLES, name);
/* TODO: remove this when/if EVAL_PARTICLES is sufficient
* for up to date particles.
*/
- DEG_add_object_relation(handle, eff->ob, DEG_OB_COMP_GEOMETRY, name);
+ DEG_add_object_relation(handle, relation->ob, DEG_OB_COMP_GEOMETRY, name);
}
- if (eff->pd->forcefield == PFIELD_SMOKEFLOW && eff->pd->f_source) {
+ if (relation->pd->forcefield == PFIELD_SMOKEFLOW && relation->pd->f_source) {
DEG_add_object_relation(handle,
- eff->pd->f_source,
+ relation->pd->f_source,
DEG_OB_COMP_TRANSFORM,
"Smoke Force Domain");
DEG_add_object_relation(handle,
- eff->pd->f_source,
+ relation->pd->f_source,
DEG_OB_COMP_GEOMETRY,
"Smoke Force Domain");
}
- if (add_absorption && (eff->pd->flag & PFIELD_VISIBILITY)) {
+ if (add_absorption && (relation->pd->flag & PFIELD_VISIBILITY)) {
DEG_add_collision_relations(handle,
scene,
object,
NULL,
- eff->ob->lay,
eModifierType_Collision,
NULL,
true,
@@ -382,5 +392,4 @@ void DEG_add_forcefield_relations(DepsNodeHandle *handle,
}
}
}
- pdEndEffectors(&effectors);
}