svn merge https://svn.blender.org/svnroot/bf-blender/trunk/blender -r20855:20928
[blender.git] / source / blender / blenkernel / intern / node.c
index d41dda4c81ea06c04755e5d59e1df2813d6efb89..0f42ba0d2e281ccfc3ce1f2cf801740e52c05b46 100644 (file)
@@ -1012,8 +1012,7 @@ bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node, int internal)
                oldsock->new_sock= sock;
        }
        
-       if(nnode->id)
-               nnode->id->us++;
+       /* don't increase node->id users, freenode doesn't decrement either */
        
        if(node->typeinfo->copystoragefunc)
                node->typeinfo->copystoragefunc(node, nnode);
@@ -1056,6 +1055,14 @@ bNodeTree *ntreeAddTree(int type)
        ntree->type= type;
        ntree->alltypes.first = NULL;
        ntree->alltypes.last = NULL;
+
+       /* this helps RNA identify ID pointers as nodetree */
+    if(ntree->type==NTREE_SHADER)
+               BLI_strncpy(ntree->id.name, "NTShader Nodetree", sizeof(ntree->id.name));
+    else if(ntree->type==NTREE_COMPOSIT)
+               BLI_strncpy(ntree->id.name, "NTComposit Nodetree", sizeof(ntree->id.name));
+    else if(ntree->type==NTREE_TEXTURE)
+               BLI_strncpy(ntree->id.name, "NTTexture Nodetree", sizeof(ntree->id.name));
        
        ntreeInitTypes(ntree);
        return ntree;
@@ -1124,7 +1131,8 @@ bNodeTree *ntreeCopyTree(bNodeTree *ntree, int internal_select)
        
        /* check for copying links */
        for(link= ntree->links.first; link; link= link->next) {
-               if(link->fromnode->new_node && link->tonode->new_node) {
+               if(link->fromnode==NULL || link->tonode==NULL);
+               else if(link->fromnode->new_node && link->tonode->new_node) {
                        nlink= nodeAddLink(newtree, link->fromnode->new_node, NULL, link->tonode->new_node, NULL);
                        /* sockets were copied in order */
                        for(a=0, sock= link->fromnode->outputs.first; sock; sock= sock->next, a++) {
@@ -1739,7 +1747,8 @@ void ntreeSolveOrder(bNodeTree *ntree)
                might be different for editor or for "real" use... */
 }
 
-/* should be callback! */
+/* Should be callback! */
+/* Do not call execs here */
 void NodeTagChanged(bNodeTree *ntree, bNode *node)
 {
        if(ntree->type==NTREE_COMPOSIT) {
@@ -1753,8 +1762,6 @@ void NodeTagChanged(bNodeTree *ntree, bNode *node)
                }
                node->need_exec= 1;
        }
-       else if(ntree->type == NTREE_TEXTURE)
-               ntreeTexUpdatePreviews(ntree);
 }
 
 void NodeTagIDChanged(bNodeTree *ntree, ID *id)
@@ -1983,9 +1990,9 @@ static void group_tag_used_outputs(bNode *gnode, bNodeStack *stack)
        }
 }
 
+/* notes below are ancient! (ton) */
 /* stack indices make sure all nodes only write in allocated data, for making it thread safe */
 /* only root tree gets the stack, to enable instances to have own stack entries */
-/* only two threads now! */
 /* per tree (and per group) unique indices are created */
 /* the index_ext we need to be able to map from groups to the group-node own stack */
 
@@ -1999,14 +2006,13 @@ static bNodeThreadStack *ntreeGetThreadStack(bNodeTree *ntree, int thread)
 {
        ListBase *lb= &ntree->threadstack[thread];
        bNodeThreadStack *nts;
-
+       
        for(nts=lb->first; nts; nts=nts->next) {
                if(!nts->used) {
                        nts->used= 1;
                        return nts;
                }
        }
-       
        nts= MEM_callocN(sizeof(bNodeThreadStack), "bNodeThreadStack");
        nts->stack= MEM_dupallocN(ntree->stack);
        nts->used= 1;
@@ -2063,6 +2069,11 @@ void ntreeBeginExecTree(bNodeTree *ntree)
                /* tag used outputs, so we know when we can skip operations */
                for(node= ntree->nodes.first; node; node= node->next) {
                        bNodeSocket *sock;
+                       
+                       /* composite has own need_exec tag handling */
+                       if(ntree->type!=NTREE_COMPOSIT)
+                               node->need_exec= 1;
+
                        for(sock= node->inputs.first; sock; sock= sock->next) {
                                if(sock->link) {
                                        ns= ntree->stack + sock->link->fromsock->stack_index;
@@ -2071,9 +2082,22 @@ void ntreeBeginExecTree(bNodeTree *ntree)
                                }
                                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;
+                                               }
+                                       }
+                               }
                        }
