[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [31452] branches/particles-2010/source/ blender: Reworked most of the ntreeUpdate function to fix group nodes.

Lukas Toenne lukas.toenne at googlemail.com
Thu Aug 19 10:17:46 CEST 2010


Revision: 31452
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=31452
Author:   lukastoenne
Date:     2010-08-19 10:17:45 +0200 (Thu, 19 Aug 2010)

Log Message:
-----------
Reworked most of the ntreeUpdate function to fix group nodes. These updates should all work for nested groups as well, so this should be future proof. List sockets won't work for groups yet, but these need a better mechanism in general, which should be part of removing the fixed socket type binding to allow more flexible node definitions.

Modified Paths:
--------------
    branches/particles-2010/source/blender/blenkernel/intern/node.c
    branches/particles-2010/source/blender/editors/space_node/node_draw.c
    branches/particles-2010/source/blender/editors/space_node/node_edit.c
    branches/particles-2010/source/blender/makesdna/DNA_node_types.h
    branches/particles-2010/source/blender/nodes/intern/SIM_nodes/SIM_set_vertex_data.c

Modified: branches/particles-2010/source/blender/blenkernel/intern/node.c
===================================================================
--- branches/particles-2010/source/blender/blenkernel/intern/node.c	2010-08-19 05:58:22 UTC (rev 31451)
+++ branches/particles-2010/source/blender/blenkernel/intern/node.c	2010-08-19 08:17:45 UTC (rev 31452)
@@ -271,6 +271,9 @@
 		else
 			sock= sock->next;
 	}
+	
+	if (r_verified->first == NULL)
+		node_add_socket_type(r_verified, stype);
 }
 
 static void verify_socket_list(bNodeTree *ntree, ListBase *lb, bNodeSocketType *stype_first)
@@ -310,6 +313,17 @@
 		
 		verify_socket_list(ntree, &node->inputs, ntype->inputs);
 		verify_socket_list(ntree, &node->outputs, ntype->outputs);
+		
+		{
+			bNodeSocket *sock;
+			printf("Verified sockets of %s:\n", node->name);
+			for (sock=node->inputs.first; sock; sock = sock->next) {
+				printf("Input %s\n", sock->name);
+			}
+			for (sock=node->outputs.first; sock; sock = sock->next) {
+				printf("Output %s\n", sock->name);
+			}
+		}
 	}
 }
 
@@ -1579,36 +1593,19 @@
 
 /* ************** dependency stuff *********** */
 
-#if 0
-/* node is guaranteed to be not checked before */
-static int node_recurs_check(bNode *node, bNode ***nsort, int level)
+static void clear_update_flags_recursive(bNodeTree *ntree)
 {
-	bNode *fromnode;
-	bNodeSocket *sock;
-	int has_inputlinks= 0;
+	bNode *node;
 	
-	node->done= 1;
-	level++;
+	ntree->flag &= ~NTREE_NODES_SORTED;
+	ntree->flag &= ~NTREE_LINKS_SORTED;
+	ntree->flag &= ~NTREE_TYPES_RESOLVED;
+	ntree->flag &= ~NTREE_LINKS_VALIDATED;
 	
-	for(sock= node->inputs.first; sock; sock= sock->next) {
-		if(sock->link) {
-			has_inputlinks= 1;
-			fromnode= sock->link->fromnode;
-			if(fromnode && fromnode->done==0) {
-				fromnode->level= node_recurs_check(fromnode, nsort, level);
-			}
-		}
-	}
-	printf("node sort %s level %d\n", node->name, level);
-	**nsort= node;
-	(*nsort)++;
-	
-	if(has_inputlinks)
-		return level;
-	else 
-		return 0xFFF;
+	for (node=ntree->nodes.first; node; node = node->next)
+		if (node->type == NODE_GROUP && node->id)
+			clear_update_flags_recursive((bNodeTree*)node->id);
 }
-#endif
 
 /* node is guaranteed to be not checked before */
 static int node_recurs_check(bNode *node, bNode ***nsort)
@@ -1636,15 +1633,18 @@
 	return level;
 }
 
