=bmesh= merge from trunk at r36529
[blender.git] / source / blender / blenkernel / intern / node.c
index 03fdcdd0c917b572f7af6d6257b0c9c02d1f6b57..ae90d3df3e4725bfefafdbcf0daa2683e3c70038 100644 (file)
@@ -56,7 +56,6 @@
 #include "BKE_fcurve.h"
 #include "BKE_node.h"
 #include "BKE_utildefines.h"
-#include "BKE_node.h"
 
 #include "PIL_time.h"
 
@@ -968,6 +967,11 @@ bNode *nodeAddNodeType(bNodeTree *ntree, int type, bNodeTree *ngroup, ID *id)
        } else
                ntype= node_get_type(ntree, type, id);
 
+       if(ntype == NULL) {
+               printf("nodeAddNodeType() error: '%d' type invalid\n", type);
+               return NULL;
+       }
+
        node= MEM_callocN(sizeof(bNode), "new node");
        BLI_addtail(&ntree->nodes, node);
        node->typeinfo= ntype;
@@ -1189,7 +1193,9 @@ bNodeTree *ntreeCopyTree(bNodeTree *ntree)
                newtree= MEM_dupallocN(ntree);
                copy_libblock_data(&newtree->id, &ntree->id, TRUE); /* copy animdata and ID props */
        }
-       
+
+       id_us_plus((ID *)newtree->gpd);
+
        /* in case a running nodetree is copied */
        newtree->init &= ~(NTREE_EXEC_INIT);
        newtree->threadstack= NULL;
@@ -1431,6 +1437,8 @@ void ntreeFreeTree(bNodeTree *ntree)
        
        BKE_free_animdata((ID *)ntree);
 
+       id_us_min((ID *)ntree->gpd);
+
        BLI_freelistN(&ntree->links);   /* do first, then unlink_node goes fast */
        
        for(node= ntree->nodes.first; node; node= next) {
@@ -1998,11 +2006,23 @@ static void node_group_execute(bNodeStack *stack, void *data, bNode *gnode, bNod
        if (ntree->type==NTREE_COMPOSIT) {
                bNodeSocket *sock;
                bNodeStack *ns;
+               
+               /* clear hasoutput on all local stack data,
+                * only the group output will be used from now on
+                */
+               for (node=ntree->nodes.first; node; node=node->next) {
+                       for (sock=node->outputs.first; sock; sock=sock->next) {
+                               if (sock->stack_type==SOCK_STACK_LOCAL) {
+                                       ns= get_socket_stack(stack, sock, in);
+                                       ns->hasoutput = 0;
+                               }
+                       }
+               }
+               /* use the hasoutput flag to tag external sockets */
                for (sock=ntree->outputs.first; sock; sock=sock->next) {
-                       /* use the hasoutput flag to tag external sockets */
                        if (sock->stack_type==SOCK_STACK_LOCAL) {
                                ns= get_socket_stack(stack, sock, in);
-                               ns->hasoutput = 0;
+                               ns->hasoutput = 1;
                        }
                }
                /* now free all stacks that are not used from outside */
@@ -2010,11 +2030,9 @@ static void node_group_execute(bNodeStack *stack, void *data, bNode *gnode, bNod
                        for (sock=node->outputs.first; sock; sock=sock->next) {
                                if (sock->stack_type==SOCK_STACK_LOCAL ) {
                                        ns= get_socket_stack(stack, sock, in);
-                                       if (ns->hasoutput!=0 && ns->data) {
+                                       if (ns->hasoutput==0 && ns->data) {
                                                free_compbuf(ns->data);
                                                ns->data = NULL;
-                                               /* reset the flag */
-                                               ns->hasoutput = 1;
                                        }
                                }
                        }
@@ -2230,9 +2248,37 @@ static void group_tag_used_outputs(bNode *gnode, bNodeStack *stack, bNodeStack *
                        }
                }
                
+               /* non-composite trees do all nodes by default */
+               if (ntree->type!=NTREE_COMPOSIT)
+                       node->need_exec = 1;
+               
+               for(sock= node->inputs.first; sock; sock= sock->next) {
+                       bNodeStack *ns = get_socket_stack(stack, sock, gin);
+                       if (ns) {
+                               ns->hasoutput = 1;
+                               
+                               /* sock type is needed to detect rgba or value or vector types */
+                               if(sock->link && sock->link->fromsock)
+                                       ns->sockettype= sock->link->fromsock->type;
+                               else
+                                       sock->ns.sockettype= sock->type;
+                       }
+                       
+                       if(sock->link) {
+                               bNodeLink *link= sock->link;
+                               /* this is the test for a cyclic case */
+                               if(link->fromnode && link->tonode) {
+                                       if(link->fromnode->level >= link->tonode->level && link->tonode->level!=0xFFF);
+                                       else {
+                                               node->need_exec= 0;
+                                       }
+                               }
+                       }
+               }
+               
                /* set stack types (for local stack entries) */
                for(sock= node->outputs.first; sock; sock= sock->next) {
-                       bNodeStack *ns = get_socket_stack(stack, sock, NULL);
+                       bNodeStack *ns = get_socket_stack(stack, sock, gin);
                        if (ns)
                                ns->sockettype = sock->type;
                }
@@ -2282,13 +2328,18 @@ static void tex_end_exec(bNodeTree *ntree)
        bNodeStack *ns;
        int th, a;
        
-       if(ntree->threadstack)
-               for(th=0; th<BLENDER_MAX_THREADS; th++)
-                       for(nts=ntree->threadstack[th].first; nts; nts=nts->next)
-                               for(ns= nts->stack, a=0; a<ntree->stacksize; a++, ns++)
-                                       if(ns->data)
+       if(ntree->threadstack) {
+               for(th=0; th<BLENDER_MAX_THREADS; th++) {
+                       for(nts=ntree->threadstack[th].first; nts; nts=nts->next) {
+                               for(ns= nts->stack, a=0; a<ntree->stacksize; a++, ns++) {
+                                       if(ns->data) {
                                                MEM_freeN(ns->data);
-                                               
+                                               ns->data= NULL;
+                                       }
+                               }
+                       }
+               }
+       }
 }
 
 void ntreeBeginExecTree(bNodeTree *ntree)
@@ -2321,7 +2372,7 @@ void ntreeBeginExecTree(bNodeTree *ntree)
                for(node= ntree->nodes.first; node; node= node->next) {
                        bNodeSocket *sock;
                        
-                       /* composite has own need_exec tag handling */
+                       /* non-composite trees do all nodes by default */
                        if(ntree->type!=NTREE_COMPOSIT)
                                node->need_exec= 1;