[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [56654] trunk/blender/source/blender/ compositor/nodes: Fix for #35291, Deleting 'Group Output' node in compositor causes Segfault.

Lukas Toenne lukas.toenne at googlemail.com
Fri May 10 14:19:42 CEST 2013


Revision: 56654
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=56654
Author:   lukastoenne
Date:     2013-05-10 12:19:42 +0000 (Fri, 10 May 2013)
Log Message:
-----------
Fix for #35291, Deleting 'Group Output' node in compositor causes Segfault. A group without an output node in compositor would leave the original Node instance in the graph with outgoing connections. This causes trouble because the Node is expected to be a NodeOperation. Now group nodes always get disconnected and if no output node is present will use the default group output values (which is slightly less confusing than using input values from connected nodes).

Modified Paths:
--------------
    trunk/blender/source/blender/compositor/nodes/COM_GroupNode.cpp
    trunk/blender/source/blender/compositor/nodes/COM_GroupNode.h

Modified: trunk/blender/source/blender/compositor/nodes/COM_GroupNode.cpp
===================================================================
--- trunk/blender/source/blender/compositor/nodes/COM_GroupNode.cpp	2013-05-10 12:16:12 UTC (rev 56653)
+++ trunk/blender/source/blender/compositor/nodes/COM_GroupNode.cpp	2013-05-10 12:19:42 UTC (rev 56654)
@@ -26,7 +26,14 @@
 #include "COM_SocketProxyNode.h"
 #include "COM_SetColorOperation.h"
 #include "COM_ExecutionSystemHelper.h"
+#include "COM_SetValueOperation.h"
+#include "COM_SetVectorOperation.h"
+#include "COM_SetColorOperation.h"
 
+extern "C" {
+#include "RNA_access.h"
+}
+
 GroupNode::GroupNode(bNode *editorNode) : Node(editorNode)
 {
 	/* pass */
@@ -83,6 +90,7 @@
 
 	const bool groupnodeBuffering = system.getContext().isGroupnodeBufferEnabled();
 
+	bool has_output = false;
 	/* create proxy nodes for group input/output nodes */
 	for (bNode *bionode = (bNode *)subtree->nodes.first; bionode; bionode = bionode->next) {
 		if (bionode->type == NODE_GROUP_INPUT) {
@@ -100,6 +108,7 @@
 		}
 		
 		if (bionode->type == NODE_GROUP_OUTPUT && (bionode->flag & NODE_DO_OUTPUT)) {
+			has_output = true;
 			for (bNodeSocket *bsock = (bNodeSocket *)bionode->inputs.first; bsock; bsock = bsock->next) {
 				OutputSocket *gsock;
 				find_group_output(this, bsock->identifier, &gsock);
@@ -114,11 +123,91 @@
 		}
 	}
 	
+	/* in case no output node exists, add input value operations using defaults */
+	if (!has_output) {
+		for (int index = 0; index < getNumberOfOutputSockets(); ++index) {
+			OutputSocket *output = getOutputSocket(index);
+			addDefaultOutputOperation(system, output);
+		}
+	}
+	
 	/* unlink the group node itself, input links have been duplicated */
 	for (int index = 0; index < this->getNumberOfInputSockets(); ++index) {
 		InputSocket *sock = this->getInputSocket(index);
 		sock->unlinkConnections(&system);
 	}
+	for (int index = 0; index < this->getNumberOfOutputSockets(); ++index) {
+		OutputSocket *sock = this->getOutputSocket(index);
+		sock->clearConnections();
+	}
 	
 	ExecutionSystemHelper::addbNodeTree(system, nodes_start, subtree, this->getInstanceKey());
 }
+
+bNodeSocket *GroupNode::findInterfaceInput(InputSocket *socket)
+{
+	bNode *bnode = this->getbNode();
+	bNodeTree *subtree = (bNodeTree *)bnode->id;
+	if (!subtree)
+		return NULL;
+	
+	const char *identifier = socket->getbNodeSocket()->identifier;
+	for (bNodeSocket *iosock = (bNodeSocket *)subtree->inputs.first; iosock; iosock = iosock->next)
+		if (STREQ(iosock->identifier, identifier))
+			return iosock;
+	return NULL;
+}
+
+bNodeSocket *GroupNode::findInterfaceOutput(OutputSocket *socket)
+{
+	bNode *bnode = this->getbNode();
+	bNodeTree *subtree = (bNodeTree *)bnode->id;
+	if (!subtree)
+		return NULL;
+	
+	const char *identifier = socket->getbNodeSocket()->identifier;
+	for (bNodeSocket *iosock = (bNodeSocket *)subtree->outputs.first; iosock; iosock = iosock->next)
+		if (STREQ(iosock->identifier, identifier))
+			return iosock;
+	return NULL;
+}
+
+void GroupNode::addDefaultOutputOperation(ExecutionSystem &system, OutputSocket *outputsocket)
+{
+	bNodeSocket *iosock = findInterfaceOutput(outputsocket);
+	if (!iosock)
+		return;
+	
+	PointerRNA ptr;
+	RNA_pointer_create(&getbNodeTree()->id, &RNA_NodeSocket, iosock, &ptr);
+	
+	NodeOperation *operation = NULL;
+	switch (iosock->typeinfo->type) {
+		case SOCK_FLOAT: {
+			float value = RNA_float_get(&ptr, "default_value");
+			SetValueOperation *value_op = new SetValueOperation();
+			value_op->setValue(value);
+			operation = value_op;
+			break;
+		}
+		case SOCK_VECTOR: {
+			float vector[3];
+			RNA_float_get_array(&ptr, "default_value", vector);
+			SetVectorOperation *vector_op = new SetVectorOperation();
+			vector_op->setVector(vector);
+			operation = vector_op;
+			break;
+		}
+		case SOCK_RGBA: {
+			float color[4];
+			RNA_float_get_array(&ptr, "default_value", color);
+			SetColorOperation *color_op = new SetColorOperation();
+			color_op->setChannels(color);
+			operation = color_op;
+			break;
+		}
+	}
+	
+	outputsocket->relinkConnections(operation->getOutputSocket());
+	system.addOperation(operation);
+}

Modified: trunk/blender/source/blender/compositor/nodes/COM_GroupNode.h
===================================================================
--- trunk/blender/source/blender/compositor/nodes/COM_GroupNode.h	2013-05-10 12:16:12 UTC (rev 56653)
+++ trunk/blender/source/blender/compositor/nodes/COM_GroupNode.h	2013-05-10 12:19:42 UTC (rev 56654)
@@ -52,6 +52,10 @@
 	 * @param system the ExecutionSystem where to add the subtree
 	 */
 	void ungroup(ExecutionSystem &system);
+
+	bNodeSocket *findInterfaceInput(InputSocket *socket);
+	bNodeSocket *findInterfaceOutput(OutputSocket *socket);
+	void addDefaultOutputOperation(ExecutionSystem &system, OutputSocket *outputsocket);
 };
 
 #endif




More information about the Bf-blender-cvs mailing list