diff options
Diffstat (limited to 'source/blender/depsgraph/intern/builder')
5 files changed, 56 insertions, 93 deletions
diff --git a/source/blender/depsgraph/intern/builder/deg_builder.cc b/source/blender/depsgraph/intern/builder/deg_builder.cc index 1fec1fb3219..5353f71685c 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder.cc @@ -29,6 +29,7 @@ #include "intern/depsgraph_tag.h" #include "intern/depsgraph_type.h" #include "intern/eval/deg_eval_copy_on_write.h" +#include "intern/eval/deg_eval_visibility.h" #include "intern/node/deg_node.h" #include "intern/node/deg_node_component.h" #include "intern/node/deg_node_id.h" @@ -71,10 +72,15 @@ bool DepsgraphBuilder::need_pull_base_into_graph(const Base *base) if (base->flag & base_flag) { return true; } + /* More involved check: since we don't support dynamic changes in dependency graph topology and * all visible objects are to be part of dependency graph, we pull all objects which has animated * visibility. */ - const Object *object = base->object; + return is_object_visibility_animated(base->object); +} + +bool DepsgraphBuilder::is_object_visibility_animated(const Object *object) +{ AnimatedPropertyID property_id; if (graph_->mode == DAG_EVAL_VIEWPORT) { property_id = AnimatedPropertyID(&object->id, &RNA_Object, "hide_viewport"); @@ -127,84 +133,9 @@ bool DepsgraphBuilder::check_pchan_has_bbone_segments(const Object *object, cons /** \name Builder Finalizer. * \{ */ -namespace { - -void deg_graph_build_flush_visibility(Depsgraph *graph) -{ - enum { - DEG_NODE_VISITED = (1 << 0), - }; - - BLI_Stack *stack = BLI_stack_new(sizeof(OperationNode *), "DEG flush layers stack"); - for (IDNode *id_node : graph->id_nodes) { - for (ComponentNode *comp_node : id_node->components.values()) { - comp_node->affects_directly_visible |= id_node->is_directly_visible; - } - } - - 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 layers to parents. */ - for (Relation *rel : op_node->inlinks) { - if (rel->from->type == NodeType::OPERATION) { - OperationNode *op_from = (OperationNode *)rel->from; - ComponentNode *comp_from = op_from->owner; - const bool target_directly_visible = op_node->owner->affects_directly_visible; - - /* Visibility component forces all components of the current ID to be considered as - * affecting directly visible. */ - if (comp_from->type == NodeType::VISIBILITY) { - if (target_directly_visible) { - IDNode *id_node_from = comp_from->owner; - for (ComponentNode *comp_node : id_node_from->components.values()) { - comp_node->affects_directly_visible |= target_directly_visible; - } - } - } - else { - comp_from->affects_directly_visible |= target_directly_visible; - } - } - } - /* 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); -} - -} // namespace - void deg_graph_build_finalize(Main *bmain, Depsgraph *graph) { - /* Make sure dependencies of visible ID data-blocks are visible. */ - deg_graph_build_flush_visibility(graph); + deg_graph_flush_visibility_flags(graph); deg_graph_remove_unused_noops(graph); /* Re-tag IDs for update if it was tagged before the relations diff --git a/source/blender/depsgraph/intern/builder/deg_builder.h b/source/blender/depsgraph/intern/builder/deg_builder.h index 950ebfb35ba..c44e5fd5f4d 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder.h +++ b/source/blender/depsgraph/intern/builder/deg_builder.h @@ -24,6 +24,8 @@ class DepsgraphBuilder { virtual bool need_pull_base_into_graph(const Base *base); + virtual bool is_object_visibility_animated(const Object *object); + virtual bool check_pchan_has_bbone(const Object *object, const bPoseChannel *pchan); virtual bool check_pchan_has_bbone_segments(const Object *object, const bPoseChannel *pchan); virtual bool check_pchan_has_bbone_segments(const Object *object, const char *bone_name); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc index 473dda2290c..c65c4beeed6 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc @@ -107,6 +107,7 @@ #include "intern/depsgraph_tag.h" #include "intern/depsgraph_type.h" #include "intern/eval/deg_eval_copy_on_write.h" +#include "intern/eval/deg_eval_visibility.h" #include "intern/node/deg_node.h" #include "intern/node/deg_node_component.h" #include "intern/node/deg_node_id.h" @@ -179,11 +180,27 @@ IDNode *DepsgraphNodeBuilder::add_id_node(ID *id) } ComponentNode *visibility_component = id_node->add_component(NodeType::VISIBILITY); - OperationNode *visibility_operation = visibility_component->add_operation( - nullptr, OperationCode::VISIBILITY); + OperationNode *visibility_operation; + + /* Optimization: currently only objects need a special visibility evaluation. For the rest ID + * types keep the node as a NO-OP so that relations can still be routed, but without penalty + * during the graph evaluation. */ + if (id_type == ID_OB) { + visibility_operation = visibility_component->add_operation( + [id_node](::Depsgraph *depsgraph) { + deg_evaluate_object_node_visibility(depsgraph, id_node); + }, + OperationCode::VISIBILITY); + } + else { + visibility_operation = visibility_component->add_operation(nullptr, + OperationCode::VISIBILITY); + } + /* Pin the node so that it and its relations are preserved by the unused nodes/relations * deletion. This is mainly to make it easier to debug visibility. */ - visibility_operation->flag |= OperationFlag::DEPSOP_FLAG_PINNED; + visibility_operation->flag |= (OperationFlag::DEPSOP_FLAG_PINNED | + OperationFlag::DEPSOP_FLAG_AFFECTS_VISIBILITY); graph_->operations.append(visibility_operation); } return id_node; @@ -652,7 +669,7 @@ void DepsgraphNodeBuilder::build_collection(LayerCollection *from_layer_collecti IDNode *id_node; if (built_map_.checkIsBuiltAndTag(collection)) { id_node = find_id_node(&collection->id); - if (is_collection_visible && id_node->is_directly_visible == false && + if (is_collection_visible && id_node->is_visible_on_build == false && id_node->is_collection_fully_expanded == true) { /* Collection became visible, make sure nested collections and * objects are poked with the new visibility flag, since they @@ -669,7 +686,7 @@ void DepsgraphNodeBuilder::build_collection(LayerCollection *from_layer_collecti else { /* Collection itself. */ id_node = add_id_node(&collection->id); - id_node->is_directly_visible = is_collection_visible; + id_node->is_visible_on_build = is_collection_visible; build_idproperties(collection->id.properties); add_operation_node(&collection->id, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL_DONE); @@ -716,7 +733,7 @@ void DepsgraphNodeBuilder::build_object(int base_index, build_object_flags(base_index, object, linked_state); } id_node->linked_state = max(id_node->linked_state, linked_state); - id_node->is_directly_visible |= is_visible; + id_node->is_visible_on_build |= is_visible; id_node->has_base |= (base_index != -1); /* There is no relation path which will connect current object with all the ones which come @@ -735,10 +752,10 @@ void DepsgraphNodeBuilder::build_object(int base_index, * Probably need to assign that to something non-nullptr, but then the logic here will still be * somewhat weird. */ if (scene_ != nullptr && object == scene_->camera) { - id_node->is_directly_visible = true; + id_node->is_visible_on_build = true; } else { - id_node->is_directly_visible = is_visible; + id_node->is_visible_on_build = is_visible; } id_node->has_base |= (base_index != -1); /* Various flags, flushing from bases/collections. */ diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc index 32ec94211a0..5af9e7d4fe9 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc @@ -92,14 +92,20 @@ void DepsgraphNodeBuilder::build_view_layer(Scene *scene, int base_index = 0; LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) { /* object itself */ - if (need_pull_base_into_graph(base)) { - /* NOTE: We consider object visible even if it's currently - * restricted by the base/restriction flags. Otherwise its drivers - * will never be evaluated. - * - * TODO(sergey): Need to go more granular on visibility checks. */ - build_object(base_index, base->object, linked_state, true); - base_index++; + if (!need_pull_base_into_graph(base)) { + continue; + } + + /* NOTE: We consider object visible even if it's currently + * restricted by the base/restriction flags. Otherwise its drivers + * will never be evaluated. + * + * TODO(sergey): Need to go more granular on visibility checks. */ + build_object(base_index, base->object, linked_state, true); + base_index++; + + if (!graph_->has_animated_visibility) { + graph_->has_animated_visibility |= is_object_visibility_animated(base->object); } } build_layer_collections(&view_layer->layer_collections); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 4fe8a626af5..f2646ebc1f1 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -810,6 +810,13 @@ void DepsgraphRelationBuilder::build_object(Object *object) /* Parameters. */ build_parameters(&object->id); + + /* Visibility. + * Evaluate visibility node after the object's base_flags has been updated to the current state + * of collections restrict and object's restrict flags. */ + const ComponentKey object_from_layer_entry_key(&object->id, NodeType::OBJECT_FROM_LAYER); + const ComponentKey visibility_key(&object->id, NodeType::VISIBILITY); + add_relation(object_from_layer_entry_key, visibility_key, "Object Visibility"); } /* NOTE: Implies that the object has base in the current view layer. */ |