[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [31478] branches/particles-2010/source/ blender: Fixed and cleaned up the update procedure for group nodes.

Lukas Toenne lukas.toenne at googlemail.com
Fri Aug 20 12:35:53 CEST 2010


Revision: 31478
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=31478
Author:   lukastoenne
Date:     2010-08-20 12:35:48 +0200 (Fri, 20 Aug 2010)

Log Message:
-----------
Fixed and cleaned up the update procedure for group nodes. The update functions are responsible not only for sorting the nodes (as in current trees), but also for resolving adaptable socket types and contexts in simulation trees. They should now also generally work for nested node groups, so implementing these is merely a matter of solving some UI design questions.

Modified Paths:
--------------
    branches/particles-2010/source/blender/blenkernel/BKE_node.h
    branches/particles-2010/source/blender/blenkernel/intern/node.c
    branches/particles-2010/source/blender/editors/space_node/node_edit.c
    branches/particles-2010/source/blender/editors/space_node/node_header.c
    branches/particles-2010/source/blender/makesdna/DNA_node_types.h
    branches/particles-2010/source/blender/nodes/intern/node_tree_simulation.c

Modified: branches/particles-2010/source/blender/blenkernel/BKE_node.h
===================================================================
--- branches/particles-2010/source/blender/blenkernel/BKE_node.h	2010-08-20 10:17:39 UTC (rev 31477)
+++ branches/particles-2010/source/blender/blenkernel/BKE_node.h	2010-08-20 10:35:48 UTC (rev 31478)
@@ -185,11 +185,10 @@
 
 void			ntreeSocketUseFlags(struct bNodeTree *ntree);
 
-void			ntreeUpdate(struct bNodeTree *ntree);
-//void			ntreeSolveOrder(struct bNodeTree *ntree);
-//void			ntreeUpdateListSockets(struct bNodeTree *ntree);
-//void			ntreeUpdateSocketTypes(struct bNodeTree *ntree);
-//void			ntreeUpdateLinks(struct bNodeTree *ntree);
+void			ntreeUpdateTree(struct bNodeTree *ntree);
+void			ntreeUpdateGroupTree(struct bNodeTree *ntree, struct bNodeTree *group);
+void			ntreeUpdateFullTree(struct bNodeTree *ntree);
+void			ntreeUpdateListSockets(struct bNodeTree *ntree);
 
 void			ntreeBeginExecTree(struct bNodeTree *ntree);
 void			ntreeExecTree(struct bNodeTree *ntree, void *callerdata, int thread);

Modified: branches/particles-2010/source/blender/blenkernel/intern/node.c
===================================================================
--- branches/particles-2010/source/blender/blenkernel/intern/node.c	2010-08-20 10:17:39 UTC (rev 31477)
+++ branches/particles-2010/source/blender/blenkernel/intern/node.c	2010-08-20 10:35:48 UTC (rev 31478)
@@ -656,7 +656,7 @@
 		}
 	}
 
-	ntreeUpdate(ntree);
+	ntreeUpdateTree(ntree);
 
 	return gnode;
 }
@@ -837,9 +837,9 @@
 	
 	nodeFreeNode(ntree, gnode);
 	
-	/* solve order goes fine, but the level tags not... doing it twice works for now. solve this once */
-	ntreeUpdate(ntree);
-	ntreeUpdate(ntree);
+	/* TODO solve order goes fine, but the level tags not... doing it twice works for now. solve this once */
+	ntreeUpdateTree(ntree);
+	ntreeUpdateTree(ntree);
 	
 	return 1;
 }
@@ -1130,9 +1130,9 @@
 				newtree->owntype->outputs= MEM_dupallocN(ntree->owntype->outputs);
 		}
 	}
-	/* weird this is required... there seem to be link pointers wrong still? */
+	/* TODO weird this is required... there seem to be link pointers wrong still? */
 	/* anyhoo, doing this solves crashes on copying entire tree (copy scene) and delete nodes */
