[Bf-blender-cvs] [2a5f319465b] blender2.8: Depsgraph: Add query methods to identify all the ID's that a given datablock depends on

Joshua Leung noreply at git.blender.org
Tue Aug 21 06:53:21 CEST 2018


Commit: 2a5f319465b2d94ddff1d3d1402d3c46e4e2c0e8
Author: Joshua Leung
Date:   Tue Aug 21 16:20:54 2018 +1200
Branches: blender2.8
https://developer.blender.org/rB2a5f319465b2d94ddff1d3d1402d3c46e4e2c0e8

Depsgraph: Add query methods to identify all the ID's that a given datablock depends on

This commit adds a new method, DEG_foreach_ancestor_ID()
to accompany the existing DEG_foreach_descendent_ID().

It can be used to help print/collect all the ID's that
a given ID block depends on (i.e. all the datablocks that
need to be evaluated before the datablock of interest can
be evaluated)

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

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 1c4e11d1197..41650769fcf 100644
--- a/source/blender/depsgraph/DEG_depsgraph_query.h
+++ b/source/blender/depsgraph/DEG_depsgraph_query.h
@@ -197,6 +197,9 @@ typedef void (*DEGForeachIDCallback)(ID *id, void *user_data);
 /* NOTE: Modifies runtime flags in depsgraph nodes, so can not be used in
  * parallel. Keep an eye on that!
  */
+void DEG_foreach_ancestor_ID(const Depsgraph *depsgraph,
+                             const ID *id,
+                             DEGForeachIDCallback callback, void *user_data);
 void DEG_foreach_dependent_ID(const Depsgraph *depsgraph,
                               const ID *id,
                               DEGForeachIDCallback callback, void *user_data);
diff --git a/source/blender/depsgraph/intern/depsgraph_query_foreach.cc b/source/blender/depsgraph/intern/depsgraph_query_foreach.cc
index 5fb6a01d894..83d81d82b26 100644
--- a/source/blender/depsgraph/intern/depsgraph_query_foreach.cc
+++ b/source/blender/depsgraph/intern/depsgraph_query_foreach.cc
@@ -136,6 +136,71 @@ 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)
+{
+	/* Start with getting ID node from the graph. */
+	IDDepsNode *target_id_node = graph->find_id_node(id);
+	if (target_id_node == NULL) {
+		/* TODO(sergey): Shall we inform or assert here about attempt to start
+		 * iterating over non-existing ID?
+		 */
+		return;
+	}
+	/* Make sure all runtime flags are ready and clear. */
+	deg_foreach_clear_flags(graph);
+	/* Start with scheduling all operations from ID node. */
+	TraversalQueue queue;
+	GHASH_FOREACH_BEGIN(ComponentDepsNode *, comp_node, target_id_node->components)
+	{
+		foreach (OperationDepsNode *op_node, comp_node->operations) {
+			queue.push_back(op_node);
+			op_node->scheduled = true;
+		}
+	}
+	GHASH_FOREACH_END();
+	target_id_node->done = true;
+	/* Process the queue. */
+	while (!queue.empty()) {
+		/* get next operation node to process. */
+		OperationDepsNode *op_node = queue.front();
+		queue.pop_front();
+		for (;;) {
+			/* Check whether we need to inform callee about corresponding ID node. */
+			ComponentDepsNode *comp_node = op_node->owner;
+			IDDepsNode *id_node = comp_node->owner;
+			if (!id_node->done) {
+				/* TODO(sergey): Is it orig or CoW? */
+				callback(id_node->id_orig, user_data);
+				id_node->done = true;
+			}
+			/* Schedule incoming operation nodes. */
+			if (op_node->inlinks.size() == 1) {
+				OperationDepsNode *from_node = (OperationDepsNode *)op_node->inlinks[0]->from;
+				if (from_node->scheduled == false) {
+					from_node->scheduled = true;
+					op_node = from_node;
+				}
+				else {
+					break;
+				}
+			}
+			else {
+				foreach (DepsRelation *rel, op_node->inlinks) {
+					OperationDepsNode *from_node = (OperationDepsNode *)rel->from;
+					if (from_node->scheduled == false) {
+						queue.push_front(from_node);
+						from_node->scheduled = true;
+					}
+				}
+				break;
+			}
+		}
+	}
+}
+
 static void deg_foreach_id(const Depsgraph *depsgraph,
                            DEGForeachIDCallback callback, void *user_data)
 {
@@ -155,6 +220,15 @@ void DEG_foreach_dependent_ID(const Depsgraph *depsgraph,
 	                              callback, user_data);
 }
 
+void DEG_foreach_ancestor_ID(const Depsgraph *depsgraph,
+                             const ID *id,
+                             DEGForeachIDCallback callback, void *user_data)
+{
+	DEG::deg_foreach_ancestor_ID((const DEG::Depsgraph *)depsgraph,
+	                             id,
+	                             callback, user_data);
+}
+
 void DEG_foreach_ID(const Depsgraph *depsgraph,
                     DEGForeachIDCallback callback, void *user_data)
 {



More information about the Bf-blender-cvs mailing list