[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [36496] branches/particles-2010/source/ blender: Fixed memory bug when copying node trees, group tree sockets did not duplicate their default button values.

Lukas Toenne lukas.toenne at googlemail.com
Thu May 5 12:03:55 CEST 2011


Revision: 36496
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=36496
Author:   lukastoenne
Date:     2011-05-05 10:03:54 +0000 (Thu, 05 May 2011)
Log Message:
-----------
Fixed memory bug when copying node trees, group tree sockets did not duplicate their default button values.
Added correct cloning of socket default values when exposing a group socket.
Added simple conversion of socket default values when ungrouping a group (this will be part of a more sophisticated converter system in the future).

Modified Paths:
--------------
    branches/particles-2010/source/blender/blenkernel/intern/node.c
    branches/particles-2010/source/blender/nodes/intern/node_common.c

Modified: branches/particles-2010/source/blender/blenkernel/intern/node.c
===================================================================
--- branches/particles-2010/source/blender/blenkernel/intern/node.c	2011-05-05 09:43:45 UTC (rev 36495)
+++ branches/particles-2010/source/blender/blenkernel/intern/node.c	2011-05-05 10:03:54 UTC (rev 36496)
@@ -579,8 +579,7 @@
 		oldsock->new_sock= sock;
 		sock->stack_index= 0;
 		
-		if (sock->default_value)
-			sock->default_value = MEM_dupallocN(sock->default_value);
+		sock->default_value = (oldsock->default_value ? MEM_dupallocN(oldsock->default_value) : NULL);
 		
 		if (sock->panel)
 			sock->panel = sock->panel->new_panel;
@@ -592,8 +591,7 @@
 		oldsock->new_sock= sock;
 		sock->stack_index= 0;
 		
-		if (sock->default_value)
-			sock->default_value = MEM_dupallocN(sock->default_value);
+		sock->default_value = (oldsock->default_value ? MEM_dupallocN(oldsock->default_value) : NULL);
 		
 		if (sock->panel)
 			sock->panel = sock->panel->new_panel;
@@ -841,11 +839,13 @@
 	for(gsock= newtree->inputs.first, oldgsock= ntree->inputs.first; gsock; gsock=gsock->next, oldgsock=oldgsock->next) {
 		oldgsock->new_sock= gsock;
 		gsock->groupsock = (oldgsock->groupsock ? oldgsock->groupsock->new_sock : NULL);
+		gsock->default_value = (oldgsock->default_value ? MEM_dupallocN(oldgsock->default_value) : NULL);
 	}
 	BLI_duplicatelist(&newtree->outputs, &ntree->outputs);
 	for(gsock= newtree->outputs.first, oldgsock= ntree->outputs.first; gsock; gsock=gsock->next, oldgsock=oldgsock->next) {
 		oldgsock->new_sock= gsock;
 		gsock->groupsock = (oldgsock->groupsock ? oldgsock->groupsock->new_sock : NULL);
+		gsock->default_value = (oldgsock->default_value ? MEM_dupallocN(oldgsock->default_value) : NULL);
 	}
 	
 	/* copy links */

Modified: branches/particles-2010/source/blender/nodes/intern/node_common.c
===================================================================
--- branches/particles-2010/source/blender/nodes/intern/node_common.c	2011-05-05 09:43:45 UTC (rev 36495)
+++ branches/particles-2010/source/blender/nodes/intern/node_common.c	2011-05-05 10:03:54 UTC (rev 36496)
@@ -235,6 +235,184 @@
 	return gnode;
 }
 