-	ntreeUpdate(ntree);
+	ntreeUpdateTree(ntree);
 
 	return newtree;
 }
@@ -1333,6 +1333,10 @@
 			MEM_freeN(ntree->owntype->outputs);
 		MEM_freeN(ntree->owntype);
 	}
+	
+	if (ntree->islands) {
+		MEM_freeN(ntree->islands);
+	}
 }
 
 void ntreeFreeCache(bNodeTree *ntree)
@@ -1593,18 +1597,33 @@
 
 /* ************** dependency stuff *********** */
 
-static void clear_update_flags_recursive(bNodeTree *ntree)
+/* sets the update flags for all trees containing another updated tree */
+static int set_update_flag_recursive(bNodeTree *ntree)
 {
 	bNode *node;
+	int update;
 	
-	ntree->flag &= ~NTREE_NODES_SORTED;
-	ntree->flag &= ~NTREE_LINKS_SORTED;
-	ntree->flag &= ~NTREE_TYPES_RESOLVED;
-	ntree->flag &= ~NTREE_LINKS_VALIDATED;
+	for (node=ntree->nodes.first; node; node = node->next)
+		if (node->type == NODE_GROUP && node->id)
+			update = set_update_flag_recursive((bNodeTree*)node->id);
 	
+	if (update) {
+		ntree->flag |= NTREE_UPDATE;
+	}
+	
+	return ((ntree->flag & NTREE_UPDATE) != 0);
+}
+
+/* sets the update flags for all trees in the hierarchy */
+static void set_all_update_flags_recursive(bNodeTree *ntree)
+{
+	bNode *node;
+	
 	for (node=ntree->nodes.first; node; node = node->next)
 		if (node->type == NODE_GROUP && node->id)
-			clear_update_flags_recursive((bNodeTree*)node->id);
+			set_all_update_flags_recursive((bNodeTree*)node->id);
+	
+	ntree->flag |= NTREE_UPDATE;
 }
 
 /* node is guaranteed to be not checked before */
@@ -1633,19 +1652,13 @@
 	return level;
 }
 
-static void solve_order_recursive(bNodeTree *ntree)
+static void solve_node_order(bNodeTree *ntree)
 {
 	bNode *node, **nodesort, **nsort;
 	bNodeSocket *sock;
 	bNodeLink *link;
 	int a, totnode=0;
 	
-	/* 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 */
 	for(node= ntree->nodes.first; node; node= node->next) {
@@ -1712,14 +1725,9 @@
 				node->flag |= NODE_DO_OUTPUT;
 		}
 	}
-	
-	/* 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)
+void ntreeUpdateListSockets(bNodeTree *ntree)
 {
 	bNode *node;
 	bNodeSocketType *stype;
@@ -1851,26 +1859,19 @@
 	return (link->fromsock->stype->type == SOCK_ANY || link->tosock->stype->type == SOCK_ANY);
 }
 
-static void resolve_socket_types_recursive(bNodeTree *ntree)
+static void calc_type_islands_recursive(bNodeTree *ntree)
 {
-	bNodeTreeTypeInfo *tti;
 	bNode *node;
 	bNodeSocket *sock;
 	bNodeLink *link;
 	int totsock;
-	bNodeSocketIsland *islands, *island, *cur;
-	int restype, resolved, number, i;
+	bNodeSocketIsland *cur;
 	
-	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);
-	}
-
+	/* calculate nested groups */
+	for (node=ntree->nodes.first; node; node = node->next)
+		if (node->type == NODE_GROUP && node->id && ((bNodeTree*)node->id)->islands == NULL)
+			calc_type_islands_recursive((bNodeTree*)node->id);
+			
 	/* initialise island indices */
 	totsock = 0;
 	for (node=ntree->nodes.first; node; node = node->next) {
@@ -1881,7 +1882,7 @@
 	}
 	
 	/* create the island pointer array */
