[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [56133] trunk/blender/source/blender: Fix for #35010, Node Groups don't show up anymore in Material Surface.

Lukas Toenne lukas.toenne at googlemail.com
Thu Apr 18 13:36:11 CEST 2013


Revision: 56133
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=56133
Author:   lukastoenne
Date:     2013-04-18 11:36:11 +0000 (Thu, 18 Apr 2013)
Log Message:
-----------
Fix for #35010, Node Groups don't show up anymore in Material Surface. Fixing the node tree view was a bit of a todo item after pynodes.

To make the type-dependent socket linking in this template a bit more manageable, there are now separate functions that generate "items" for a particular node type consisting of the socket index, name and possibly additional properties required (currently only node groups vs. all other types). This is still nowhere near flexible enough to be used as a generic template all node systems, but works for now.

In order to make this usable as a generic tool we will have to devise a way of storing, comparing, applying node settings *outside of actual node instances*. Then each node needs to tell how sockets are generated based on these properties. For the current nodes this would be far too complicated ...

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/intern/node.c
    trunk/blender/source/blender/editors/space_node/node_templates.c
    trunk/blender/source/blender/nodes/shader/nodes/node_shader_common.c

Modified: trunk/blender/source/blender/blenkernel/intern/node.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/node.c	2013-04-18 11:09:25 UTC (rev 56132)
+++ trunk/blender/source/blender/blenkernel/intern/node.c	2013-04-18 11:36:11 UTC (rev 56133)
@@ -796,8 +796,11 @@
 	const char *idname = NULL;
 	
 	NODE_TYPES_BEGIN(ntype)
-		if (ntype->type == type) {
-			idname = DATA_(ntype->idname);
+		/* do an extra poll here, because some int types are used
+		 * for multiple node types, this helps find the desired type
+		 */
+		if (ntype->type == type && (!ntype->poll || ntype->poll(ntype, ntree))) {
+			idname = ntype->idname;
 			break;
 		}
 	NODE_TYPES_END

Modified: trunk/blender/source/blender/editors/space_node/node_templates.c
===================================================================
--- trunk/blender/source/blender/editors/space_node/node_templates.c	2013-04-18 11:09:25 UTC (rev 56132)
+++ trunk/blender/source/blender/editors/space_node/node_templates.c	2013-04-18 11:36:11 UTC (rev 56133)
@@ -57,6 +57,44 @@
 
 /************************* Node Socket Manipulation **************************/
 
+/* describes an instance of a node type and a specific socket to link */
+typedef struct NodeLinkItem {
+	int socket_index;			/* index for linking */
+	int socket_type;			/* socket type for compatibility check */
+	const char *socket_name;	/* ui label of the socket */
+	const char *node_name;		/* ui label of the node */
+	
+	/* extra settings */
+	bNodeTree *ngroup;		/* group node tree */
+} NodeLinkItem;
+
+/* Compare an existing node to a link item to see if it can be reused.
+ * item must be for the same node type!
+ * XXX should become a node type callback
+ */
+static bool node_link_item_compare(bNode *node, NodeLinkItem *item)
+{
+	if (node->type == NODE_GROUP) {
+		return (node->id == (ID *)item->ngroup);
+	}
+	else
+		return true;
+}
+
+static void node_link_item_apply(bNode *node, NodeLinkItem *item)
+{
+	if (node->type == NODE_GROUP) {
+		node->id = (ID *)item->ngroup;
+		ntreeUpdateTree(item->ngroup);
+	}
+	else {
+		/* nothing to do for now */
+	}
+	
+	if (node->id)
+		id_us_plus(node->id);
+}
+
 static void node_tag_recursive(bNode *node)
 {
 	bNodeSocket *input;
@@ -149,7 +187,8 @@
 }
 
 /* add new node connected to this socket, or replace an existing one */
-static void node_socket_add_replace(const bContext *C, bNodeTree *ntree, bNode *node_to, bNodeSocket *sock_to, int type, bNodeTree *ngroup, int sock_num)
+static void node_socket_add_replace(const bContext *C, bNodeTree *ntree, bNode *node_to, bNodeSocket *sock_to,
+                                    int type, NodeLinkItem *item)
 {
 	bNode *node_from;
 	bNodeSocket *sock_from_tmp;
@@ -170,9 +209,7 @@
 		if (!(node_from->inputs.first == NULL && !(node_from->typeinfo->flag & NODE_OPTIONS)))
 			node_from = NULL;
 
-	/* XXX how can this be done nicely? bNodeTemplate is removed, it doesn't work for generic custom nodes */
-	if (node_prev && node_prev->type == type &&
-	    (type != NODE_GROUP || node_prev->id == &ngroup->id))
+	if (node_prev && node_prev->type == type && node_link_item_compare(node_prev, item))
 	{
 		/* keep the previous node if it's the same type */
 		node_from = node_prev;
@@ -182,19 +219,13 @@
 		node_from->locx = node_to->locx - (node_from->typeinfo->width + 50);
 		node_from->locy = node_to->locy;
 		
-		/* XXX bad, should be dispatched to generic operator or something ... */
-		if (type == NODE_GROUP) {
-			node_from->id = (ID *)ngroup;
-		}
-		
-		if (node_from->id)
-			id_us_plus(node_from->id);
+		node_link_item_apply(node_from, item);
 	}
 
 	nodeSetActive(ntree, node_from);
 
 	/* add link */
-	sock_from_tmp = BLI_findlink(&node_from->outputs, sock_num);
+	sock_from_tmp = BLI_findlink(&node_from->outputs, item->socket_index);
 	nodeAddLink(ntree, node_from, sock_from_tmp, node_to, sock_to);
 	sock_to->flag &= ~SOCK_COLLAPSED;
 
@@ -215,11 +246,9 @@
 						nodeRemLink(ntree, link);
 					}
 
-#if 0 /* XXX TODO */
-					node_socket_free_default_value(sock_from->typeinfo, sock_from->default_value);
-					sock_from->default_value = node_socket_make_default_value(sock_from->typeinfo);
-					node_socket_copy_default_value(sock_from->typeinfo, sock_from->default_value, sock_prev->default_value);
-#endif
+					if (sock_from->default_value)
+						MEM_freeN(sock_from->default_value);
+					node_socket_copy_default_value(sock_from->default_value, sock_prev->default_value);
 				}
 			}
 		}
