[Bf-blender-cvs] [9e155eb1f00] master: Depsgraph: Add dependencies traversal which is aware of component

Sergey Sharybin noreply at git.blender.org
Fri Jul 5 16:09:08 CEST 2019


Commit: 9e155eb1f0083354ab5d66f233b1067d16088d62
Author: Sergey Sharybin
Date:   Thu Jul 4 15:04:03 2019 +0200
Branches: master
https://developer.blender.org/rB9e155eb1f0083354ab5d66f233b1067d16088d62

Depsgraph: Add dependencies traversal which is aware of component

Sometimes it is required to know which exact part of ID is being
dependent on the given iD. Now it is possible.

===================================================================

M	source/blender/depsgraph/DEG_depsgraph_query.h
M	source/blender/depsgraph/intern/depsgraph_query_foreach.cc

===================================================================

diff --git a/source/blender/depsgraph/DEG_depsgraph_query.h b/source/blender/depsgraph/DEG_depsgraph_query.h
index 4148529d3f8..35176284abb 100644
--- a/source/blender/depsgraph/DEG_depsgraph_query.h
+++ b/source/blender/depsgraph/DEG_depsgraph_query.h
@@ -219,6 +219,9 @@ void DEG_iterator_ids_end(struct BLI_Iterator *iter);
 /* ************************ DEG traversal ********************* */
 
 typedef void (*DEGForeachIDCallback)(ID *id, void *user_data);
