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/eval/deg_eval_visibility.cc')
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_visibility.cc147
1 files changed, 147 insertions, 0 deletions
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_visibility.cc b/source/blender/depsgraph/intern/eval/deg_eval_visibility.cc
new file mode 100644
index 00000000000..8bf26e45e2a
--- /dev/null
+++ b/source/blender/depsgraph/intern/eval/deg_eval_visibility.cc
@@ -0,0 +1,147 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2022 Blender Foundation. All rights reserved. */
+
+/** \file
+ * \ingroup depsgraph
+ */
+
+#include "intern/eval/deg_eval_visibility.h"
+
+#include "DNA_layer_types.h"
+#include "DNA_object_types.h"
+
+#include "BLI_assert.h"
+#include "BLI_stack.h"
+
+#include "DEG_depsgraph.h"
+
+#include "intern/depsgraph.h"
+#include "intern/depsgraph_relation.h"
+#include "intern/node/deg_node.h"
+#include "intern/node/deg_node_component.h"
+#include "intern/node/deg_node_id.h"
+#include "intern/node/deg_node_operation.h"
+
+namespace blender::deg {
+
+void deg_evaluate_object_node_visibility(::Depsgraph *depsgraph, IDNode *id_node)
+{
+ BLI_assert(GS(id_node->id_cow->name) == ID_OB);
+
+ Depsgraph *graph = reinterpret_cast<Depsgraph *>(depsgraph);
+ const Object *object = reinterpret_cast<const Object *>(id_node->id_cow);
+
+ DEG_debug_print_eval(depsgraph, __func__, object->id.name, &object->id);
+
+ const int required_flags = (graph->mode == DAG_EVAL_VIEWPORT) ? BASE_ENABLED_VIEWPORT :
+ BASE_ENABLED_RENDER;
+
+ const bool is_enabled = object->base_flag & required_flags;
+
+ if (id_node->is_enabled_on_eval != is_enabled) {
+ id_node->is_enabled_on_eval = is_enabled;
+
+ /* Tag dependency graph for changed visibility, so that it is updated on all dependencies prior
+ * to a pass of an actual evaluation. */
+ graph->need_update_nodes_visibility = true;
+ }
+}
+
+void deg_graph_flush_visibility_flags(Depsgraph *graph)
+{
+ enum {
+ DEG_NODE_VISITED = (1 << 0),
+ };
+
+ for (IDNode *id_node : graph->id_nodes) {
+ for (ComponentNode *comp_node : id_node->components.values()) {
+ comp_node->possibly_affects_visible_id = id_node->is_visible_on_build;
+ comp_node->affects_visible_id = id_node->is_visible_on_build && id_node->is_enabled_on_eval;
+ }
+ }
+
+ BLI_Stack *stack = BLI_stack_new(sizeof(OperationNode *), "DEG flush layers stack");
+
+ for (OperationNode *op_node : graph->operations) {
+ op_node->custom_flags = 0;
+ op_node->num_links_pending = 0;
+ for (Relation *rel : op_node->outlinks) {
+ if ((rel->from->type == NodeType::OPERATION) && (rel->flag & RELATION_FLAG_CYCLIC) == 0) {
+ ++op_node->num_links_pending;
+ }
+ }
+ if (op_node->num_links_pending == 0) {
+ BLI_stack_push(stack, &op_node);
+ op_node->custom_flags |= DEG_NODE_VISITED;
+ }
+ }
+
+ while (!BLI_stack_is_empty(stack)) {
+ OperationNode *op_node;
+ BLI_stack_pop(stack, &op_node);
+
+ /* Flush flags to parents. */
+ for (Relation *rel : op_node->inlinks) {
+ if (rel->from->type == NodeType::OPERATION) {
+ const OperationNode *op_to = reinterpret_cast<const OperationNode *>(rel->to);
+ const ComponentNode *comp_to = op_to->owner;
+ OperationNode *op_from = reinterpret_cast<OperationNode *>(rel->from);
+ ComponentNode *comp_from = op_from->owner;
+
+ const bool target_possibly_affects_visible_id = comp_to->possibly_affects_visible_id;
+ const bool target_affects_visible_id = comp_to->affects_visible_id;
+
+ op_from->flag |= (op_to->flag & OperationFlag::DEPSOP_FLAG_AFFECTS_VISIBILITY);
+
+ /* Visibility component forces all components of the current ID to be considered as
+ * affecting directly visible. */
+ if (comp_from->type == NodeType::VISIBILITY) {
+ const IDNode *id_node_from = comp_from->owner;
+ if (target_possibly_affects_visible_id) {
+ for (ComponentNode *comp_node : id_node_from->components.values()) {
+ comp_node->possibly_affects_visible_id |= target_possibly_affects_visible_id;
+ }
+ }
+ if (target_affects_visible_id) {
+ for (ComponentNode *comp_node : id_node_from->components.values()) {
+ comp_node->affects_visible_id |= target_affects_visible_id;
+ }
+ }
+ }
+ else {
+ comp_from->possibly_affects_visible_id |= target_possibly_affects_visible_id;
+ comp_from->affects_visible_id |= target_affects_visible_id;
+ }
+ }
+ }
+
+ /* Schedule parent nodes. */
+ for (Relation *rel : op_node->inlinks) {
+ if (rel->from->type == NodeType::OPERATION) {
+ OperationNode *op_from = (OperationNode *)rel->from;
+ if ((rel->flag & RELATION_FLAG_CYCLIC) == 0) {
+ BLI_assert(op_from->num_links_pending > 0);
+ --op_from->num_links_pending;
+ }
+ if ((op_from->num_links_pending == 0) && (op_from->custom_flags & DEG_NODE_VISITED) == 0) {
+ BLI_stack_push(stack, &op_from);
+ op_from->custom_flags |= DEG_NODE_VISITED;
+ }
+ }
+ }
+ }
+ BLI_stack_free(stack);
+
+ graph->need_update_nodes_visibility = false;
+}
+
+void deg_graph_flush_visibility_flags_if_needed(Depsgraph *graph)
+{
+ if (!graph->need_update_nodes_visibility) {
+ return;
+ }
+
+ deg_graph_flush_visibility_flags(graph);
+}
+
+} // namespace blender::deg