-	cur = islands = MEM_callocN(totsock * sizeof(bNodeSocketIsland), "bNodeSocketIsland");
+	cur = ntree->islands = MEM_callocN((totsock+1) * sizeof(bNodeSocketIsland), "bNodeSocketIsland");
 	for (node=ntree->nodes.first; node; node = node->next) {
 		for (sock=node->inputs.first; sock; sock = sock->next) {
 			cur->sock = sock;
@@ -1896,134 +1897,145 @@
 			++cur;
 		}
 	}
+	/* marks the end of the island list */
+	cur->sock = NULL;
+	cur->node = NULL;
+	cur->next = cur->prev = NULL;
 	
 	/* merge islands inside nodes */
 	for (node=ntree->nodes.first; node; node = node->next) {
-		merge_node_type_islands(node, islands);
+		merge_node_type_islands(node, ntree->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(islands, link->fromsock->island, link->tosock->island);
+				merge_socket_islands(ntree->islands, link->fromsock->island, link->tosock->island);
 	}
+}
 
-	/* now resolve all islands to the best available socket type */
-	number = -1;
-	island = islands;
-	for (i = 0; i < totsock; ++i, ++island) {
-		if (island->sock->island > number) {
-			number = island->sock->island;
-			resolved = 0;
-			restype = SOCK_ANY;
-			for (cur = island; cur; cur = cur->next) {
-				if (!resolved) {
-					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 (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
-									restype = SOCK_ANY;
-							}
-							else
-								restype = SOCK_ANY;
-						}
-						else {
-							if (tti->compatibleSocketTypes(restype, cur->sock->type))
-								restype = tti->preferredSocketType(restype, cur->sock->type);
-							else
-								restype = SOCK_ANY;
-						}
-					}
-				}
-			}
-			
-			for (cur = island; cur; cur = cur->next)
-				if (cur->sock->stype->type == SOCK_ANY)
-					cur->sock->type = restype;
-		}
-	}
+static void free_islands_recursive(bNodeTree *ntree)
+{
+	bNode *node;
 	
-	MEM_freeN(islands);
+	/* free islands in groups */
+	for (node=ntree->nodes.first; node; node = node->next)
+		if (node->type == NODE_GROUP && node->id)
+			free_islands_recursive((bNodeTree*)node->id);
 	
-	ntree->flag |= NTREE_TYPES_RESOLVED;
+	if (ntree->islands != NULL) {
+		MEM_freeN(ntree->islands);
+		ntree->islands = NULL;
+	}
 }
 
-/* returns 0 if link a can influence b, 1 otherwise */
-static int compare_link_by_level(void *a, void *b)
+static void find_island_socket_type_recursive(bNodeTree *ntree, int island, int *restype, int *resolved)
 {
-	bNode *ato = ((bNodeLink*)a)->tonode;
-	bNode *afrom = ((bNodeLink*)a)->fromnode;
-	bNode *bto = ((bNodeLink*)b)->tonode;
-	bNode *bfrom = ((bNodeLink*)b)->fromnode;
+	bNodeTreeTypeInfo *tti;
+	bNodeSocketIsland *cur;
 	
-	if (ato && afrom && bto && bfrom) {
-		/* this ensures that links, whose from/to-nodes can influence each other are sorted */
-		if (ato->level >= bfrom->level) {
-			return 0;
+	tti = ntreeGetTypeInfo(ntree->type);
+	if (!tti->preferredSocketType || !tti->compatibleSocketTypes)
+		return;
+	
+	for (cur = ntree->islands + island; cur; cur = cur->next) {
+		if (cur->node->type == NODE_GROUP) {
+			if (cur->node->id && cur->sock->tosock)
+				find_island_socket_type_recursive((bNodeTree*)cur->node->id, cur->sock->tosock->island, restype, resolved);
 		}
 		else {
-			return 1;
+			if (!(*resolved)) {
+				*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;
+				}
+			}
 		}

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list