Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Gavrilov <angavrilov@gmail.com>2016-06-19 16:51:10 +0300
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2016-06-19 21:17:27 +0300
commit81e391a72747fe4d8ab1978a0929719844df35a1 (patch)
tree1e9dad8cdd1e71bf0b74500d4fe5952027e36589 /intern/cycles
parent98547e8817b35470fdf3bc19ded9b6695db5a8ad (diff)
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.
Diffstat (limited to 'intern/cycles')
-rw-r--r--intern/cycles/render/graph.cpp27
1 files changed, 17 insertions, 10 deletions
diff --git a/intern/cycles/render/graph.cpp b/intern/cycles/render/graph.cpp
index a1b992a2c31..fd48bf2631e 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);
}
}
}