+/* XXX This is a makeshift function to have useful initial group socket values.
+ * In the end this should be implemented by a flexible socket data conversion system,
+ * which is yet to be implemented. The idea is that beside default standard conversions,
+ * such as int-to-float, it should be possible to quickly select a conversion method or
+ * a chain of conversions for each input, whenever there is more than one option.
+ * E.g. a vector-to-float conversion could use either of the x/y/z components or
+ * the vector length.
+ *
+ * In the interface this could be implemented by a pseudo-script textbox on linked inputs,
+ * with quick selection from a predefined list of conversion options. Some Examples:
+ * - vector component 'z' (vector->float):						"z"
+ * - greyscale color (float->color):							"grey"
+ * - color luminance (color->float):							"lum"
+ * - matrix column 2 length (matrix->vector->float):			"col[1].len"
+ * - mesh vertex coordinate 'y' (mesh->vertex->vector->float):	"vertex.co.y"
+ *
+ * The actual conversion is then done by a series of conversion functions,
+ * which are defined in the socket type structs.
+ */
+static void convert_socket_value(bNodeSocket *from, bNodeSocket *to)
+{
+	/* XXX only one of these pointers is valid! just putting them here for convenience */
+	bNodeSocketValueFloat *fromfloat= (bNodeSocketValueFloat*)from->default_value;
+	bNodeSocketValueInt *fromint= (bNodeSocketValueInt*)from->default_value;
+	bNodeSocketValueBoolean *frombool= (bNodeSocketValueBoolean*)from->default_value;
+	bNodeSocketValueVector *fromvector= (bNodeSocketValueVector*)from->default_value;
+	bNodeSocketValueRGBA *fromrgba= (bNodeSocketValueRGBA*)from->default_value;
+
+	bNodeSocketValueFloat *tofloat= (bNodeSocketValueFloat*)to->default_value;
+	bNodeSocketValueInt *toint= (bNodeSocketValueInt*)to->default_value;
+	bNodeSocketValueBoolean *tobool= (bNodeSocketValueBoolean*)to->default_value;
+	bNodeSocketValueVector *tovector= (bNodeSocketValueVector*)to->default_value;
+	bNodeSocketValueRGBA *torgba= (bNodeSocketValueRGBA*)to->default_value;
+
+	switch (from->type) {
+	case SOCK_VALUE:
+	case SOCK_FLOAT:
+		switch (to->type) {
+		case SOCK_VALUE:
+		case SOCK_FLOAT:
+			tofloat->value = fromfloat->value;
+			break;
+		case SOCK_INT:
+			toint->value = (int)fromfloat->value;
+			break;
+		case SOCK_BOOLEAN:
+			tobool->value = (fromfloat->value > 0.0f);
+			break;
+		case SOCK_VECTOR:
+			tovector->value[0] = tovector->value[1] = tovector->value[2] = fromfloat->value;
+			break;
+		case SOCK_RGBA:
+			torgba->value[0] = torgba->value[1] = torgba->value[2] = torgba->value[3] = fromfloat->value;
+			break;
+		}
+		break;
+	case SOCK_INT:
+		switch (to->type) {
+		case SOCK_VALUE:
+		case SOCK_FLOAT:
+			tofloat->value = (float)fromint->value;
+			break;
+		case SOCK_INT:
+			toint->value = fromint->value;
+			break;
+		case SOCK_BOOLEAN:
+			tobool->value = (fromint->value > 0);
+			break;
+		case SOCK_VECTOR:
+			tovector->value[0] = tovector->value[1] = tovector->value[2] = (float)fromint->value;
+			break;
+		case SOCK_RGBA:
+			torgba->value[0] = torgba->value[1] = torgba->value[2] = torgba->value[3] = (float)fromint->value;
+			break;
+		}
+		break;
+	case SOCK_BOOLEAN:
+		switch (to->type) {
+		case SOCK_VALUE:
+		case SOCK_FLOAT:
+			tofloat->value = (float)frombool->value;
+			break;
+		case SOCK_INT:
+			toint->value = (int)frombool->value;
+			break;
+		case SOCK_BOOLEAN:
+			tobool->value = frombool->value;
+			break;
+		case SOCK_VECTOR:
+			tovector->value[0] = tovector->value[1] = tovector->value[2] = (float)frombool->value;
+			break;
+		case SOCK_RGBA:
+			torgba->value[0] = torgba->value[1] = torgba->value[2] = torgba->value[3] = (float)frombool->value;
+			break;
+		}
+		break;
+	case SOCK_VECTOR:
+		switch (to->type) {
+		case SOCK_VALUE:
+		case SOCK_FLOAT:
+			tofloat->value = fromvector->value[0];
+			break;
+		case SOCK_INT:
+			toint->value = (int)fromvector->value[0];
+			break;
+		case SOCK_BOOLEAN:
+			tobool->value = (fromvector->value[0] > 0.0f);
+			break;
+		case SOCK_VECTOR:
+			copy_v3_v3(tovector->value, fromvector->value);
+			break;
+		case SOCK_RGBA:
+			copy_v3_v3(torgba->value, fromvector->value);
+			torgba->value[3] = 1.0f;
+			break;
+		}
+		break;
+	case SOCK_RGBA:
+		switch (to->type) {
+		case SOCK_VALUE:
+		case SOCK_FLOAT:
+			tofloat->value = fromrgba->value[0];
+			break;
+		case SOCK_INT:
+			toint->value = (int)fromrgba->value[0];
+			break;
+		case SOCK_BOOLEAN:
+			tobool->value = (fromrgba->value[0] > 0.0f);
+			break;
+		case SOCK_VECTOR:
+			copy_v3_v3(tovector->value, fromrgba->value);
+			break;
+		case SOCK_RGBA:
+			copy_v4_v4(torgba->value, fromrgba->value);
+			break;
+		}
+		break;
+	}
+}
+
+static void copy_socket_value(bNodeSocket *from, bNodeSocket *to)
+{
+	/* XXX only one of these pointers is valid! just putting them here for convenience */
+	bNodeSocketValueFloat *fromfloat= (bNodeSocketValueFloat*)from->default_value;
+	bNodeSocketValueInt *fromint= (bNodeSocketValueInt*)from->default_value;
+	bNodeSocketValueBoolean *frombool= (bNodeSocketValueBoolean*)from->default_value;
+	bNodeSocketValueVector *fromvector= (bNodeSocketValueVector*)from->default_value;
+	bNodeSocketValueRGBA *fromrgba= (bNodeSocketValueRGBA*)from->default_value;
+
+	bNodeSocketValueFloat *tofloat= (bNodeSocketValueFloat*)to->default_value;
+	bNodeSocketValueInt *toint= (bNodeSocketValueInt*)to->default_value;
+	bNodeSocketValueBoolean *tobool= (bNodeSocketValueBoolean*)to->default_value;
+	bNodeSocketValueVector *tovector= (bNodeSocketValueVector*)to->default_value;
+	bNodeSocketValueRGBA *torgba= (bNodeSocketValueRGBA*)to->default_value;
+
+	if (from->type != to->type)
+		return;
+
+	switch (from->type) {
+	case SOCK_VALUE:
+	case SOCK_FLOAT:
+		*tofloat = *fromfloat;
+		break;
+	case SOCK_INT:
+		*toint = *fromint;
+		break;
+	case SOCK_BOOLEAN:
+		*tobool = *frombool;
+		break;
+	case SOCK_VECTOR:
+		*tovector = *fromvector;
+		break;
+	case SOCK_RGBA:
+		*torgba = *fromrgba;
+		break;
+	}
+}
+
 /* returns 1 if its OK */
 int node_group_ungroup(bNodeTree *ntree, bNode *gnode)
 {
@@ -305,9 +483,8 @@
 					}
 				}
 				else {
-					/* XXX TODO: copy the default input value from the group socket default (gsock->default_value)
-					 * to the external socket (link->tosock->default_value). This may require conversion!
-					 */
+					/* copy the default input value from the group socket default to the external socket */
+					convert_socket_value(gsock, link->tosock);
 				}
 			}
 		}
