diff options
Diffstat (limited to 'source/blender/depsgraph/intern/node')
10 files changed, 112 insertions, 61 deletions
diff --git a/source/blender/depsgraph/intern/node/deg_node.h b/source/blender/depsgraph/intern/node/deg_node.h index 509867ad47a..db912ee3a82 100644 --- a/source/blender/depsgraph/intern/node/deg_node.h +++ b/source/blender/depsgraph/intern/node/deg_node.h @@ -18,8 +18,7 @@ struct ID; struct Scene; -namespace blender { -namespace deg { +namespace blender::deg { struct Depsgraph; struct OperationNode; @@ -65,7 +64,7 @@ enum class NodeType { ANIMATION, /* Transform Component (Parenting/Constraints) */ TRANSFORM, - /* Geometry Component (#Mesh / #DispList) */ + /* Geometry Component (#Mesh, #Curves, etc.) */ GEOMETRY, /* Sequencer Component (Scene Only) */ SEQUENCER, @@ -217,5 +216,4 @@ struct Node { void deg_register_base_depsnodes(); -} // namespace deg -} // namespace blender +} // namespace blender::deg diff --git a/source/blender/depsgraph/intern/node/deg_node_component.cc b/source/blender/depsgraph/intern/node/deg_node_component.cc index cfcbec46569..f2d82e80fa6 100644 --- a/source/blender/depsgraph/intern/node/deg_node_component.cc +++ b/source/blender/depsgraph/intern/node/deg_node_component.cc @@ -67,7 +67,10 @@ uint64_t ComponentNode::OperationIDKey::hash() const } ComponentNode::ComponentNode() - : entry_operation(nullptr), exit_operation(nullptr), affects_directly_visible(false) + : entry_operation(nullptr), + exit_operation(nullptr), + possibly_affects_visible_id(false), + affects_visible_id(false) { operations_map = new Map<ComponentNode::OperationIDKey, OperationNode *>(); } @@ -90,7 +93,7 @@ string ComponentNode::identifier() const const string idname = this->owner->name; const string typebuf = "" + to_string(static_cast<int>(type)) + ")"; return typebuf + name + " : " + idname + - "( affects_directly_visible: " + (affects_directly_visible ? "true" : "false") + ")"; + "( affects_visible_id: " + (affects_visible_id ? "true" : "false") + ")"; } OperationNode *ComponentNode::find_operation(OperationIDKey key) const @@ -215,10 +218,9 @@ void ComponentNode::clear_operations() void ComponentNode::tag_update(Depsgraph *graph, eUpdateSource source) { - OperationNode *entry_op = get_entry_operation(); - if (entry_op != nullptr && entry_op->flag & DEPSOP_FLAG_NEEDS_UPDATE) { - return; - } + /* Note that the node might already be tagged for an update due invisible state of the node + * during previous dependency evaluation. Here the node gets re-tagged, so we need to give + * the evaluated clues that evaluation needs to happen again. */ for (OperationNode *op_node : operations) { op_node->tag_update(graph, source); } diff --git a/source/blender/depsgraph/intern/node/deg_node_component.h b/source/blender/depsgraph/intern/node/deg_node_component.h index 6958866af3b..f7f38b88854 100644 --- a/source/blender/depsgraph/intern/node/deg_node_component.h +++ b/source/blender/depsgraph/intern/node/deg_node_component.h @@ -22,10 +22,8 @@ struct ID; struct bPoseChannel; -namespace blender { -namespace deg { +namespace blender::deg { -struct BoneComponentNode; struct Depsgraph; struct IDNode; struct OperationNode; @@ -56,32 +54,45 @@ struct ComponentNode : public Node { virtual string identifier() const override; - /* Find an existing operation, if requested operation does not exist - * nullptr will be returned. */ + /* Find an existing operation, if requested operation does not exist nullptr will be returned. + * See #add_operation for the meaning and examples of #name and #name_tag. + */ OperationNode *find_operation(OperationIDKey key) const; - OperationNode *find_operation(OperationCode opcode, const char *name, int name_tag) const; + OperationNode *find_operation(OperationCode opcode, + const char *name = "", + int name_tag = -1) const; - /* Find an existing operation, will throw an assert() if it does not exist. */ + /* Find an existing operation, will throw an assert() if it does not exist. + * See #add_operation for the meaning and examples of #name and #name_tag. */ OperationNode *get_operation(OperationIDKey key) const; - OperationNode *get_operation(OperationCode opcode, const char *name, int name_tag) const; + OperationNode *get_operation(OperationCode opcode, + const char *name = "", + int name_tag = -1) const; /* Check operation exists and return it. */ bool has_operation(OperationIDKey key) const; - bool has_operation(OperationCode opcode, const char *name, int name_tag) const; + bool has_operation(OperationCode opcode, const char *name = "", int name_tag = -1) const; /** * Create a new node for representing an operation and add this to graph + * * \warning If an existing node is found, it will be modified. This helps * when node may have been partially created earlier (e.g. parent ref before * parent item is added) * * \param opcode: The operation to perform. - * \param name: Identifier for operation - used to find/locate it again. + * \param name: An optional identifier for operation. It will be used to tell operation nodes + * with the same code apart. For example, parameter operation code will have name + * set to the corresponding custom property name + * \param name_tag: An optional integer tag for the name. Is an additional way to tell operations + * apart. For example, RNA path to an array property will have the same opcode + * of PARAMETERS, name corresponding to the property name, and name tag + * corresponding to the array index within the property. */ OperationNode *add_operation(const DepsEvalOperationCb &op, OperationCode opcode, - const char *name, - int name_tag); + const char *name = "", + int name_tag = -1); /* Entry/exit operations management. * @@ -125,9 +136,17 @@ struct ComponentNode : public Node { return true; } - /* Denotes whether this component affects (possibly indirectly) on a - * directly visible object. */ - bool affects_directly_visible; + /* The component has (possibly indirect) effect on a data-block whose node has + * is_visible_on_build set to true. + * + * This field is ensured to be up-to-date prior to `IDNode::finalize_build()`. */ + bool possibly_affects_visible_id; + + /* Denotes whether this component actually affects (possibly indirectly) on a directly visible + * object. Includes possibly run-time visibility update of ID nodes. + * + * NOTE: Is only reliable after `deg_graph_flush_visibility()`. */ + bool affects_visible_id; }; /* ---------------------------------------- */ @@ -186,7 +205,7 @@ DEG_COMPONENT_NODE_DECLARE_GENERIC(Synchronization); DEG_COMPONENT_NODE_DECLARE_GENERIC(Audio); DEG_COMPONENT_NODE_DECLARE_GENERIC(Armature); DEG_COMPONENT_NODE_DECLARE_GENERIC(GenericDatablock); -DEG_COMPONENT_NODE_DECLARE_NO_COW(Visibility); +DEG_COMPONENT_NODE_DECLARE_NO_COW_TAG_ON_UPDATE(Visibility); DEG_COMPONENT_NODE_DECLARE_GENERIC(Simulation); DEG_COMPONENT_NODE_DECLARE_GENERIC(NTreeOutput); @@ -218,5 +237,4 @@ struct ParametersComponentNode : public ComponentNode { void deg_register_component_depsnodes(); -} // namespace deg -} // namespace blender +} // namespace blender::deg diff --git a/source/blender/depsgraph/intern/node/deg_node_factory.h b/source/blender/depsgraph/intern/node/deg_node_factory.h index 6caf99ac9ba..ec5029e8352 100644 --- a/source/blender/depsgraph/intern/node/deg_node_factory.h +++ b/source/blender/depsgraph/intern/node/deg_node_factory.h @@ -14,9 +14,7 @@ struct ID; -namespace blender { -namespace deg { - +namespace blender::deg { struct DepsNodeFactory { virtual NodeType type() const = 0; virtual const char *type_name() const = 0; @@ -41,7 +39,6 @@ void register_node_typeinfo(DepsNodeFactory *factory); /* Get typeinfo for specified type */ DepsNodeFactory *type_get_factory(NodeType type); -} // namespace deg -} // namespace blender +} // namespace blender::deg #include "intern/node/deg_node_factory_impl.h" diff --git a/source/blender/depsgraph/intern/node/deg_node_factory_impl.h b/source/blender/depsgraph/intern/node/deg_node_factory_impl.h index 76a91860cc1..d9d0a1c1e3e 100644 --- a/source/blender/depsgraph/intern/node/deg_node_factory_impl.h +++ b/source/blender/depsgraph/intern/node/deg_node_factory_impl.h @@ -11,8 +11,7 @@ struct ID; -namespace blender { -namespace deg { +namespace blender::deg { template<class ModeObjectType> NodeType DepsNodeFactoryImpl<ModeObjectType>::type() const { @@ -48,5 +47,4 @@ Node *DepsNodeFactoryImpl<ModeObjectType>::create_node(const ID *id, return node; } -} // namespace deg -} // namespace blender +} // namespace blender::deg diff --git a/source/blender/depsgraph/intern/node/deg_node_id.cc b/source/blender/depsgraph/intern/node/deg_node_id.cc index 99224501e98..735d606ac9e 100644 --- a/source/blender/depsgraph/intern/node/deg_node_id.cc +++ b/source/blender/depsgraph/intern/node/deg_node_id.cc @@ -69,7 +69,8 @@ void IDNode::init(const ID *id, const char *UNUSED(subdata)) customdata_masks = DEGCustomDataMeshMasks(); previous_customdata_masks = DEGCustomDataMeshMasks(); linked_state = DEG_ID_LINKED_INDIRECTLY; - is_directly_visible = true; + is_visible_on_build = true; + is_enabled_on_eval = true; is_collection_fully_expanded = false; has_base = false; is_user_modified = false; @@ -138,8 +139,8 @@ string IDNode::identifier() const BLI_snprintf(orig_ptr, sizeof(orig_ptr), "%p", id_orig); BLI_snprintf(cow_ptr, sizeof(cow_ptr), "%p", id_cow); return string(nodeTypeAsString(type)) + " : " + name + " (orig: " + orig_ptr + - ", eval: " + cow_ptr + ", is_directly_visible " + - (is_directly_visible ? "true" : "false") + ")"; + ", eval: " + cow_ptr + ", is_visible_on_build " + + (is_visible_on_build ? "true" : "false") + ")"; } ComponentNode *IDNode::find_component(NodeType type, const char *name) const @@ -188,7 +189,7 @@ IDComponentsMask IDNode::get_visible_components_mask() const { IDComponentsMask result = 0; for (ComponentNode *comp_node : components.values()) { - if (comp_node->affects_directly_visible) { + if (comp_node->possibly_affects_visible_id) { const int component_type_as_int = static_cast<int>(comp_node->type); BLI_assert(component_type_as_int < 64); result |= (1ULL << component_type_as_int); diff --git a/source/blender/depsgraph/intern/node/deg_node_id.h b/source/blender/depsgraph/intern/node/deg_node_id.h index a8b6294b482..7f0a656cb8d 100644 --- a/source/blender/depsgraph/intern/node/deg_node_id.h +++ b/source/blender/depsgraph/intern/node/deg_node_id.h @@ -12,8 +12,7 @@ #include "DNA_ID.h" #include "intern/node/deg_node.h" -namespace blender { -namespace deg { +namespace blender::deg { struct ComponentNode; @@ -92,8 +91,21 @@ struct IDNode : public Node { eDepsNode_LinkedState_Type linked_state; - /* Indicates the data-block is visible in the evaluated scene. */ - bool is_directly_visible; + /* Indicates the data-block is to be considered visible in the evaluated scene. + * + * This flag is set during dependency graph build where check for an actual visibility might not + * be available yet due to driven or animated restriction flags. So it is more of an intent or, + * in other words, plausibility of the data-block to be visible. */ + bool is_visible_on_build; + + /* Evaluated state of whether evaluation considered this data-block "enabled". + * + * For objects this is derived from the base restriction flags, which might be animated or + * driven. It is set to `BASE_ENABLED_<VIEWPORT, RENDER>` (depending on the graph mode) after + * the object's flags from layer were evaluated. + * + * For other data-types is currently always true. */ + bool is_enabled_on_eval; /* For the collection type of ID, denotes whether collection was fully * recursed into. */ @@ -117,5 +129,4 @@ struct IDNode : public Node { DEG_DEPSNODE_DECLARE; }; -} // namespace deg -} // namespace blender +} // namespace blender::deg diff --git a/source/blender/depsgraph/intern/node/deg_node_operation.cc b/source/blender/depsgraph/intern/node/deg_node_operation.cc index c29aeefd9b2..016af735fcf 100644 --- a/source/blender/depsgraph/intern/node/deg_node_operation.cc +++ b/source/blender/depsgraph/intern/node/deg_node_operation.cc @@ -32,6 +32,8 @@ const char *operationCodeAsString(OperationCode opcode) return "PARAMETERS_EVAL"; case OperationCode::PARAMETERS_EXIT: return "PARAMETERS_EXIT"; + case OperationCode::VISIBILITY: + return "VISIBILITY"; /* Animation, Drivers, etc. */ case OperationCode::ANIMATION_ENTRY: return "ANIMATION_ENTRY"; @@ -82,6 +84,8 @@ const char *operationCodeAsString(OperationCode opcode) /* Geometry. */ case OperationCode::GEOMETRY_EVAL_INIT: return "GEOMETRY_EVAL_INIT"; + case OperationCode::MODIFIER: + return "MODIFIER"; case OperationCode::GEOMETRY_EVAL: return "GEOMETRY_EVAL"; case OperationCode::GEOMETRY_EVAL_DONE: @@ -216,9 +220,23 @@ string OperationNode::full_identifier() const void OperationNode::tag_update(Depsgraph *graph, eUpdateSource source) { - if ((flag & DEPSOP_FLAG_NEEDS_UPDATE) == 0) { - graph->add_entry_tag(this); + /* Ensure that there is an entry tag for this update. + * + * Note that the node might already be tagged for an update due invisible state of the node + * during previous dependency evaluation. Here the node gets re-tagged, so we need to give + * the evaluated clues that evaluation needs to happen again. */ + graph->add_entry_tag(this); + + /* Enforce dynamic visibility code-path update. + * This ensures visibility flags are consistently propagated throughout the dependency graph when + * there is no animated visibility in the graph. + * + * For example this ensures that graph is updated properly when manually toggling non-animated + * modifier visibility. */ + if (opcode == OperationCode::VISIBILITY) { + graph->need_update_nodes_visibility = true; } + /* Tag for update, but also note that this was the source of an update. */ flag |= (DEPSOP_FLAG_NEEDS_UPDATE | DEPSOP_FLAG_DIRECTLY_MODIFIED); switch (source) { diff --git a/source/blender/depsgraph/intern/node/deg_node_operation.h b/source/blender/depsgraph/intern/node/deg_node_operation.h index d4916be1113..cb3beb56556 100644 --- a/source/blender/depsgraph/intern/node/deg_node_operation.h +++ b/source/blender/depsgraph/intern/node/deg_node_operation.h @@ -13,8 +13,7 @@ struct Depsgraph; -namespace blender { -namespace deg { +namespace blender::deg { struct ComponentNode; @@ -34,6 +33,7 @@ enum class OperationCode { PARAMETERS_ENTRY, PARAMETERS_EVAL, PARAMETERS_EXIT, + VISIBILITY, /* Animation, Drivers, etc. --------------------------------------------- */ /* NLA + Action */ @@ -84,6 +84,8 @@ enum class OperationCode { /* Initialize evaluation of the geometry. Is an entry operation of geometry * component. */ GEOMETRY_EVAL_INIT, + /* Modifier. */ + MODIFIER, /* Evaluate the whole geometry, including modifiers. */ GEOMETRY_EVAL, /* Evaluation of geometry is completely done. */ @@ -202,15 +204,24 @@ const char *operationCodeAsString(OperationCode opcode); enum OperationFlag { /* Node needs to be updated. */ DEPSOP_FLAG_NEEDS_UPDATE = (1 << 0), + /* Node was directly modified, causing need for update. */ DEPSOP_FLAG_DIRECTLY_MODIFIED = (1 << 1), + /* Node was updated due to user input. */ DEPSOP_FLAG_USER_MODIFIED = (1 << 2), - /* Node may not be removed, even when it has no evaluation callback and no - * outgoing relations. This is for NO-OP nodes that are purely used to indicate a - * relation between components/IDs, and not for connecting to an operation. */ + + /* Node may not be removed, even when it has no evaluation callback and no outgoing relations. + * This is for NO-OP nodes that are purely used to indicate a relation between components/IDs, + * and not for connecting to an operation. */ DEPSOP_FLAG_PINNED = (1 << 3), + /* The operation directly or indirectly affects ID node visibility. */ + DEPSOP_FLAG_AFFECTS_VISIBILITY = (1 << 4), + + /* Evaluation of the node is temporarily disabled. */ + DEPSOP_FLAG_MUTE = (1 << 5), + /* Set of flags which gets flushed along the relations. */ DEPSOP_FLAG_FLUSH = (DEPSOP_FLAG_USER_MODIFIED), }; @@ -268,5 +279,4 @@ struct OperationNode : public Node { void deg_register_operation_depsnodes(); -} // namespace deg -} // namespace blender +} // namespace blender::deg diff --git a/source/blender/depsgraph/intern/node/deg_node_time.h b/source/blender/depsgraph/intern/node/deg_node_time.h index fcfe9a0fa80..3946b63384d 100644 --- a/source/blender/depsgraph/intern/node/deg_node_time.h +++ b/source/blender/depsgraph/intern/node/deg_node_time.h @@ -9,8 +9,7 @@ #include "intern/node/deg_node.h" -namespace blender { -namespace deg { +namespace blender::deg { /* Time Source Node. */ struct TimeSourceNode : public Node { @@ -25,5 +24,4 @@ struct TimeSourceNode : public Node { DEG_DEPSNODE_DECLARE; }; -} // namespace deg -} // namespace blender +} // namespace blender::deg |