@@ -255,13 +284,77 @@
 	bNode *node;
 	bNodeSocket *sock;
 
-	bNodeTree *ngroup;
-	int type;
-	int output;
+	bNodeType *node_type;
+	NodeLinkItem item;
 
 	uiLayout *layout;
 } NodeLinkArg;
 
+static void ui_node_link_items(NodeLinkArg *arg, int in_out, NodeLinkItem **r_items, int *r_totitems)
+{
+	/* XXX this should become a callback for node types! */
+	NodeLinkItem *items = NULL;
+	int totitems = 0;
+	
+	if (arg->node_type->type == NODE_GROUP) {
+		bNodeTree *ngroup;
+		int i;
+		
+		for (ngroup = arg->bmain->nodetree.first; ngroup; ngroup = ngroup->id.next) {
+			ListBase *lb = (in_out==SOCK_IN ? &ngroup->inputs : &ngroup->outputs);
+			totitems += BLI_countlist(lb);
+		}
+		
+		if (totitems > 0) {
+			items = MEM_callocN(sizeof(NodeLinkItem) * totitems, "ui node link items");
+			
+			i = 0;
+			for (ngroup = arg->bmain->nodetree.first; ngroup; ngroup = ngroup->id.next) {
+				ListBase *lb = (in_out == SOCK_IN ? &ngroup->inputs : &ngroup->outputs);
+				bNodeSocket *stemp;
+				int index;
+				for (stemp = lb->first, index = 0; stemp; stemp = stemp->next, ++index) {
+					NodeLinkItem *item = &items[i++];
+					
+					item->socket_index = index;
+					/* note: int stemp->type is not fully reliable, not used for node group
+					 * interface sockets. use the typeinfo->type instead.
+					 */
+					item->socket_type = stemp->typeinfo->type;
+					item->socket_name = stemp->name;
+					item->node_name = ngroup->id.name + 2;
+					item->ngroup = ngroup;
+				}
+			}
+		}
+	}
+	else {
+		bNodeSocketTemplate *socket_templates = (in_out == SOCK_IN ? arg->node_type->inputs : arg->node_type->outputs);
+		bNodeSocketTemplate *stemp;
+		int i;
+		
+		for (stemp = socket_templates; stemp && stemp->type != -1; ++stemp)
+			++totitems;
+		
+		if (totitems > 0) {
+			items = MEM_callocN(sizeof(NodeLinkItem) * totitems, "ui node link items");
+			
+			i = 0;
+			for (stemp = socket_templates; stemp && stemp->type != -1; ++stemp) {
+				NodeLinkItem *item = &items[i++];
+				
+				item->socket_index = i;
+				item->socket_type = stemp->type;
+				item->socket_name = stemp->name;
+				item->node_name = arg->node_type->ui_name;
+			}
+		}
+	}
+	
+	*r_items = items;
+	*r_totitems = totitems;
+}
+
 static void ui_node_link(bContext *C, void *arg_p, void *event_p)
 {
 	NodeLinkArg *arg = (NodeLinkArg *)arg_p;
@@ -276,7 +369,7 @@
 	else if (event == UI_NODE_LINK_REMOVE)
 		node_socket_remove(bmain, ntree, node_to, sock_to);
 	else
-		node_socket_add_replace(C, ntree, node_to, sock_to, arg->type, arg->ngroup, arg->output);
+		node_socket_add_replace(C, ntree, node_to, sock_to, arg->node_type->type, &arg->item);
 
 	ED_undo_push(C, "Node input modify");
 }