+typedef void (*DEGForeachIDComponentCallback)(ID *id,
+                                              eDepsObjectComponentType component,
+                                              void *user_data);
 
 /* NOTE: Modifies runtime flags in depsgraph nodes, so can not be used in
  * parallel. Keep an eye on that!
@@ -232,6 +235,11 @@ void DEG_foreach_dependent_ID(const Depsgraph *depsgraph,
                               DEGForeachIDCallback callback,
                               void *user_data);
 
+void DEG_foreach_dependent_ID_component(const Depsgraph *depsgraph,
+                                        const ID *id,
+                                        DEGForeachIDComponentCallback callback,
+                                        void *user_data);
+
 void DEG_foreach_ID(const Depsgraph *depsgraph, DEGForeachIDCallback callback, void *user_data);
 
 #ifdef __cplusplus
diff --git a/source/blender/depsgraph/intern/depsgraph_query_foreach.cc b/source/blender/depsgraph/intern/depsgraph_query_foreach.cc
index 717793d60f1..f5fcdf8e5d1 100644
--- a/source/blender/depsgraph/intern/depsgraph_query_foreach.cc
+++ b/source/blender/depsgraph/intern/depsgraph_query_foreach.cc
@@ -48,25 +48,29 @@ extern "C" {
 /* ************************ DEG TRAVERSAL ********************* */
 
 namespace DEG {
+namespace {
 
 typedef std::deque<OperationNode *> TraversalQueue;
 enum {
   DEG_NODE_VISITED = (1 << 0),
 };
 
-static void deg_foreach_clear_flags(const Depsgraph *graph)
+typedef void (*DEGForeachOperation)(OperationNode *op_node, void *user_data);
+
+void deg_foreach_clear_flags(const Depsgraph *graph)
 {
   for (OperationNode *op_node : graph->operations) {
     op_node->scheduled = false;
+    op_node->owner->custom_flags = 0;
   }
   for (IDNode *id_node : graph->id_nodes) {
     id_node->custom_flags = 0;
   }
 }
 
-static void deg_foreach_dependent_ID(const Depsgraph *graph,
+void deg_foreach_dependent_operation(const Depsgraph *graph,
                                      const ID *id,
-                                     DEGForeachIDCallback callback,
+                                     DEGForeachOperation callback,
                                      void *user_data)
 {
   /* Start with getting ID node from the graph. */
@@ -84,6 +88,7 @@ static void deg_foreach_dependent_ID(const Depsgraph *graph,
     for (OperationNode *op_node : comp_node->operations) {
       queue.push_back(op_node);
       op_node->scheduled = true;
+      op_node->owner->custom_flags |= DEG_NODE_VISITED;
     }
   }
   GHASH_FOREACH_END();
@@ -94,14 +99,7 @@ static void deg_foreach_dependent_ID(const Depsgraph *graph,
     OperationNode *op_node = queue.front();
     queue.pop_front();
     for (;;) {
-      /* Check whether we need to inform callee about corresponding ID node. */
-      ComponentNode *comp_node = op_node->owner;
-      IDNode *id_node = comp_node->owner;
-      if ((id_node->custom_flags & DEG_NODE_VISITED) == 0) {
-        /* TODO(sergey): Is it orig or CoW? */
-        callback(id_node->id_orig, user_data);
-        id_node->custom_flags |= DEG_NODE_VISITED;
-      }
+      callback(op_node, user_data);
       /* Schedule outgoing operation nodes. */
       if (op_node->outlinks.size() == 1) {
         OperationNode *to_node = (OperationNode *)op_node->outlinks[0]->to;
@@ -127,10 +125,65 @@ static void deg_foreach_dependent_ID(const Depsgraph *graph,
   }
 }
 
-static void deg_foreach_ancestor_ID(const Depsgraph *graph,
-                                    const ID *id,
-                                    DEGForeachIDCallback callback,
-                                    void *user_data)
+struct ForeachIDComponentData {
+  DEGForeachIDComponentCallback callback;
+  void *user_data;
+};
+
+void deg_foreach_dependent_component_callback(OperationNode *op_node, void *user_data_v)
+{
+  ForeachIDComponentData *user_data = reinterpret_cast<ForeachIDComponentData *>(user_data_v);
+  ComponentNode *comp_node = op_node->owner;
+  if ((comp_node->custom_flags & DEG_NODE_VISITED) == 0) {
+    IDNode *id_node = comp_node->owner;
+    user_data->callback(
+        id_node->id_orig, nodeTypeToObjectComponent(comp_node->type), user_data->user_data);
+    comp_node->custom_flags |= DEG_NODE_VISITED;
+  }
+}
+
+void deg_foreach_dependent_ID_component(const Depsgraph *graph,
+                                        const ID *id,
+                                        DEGForeachIDComponentCallback callback,
+                                        void *user_data)
+{
+  ForeachIDComponentData data;
+  data.callback = callback;
+  data.user_data = user_data;
+  deg_foreach_dependent_operation(graph, id, deg_foreach_dependent_component_callback, &data);
+}
+
+struct ForeachIDData {
+  DEGForeachIDCallback callback;
+  void *user_data;
+};
+
+void deg_foreach_dependent_ID_callback(OperationNode *op_node, void *user_data_v)
+{
+  ForeachIDData *user_data = reinterpret_cast<ForeachIDData *>(user_data_v);
+  ComponentNode *comp_node = op_node->owner;
+  IDNode *id_node = comp_node->owner;
+  if ((id_node->custom_flags & DEG_NODE_VISITED) == 0) {
+    user_data->callback(id_node->id_orig, user_data->user_data);
+    id_node->custom_flags |= DEG_NODE_VISITED;
+  }
+}
+
+void deg_foreach_dependent_ID(const Depsgraph *graph,
+                              const ID *id,
+                              DEGForeachIDCallback callback,
+                              void *user_data)
+{
+  ForeachIDData data;
+  data.callback = callback;
+  data.user_data = user_data;
+  deg_foreach_dependent_operation(graph, id, deg_foreach_dependent_ID_callback, &data);
+}
+
+void deg_foreach_ancestor_ID(const Depsgraph *graph,
+                             const ID *id,
+                             DEGForeachIDCallback callback,
+                             void *user_data)
 {
   /* Start with getting ID node from the graph. */
   IDNode *target_id_node = graph->find_id_node(id);
@@ -196,15 +249,14 @@ static void deg_foreach_ancestor_ID(const Depsgraph *graph,
   }
 }
 
-static void deg_foreach_id(const Depsgraph *depsgraph,
-                           DEGForeachIDCallback callback,
-                           void *user_data)
+void deg_foreach_id(const Depsgraph *depsgraph, DEGForeachIDCallback callback, void *user_data)
 {
   for (const IDNode *id_node : depsgraph->id_nodes) {
     callback(id_node->id_orig, user_data);
   }
 }
 
+}  // namespace
 }  // namespace DEG
 
 void DEG_foreach_dependent_ID(const Depsgraph *depsgraph,
@@ -215,6 +267,15 @@ void DEG_foreach_dependent_ID(const Depsgraph *depsgraph,
   DEG::deg_foreach_dependent_ID((const DEG::Depsgraph *)depsgraph, id, callback, user_data);
 }
 
+void DEG_foreach_dependent_ID_component(const Depsgraph *depsgraph,
+                                        const ID *id,
+                                        DEGForeachIDComponentCallback callback,
+                                        void *user_data)
+{
+  DEG::deg_foreach_dependent_ID_component(
+      (const DEG::Depsgraph *)depsgraph, id, callback, user_data);
+}
+
 void DEG_foreach_ancestor_ID(const Depsgraph *depsgraph,
                              const ID *id,
                              DEGForeachIDCallback callback,



More information about the Bf-blender-cvs mailing list