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:
authorLukas Toenne <lukas.toenne@googlemail.com>2011-12-18 19:34:06 +0400
committerLukas Toenne <lukas.toenne@googlemail.com>2011-12-18 19:34:06 +0400
commit5f6bd44c82bef24a43696449d8b905beeb53015b (patch)
tree7e955e53c4e9ee8a44c716b79ceaeebc34511b08 /intern/cycles/render/graph.cpp
parentb49463c439820c5039caf63421bdc8f3a58554b2 (diff)
Generalized node groups for Cycles.
This allows group nodes inside other group nodes in cycles and makes the code more generic for all possible cases, like direct group input-to-output links and unused group sockets. Previous code tried to connect external nodes and internal group sockets by following links until a "real" node input/output. This quickly becomes complicated in corner cases as described above and can lead to unexpected behavior when the group socket is of a different type than the internal/external sockets, but that conversion is skipped. The new code uses the concept of "proxy nodes" similar to what the new compositor does. Each group socket is replaced with a proxy node with a single input and output, to which other nodes in the same tree and internal nodes can link to. After all groups have been expanded in the graph, these proxy nodes are removed again, adding converter nodes if necessary.
Diffstat (limited to 'intern/cycles/render/graph.cpp')
-rw-r--r--intern/cycles/render/graph.cpp53
1 files changed, 51 insertions, 2 deletions
diff --git a/intern/cycles/render/graph.cpp b/intern/cycles/render/graph.cpp
index cdded403cbe..cc29047f048 100644
--- a/intern/cycles/render/graph.cpp
+++ b/intern/cycles/render/graph.cpp
@@ -292,6 +292,42 @@ void ShaderGraph::copy_nodes(set<ShaderNode*>& nodes, map<ShaderNode*, ShaderNod
}
}
+void ShaderGraph::remove_proxy_nodes(vector<bool>& removed)
+{
+ foreach(ShaderNode *node, nodes) {
+ ProxyNode *proxy = dynamic_cast<ProxyNode*>(node);
+ if (proxy) {
+ ShaderInput *input = proxy->inputs[0];
+ ShaderOutput *output = proxy->outputs[0];
+
+ /* temp. copy of the output links list.
+ * output->links is modified when we disconnect!
+ */
+ vector<ShaderInput*> links(output->links);
+ ShaderOutput *from = input->link;
+
+ /* bypass the proxy node */
+ if (from) {
+ disconnect(input);
+ foreach(ShaderInput *to, links) {
+ disconnect(to);
+ connect(from, to);
+ }
+ }
+ else {
+ foreach(ShaderInput *to, links) {
+ disconnect(to);
+
+ /* transfer the default input value to the target socket */
+ to->set(input->value);
+ }
+ }
+
+ removed[proxy->id] = true;
+ }
+ }
+}
+
void ShaderGraph::break_cycles(ShaderNode *node, vector<bool>& visited, vector<bool>& on_stack)
{
visited[node->id] = true;
@@ -322,15 +358,28 @@ void ShaderGraph::clean()
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);
/* remove unused nodes */
- list<ShaderNode*> newnodes;
-
foreach(ShaderNode *node, nodes) {
if(visited[node->id])
newnodes.push_back(node);