-static void ntreeSolveOrder(bNodeTree *ntree)
+static void solve_order_recursive(bNodeTree *ntree)
 {
 	bNode *node, **nodesort, **nsort;
 	bNodeSocket *sock;
 	bNodeLink *link;
 	int a, totnode=0;
 	
-	/* the solve-order is called on each tree change, so we should be sure no exec can be running */
-	ntreeEndExecTree(ntree);
+	/* sort nodes in nested groups recursively */
+	for (node=ntree->nodes.first; node; node = node->next) {
+		if (node->type == NODE_GROUP && node->id && (((bNodeTree*)node->id)->flag & NTREE_NODES_SORTED)==0)
+			solve_order_recursive((bNodeTree*)node->id);
+	}
 
 	/* set links pointers the input sockets, to find dependencies */
 	/* first clear data */
@@ -1667,7 +1667,6 @@
 	/* recursive check */
 	for(node= ntree->nodes.first; node; node= node->next) {
 		if(node->done==0) {
-//			node->level= node_recurs_check(node, &nsort, 0);
 			node->level= node_recurs_check(node, &nsort);
 		}
 	}
@@ -1716,6 +1715,8 @@
 	
 	/* here we could recursively set which nodes have to be done,
 		might be different for editor or for "real" use... */
+	
+	ntree->flag |= NTREE_NODES_SORTED;
 }
 
 static void ntreeUpdateListSockets(bNodeTree *ntree)
@@ -1754,6 +1755,12 @@
 	}
 }
 
+typedef struct bNodeSocketIsland {
+	struct bNodeSocketIsland *next, *prev;
+	struct bNodeSocket *sock;
+	struct bNode *node;
+} bNodeSocketIsland;
+
 static void merge_socket_islands(bNodeSocketIsland *islands, int a, int b)
 {
 	bNodeSocketIsland *i;
@@ -1780,23 +1787,62 @@
 	}
 }
 