@@ -335,8 +428,9 @@
 			compatibility = NODE_OLD_SHADING;
 	}
 
-	NODE_TYPES_BEGIN(ntype)
-		bNodeSocketTemplate *stemp;
+	NODE_TYPES_BEGIN(ntype) {
+		NodeLinkItem *items;
+		int totitems;
 		char name[UI_MAX_NAME_STR];
 		int i, j, num = 0;
 		
@@ -346,12 +440,17 @@
 		if (ntype->nclass != nclass)
 			continue;
 		
-		for (i = 0, stemp = ntype->outputs; stemp && stemp->type != -1; stemp++, i++)
-			if (ui_compatible_sockets(stemp->type, sock->type))
+		arg->node_type = ntype;
+		
+		ui_node_link_items(arg, SOCK_OUT, &items, &totitems);
+		
+		for (i = 0; i < totitems; ++i)
+			if (ui_compatible_sockets(items[i].socket_type, sock->type))
 				num++;
 		
-		for (i = 0, j = 0, stemp = ntype->outputs; stemp && stemp->type != -1; stemp++, i++) {
-			if (!ui_compatible_sockets(stemp->type, sock->type))
+		j = 0;
+		for (i = 0; i < totitems; ++i) {
+			if (!ui_compatible_sockets(items[i].socket_type, sock->type))
 				continue;
 			
 			if (first) {
@@ -367,25 +466,28 @@
 			
 			if (num > 1) {
 				if (j == 0) {
-					uiItemL(column, IFACE_(ntype->ui_name), ICON_NODE);
+					uiItemL(column, IFACE_(items[i].node_name), ICON_NODE);
 					but = block->buttons.last;
 					but->flag = UI_TEXT_LEFT;
 				}
 				
-				BLI_snprintf(name, UI_MAX_NAME_STR, "  %s", IFACE_(stemp->name));
+				BLI_snprintf(name, UI_MAX_NAME_STR, "  %s", IFACE_(items[i].socket_name));
 				j++;
 			}
 			else
-				BLI_strncpy(name, IFACE_(ntype->ui_name), UI_MAX_NAME_STR);
+				BLI_strncpy(name, IFACE_(items[i].node_name), UI_MAX_NAME_STR);
 			
 			but = uiDefBut(block, BUT, 0, name, 0, 0, UI_UNIT_X * 4, UI_UNIT_Y,
 			               NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Add node to input"));
 			
 			argN = MEM_dupallocN(arg);
-			argN->type = ntype->type;
-			argN->output = i;
+			argN->item = items[i];
 			uiButSetNFunc(but, ui_node_link, argN, NULL);
 		}
+		
+		if (items)
+			MEM_freeN(items);
+	}
 	NODE_TYPES_END
 }
 
@@ -448,8 +550,6 @@
 	arg->ntree = ntree;
 	arg->node = node;
 	arg->sock = sock;
-	arg->type = 0;
-	arg->output = 0;
 
 	uiBlockSetCurLayout(block, layout);
 

Modified: trunk/blender/source/blender/nodes/shader/nodes/node_shader_common.c
===================================================================
--- trunk/blender/source/blender/nodes/shader/nodes/node_shader_common.c	2013-04-18 11:09:25 UTC (rev 56132)
+++ trunk/blender/source/blender/nodes/shader/nodes/node_shader_common.c	2013-04-18 11:36:11 UTC (rev 56133)
@@ -237,6 +237,7 @@
 	BLI_assert(ntype.ext.srna != NULL);
 	RNA_struct_blender_type_set(ntype.ext.srna, &ntype);
 	
+	node_type_compatibility(&ntype, NODE_OLD_SHADING|NODE_NEW_SHADING);
 	node_type_socket_templates(&ntype, NULL, NULL);
 	node_type_size(&ntype, 120, 60, 200);
 	node_type_label(&ntype, node_group_label);




More information about the Bf-blender-cvs mailing list