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>2013-03-20 17:17:35 +0400
committerLukas Toenne <lukas.toenne@googlemail.com>2013-03-20 17:17:35 +0400
commit1c3b3321e70ed95046705677bca329a929288ddd (patch)
tree04a75c98a2f50e2faa54c285afb49349c7733e39
parent0130d7dcd4a06a777cb7bd2f9a38dd9ea84085a6 (diff)
Fix for #34708 and #34709, cycles group nodes were not working well with 0 or 2+ group input/output nodes.
The issue here was that the proxy nodes created for connecting extern group node sockets to the internal nodes were generated by the input/output nodes themselves. 0 input/output nodes: there would be no proxy that external group node sockets can map to 2+ input/output nodes: additional nodes would overwrite entries from previous nodes, so that only one of the input/output nodes would be used. Solution is to always generate exactly 1 proxy node for every group socket in advance, regardless of whether it is used internally. Internal node sockets can then all map to this proxy node. In the case out output nodes there should only ever be one active node, otherwise the connection to the proxy would be ambiguous. For this purpose the NODE_DO_OUTPUT flag has been exposed to RNA, so that cycles can check it and only use the active output.
-rw-r--r--intern/cycles/blender/blender_shader.cpp77
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c5
2 files changed, 42 insertions, 40 deletions
diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp
index 45a97f1d530..bf934147527 100644
--- a/intern/cycles/blender/blender_shader.cpp
+++ b/intern/cycles/blender/blender_shader.cpp
@@ -680,66 +680,63 @@ static void add_nodes(Scene *scene, BL::BlendData b_data, BL::Scene b_scene, Sha
}
}
else if (b_node->is_a(&RNA_ShaderNodeGroup)) {
+
BL::NodeGroup b_gnode(*b_node);
BL::ShaderNodeTree b_group_ntree(b_gnode.node_tree());
ProxyMap group_proxy_map;
- if (!b_group_ntree)
- continue;
-
- add_nodes(scene, b_data, b_scene, graph, b_group_ntree, group_proxy_map);
-
- /* map the outer socket to the internal proxy nodes */
+ /* Add a proxy node for each socket
+ * Do this even if the node group has no internal tree,
+ * so that links have something to connect to and assert won't fail.
+ */
for(b_node->inputs.begin(b_input); b_input != b_node->inputs.end(); ++b_input) {
+ ProxyNode *proxy = new ProxyNode(convert_socket_type(*b_input));
+ graph->add(proxy);
- /* get internal proxy node from group proxy map */
- assert(group_proxy_map.find(b_input->identifier()) != group_proxy_map.end());
- assert(group_proxy_map[b_input->identifier()]->special_type == SHADER_SPECIAL_TYPE_PROXY);
- ProxyNode *proxy = group_proxy_map[b_input->identifier()];
+ /* register the proxy node for internal binding */
+ group_proxy_map[b_input->identifier()] = proxy;
input_map[b_input->ptr.data] = proxy->inputs[0];
-
- /* input value for proxy inputs is defined by group node */
- set_default_value(proxy->inputs[0], *b_node, *b_input, b_data, b_ntree);
}
-
- /* map the outer socket to the internal proxy nodes */
for(b_node->outputs.begin(b_output); b_output != b_node->outputs.end(); ++b_output) {
+ ProxyNode *proxy = new ProxyNode(convert_socket_type(*b_output));
+ graph->add(proxy);
- /* get internal proxy node from group node map */
- assert(group_proxy_map.find(b_output->identifier()) != group_proxy_map.end());
- assert(group_proxy_map[b_output->identifier()]->special_type == SHADER_SPECIAL_TYPE_PROXY);
- ProxyNode *proxy = group_proxy_map[b_output->identifier()];
+ /* register the proxy node for internal binding */
+ group_proxy_map[b_output->identifier()] = proxy;
output_map[b_output->ptr.data] = proxy->outputs[0];
}
+
+ if (b_group_ntree)
+ add_nodes(scene, b_data, b_scene, graph, b_group_ntree, group_proxy_map);
}
else if (b_node->is_a(&RNA_NodeGroupInput)) {
- /* add a proxy node for each socket */
+ /* map each socket to a proxy node */
for(b_node->outputs.begin(b_output); b_output != b_node->outputs.end(); ++b_output) {
- ProxyNode *proxy = new ProxyNode(convert_socket_type(*b_output));
-
- output_map[b_output->ptr.data] = proxy->outputs[0];
-
- /* register the proxy node for external binding */
- proxy_map[b_output->identifier()] = proxy;
-
- graph->add(proxy);
+ ProxyMap::iterator proxy_it = proxy_map.find(b_output->identifier());
+ if (proxy_it != proxy_map.end()) {
+ ProxyNode *proxy = proxy_it->second;
+
+ output_map[b_output->ptr.data] = proxy->outputs[0];
+ }
}
}
else if (b_node->is_a(&RNA_NodeGroupOutput)) {
- /* add a proxy node for each socket */
- for(b_node->inputs.begin(b_input); b_input != b_node->inputs.end(); ++b_input) {
- ProxyNode *proxy = new ProxyNode(convert_socket_type(*b_input));
-
- input_map[b_input->ptr.data] = proxy->inputs[0];
-
- set_default_value(proxy->inputs[0], *b_node, *b_input, b_data, b_ntree);
-
- /* register the proxy node for external binding */
- proxy_map[b_input->identifier()] = proxy;
-
- graph->add(proxy);
+ BL::NodeGroupOutput b_output_node(*b_node);
+ /* only the active group output is used */
+ if (b_output_node.is_active_output()) {
+ /* map each socket to a proxy node */
+ for(b_node->inputs.begin(b_input); b_input != b_node->inputs.end(); ++b_input) {
+ ProxyMap::iterator proxy_it = proxy_map.find(b_input->identifier());
+ if (proxy_it != proxy_map.end()) {
+ ProxyNode *proxy = proxy_it->second;
+
+ input_map[b_input->ptr.data] = proxy->inputs[0];
+
+ set_default_value(proxy->inputs[0], *b_node, *b_input, b_data, b_ntree);
+ }
+ }
}
}
else {
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index 45a81e1a2ab..6add49a5292 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -2843,6 +2843,11 @@ static void def_group_output(StructRNA *srna)
RNA_def_property_struct_type(prop, "PropertyGroup");
RNA_def_property_flag(prop, PROP_IDPROPERTY);
RNA_def_property_ui_text(prop, "Interface", "Interface socket data");
+
+ prop = RNA_def_property(srna, "is_active_output", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", NODE_DO_OUTPUT);
+ RNA_def_property_ui_text(prop, "Active Output", "True if this node is used as the active group output");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
}
static void def_group(StructRNA *srna)