@@ -334,9 +511,8 @@
 				link->fromsock = insock->link->fromsock;
 			}
 			else {
-				/* XXX TODO: copy the default input value from the group node socket default (insock->default_value)
-				 * to the internal socket (link->tosock->default_value). This may require conversion!
-				 */
+				/* copy the default input value from the group node socket default to the internal socket */
+				convert_socket_value(insock, link->tosock);
 				nodeRemLink(wgroup, link);
 			}
 		}
@@ -414,7 +590,8 @@
 {
 	bNodeSocket *gsock= node_group_add_socket(ngroup, sock->name, sock->type, in_out);
 	
-	/* XXX TODO: initialize the default value. */
+	/* initialize the default value. */
+	copy_socket_value(sock, gsock);
 	
 	return gsock;
 }
@@ -429,7 +606,8 @@
 			if (!sock->link && !(sock->flag & SOCK_HIDDEN)) {
 				gsock = node_group_add_socket(ngroup, sock->name, sock->type, SOCK_IN);
 				
-				/* XXX TODO: initialize the default value. */
+				/* initialize the default value. */
+				copy_socket_value(sock, gsock);
 				
 				sock->link = nodeAddLink(ngroup, NULL, gsock, node, sock);
 			}
@@ -438,7 +616,8 @@
 			if (nodeCountSocketLinks(ngroup, sock)==0 && !(sock->flag & SOCK_HIDDEN)) {
 				gsock = node_group_add_socket(ngroup, sock->name, sock->type, SOCK_OUT);
 				
-				/* XXX TODO: initialize the default value. */
+				/* initialize the default value. */
+				copy_socket_value(sock, gsock);
 				
 				gsock->link = nodeAddLink(ngroup, node, sock, NULL, gsock);
 			}




More information about the Bf-blender-cvs mailing list