Fixed do_versions for node groups which contain nodes that have changed sockets....
authorLukas Toenne <lukas.toenne@googlemail.com>
Mon, 21 Feb 2011 18:18:37 +0000 (18:18 +0000)
committerLukas Toenne <lukas.toenne@googlemail.com>
Mon, 21 Feb 2011 18:18:37 +0000 (18:18 +0000)
source/blender/blenkernel/intern/node.c
source/blender/blenloader/intern/readfile.c
source/blender/makesdna/DNA_node_types.h

index cebbab459284c36c7a2352a6d1d3468b06b58be9..7fd0a2d661a39e2bd60366b45954c77d31e2ff48 100644 (file)
@@ -878,14 +878,23 @@ void nodeAddAllGroupSockets(bNodeTree *ngroup)
        bNode *node;
        bNodeSocket *sock, *gsock;
        
+       printf("Verifying group '%s':\n", ngroup->id.name+2);
        for (node=ngroup->nodes.first; node; node=node->next) {
+               printf("\tNode '%s':\n", node->name);
                for (sock=node->inputs.first; sock; sock=sock->next) {
+                       printf("\t\tInput '%s': link=%p, hidden=%d\n", sock->name, sock->link, (sock->flag & SOCK_HIDDEN));
+//                     if (sock->link) {
+//                             if (sock->link->fromnode)
+//                                     printf("fromnode=%s ", sock->link->fromnode->name);
+//                             printf("fromsock=%s")
+//                     }
                        if (!sock->link && !(sock->flag & SOCK_HIDDEN)) {
                                gsock = nodeAddGroupSocketCopy(ngroup, sock, SOCK_IN);
                                sock->link = nodeAddLink(ngroup, NULL, gsock, node, sock);
                        }
                }
                for (sock=node->outputs.first; sock; sock=sock->next) {
+                       printf("\t\tOutput '%s': #links=%d, hidden=%d\n", sock->name, nodeCountSocketLinks(ngroup, sock), (sock->flag & SOCK_HIDDEN));
                        if (nodeCountSocketLinks(ngroup, sock)==0 && !(sock->flag & SOCK_HIDDEN)) {
                                gsock = nodeAddGroupSocketCopy(ngroup, sock, SOCK_OUT);
                                gsock->link = nodeAddLink(ngroup, node, sock, NULL, gsock);
index 3f722cc8cf3293a03a37c49abc692dd4e43cb009..8e9273fafc51a44f0cff36326ffca00a5a8e2dee 100644 (file)
@@ -2028,6 +2028,55 @@ static void lib_link_nodetree(FileData *fd, Main *main)
        }
 }
 
+/* updates group node socket own_index so that
+ * external links to/from the group node are preserved.
+ */
+static void lib_node_do_versions_group(bNode *gnode)
+{
+       bNodeTree *ngroup= (bNodeTree*)gnode->id;
+       bNode *intnode;
+       bNodeSocket *sock, *gsock, *intsock;
+       int found;
+       
+       for (sock=gnode->outputs.first; sock; sock=sock->next) {
+               int old_index = sock->to_index;
+               for (gsock=ngroup->outputs.first; gsock; gsock=gsock->next) {
+                       if (gsock->link && gsock->link->fromsock->own_index == old_index) {
+                               sock->own_index = gsock->own_index;
+                               break;
+                       }
+               }
+       }
+       for (sock=gnode->inputs.first; sock; sock=sock->next) {
+               int old_index = sock->to_index;
+               /* can't use break in double loop */
+               found = 0;
+               for (intnode=ngroup->nodes.first; intnode && !found; intnode=intnode->next) {
+                       for (intsock=intnode->inputs.first; intsock; intsock=intsock->next) {
+                               if (intsock->own_index == old_index && intsock->link) {
+                                       sock->own_index = intsock->link->fromsock->own_index;
+                                       found = 1;
+                                       break;
+                               }
+                       }
+               }
+       }
+}
+
+/* updates external links for all group nodes in a tree */
+static void lib_nodetree_do_versions_group(bNodeTree *ntree)
+{
+       bNode *node;
+       
+       for (node=ntree->nodes.first; node; node=node->next) {
+               if (node->type==NODE_GROUP) {
+                       bNodeTree *ngroup= (bNodeTree*)node->id;
+                       if (ngroup->flag & NTREE_DO_VERSIONS)
+                               lib_node_do_versions_group(node);
+               }
+       }
+}
+
 /* verify types for nodes and groups, all data has to be read */
 /* open = 0: appending/linking, open = 1: open new file (need to clean out dynamic
 * typedefs*/
@@ -2049,6 +2098,37 @@ static void lib_verify_nodetree(Main *main, int UNUSED(open))
                ntreeVerifyTypes(ntree);                /* internal nodes, no groups! */
        }
        
