[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [55440] trunk/blender: Fix for #34708 and #34709, cycles group nodes were not working well with 0 or 2+ group input/ output nodes.

Lukas Toenne lukas.toenne at googlemail.com
Wed Mar 20 14:17:35 CET 2013


Revision: 55440
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=55440
Author:   lukastoenne
Date:     2013-03-20 13:17:35 +0000 (Wed, 20 Mar 2013)
Log Message:
-----------
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.

Modified Paths:
--------------
    trunk/blender/intern/cycles/blender/blender_shader.cpp
    trunk/blender/source/blender/makesrna/intern/rna_nodetree.c

Modified: trunk/blender/intern/cycles/blender/blender_shader.cpp
===================================================================
--- trunk/blender/intern/cycles/blender/blender_shader.cpp	2013-03-20 13:02:40 UTC (rev 55439)
+++ trunk/blender/intern/cycles/blender/blender_shader.cpp	2013-03-20 13:17:35 UTC (rev 55440)
@@ -680,66 +680,63 @@
 			}
 		}
 		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 {

Modified: trunk/blender/source/blender/makesrna/intern/rna_nodetree.c
===================================================================
--- trunk/blender/source/blender/makesrna/intern/rna_nodetree.c	2013-03-20 13:02:40 UTC (rev 55439)
+++ trunk/blender/source/blender/makesrna/intern/rna_nodetree.c	2013-03-20 13:17:35 UTC (rev 55440)
@@ -2843,6 +2843,11 @@
 	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)




More information about the Bf-blender-cvs mailing list