Cleanup: remove redundant doxygen \file argument
[blender.git] / source / blender / depsgraph / intern / depsgraph_tag.cc
index 26a12f4..adadd9b 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version 2
  *
  * The Original Code is Copyright (C) 2013 Blender Foundation.
  * All rights reserved.
- *
- * Original Author: Joshua Leung
- * Contributor(s): None Yet
- *
- * ***** END GPL LICENSE BLOCK *****
  */
 
-/** \file blender/depsgraph/intern/depsgraph_tag.cc
- *  \ingroup depsgraph
+/** \file \ingroup depsgraph
  *
  * Core routines for how the Depsgraph works.
  */
 
+#include "intern/depsgraph_tag.h"
+
 #include <stdio.h>
 #include <cstring>  /* required for memset */
 #include <queue>
@@ -51,6 +45,7 @@ extern "C" {
 #include "DNA_windowmanager_types.h"
 
 #include "BKE_animsys.h"
+#include "BKE_global.h"
 #include "BKE_idcode.h"
 #include "BKE_node.h"
 #include "BKE_scene.h"
@@ -62,18 +57,19 @@ extern "C" {
 } /* extern "C" */
 
 #include "DEG_depsgraph.h"
+#include "DEG_depsgraph_debug.h"
 #include "DEG_depsgraph_query.h"
 
 #include "intern/builder/deg_builder.h"
+#include "intern/depsgraph.h"
+#include "intern/depsgraph_update.h"
 #include "intern/eval/deg_eval_copy_on_write.h"
 #include "intern/eval/deg_eval_flush.h"
-#include "intern/nodes/deg_node.h"
-#include "intern/nodes/deg_node_component.h"
-#include "intern/nodes/deg_node_id.h"
-#include "intern/nodes/deg_node_operation.h"
-
-#include "intern/depsgraph_intern.h"
-#include "util/deg_util_foreach.h"
+#include "intern/node/deg_node.h"
+#include "intern/node/deg_node_component.h"
+#include "intern/node/deg_node_factory.h"
+#include "intern/node/deg_node_id.h"
+#include "intern/node/deg_node_operation.h"
 
 /* *********************** */
 /* Update Tagging/Flushing */
@@ -82,21 +78,24 @@ namespace DEG {
 
 namespace {
 
-void deg_graph_id_tag_update(Main *bmain, Depsgraph *graph, ID *id, int flag);
-
 void depsgraph_geometry_tag_to_component(const ID *id,
-                                         eDepsNode_Type *component_type)
+                                         NodeType *component_type)
 {
-       const eDepsNode_Type result = deg_geometry_tag_to_component(id);
-       if (result != DEG_NODE_TYPE_UNDEFINED) {
+       const NodeType result = geometry_tag_to_component(id);
+       if (result != NodeType::UNDEFINED) {
                *component_type = result;
        }
 }
 
+bool is_selectable_data_id_type(const ID_Type id_type)
+{
+       return ELEM(id_type, ID_ME, ID_CU, ID_MB, ID_LT, ID_GD);
+}
+
 void depsgraph_select_tag_to_component_opcode(
         const ID *id,
-        eDepsNode_Type *component_type,
-        eDepsOperation_Code *operation_code)
+        NodeType *component_type,
+        OperationCode *operation_code)
 {
        const ID_Type id_type = GS(id->name);
        if (id_type == ID_SCE) {
@@ -107,72 +106,75 @@ void depsgraph_select_tag_to_component_opcode(
                 *
                 * TODO(sergey): We can introduce explicit exit operation which
                 * does nothing and which is only used to cascade flush down the
-                * road.
-                */
-               *component_type = DEG_NODE_TYPE_LAYER_COLLECTIONS;
-               *operation_code = DEG_OPCODE_VIEW_LAYER_EVAL;
+                * road. */
+               *component_type = NodeType::LAYER_COLLECTIONS;
+               *operation_code = OperationCode::VIEW_LAYER_EVAL;
        }
        else if (id_type == ID_OB) {
-               *component_type = DEG_NODE_TYPE_OBJECT_FROM_LAYER;
-               *operation_code = DEG_OPCODE_OBJECT_BASE_FLAGS;
+               *component_type = NodeType::OBJECT_FROM_LAYER;
+               *operation_code = OperationCode::OBJECT_BASE_FLAGS;
        }
        else if (id_type == ID_MC) {
-               *component_type = DEG_NODE_TYPE_BATCH_CACHE;
-               *operation_code = DEG_OPCODE_MOVIECLIP_SELECT_UPDATE;
+               *component_type = NodeType::BATCH_CACHE;
+               *operation_code = OperationCode::MOVIECLIP_SELECT_UPDATE;
+       }
+       else if (is_selectable_data_id_type(id_type)) {
+               *component_type = NodeType::BATCH_CACHE;
+               *operation_code = OperationCode::GEOMETRY_SELECT_UPDATE;
        }
        else {
-               *component_type = DEG_NODE_TYPE_BATCH_CACHE;
-               *operation_code = DEG_OPCODE_GEOMETRY_SELECT_UPDATE;
+               *component_type = NodeType::COPY_ON_WRITE;
+               *operation_code = OperationCode::COPY_ON_WRITE;
        }
 }
 
 void depsgraph_base_flags_tag_to_component_opcode(
         const ID *id,
-        eDepsNode_Type *component_type,
-        eDepsOperation_Code *operation_code)
+        NodeType *component_type,
+        OperationCode *operation_code)
 {
        const ID_Type id_type = GS(id->name);
        if (id_type == ID_SCE) {
-               *component_type = DEG_NODE_TYPE_LAYER_COLLECTIONS;
-               *operation_code = DEG_OPCODE_VIEW_LAYER_EVAL;
+               *component_type = NodeType::LAYER_COLLECTIONS;
+               *operation_code = OperationCode::VIEW_LAYER_EVAL;
        }
        else if (id_type == ID_OB) {
-               *component_type = DEG_NODE_TYPE_OBJECT_FROM_LAYER;
-               *operation_code = DEG_OPCODE_OBJECT_BASE_FLAGS;
+               *component_type = NodeType::OBJECT_FROM_LAYER;
+               *operation_code = OperationCode::OBJECT_BASE_FLAGS;
        }
 }
 
-eDepsOperation_Code psysTagToOperationCode(IDRecalcFlag tag)
+OperationCode psysTagToOperationCode(IDRecalcFlag tag)
 {
        if (tag == ID_RECALC_PSYS_RESET) {
-               return DEG_OPCODE_PARTICLE_SETTINGS_RESET;
+               return OperationCode::PARTICLE_SETTINGS_RESET;
        }
-       return DEG_OPCODE_OPERATION;
+       return OperationCode::OPERATION;
 }
 
 void depsgraph_tag_to_component_opcode(const ID *id,
                                        IDRecalcFlag tag,
-                                       eDepsNode_Type *component_type,
-                                       eDepsOperation_Code *operation_code)
+                                       NodeType *component_type,
+                                       OperationCode *operation_code)
 {
        const ID_Type id_type = GS(id->name);
-       *component_type = DEG_NODE_TYPE_UNDEFINED;
-       *operation_code = DEG_OPCODE_OPERATION;
+       *component_type = NodeType::UNDEFINED;
+       *operation_code = OperationCode::OPERATION;
        /* Special case for now, in the future we should get rid of this. */
        if (tag == 0) {
-               *component_type = DEG_NODE_TYPE_ID_REF;
-               *operation_code = DEG_OPCODE_OPERATION;
+               *component_type = NodeType::ID_REF;
+               *operation_code = OperationCode::OPERATION;
                return;
        }
        switch (tag) {
                case ID_RECALC_TRANSFORM:
-                       *component_type = DEG_NODE_TYPE_TRANSFORM;
+                       *component_type = NodeType::TRANSFORM;
                        break;
                case ID_RECALC_GEOMETRY:
                        depsgraph_geometry_tag_to_component(id, component_type);
                        break;
                case ID_RECALC_ANIMATION:
-                       *component_type = DEG_NODE_TYPE_ANIMATION;
+                       *component_type = NodeType::ANIMATION;
                        break;
                case ID_RECALC_PSYS_REDO:
                case ID_RECALC_PSYS_RESET:
@@ -183,24 +185,23 @@ void depsgraph_tag_to_component_opcode(const ID *id,
                                 * - For particle settings node we need to use different
                                 *   component. Will be nice to get this unified with object,
                                 *   but we can survive for now with single exception here.
-                                *   Particles needs reconsideration anyway,
-                                */
-                               *component_type = DEG_NODE_TYPE_PARTICLE_SETTINGS;
+                                *   Particles needs reconsideration anyway, */
+                               *component_type = NodeType::PARTICLE_SETTINGS;
                                *operation_code = psysTagToOperationCode(tag);
                        }
                        else {
-                               *component_type = DEG_NODE_TYPE_PARTICLE_SYSTEM;
+                               *component_type = NodeType::PARTICLE_SYSTEM;
                        }
                        break;
                case ID_RECALC_COPY_ON_WRITE:
-                       *component_type = DEG_NODE_TYPE_COPY_ON_WRITE;
+                       *component_type = NodeType::COPY_ON_WRITE;
                        break;
                case ID_RECALC_SHADING:
                        if (id_type == ID_NT) {
-                               *component_type = DEG_NODE_TYPE_SHADING_PARAMETERS;
+                               *component_type = NodeType::SHADING_PARAMETERS;
                        }
                        else {
-                               *component_type = DEG_NODE_TYPE_SHADING;
+                               *component_type = NodeType::SHADING;
                        }
                        break;
                case ID_RECALC_SELECT:
@@ -214,12 +215,11 @@ void depsgraph_tag_to_component_opcode(const ID *id,
                                                                     operation_code);
                        break;
                case ID_RECALC_POINT_CACHE:
-                       *component_type = DEG_NODE_TYPE_POINT_CACHE;
+                       *component_type = NodeType::POINT_CACHE;
                        break;
                case ID_RECALC_EDITORS:
                        /* There is no such node in depsgraph, this tag is to be handled
-                        * separately.
-                        */
+                        * separately. */
                        break;
                case ID_RECALC_ALL:
                case ID_RECALC_PSYS_ALL:
@@ -228,20 +228,23 @@ void depsgraph_tag_to_component_opcode(const ID *id,
        }
 }
 
-void id_tag_update_ntree_special(Main *bmain, Depsgraph *graph, ID *id, int flag)
+void id_tag_update_ntree_special(Main *bmain,
+                                 Depsgraph *graph,
+                                 ID *id,
+                                 int flag,
+                                 eUpdateSource update_source)
 {
        bNodeTree *ntree = ntreeFromID(id);
        if (ntree == NULL) {
                return;
        }
-       deg_graph_id_tag_update(bmain, graph, &ntree->id, flag);
+       graph_id_tag_update(bmain, graph, &ntree->id, flag, update_source);
 }
 
 void depsgraph_update_editors_tag(Main *bmain, Depsgraph *graph, ID *id)
 {
        /* NOTE: We handle this immediately, without delaying anything, to be
-        * sure we don't cause threading issues with OpenGL.
-        */
+        * sure we don't cause threading issues with OpenGL. */
        /* TODO(sergey): Make sure this works for CoW-ed datablocks as well. */
        DEGEditorUpdateContext update_ctx = {NULL};
        update_ctx.bmain = bmain;
@@ -252,30 +255,31 @@ void depsgraph_update_editors_tag(Main *bmain, Depsgraph *graph, ID *id)
 }
 
 void depsgraph_tag_component(Depsgraph *graph,
-                             IDDepsNode *id_node,
-                             eDepsNode_Type component_type,
-                             eDepsOperation_Code operation_code)
+                             IDNode *id_node,
+                             NodeType component_type,
+                             OperationCode operation_code,
+                             eUpdateSource update_source)
 {
-       ComponentDepsNode *component_node =
+       ComponentNode *component_node =
                id_node->find_component(component_type);
        if (component_node == NULL) {
                return;
        }
-       if (operation_code == DEG_OPCODE_OPERATION) {
-               component_node->tag_update(graph, DEG_UPDATE_SOURCE_USER_EDIT);
+       if (operation_code == OperationCode::OPERATION) {
+               component_node->tag_update(graph, update_source);
        }
        else {
-               OperationDepsNode *operation_node =
+               OperationNode *operation_node =
                        component_node->find_operation(operation_code);
                if (operation_node != NULL) {
-                       operation_node->tag_update(graph, DEG_UPDATE_SOURCE_USER_EDIT);
+                       operation_node->tag_update(graph, update_source);
                }
        }
        /* If component depends on copy-on-write, tag it as well. */
        if (component_node->need_tag_cow_before_update()) {
-               ComponentDepsNode *cow_comp =
-                       id_node->find_component(DEG_NODE_TYPE_COPY_ON_WRITE);
-               cow_comp->tag_update(graph, DEG_UPDATE_SOURCE_USER_EDIT);
+               ComponentNode *cow_comp =
+                       id_node->find_component(NodeType::COPY_ON_WRITE);
+               cow_comp->tag_update(graph, update_source);
                id_node->id_orig->recalc |= ID_RECALC_COPY_ON_WRITE;
        }
 }
@@ -284,12 +288,12 @@ void depsgraph_tag_component(Depsgraph *graph,
  *
  * Mainly, old code was tagging object with ID_RECALC_GEOMETRY tag to inform
  * that object's data datablock changed. Now API expects that ID is given
- * explicitly, but not all areas are aware of this yet.
- */
+ * explicitly, but not all areas are aware of this yet. */
 void deg_graph_id_tag_legacy_compat(Main *bmain,
                                     Depsgraph *depsgraph,
                                     ID *id,
-                                    IDRecalcFlag tag)
+                                    IDRecalcFlag tag,
+                                    eUpdateSource update_source)
 {
        if (tag == ID_RECALC_GEOMETRY || tag == 0) {
                switch (GS(id->name)) {
@@ -298,20 +302,21 @@ void deg_graph_id_tag_legacy_compat(Main *bmain,
                                Object *object = (Object *)id;
                                ID *data_id = (ID *)object->data;
                                if (data_id != NULL) {
-                                       deg_graph_id_tag_update(bmain, depsgraph, data_id, 0);
+                                       graph_id_tag_update(
+                                               bmain, depsgraph, data_id, 0, update_source);
                                }
                                break;
                        }
                        /* TODO(sergey): Shape keys are annoying, maybe we should find a
                         * way to chain geometry evaluation to them, so we don't need extra
-                        * tagging here.
-                        */
+                        * tagging here. */
                        case ID_ME:
                        {
                                Mesh *mesh = (Mesh *)id;
                                ID *key_id = &mesh->key->id;
                                if (key_id != NULL) {
-                                       deg_graph_id_tag_update(bmain, depsgraph, key_id, 0);
+                                       graph_id_tag_update(
+                                               bmain, depsgraph, key_id, 0, update_source);
                                }
                                break;
                        }
@@ -320,7 +325,8 @@ void deg_graph_id_tag_legacy_compat(Main *bmain,
                                Lattice *lattice = (Lattice *)id;
                                ID *key_id = &lattice->key->id;
                                if (key_id != NULL) {
-                                       deg_graph_id_tag_update(bmain, depsgraph, key_id, 0);
+                                       graph_id_tag_update(
+                                               bmain, depsgraph, key_id, 0, update_source);
                                }
                                break;
                        }
@@ -329,7 +335,8 @@ void deg_graph_id_tag_legacy_compat(Main *bmain,
                                Curve *curve = (Curve *)id;
                                ID *key_id = &curve->key->id;
                                if (key_id != NULL) {
-                                       deg_graph_id_tag_update(bmain, depsgraph, key_id, 0);
+                                       graph_id_tag_update(
+                                               bmain, depsgraph, key_id, 0, update_source);
                                }
                                break;
                        }
@@ -339,11 +346,12 @@ void deg_graph_id_tag_legacy_compat(Main *bmain,
        }
 }
 
-static void deg_graph_id_tag_update_single_flag(Main *bmain,
-                                                Depsgraph *graph,
-                                                ID *id,
-                                                IDDepsNode *id_node,
-                                                IDRecalcFlag tag)
+static void graph_id_tag_update_single_flag(Main *bmain,
+                                            Depsgraph *graph,
+                                            ID *id,
+                                            IDNode *id_node,
+                                            IDRecalcFlag tag,
+                                            eUpdateSource update_source)
 {
        if (tag == ID_RECALC_EDITORS) {
                if (graph != NULL) {
@@ -352,40 +360,39 @@ static void deg_graph_id_tag_update_single_flag(Main *bmain,
                return;
        }
        /* Get description of what is to be tagged. */
-       eDepsNode_Type component_type;
-       eDepsOperation_Code operation_code;
+       NodeType component_type;
+       OperationCode operation_code;
        depsgraph_tag_to_component_opcode(id,
                                          tag,
                                          &component_type,
                                          &operation_code);
        /* Check whether we've got something to tag. */
-       if (component_type == DEG_NODE_TYPE_UNDEFINED) {
+       if (component_type == NodeType::UNDEFINED) {
                /* Given ID does not support tag. */
                /* TODO(sergey): Shall we raise some panic here? */
                return;
        }
        /* Tag ID recalc flag. */
-       DepsNodeFactory *factory = deg_type_get_factory(component_type);
+       DepsNodeFactory *factory = type_get_factory(component_type);
        BLI_assert(factory != NULL);
        id->recalc |= factory->id_recalc_tag();
        /* Some sanity checks before moving forward. */
        if (id_node == NULL) {
                /* Happens when object is tagged for update and not yet in the
-                * dependency graph (but will be after relations update).
-                */
+                * dependency graph (but will be after relations update). */
                return;
        }
        /* Tag corresponding dependency graph operation for update. */
-       if (component_type == DEG_NODE_TYPE_ID_REF) {
-               id_node->tag_update(graph, DEG_UPDATE_SOURCE_USER_EDIT);
+       if (component_type == NodeType::ID_REF) {
+               id_node->tag_update(graph, update_source);
        }
        else {
-               depsgraph_tag_component(graph, id_node, component_type, operation_code);
+               depsgraph_tag_component(
+                       graph, id_node, component_type, operation_code, update_source);
        }
        /* TODO(sergey): Get rid of this once all areas are using proper data ID
-        * for tagging.
-        */
-       deg_graph_id_tag_legacy_compat(bmain, graph, id, tag);
+        * for tagging. */
+       deg_graph_id_tag_legacy_compat(bmain, graph, id, tag, update_source);
 
 }
 
@@ -407,8 +414,7 @@ string stringify_update_bitfield(int flag)
        string result = "";
        int current_flag = flag;
        /* Special cases to avoid ALL flags form being split into
-        * individual bits.
-        */
+        * individual bits. */
        if ((current_flag & ID_RECALC_PSYS_ALL) == ID_RECALC_PSYS_ALL) {
                result = stringify_append_bit(result, ID_RECALC_PSYS_ALL);
        }
@@ -421,13 +427,27 @@ string stringify_update_bitfield(int flag)
        return result;
 }
 
+const char *update_source_as_string(eUpdateSource source)
+{
+       switch (source) {
+               case DEG_UPDATE_SOURCE_TIME: return "TIME";
+               case DEG_UPDATE_SOURCE_USER_EDIT: return "USER_EDIT";
+               case DEG_UPDATE_SOURCE_RELATIONS: return "RELATIONS";
+               case DEG_UPDATE_SOURCE_VISIBILITY: return "VISIBILITY";
+       }
+       BLI_assert(!"Should never happen.");
+       return "UNKNOWN";
+}
+
 /* Special tag function which tags all components which needs to be tagged
  * for update flag=0.
  *
  * TODO(sergey): This is something to be avoid in the future, make it more
- * explicit and granular for users to tag what they really need.
- */
-void deg_graph_node_tag_zero(Main *bmain, Depsgraph *graph, IDDepsNode *id_node)
+ * explicit and granular for users to tag what they really need. */
+void deg_graph_node_tag_zero(Main *bmain,
+                             Depsgraph *graph,
+                             IDNode *id_node,
+                             eUpdateSource update_source)
 {
        if (id_node == NULL) {
                return;
@@ -435,85 +455,31 @@ void deg_graph_node_tag_zero(Main *bmain, Depsgraph *graph, IDDepsNode *id_node)
        ID *id = id_node->id_orig;
        /* TODO(sergey): Which recalc flags to set here? */
        id->recalc |= ID_RECALC_ALL & ~(ID_RECALC_PSYS_ALL | ID_RECALC_ANIMATION);
-       GHASH_FOREACH_BEGIN(ComponentDepsNode *, comp_node, id_node->components)
+       GHASH_FOREACH_BEGIN(ComponentNode *, comp_node, id_node->components)
        {
-               if (comp_node->type == DEG_NODE_TYPE_ANIMATION) {
+               if (comp_node->type == NodeType::ANIMATION) {
                        continue;
                }
                comp_node->tag_update(graph, DEG_UPDATE_SOURCE_USER_EDIT);
        }
        GHASH_FOREACH_END();
-       deg_graph_id_tag_legacy_compat(bmain, graph, id, (IDRecalcFlag)0);
-}
-
-void deg_graph_id_tag_update(Main *bmain, Depsgraph *graph, ID *id, int flag)
-{
-       const int debug_flags = (graph != NULL)
-               ? DEG_debug_flags_get((::Depsgraph *)graph)
-               : G.debug;
-       if (debug_flags & G_DEBUG_DEPSGRAPH_TAG) {
-               printf("%s: id=%s flags=%s\n",
-                      __func__,
-                      id->name,
-                      stringify_update_bitfield(flag).c_str());
-       }
-       IDDepsNode *id_node = (graph != NULL) ? graph->find_id_node(id)
-                                             : NULL;
-       DEG_id_type_tag(bmain, GS(id->name));
-       if (flag == 0) {
-               deg_graph_node_tag_zero(bmain, graph, id_node);
-       }
-       id->recalc |= flag;
-       int current_flag = flag;
-       while (current_flag != 0) {
-               IDRecalcFlag tag =
-                       (IDRecalcFlag)(1 << bitscan_forward_clear_i(&current_flag));
-               deg_graph_id_tag_update_single_flag(bmain,
-                                                   graph,
-                                                   id,
-                                                   id_node,
-                                                   tag);
-       }
-       /* Special case for nested node tree datablocks. */
-       id_tag_update_ntree_special(bmain, graph, id, flag);
-       /* Direct update tags means that something outside of simulated/cached
-        * physics did change and that cache is to be invalidated.
-        */
-       deg_graph_id_tag_update_single_flag(
-               bmain, graph, id, id_node, ID_RECALC_POINT_CACHE);
-}
-
-void deg_id_tag_update(Main *bmain, ID *id, int flag)
-{
-       deg_graph_id_tag_update(bmain, NULL, id, flag);
-       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_id_tag_update(bmain, depsgraph, id, flag);
-                       }
-               }
-       }
+       deg_graph_id_tag_legacy_compat(
+               bmain, graph, id, (IDRecalcFlag)0, update_source);
 }
 
 void deg_graph_on_visible_update(Main *bmain, Depsgraph *graph)
 {
-       foreach (DEG::IDDepsNode *id_node, graph->id_nodes) {
+       for (DEG::IDNode *id_node : graph->id_nodes) {
                if (!id_node->visible_components_mask) {
                        /* ID has no components which affects anything visible. no meed
-                        * bother with it to tag or anything.
-                        */
+                        * bother with it to tag or anything. */
                        continue;
                }
                if (id_node->visible_components_mask ==
                    id_node->previously_visible_components_mask)
                {
                        /* The ID was already visible and evaluated, all the subsequent
-                        * updates and tags are to be done explicitly.
-                        */
+                        * updates and tags are to be done explicitly. */
                        continue;
                }
                int flag = 0;
@@ -524,13 +490,15 @@ void deg_graph_on_visible_update(Main *bmain, Depsgraph *graph)
                 * not a good idea because that might reset particles cache (or any
                 * other type of cache).
                 *
-                * TODO(sergey): Need to generalize this somehow.
-                */
+                * TODO(sergey): Need to generalize this somehow. */
                const ID_Type id_type = GS(id_node->id_orig->name);
                if (id_type == ID_OB) {
                        flag |= ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY;
                }
-               deg_graph_id_tag_update(bmain, graph, id_node->id_orig, flag);
+               graph_id_tag_update(bmain,
+                                   graph,
+                                   id_node->id_orig,
+                                   flag, DEG_UPDATE_SOURCE_VISIBILITY);
                if (id_type == ID_SCE) {
                        /* Make sure collection properties are up to date. */
                        id_node->tag_update(graph, DEG_UPDATE_SOURCE_VISIBILITY);
@@ -543,8 +511,7 @@ void deg_graph_on_visible_update(Main *bmain, Depsgraph *graph)
                 * dependency graph is tagged for relations update, it will be fine:
                 * since dependency graph builder re-schedules entry tags, all the
                 * tags we request from here will be applied in the updated state of
-                * dependency graph.
-                */
+                * dependency graph. */
                id_node->previously_visible_components_mask =
                        id_node->visible_components_mask;
        }
@@ -552,7 +519,7 @@ void deg_graph_on_visible_update(Main *bmain, Depsgraph *graph)
 
 }  /* namespace */
 
-eDepsNode_Type deg_geometry_tag_to_component(const ID *id)
+NodeType geometry_tag_to_component(const ID *id)
 {
        const ID_Type id_type = GS(id->name);
        switch (id_type) {
@@ -567,27 +534,87 @@ eDepsNode_Type deg_geometry_tag_to_component(const ID *id)
                                case OB_LATTICE:
                                case OB_MBALL:
                                case OB_GPENCIL:
-                                       return DEG_NODE_TYPE_GEOMETRY;
+                                       return NodeType::GEOMETRY;
                                case OB_ARMATURE:
-                                       return DEG_NODE_TYPE_EVAL_POSE;
+                                       return NodeType::EVAL_POSE;
                                        /* TODO(sergey): More cases here? */
                        }
                        break;
                }
                case ID_ME:
-                       return DEG_NODE_TYPE_GEOMETRY;
+               case ID_CU:
+               case ID_LT:
+               case ID_MB:
+                       return NodeType::GEOMETRY;
                case ID_PA: /* Particles */
-                       return DEG_NODE_TYPE_UNDEFINED;
+                       return NodeType::UNDEFINED;
                case ID_LP:
-                       return DEG_NODE_TYPE_PARAMETERS;
+                       return NodeType::PARAMETERS;
                case ID_GD:
-                       return DEG_NODE_TYPE_GEOMETRY;
+                       return NodeType::GEOMETRY;
                case ID_PAL: /* Palettes */
-                       return DEG_NODE_TYPE_PARAMETERS;
+                       return NodeType::PARAMETERS;
                default:
                        break;
        }
-       return DEG_NODE_TYPE_UNDEFINED;
+       return NodeType::UNDEFINED;
+}
+
+void id_tag_update(Main *bmain, ID *id, int flag, eUpdateSource update_source)
+{
+       graph_id_tag_update(bmain, NULL, id, flag, update_source);
+       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) {
+                               graph_id_tag_update(
+                                       bmain, depsgraph, id, flag, update_source);
+                       }
+               }
+       }
+}
+
+void graph_id_tag_update(Main *bmain,
+                         Depsgraph *graph,
+                         ID *id,
+                         int flag,
+                         eUpdateSource update_source)
+{
+       const int debug_flags = (graph != NULL)
+               ? DEG_debug_flags_get((::Depsgraph *)graph)
+               : G.debug;
+       if (debug_flags & G_DEBUG_DEPSGRAPH_TAG) {
+               printf("%s: id=%s flags=%s source=%s\n",
+                      __func__,
+                      id->name,
+                      stringify_update_bitfield(flag).c_str(),
+                      update_source_as_string(update_source));
+       }
+       IDNode *id_node = (graph != NULL) ? graph->find_id_node(id)
+                                             : NULL;
+       DEG_id_type_tag(bmain, GS(id->name));
+       if (flag == 0) {
+               deg_graph_node_tag_zero(bmain, graph, id_node, update_source);
+       }
+       id->recalc |= flag;
+       int current_flag = flag;
+       while (current_flag != 0) {
+               IDRecalcFlag tag =
+                       (IDRecalcFlag)(1 << bitscan_forward_clear_i(&current_flag));
+               graph_id_tag_update_single_flag(
+                       bmain, graph, id, id_node, tag, update_source);
+       }
+       /* Special case for nested node tree datablocks. */
+       id_tag_update_ntree_special(bmain, graph, id, flag, update_source);
+       /* Direct update tags means that something outside of simulated/cached
+        * physics did change and that cache is to be invalidated. */
+       if (update_source == DEG_UPDATE_SOURCE_USER_EDIT) {
+               graph_id_tag_update_single_flag(
+                       bmain, graph, id, id_node, ID_RECALC_POINT_CACHE, update_source);
+       }
 }
 
 }  // namespace DEG
@@ -629,7 +656,8 @@ void DEG_id_tag_update_ex(Main *bmain, ID *id, int flag)
                /* Ideally should not happen, but old depsgraph allowed this. */
                return;
        }
-       DEG::deg_id_tag_update(bmain, id, flag);
+       DEG::id_tag_update(
+               bmain, id, flag, DEG::DEG_UPDATE_SOURCE_USER_EDIT);
 }
 
 void DEG_graph_id_tag_update(struct Main *bmain,
@@ -638,7 +666,8 @@ void DEG_graph_id_tag_update(struct Main *bmain,
                              int flag)
 {
        DEG::Depsgraph *graph = (DEG::Depsgraph *)depsgraph;
-       DEG::deg_graph_id_tag_update(bmain, graph, id, flag);
+       DEG::graph_id_tag_update(
+               bmain, graph, id, flag, DEG::DEG_UPDATE_SOURCE_USER_EDIT);
 }
 
 /* Mark a particular datablock type as having changing. */
@@ -646,8 +675,7 @@ void DEG_id_type_tag(Main *bmain, short id_type)
 {
        if (id_type == ID_NT) {
                /* Stupid workaround so parent datablocks of nested nodetree get looped
-                * over when we loop over tagged datablock types.
-                */
+                * over when we loop over tagged datablock types. */
                DEG_id_type_tag(bmain, ID_MA);
                DEG_id_type_tag(bmain, ID_TE);
                DEG_id_type_tag(bmain, ID_LA);
@@ -702,8 +730,7 @@ void DEG_on_visible_update(Main *bmain, const bool UNUSED(do_time))
 }
 
 /* Check if something was changed in the database and inform
- * editors about this.
- */
+ * editors about this. */
 void DEG_ids_check_recalc(Main *bmain,
                           Depsgraph *depsgraph,
                           Scene *scene,
@@ -729,7 +756,7 @@ static void deg_graph_clear_id_node_func(
         * correctly when there are multiple depsgraph with others still using
         * the recalc flag. */
        DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(data_v);
-       DEG::IDDepsNode *id_node = deg_graph->id_nodes[i];
+       DEG::IDNode *id_node = deg_graph->id_nodes[i];
        id_node->id_cow->recalc &= ~ID_RECALC_ALL;
        id_node->id_orig->recalc &= ~ID_RECALC_ALL;
 
@@ -748,15 +775,11 @@ void DEG_ids_clear_recalc(Main *UNUSED(bmain),
                           Depsgraph *depsgraph)
 {
        DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(depsgraph);
-
        /* TODO(sergey): Re-implement POST_UPDATE_HANDLER_WORKAROUND using entry_tags
-        * and id_tags storage from the new dependency graph.
-        */
-
+        * and id_tags storage from the new dependency graph. */
        if (!DEG_id_type_any_updated(depsgraph)) {
                return;
        }
-
        /* Go over all ID nodes nodes, clearing tags. */
        const int num_id_nodes = deg_graph->id_nodes.size();
        ParallelRangeSettings settings;
@@ -766,6 +789,5 @@ void DEG_ids_clear_recalc(Main *UNUSED(bmain),
                                deg_graph,
                                deg_graph_clear_id_node_func,
                                &settings);
-
        memset(deg_graph->id_type_updated, 0, sizeof(deg_graph->id_type_updated));
 }