-static void node_merge_type_islands(bNode *node, bNodeSocketIsland *islands)
+static void merge_node_type_islands(bNode *node, bNodeSocketIsland *islands)
 {
-	bNodeSocket *sock;
-	int any_island = -1;
-	for (sock=node->inputs.first; sock; sock = sock->next) {
-		if (sock->stype->type == SOCK_ANY) {
-			if (any_island >= 0)
-				merge_socket_islands(islands, any_island, sock->island);
-			any_island = sock->island;
+	bNodeSocket *sock, *msock;
+	if (node->type == NODE_GROUP) {
+		if (node->id) {
+			/* TODO this way of merging islands by internal groups is O(n^2),
+			 * where n is the total number of sockets of the group node (inputs+outputs).
+			 * Should not be a problem as this number will probably not be very large,
+			 * otherwise a more elaborate method must be found (using sorting).
+			 */
+			int cur_island = -1;
+			int internal_island;
+			for (sock=node->inputs.first; sock; sock = sock->next) {
+				if (sock->tosock && sock->island > cur_island) {
+					cur_island = sock->island;
+					internal_island = sock->tosock->island;
+					/* merge this socket with all remaining sockets whose internal island matches */
+					for (msock=sock->next; msock; msock = msock->next)
+						if (msock->tosock && msock->tosock->island == internal_island)
+							merge_socket_islands(islands, cur_island, msock->island);
+					for (msock=node->outputs.first; msock; msock = msock->next)
+						if (msock->tosock && msock->tosock->island == internal_island)
+							merge_socket_islands(islands, cur_island, msock->island);
+				}
+			}
+			for (sock=node->outputs.first; sock; sock = sock->next) {
+				if (sock->tosock && sock->island > cur_island) {
+					cur_island = sock->island;
+					internal_island = sock->tosock->island;
+					/* merge this socket with all remaining sockets whose internal island matches */
+					for (msock=sock->next; msock; msock = msock->next)
+						if (msock->tosock && msock->tosock->island == internal_island)
+							merge_socket_islands(islands, cur_island, msock->island);
+				}
+			}
 		}
 	}
-	for (sock=node->outputs.first; sock; sock = sock->next) {
-		if (sock->stype->type == SOCK_ANY) {
-			if (any_island >= 0)
-				merge_socket_islands(islands, any_island, sock->island);
-			any_island = sock->island;
+	else {
+		/* TODO This procedure merges all sockets of ANY type to the same island.
+		 * Is there any situation where this model is insufficient?
+		 */
+		int any_island = -1;
+		for (sock=node->inputs.first; sock; sock = sock->next) {
+			if (sock->stype->type == SOCK_ANY) {
+				if (any_island >= 0)
+					merge_socket_islands(islands, any_island, sock->island);
+				any_island = sock->island;
+			}
 		}
+		for (sock=node->outputs.first; sock; sock = sock->next) {
+			if (sock->stype->type == SOCK_ANY) {
+				if (any_island >= 0)
+					merge_socket_islands(islands, any_island, sock->island);
+				any_island = sock->island;
+			}
+		}
 	}
 }
 
@@ -1805,13 +1851,26 @@
 	return (link->fromsock->stype->type == SOCK_ANY || link->tosock->stype->type == SOCK_ANY);
 }
 
-static void ntreeInitSocketIslands(bNodeTree *ntree, bNodeSocketIsland **r_islands, int *r_totsock)
+static void resolve_socket_types_recursive(bNodeTree *ntree)
 {
+	bNodeTreeTypeInfo *tti;
 	bNode *node;
 	bNodeSocket *sock;
-	bNodeSocketIsland *islands, *cur;
+	bNodeLink *link;
 	int totsock;
+	bNodeSocketIsland *islands, *island, *cur;
+	int restype, resolved, number, i;
 	
+	tti = ntreeGetTypeInfo(ntree->type);
+	if (!tti->preferredSocketType || !tti->compatibleSocketTypes)
+		return;
+	
+	/* first create islands inside groups, we need them to merge sockets of the group node container */
+	for (node=ntree->nodes.first; node; node = node->next) {
+		if (node->type == NODE_GROUP && node->id && (((bNodeTree*)node->id)->flag & NTREE_TYPES_RESOLVED)==0)
+			resolve_socket_types_recursive((bNodeTree*)node->id);
+	}
+
 	/* initialise island indices */
 	totsock = 0;
 	for (node=ntree->nodes.first; node; node = node->next) {
@@ -1826,50 +1885,32 @@
 	for (node=ntree->nodes.first; node; node = node->next) {
 		for (sock=node->inputs.first; sock; sock = sock->next) {
 			cur->sock = sock;
+			cur->node = node;
 			cur->next = cur->prev = NULL;
 			++cur;
 		}
 		for (sock=node->outputs.first; sock; sock = sock->next) {
 			cur->sock = sock;
+			cur->node = node;
 			cur->next = cur->prev = NULL;
 			++cur;
 		}
 	}
 	
-	*r_islands = islands;
-	*r_totsock = totsock;
-}
-
-static void ntreeUpdateSocketTypes(bNodeTree *ntree)
-{
-	bNodeTreeTypeInfo *tti;
-	bNode *node;
-	bNodeLink *link;
-	bNodeSocketIsland *island_map, *island;
-	int totsock;
-	int i, number;
-	bNodeSocketIsland *cur;
-	int restype, resolved;
-	
-	tti = ntreeGetTypeInfo(ntree->type);
-	if (!tti->preferredSocketType || !tti->compatibleSocketTypes)
-		return;
-	
-	ntreeInitSocketIslands(ntree, &island_map, &totsock);
-	
 	/* merge islands inside nodes */
 	for (node=ntree->nodes.first; node; node = node->next) {
-		node_merge_type_islands(node, island_map);
+		merge_node_type_islands(node, islands);
 	}
 	/* merge islands by links */
 	for (link=ntree->links.first; link; link = link->next) {
 		if (link->fromsock && link->tosock)
 			if (link_merge_type(link))
-				merge_socket_islands(island_map, link->fromsock->island, link->tosock->island);
+				merge_socket_islands(islands, link->fromsock->island, link->tosock->island);
 	}
 
+	/* now resolve all islands to the best available socket type */
 	number = -1;
-	island = island_map;
+	island = islands;
 	for (i = 0; i < totsock; ++i, ++island) {
 		if (island->sock->island > number) {
 			number = island->sock->island;
@@ -1877,16 +1918,36 @@
 			restype = SOCK_ANY;
 			for (cur = island; cur; cur = cur->next) {
 				if (!resolved) {
-					restype = cur->sock->type;
-					resolved = (cur->sock->stype->type != SOCK_ANY);
+					if (cur->node->type == NODE_GROUP) {
+						if (cur->sock->tosock) {
+							restype = cur->sock->tosock->type;
+							resolved = (cur->sock->tosock->stype->type != SOCK_ANY);
+						}
+					}
+					else {
+						restype = cur->sock->type;
+						resolved = (cur->sock->stype->type != SOCK_ANY);
+					}
 				}
 				else {
 					/* restype == SOCK_ANY means the island contains incompatible types and cannot be resolved! */
 					if (restype != SOCK_ANY && cur->sock->stype->type != SOCK_ANY) {
-						if (tti->compatibleSocketTypes(restype, cur->sock->type))
-							restype = tti->preferredSocketType(restype, cur->sock->type);
-						else
-							restype = SOCK_ANY;
+						if (cur->node->type == NODE_GROUP) {
+							if (cur->sock->tosock) {
+								if (tti->compatibleSocketTypes(restype, cur->sock->tosock->type))
+									restype = tti->preferredSocketType(restype, cur->sock->tosock->type);
+								else

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list