[Bf-blender-cvs] [81e391a] master: Fix issues with node deduplication in Cycles shader graph.

Alexander Gavrilov noreply at git.blender.org
Sun Jun 19 20:37:00 CEST 2016


Commit: 81e391a72747fe4d8ab1978a0929719844df35a1
Author: Alexander Gavrilov
Date:   Sun Jun 19 16:51:10 2016 +0300
Branches: master
https://developer.blender.org/rB81e391a72747fe4d8ab1978a0929719844df35a1

Fix issues with node deduplication in Cycles shader graph.

It is not possible to use a set split by name as valid input to
check_node_input_traversed - it needs a complete set of all nodes visited so
far. On the other hand, the merge comparison loop should only check nodes that
were not just visited, but found unique. This means that there should really be
two separate data structures.

Without the fix, check_node_input_traversed actually never returns true, so
only nodes without any inputs are processed.

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

M	intern/cycles/render/graph.cpp

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

diff --git a/intern/cycles/render/graph.cpp b/intern/cycles/render/graph.cpp
index a1b992a..fd48bf2 100644
--- a/intern/cycles/render/graph.cpp
+++ b/intern/cycles/render/graph.cpp
@@ -558,8 +558,8 @@ void ShaderGraph::deduplicate_nodes()
 	 *   already deduplicated.
 	 */
 
-	ShaderNodeSet scheduled;
-	map<ustring, ShaderNodeSet> done;
+	ShaderNodeSet scheduled, done;
+	map<ustring, ShaderNodeSet> candidates;
 	queue<ShaderNode*> traverse_queue;
 
 	/* Schedule nodes which doesn't have any dependencies. */
@@ -573,7 +573,7 @@ void ShaderGraph::deduplicate_nodes()
 	while(!traverse_queue.empty()) {
 		ShaderNode *node = traverse_queue.front();
 		traverse_queue.pop();
-		done[node->name].insert(node);
+		done.insert(node);
 		/* Schedule the nodes which were depending on the current node. */
 		foreach(ShaderOutput *output, node->outputs) {
 			foreach(ShaderInput *input, output->links) {
@@ -584,21 +584,28 @@ void ShaderGraph::deduplicate_nodes()
 					continue;
 				}
 				/* Schedule node if its inputs are fully done. */
-				if(check_node_inputs_traversed(input->parent, done[input->parent->name])) {
+				if(check_node_inputs_traversed(input->parent, done)) {
 					traverse_queue.push(input->parent);
 					scheduled.insert(input->parent);
 				}
 			}
 		}
 		/* Try to merge this node with another one. */
-		foreach(ShaderNode *other_node, done[node->name]) {
+		ShaderNode *merge_with = NULL;
+		foreach(ShaderNode *other_node, candidates[node->type->name]) {
 			if (node != other_node && node->equals(*other_node)) {
-				/* TODO(sergey): Consider making it an utility function. */
-				for(int i = 0; i < node->outputs.size(); ++i) {
-					relink(node, node->outputs[i], other_node->outputs[i]);
-				}
+				merge_with = other_node;
+				break;
 			}
-			break;
+		}
+		/* If found an equivalent, merge; otherwise keep node for later merges */
+		if (merge_with != NULL) {
+			for(int i = 0; i < node->outputs.size(); ++i) {
+				relink(node, node->outputs[i], merge_with->outputs[i]);
+			}
+		}
+		else {
+			candidates[node->type->name].insert(node);
 		}
 	}
 }




More information about the Bf-blender-cvs mailing list