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:
-rw-r--r--intern/cycles/render/graph.cpp61
-rw-r--r--intern/cycles/render/graph.h2
-rw-r--r--intern/cycles/render/shader.cpp6
3 files changed, 42 insertions, 27 deletions
diff --git a/intern/cycles/render/graph.cpp b/intern/cycles/render/graph.cpp
index b026f07ce56..f081e2db7af 100644
--- a/intern/cycles/render/graph.cpp
+++ b/intern/cycles/render/graph.cpp
@@ -312,10 +312,14 @@ void ShaderGraph::copy_nodes(set<ShaderNode*>& nodes, map<ShaderNode*, ShaderNod
}
}
-void ShaderGraph::remove_proxy_nodes(vector<bool>& removed)
+void ShaderGraph::remove_unneeded_nodes()
{
+ vector<bool> removed(nodes.size(), false);
+ bool any_node_removed = false;
+
+ /* find and unlink proxy nodes */
foreach(ShaderNode *node, nodes) {
- if (node->special_type == SHADER_SPECIAL_TYPE_PROXY) {
+ if(node->special_type == SHADER_SPECIAL_TYPE_PROXY) {
ProxyNode *proxy = static_cast<ProxyNode*>(node);
ShaderInput *input = proxy->inputs[0];
ShaderOutput *output = proxy->outputs[0];
@@ -327,7 +331,7 @@ void ShaderGraph::remove_proxy_nodes(vector<bool>& removed)
ShaderOutput *from = input->link;
/* bypass the proxy node */
- if (from) {
+ if(from) {
disconnect(input);
foreach(ShaderInput *to, links) {
disconnect(to);
@@ -345,6 +349,7 @@ void ShaderGraph::remove_proxy_nodes(vector<bool>& removed)
}
removed[proxy->id] = true;
+ any_node_removed = true;
}
/* remove useless mix closures nodes */
@@ -360,7 +365,7 @@ void ShaderGraph::remove_proxy_nodes(vector<bool>& removed)
foreach(ShaderInput *input, inputs) {
disconnect(input);
- if (output)
+ if(output)
connect(output, input);
}
}
@@ -378,33 +383,47 @@ void ShaderGraph::remove_proxy_nodes(vector<bool>& removed)
vector<ShaderInput*> inputs = mix->outputs[0]->links;
foreach(ShaderInput *sock, mix->inputs)
- if(sock->link)
- disconnect(sock);
+ if(sock->link)
+ disconnect(sock);
foreach(ShaderInput *input, inputs) {
disconnect(input);
- if (output)
- connect(output, input);
+ if(output)
+ connect(output, input);
}
}
/* Factor 1.0 */
- else if (mix->inputs[0]->value.x == 1.0f) {
+ else if(mix->inputs[0]->value.x == 1.0f) {
ShaderOutput *output = mix->inputs[2]->link;
vector<ShaderInput*> inputs = mix->outputs[0]->links;
foreach(ShaderInput *sock, mix->inputs)
- if(sock->link)
- disconnect(sock);
+ if(sock->link)
+ disconnect(sock);
foreach(ShaderInput *input, inputs) {
disconnect(input);
- if (output)
+ if(output)
connect(output, input);
}
}
}
}
}
+
+ /* remove nodes */
+ if (any_node_removed) {
+ list<ShaderNode*> newnodes;
+
+ foreach(ShaderNode *node, nodes) {
+ if(!removed[node->id])
+ newnodes.push_back(node);
+ else
+ delete node;
+ }
+
+ nodes = newnodes;
+ }
}
void ShaderGraph::break_cycles(ShaderNode *node, vector<bool>& visited, vector<bool>& on_stack)
@@ -433,27 +452,17 @@ void ShaderGraph::break_cycles(ShaderNode *node, vector<bool>& visited, vector<b
void ShaderGraph::clean()
{
+ /* remove proxy and unnecessary mix nodes */
+ remove_unneeded_nodes();
+
/* we do two things here: find cycles and break them, and remove unused
* nodes that don't feed into the output. how cycles are broken is
* undefined, they are invalid input, the important thing is to not crash */
- vector<bool> removed(nodes.size(), false);
vector<bool> visited(nodes.size(), false);
vector<bool> on_stack(nodes.size(), false);
list<ShaderNode*> newnodes;
-
- /* remove proxy nodes */
- remove_proxy_nodes(removed);
-
- foreach(ShaderNode *node, nodes) {
- if(!removed[node->id])
- newnodes.push_back(node);
- else
- delete node;
- }
- nodes = newnodes;
- newnodes.clear();
/* break cycles */
break_cycles(output(), visited, on_stack);
@@ -464,7 +473,7 @@ void ShaderGraph::clean()
foreach(ShaderInput *to, node->inputs) {
ShaderOutput *from = to->link;
- if (from) {
+ if(from) {
to->link = NULL;
from->links.erase(remove(from->links.begin(), from->links.end(), to), from->links.end());
}
diff --git a/intern/cycles/render/graph.h b/intern/cycles/render/graph.h
index 46043cf85d2..8e91a9ddc07 100644
--- a/intern/cycles/render/graph.h
+++ b/intern/cycles/render/graph.h
@@ -239,6 +239,7 @@ public:
void connect(ShaderOutput *from, ShaderInput *to);
void disconnect(ShaderInput *to);
+ void remove_unneeded_nodes();
void finalize(bool do_bump = false, bool do_osl = false, bool do_multi_closure = false);
protected:
@@ -247,7 +248,6 @@ protected:
void find_dependencies(set<ShaderNode*>& dependencies, ShaderInput *input);
void copy_nodes(set<ShaderNode*>& nodes, map<ShaderNode*, ShaderNode*>& nnodemap);
- void remove_proxy_nodes(vector<bool>& removed);
void break_cycles(ShaderNode *node, vector<bool>& visited, vector<bool>& on_stack);
void clean();
void bump_from_displacement();
diff --git a/intern/cycles/render/shader.cpp b/intern/cycles/render/shader.cpp
index c7f39b4151a..b061e869e2f 100644
--- a/intern/cycles/render/shader.cpp
+++ b/intern/cycles/render/shader.cpp
@@ -66,6 +66,12 @@ Shader::~Shader()
void Shader::set_graph(ShaderGraph *graph_)
{
+ /* do this here already so that we can detect if mesh or object attributes
+ * are needed, since the node attribute callbacks check if their sockets
+ * are connected but proxy nodes should not count */
+ if(graph_)
+ graph_->remove_unneeded_nodes();
+
/* assign graph */
delete graph;
delete graph_bump;