+                       
                        if(node->type==NODE_GROUP && node->id)
                                group_tag_used_outputs(node, ntree->stack);
+                       
                }
                
                if(ntree->type==NTREE_COMPOSIT)
@@ -2156,13 +2180,15 @@ void ntreeExecTree(bNodeTree *ntree, void *callerdata, int thread)
        }
        
        for(node= ntree->nodes.first; node; node= node->next) {
-               if(node->typeinfo->execfunc) {
-                       node_get_stack(node, stack, nsin, nsout);
-                       node->typeinfo->execfunc(callerdata, node, nsin, nsout);
-               }
-               else if(node->type==NODE_GROUP && node->id) {
-                       node_get_stack(node, stack, nsin, nsout);
-                       node_group_execute(stack, callerdata, node, nsin, nsout); 
+               if(node->need_exec) {
+                       if(node->typeinfo->execfunc) {
+                               node_get_stack(node, stack, nsin, nsout);
+                               node->typeinfo->execfunc(callerdata, node, nsin, nsout);
+                       }
+                       else if(node->type==NODE_GROUP && node->id) {
+                               node_get_stack(node, stack, nsin, nsout);
+                               node_group_execute(stack, callerdata, node, nsin, nsout); 
+                       }
                }
        }
 
@@ -2269,8 +2295,10 @@ static int setExecutableNodes(bNodeTree *ntree, ThreadData *thd)
                        /* is sock in use? */
                        else if(sock->link) {
                                bNodeLink *link= sock->link;
+                               
                                /* this is the test for a cyclic case */
-                               if(link->fromnode->level >= link->tonode->level && link->tonode->level!=0xFFF) {
+                               if(link->fromnode==NULL || link->tonode==NULL);
+                               else if(link->fromnode->level >= link->tonode->level && link->tonode->level!=0xFFF) {
                                        if(link->fromnode->need_exec) {
                                                node->need_exec= 1;
                                                break;
@@ -2488,8 +2516,11 @@ bNodeTree *ntreeLocalize(bNodeTree *ntree)
                node->need_exec= 0;
                
                if(ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) {
-                       if(node->id && (node->flag & NODE_DO_OUTPUT)) {
-                               node->new_node->id= (ID *)BKE_image_copy((Image *)node->id);
+                       if(node->id) {
+                               if(node->flag & NODE_DO_OUTPUT)
+                                       node->new_node->id= (ID *)BKE_image_copy((Image *)node->id);
+                               else
+                                       node->new_node->id= NULL;
                        }
                }
                
@@ -2563,6 +2594,7 @@ void ntreeLocalMerge(bNodeTree *localtree, bNodeTree *ntree)
                        
                        if(ELEM(lnode->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) {
                                if(lnode->id && (lnode->flag & NODE_DO_OUTPUT)) {
+                                       /* image_merge does sanity check for pointers */
                                        BKE_image_merge((Image *)lnode->new_node->id, (Image *)lnode->id);
                                }
                        }
@@ -2997,12 +3029,15 @@ static void registerTextureNodes(ListBase *ntypelist)
        nodeRegisterType(ntypelist, &tex_node_mix_rgb);
        nodeRegisterType(ntypelist, &tex_node_valtorgb);
        nodeRegisterType(ntypelist, &tex_node_rgbtobw);
+       nodeRegisterType(ntypelist, &tex_node_valtonor);
        nodeRegisterType(ntypelist, &tex_node_curve_rgb);
        nodeRegisterType(ntypelist, &tex_node_curve_time);
        nodeRegisterType(ntypelist, &tex_node_invert);
        nodeRegisterType(ntypelist, &tex_node_hue_sat);
        nodeRegisterType(ntypelist, &tex_node_coord);
        nodeRegisterType(ntypelist, &tex_node_distance);
+       nodeRegisterType(ntypelist, &tex_node_compose);
+       nodeRegisterType(ntypelist, &tex_node_decompose);
        
        nodeRegisterType(ntypelist, &tex_node_output);
        nodeRegisterType(ntypelist, &tex_node_viewer);
@@ -3014,6 +3049,8 @@ static void registerTextureNodes(ListBase *ntypelist)
        
        nodeRegisterType(ntypelist, &tex_node_rotate);
        nodeRegisterType(ntypelist, &tex_node_translate);
+       nodeRegisterType(ntypelist, &tex_node_scale);
+       nodeRegisterType(ntypelist, &tex_node_at);
        
        nodeRegisterType(ntypelist, &tex_node_proc_voronoi);
        nodeRegisterType(ntypelist, &tex_node_proc_blend);