[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