+       {
+               int has_old_groups=0;
+               /* XXX this should actually be part of do_versions, but since we need
+                * finished library linking, it is not possible there. Instead in do_versions
+                * we have set the NTREE_DO_VERSIONS flag, so at this point we can do the
+                * actual group node updates.
+                */
+               for(ntree= main->nodetree.first; ntree; ntree= ntree->id.next) {
+                       if (ntree->flag & NTREE_DO_VERSIONS) {
+                               /* this adds copies and links from all unlinked internal sockets to group inputs/outputs. */
+                               nodeAddAllGroupSockets(ntree);
+                               has_old_groups = 1;
+                       }
+               }
+               /* now verify all types in material trees, groups are set OK now */
+               for(ma= main->mat.first; ma; ma= ma->id.next) {
+                       if(ma->nodetree)
+                               lib_nodetree_do_versions_group(ma->nodetree);
+               }
+               /* and scene trees */
+               for(sce= main->scene.first; sce; sce= sce->id.next) {
+                       if(sce->nodetree)
+                               lib_nodetree_do_versions_group(ma->nodetree);
+               }
+               /* and texture trees */
+               for(tx= main->tex.first; tx; tx= tx->id.next) {
+                       if(tx->nodetree)
+                               lib_nodetree_do_versions_group(ma->nodetree);
+               }
+       }
+
        /* now verify all types in material trees, groups are set OK now */
        for(ma= main->mat.first; ma; ma= ma->id.next) {
                if(ma->nodetree)
@@ -11375,7 +11455,11 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                 * this mimics the old behaviour by adding all unlinked sockets to groups.
                 */
                for (ntree=main->nodetree.first; ntree; ntree=ntree->id.next) {
-                       nodeAddAllGroupSockets(ntree);
+                       /* XXX Only setting a flag here. Actual adding of group sockets
+                        * is done in lib_verify_nodetree, because at this point the internal
+                        * nodes may not be up-to-date! (missing lib-link)
+                        */
+                       ntree->flag |= NTREE_DO_VERSIONS;
                }
        }
 
index 0a4c672273b585716516e23a23bcdd7687a35786..803e5418bcc3cd8804aec9d3b3940c79561159da 100644 (file)
@@ -81,7 +81,7 @@ typedef struct bNodeSocket {
         */
        struct bNodeStack *stack_ptr;   /* constant input value */
        short stack_index;                      /* local stack index or external input number */
-       short pad;
+       short pad1;
        
        float locx, locy;
        
@@ -89,6 +89,8 @@ typedef struct bNodeSocket {
        
        int own_index;                          /* group socket identifiers, to find matching pairs after reading files */
        struct bNodeSocket *groupsock;
+       int to_index;                           /* XXX deprecated, only used for restoring old group node links */
+       int pad2;
        
        struct bNodeLink *link;         /* a link pointer, set in nodeSolveOrder() */
 } bNodeSocket;
@@ -218,8 +220,11 @@ typedef struct bNodeTree {
 #define NTREE_EXEC_INIT        2
 
 /* ntree->flag */
-#define NTREE_DS_EXPAND        1       /* for animation editors */
-#define NTREE_AUTO_EXPOSE      2       /* automatically make unhidden, unlinked group sockets external */
+#define NTREE_DS_EXPAND                1       /* for animation editors */
+/* XXX not nice, but needed as a temporary flag
+ * for group updates after library linking.
+ */
+#define NTREE_DO_VERSIONS      1024
 
 /* data structs, for node->storage */