svn merge -r 16351:16368 https://svn.blender.org/svnroot/bf-blender/trunk/blender
[blender.git] / source / blender / blenkernel / intern / node.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. 
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2005 Blender Foundation.
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): none yet.
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  */
29
30 #include <Python.h>
31 #include <stdlib.h>
32 #include <string.h>
33
34 #include "DNA_ID.h"
35 #include "DNA_image_types.h"
36 #include "DNA_node_types.h"
37 #include "DNA_material_types.h"
38 #include "DNA_text_types.h"
39 #include "DNA_scene_types.h"
40
41 #include "BKE_blender.h"
42 #include "BKE_colortools.h"
43 #include "BKE_global.h"
44 #include "BKE_image.h"
45 #include "BKE_library.h"
46 #include "BKE_main.h"
47 #include "BKE_node.h"
48 #include "BKE_texture.h"
49 #include "BKE_text.h"
50 #include "BKE_utildefines.h"
51
52 #include "BLI_arithb.h"
53 #include "BLI_blenlib.h"
54 #include "BLI_rand.h"
55 #include "BLI_threads.h"
56
57 #include "PIL_time.h"
58
59 #include "MEM_guardedalloc.h"
60 #include "IMB_imbuf.h"
61
62 #include "RE_pipeline.h"
63 #include "RE_shader_ext.h"              /* <- TexResult */
64 #include "RE_render_ext.h"              /* <- ibuf_sample() */
65
66 #include "CMP_node.h"
67 #include "intern/CMP_util.h"    /* stupid include path... */
68
69 #include "SHD_node.h"
70
71 #include "GPU_extensions.h"
72 #include "GPU_material.h"
73
74 static ListBase empty_list = {NULL, NULL};
75 ListBase node_all_composit = {NULL, NULL};
76 ListBase node_all_shaders = {NULL, NULL};
77
78 /* ************** Type stuff **********  */
79
80 static bNodeType *node_get_type(bNodeTree *ntree, int type, bNodeTree *ngroup, ID *id)
81 {
82         if(type==NODE_GROUP) {
83                 if(ngroup && GS(ngroup->id.name)==ID_NT) {
84                         return ngroup->owntype;
85                 }
86                 return NULL;
87         }
88         else {
89                 bNodeType *ntype = ntree->alltypes.first;
90                 for(; ntype; ntype= ntype->next)
91                         if(ntype->type==type && id==ntype->id )
92                                 return ntype;
93                 
94                 return NULL;
95         }
96 }
97
98 void ntreeInitTypes(bNodeTree *ntree)
99 {
100         bNode *node, *next;
101         
102         if(ntree->type==NTREE_SHADER)
103                 ntree->alltypes= node_all_shaders;
104         else if(ntree->type==NTREE_COMPOSIT)
105                 ntree->alltypes= node_all_composit;
106         else {
107                 ntree->alltypes= empty_list;
108                 printf("Error: no type definitions for nodes\n");
109         }
110         
111         for(node= ntree->nodes.first; node; node= next) {
112                 next= node->next;
113                 if(node->type==NODE_DYNAMIC) {
114                         bNodeType *stype= NULL;
115                         if(node->id==NULL) { /* empty script node */
116                                 stype= node_get_type(ntree, node->type, NULL, NULL);
117                         } else { /* not an empty script node */
118                                 stype= node_get_type(ntree, node->type, NULL, node->id);
119                                 if(!stype) {
120                                         stype= node_get_type(ntree, node->type, NULL, NULL);
121                                         /* needed info if the pynode script fails now: */
122                                         if (node->id) node->storage= ntree;
123                                 } else {
124                                         node->custom1= 0;
125                                         node->custom1= BSET(node->custom1,NODE_DYNAMIC_ADDEXIST);
126                                 }
127                         }
128                         node->typeinfo= stype;
129                         node->typeinfo->initfunc(node);
130                 } else {
131                         node->typeinfo= node_get_type(ntree, node->type, (bNodeTree *)node->id, NULL);
132                 }
133
134                 if(node->typeinfo==NULL) {
135                         printf("Error: Node type %s doesn't exist anymore, removed\n", node->name);
136                         nodeFreeNode(ntree, node);
137                 }
138         }
139                         
140         ntree->init |= NTREE_TYPE_INIT;
141 }
142
143 /* updates node with (modified) bNodeType.. this should be done for all trees */
144 void ntreeUpdateType(bNodeTree *ntree, bNodeType *ntype)
145 {
146         bNode *node;
147
148         for(node= ntree->nodes.first; node; node= node->next) {
149                 if(node->typeinfo== ntype) {
150                         nodeUpdateType(ntree, node, ntype);
151                 }
152         }
153 }
154
155 /* only used internal... we depend on type definitions! */
156 static bNodeSocket *node_add_socket_type(ListBase *lb, bNodeSocketType *stype)
157 {
158         bNodeSocket *sock= MEM_callocN(sizeof(bNodeSocket), "sock");
159         
160         BLI_strncpy(sock->name, stype->name, NODE_MAXSTR);
161         if(stype->limit==0) sock->limit= 0xFFF;
162         else sock->limit= stype->limit;
163         sock->type= stype->type;
164         
165         sock->to_index= stype->own_index;
166         sock->tosock= stype->internsock;
167         
168         sock->ns.vec[0]= stype->val1;
169         sock->ns.vec[1]= stype->val2;
170         sock->ns.vec[2]= stype->val3;
171         sock->ns.vec[3]= stype->val4;
172         sock->ns.min= stype->min;
173         sock->ns.max= stype->max;
174         
175         if(lb)
176                 BLI_addtail(lb, sock);
177
178         return sock;
179 }
180
181 static void node_rem_socket(bNodeTree *ntree, ListBase *lb, bNodeSocket *sock)
182 {
183         bNodeLink *link, *next;
184         
185         for(link= ntree->links.first; link; link= next) {
186                 next= link->next;
187                 if(link->fromsock==sock || link->tosock==sock) {
188                         nodeRemLink(ntree, link);
189                 }
190         }
191         
192         BLI_remlink(lb, sock);
193         MEM_freeN(sock);
194 }
195
196 static bNodeSocket *verify_socket(ListBase *lb, bNodeSocketType *stype)
197 {
198         bNodeSocket *sock;
199         
200         for(sock= lb->first; sock; sock= sock->next) {
201                 /* both indices are zero for non-groups, otherwise it's a unique index */
202                 if(sock->to_index==stype->own_index)
203                         if(strncmp(sock->name, stype->name, NODE_MAXSTR)==0)
204                                 break;
205         }
206         if(sock) {
207                 sock->type= stype->type;                /* in future, read this from tydefs! */
208                 if(stype->limit==0) sock->limit= 0xFFF;
209                 else sock->limit= stype->limit;
210                 sock->ns.min= stype->min;
211                 sock->ns.max= stype->max;
212                 sock->tosock= stype->internsock;
213                 
214                 BLI_remlink(lb, sock);
215                 
216                 return sock;
217         }
218         else {
219                 return node_add_socket_type(NULL, stype);
220         }
221 }
222
223 static void verify_socket_list(bNodeTree *ntree, ListBase *lb, bNodeSocketType *stype_first)
224 {
225         bNodeSocketType *stype;
226         
227         /* no inputs anymore? */
228         if(stype_first==NULL) {
229                 while(lb->first)
230                         node_rem_socket(ntree, lb, lb->first);
231         }
232         else {
233                 /* step by step compare */
234                 stype= stype_first;
235                 while(stype->type != -1) {
236                         stype->sock= verify_socket(lb, stype);
237                         stype++;
238                 }
239                 /* leftovers are removed */
240                 while(lb->first)
241                         node_rem_socket(ntree, lb, lb->first);
242                 /* and we put back the verified sockets */
243                 stype= stype_first;
244                 while(stype->type != -1) {
245                         BLI_addtail(lb, stype->sock);
246                         stype++;
247                 }
248         }
249 }
250
251 void nodeVerifyType(bNodeTree *ntree, bNode *node)
252 {
253         bNodeType *ntype= node->typeinfo;
254         
255         if(ntype) {
256                 /* might add some other verify stuff here */
257                 
258                 verify_socket_list(ntree, &node->inputs, ntype->inputs);
259                 verify_socket_list(ntree, &node->outputs, ntype->outputs);
260         }
261 }
262
263 void ntreeVerifyTypes(bNodeTree *ntree)
264 {
265         bNode *node;
266         
267         /* if((ntree->init & NTREE_TYPE_INIT)==0) */
268         ntreeInitTypes(ntree);
269
270         /* check inputs and outputs, and remove or insert them */
271         for(node= ntree->nodes.first; node; node= node->next)
272                 nodeVerifyType(ntree, node);
273         
274 }
275
276 /* ************** Group stuff ********** */
277
278 bNodeType node_group_typeinfo= {
279         /* next,prev   */       NULL, NULL,
280         /* type code   */       NODE_GROUP,
281         /* name        */       "Group",
282         /* width+range */       120, 60, 200,
283         /* class+opts  */       NODE_CLASS_GROUP, NODE_OPTIONS,
284         /* input sock  */       NULL,
285         /* output sock */       NULL,
286         /* storage     */       "",
287         /* execfunc    */       NULL,
288         /* butfunc     */       NULL,
289         /* initfunc    */       NULL,
290         /* freestoragefunc    */        NULL,
291         /* copystoragefunc    */        NULL,
292         /* id          */       NULL
293 };
294
295 /* tag internal sockets */
296 static void group_tag_internal_sockets(bNodeTree *ngroup)
297 {
298         bNode *node;
299         bNodeSocket *sock;
300         bNodeLink *link;
301         
302         /* clear intern tag, but check already for hidden sockets */
303         for(node= ngroup->nodes.first; node; node= node->next) {
304                 for(sock= node->inputs.first; sock; sock= sock->next)
305                         sock->intern= sock->flag & SOCK_HIDDEN;
306                 for(sock= node->outputs.first; sock; sock= sock->next)
307                         sock->intern= sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL);
308         }
309         /* set tag */
310         for(link= ngroup->links.first; link; link= link->next) {
311                 link->fromsock->intern= 1;
312                 link->tosock->intern= 1;
313         }
314         
315         /* remove link pointer to external links (only happens on create group) */
316         for(node= ngroup->nodes.first; node; node= node->next) {
317                 for(sock= node->inputs.first; sock; sock= sock->next)
318                         if(sock->intern==0)
319                                 sock->link= NULL;
320         }
321
322         /* set all intern sockets to own_index zero, makes sure that later use won't mixup */
323         for(node= ngroup->nodes.first; node; node= node->next) {
324                 for(sock= node->inputs.first; sock; sock= sock->next)
325                         if(sock->intern)
326                                 sock->own_index= 0;
327                 for(sock= node->outputs.first; sock; sock= sock->next)
328                         if(sock->intern)
329                                 sock->own_index= 0;
330         }
331 }
332
333 /* after editing group, new sockets are zero */
334 /* this routine ensures unique identifiers for zero sockets that are exposed */
335 static void group_verify_own_indices(bNodeTree *ngroup)
336 {
337         bNode *node;
338         bNodeSocket *sock;
339         
340         for(node= ngroup->nodes.first; node; node= node->next) {
341                 for(sock= node->inputs.first; sock; sock= sock->next)
342                         if(sock->own_index==0 && sock->intern==0)
343                                 sock->own_index= ++(ngroup->cur_index);
344                 for(sock= node->outputs.first; sock; sock= sock->next)
345                         if(sock->own_index==0 && sock->intern==0)
346                                 sock->own_index= ++(ngroup->cur_index);
347         }
348         //printf("internal index %d\n", ngroup->cur_index);
349 }
350
351
352 /* nodetrees can be used as groups, so we need typeinfo structs generated */
353 void ntreeMakeOwnType(bNodeTree *ngroup)
354 {
355         bNode *node;
356         bNodeSocket *sock;
357         int totin= 0, totout=0, a;
358
359         /* tags socket when internal linked */
360         group_tag_internal_sockets(ngroup);
361         
362         /* ensure all sockets have own unique id */
363         group_verify_own_indices(ngroup);
364         
365         /* counting stats */
366         for(node= ngroup->nodes.first; node; node= node->next) {
367                 if(node->type==NODE_GROUP)
368                         break;
369                 for(sock= node->inputs.first; sock; sock= sock->next)
370                         if(sock->intern==0) 
371                                 totin++;
372                 for(sock= node->outputs.first; sock; sock= sock->next)
373                         if(sock->intern==0) 
374                                 totout++;
375         }
376         /* debug: nodetrees in nodetrees not handled yet */
377         if(node) {
378                 printf("group in group, not supported yet\n");
379                 return;
380         }
381         
382         /* free own type struct */
383         if(ngroup->owntype) {
384                 if(ngroup->owntype->inputs)
385                         MEM_freeN(ngroup->owntype->inputs);
386                 if(ngroup->owntype->outputs)
387                         MEM_freeN(ngroup->owntype->outputs);
388                 MEM_freeN(ngroup->owntype);
389         }
390         
391         /* make own type struct */
392         ngroup->owntype= MEM_callocN(sizeof(bNodeType), "group type");
393         *ngroup->owntype= node_group_typeinfo; /* copy data, for init */
394         
395         /* input type arrays */
396         if(totin) {
397                 bNodeSocketType *stype;
398                 bNodeSocketType *inputs= MEM_callocN(sizeof(bNodeSocketType)*(totin+1), "bNodeSocketType");
399                 a= 0;
400                 
401                 for(node= ngroup->nodes.first; node; node= node->next) {
402                         /* nodes are presumed fully verified, stype and socket list are in sync */
403                         stype= node->typeinfo->inputs;
404                         for(sock= node->inputs.first; sock; sock= sock->next, stype++) {
405                                 if(sock->intern==0) {
406                                         /* debug only print */
407                                         if(stype==NULL || stype->type==-1) printf("group verification error %s\n", ngroup->id.name);
408                                         
409                                         inputs[a]= *stype;
410                                         inputs[a].own_index= sock->own_index;
411                                         inputs[a].internsock= sock;     
412                                         a++;
413                                 }
414                         }
415                 }
416                 inputs[a].type= -1;     /* terminator code */
417                 ngroup->owntype->inputs= inputs;
418         }       
419         
420         /* output type arrays */
421         if(totout) {
422                 bNodeSocketType *stype;
423                 bNodeSocketType *outputs= MEM_callocN(sizeof(bNodeSocketType)*(totout+1), "bNodeSocketType");
424                 a= 0;
425                 
426                 for(node= ngroup->nodes.first; node; node= node->next) {
427                         /* nodes are presumed fully verified, stype and socket list are in sync */
428                         stype= node->typeinfo->outputs;
429                         for(sock= node->outputs.first; sock; sock= sock->next, stype++) {
430                                 if(sock->intern==0) {
431                                         /* debug only print */
432                                         if(stype==NULL || stype->type==-1) printf("group verification error %s\n", ngroup->id.name);
433                                         
434                                         outputs[a]= *stype;
435                                         outputs[a].own_index= sock->own_index;
436                                         outputs[a].internsock= sock;    
437                                         a++;
438                                 }
439                         }
440                 }
441                 outputs[a].type= -1;    /* terminator code */
442                 ngroup->owntype->outputs= outputs;
443         }
444         
445         /* voila, the nodetree has the full definition for generating group-node instances! */
446 }
447
448
449 static bNodeSocket *groupnode_find_tosock(bNode *gnode, int index)
450 {
451         bNodeSocket *sock;
452         
453         for(sock= gnode->inputs.first; sock; sock= sock->next)
454                 if(sock->to_index==index)
455                         return sock;
456         return NULL;
457 }
458
459 static bNodeSocket *groupnode_find_fromsock(bNode *gnode, int index)
460 {
461         bNodeSocket *sock;
462         
463         for(sock= gnode->outputs.first; sock; sock= sock->next)
464                 if(sock->to_index==index)
465                         return sock;
466         return NULL;
467 }
468
469 bNode *nodeMakeGroupFromSelected(bNodeTree *ntree)
470 {
471         bNodeLink *link, *linkn;
472         bNode *node, *gnode, *nextn;
473         bNodeSocket *sock;
474         bNodeTree *ngroup;
475         float min[2], max[2];
476         int totnode=0;
477         
478         INIT_MINMAX2(min, max);
479         
480         /* is there something to group? also do some clearing */
481         for(node= ntree->nodes.first; node; node= node->next) {
482                 if(node->flag & NODE_SELECT) {
483                         /* no groups in groups */
484                         if(node->type==NODE_GROUP)
485                                 return NULL;
486                         DO_MINMAX2( (&node->locx), min, max);
487                         totnode++;
488                 }
489                 node->done= 0;
490         }
491         if(totnode==0) return NULL;
492         
493         /* check if all connections are OK, no unselected node has both
494                 inputs and outputs to a selection */
495         for(link= ntree->links.first; link; link= link->next) {
496                 if(link->fromnode->flag & NODE_SELECT)
497                         link->tonode->done |= 1;
498                 if(link->tonode->flag & NODE_SELECT)
499                         link->fromnode->done |= 2;
500         }       
501         
502         for(node= ntree->nodes.first; node; node= node->next) {
503                 if((node->flag & NODE_SELECT)==0)
504                         if(node->done==3)
505                                 break;
506         }
507         if(node) 
508                 return NULL;
509         
510         /* OK! new nodetree */
511         ngroup= alloc_libblock(&G.main->nodetree, ID_NT, "NodeGroup");
512         ngroup->type= ntree->type;
513         ngroup->alltypes= ntree->alltypes;
514         
515         /* move nodes over */
516         for(node= ntree->nodes.first; node; node= nextn) {
517                 nextn= node->next;
518                 if(node->flag & NODE_SELECT) {
519                         BLI_remlink(&ntree->nodes, node);
520                         BLI_addtail(&ngroup->nodes, node);
521                         node->locx-= 0.5f*(min[0]+max[0]);
522                         node->locy-= 0.5f*(min[1]+max[1]);
523
524                         /* set selin and selout of the nodetree */
525                         for(sock= node->inputs.first; sock; sock= sock->next) {
526                                 if(sock->flag & SOCK_SEL) {
527                                         ngroup->selin= sock;
528                                         break;
529                                 }
530                         }
531                         for(sock= node->outputs.first; sock; sock= sock->next) {
532                                 if(sock->flag & SOCK_SEL) {
533                                         ngroup->selout= sock;
534                                         break;
535                                 }
536                         }
537
538                         /* set socket own_index to zero since it can still have a value
539                          * from being in a group before, otherwise it doesn't get a unique
540                          * index in group_verify_own_indices */
541                         for(sock= node->inputs.first; sock; sock= sock->next)
542                                 sock->own_index= 0;
543                         for(sock= node->outputs.first; sock; sock= sock->next)
544                                 sock->own_index= 0;
545                 }
546         }
547
548         /* move links over */
549         for(link= ntree->links.first; link; link= linkn) {
550                 linkn= link->next;
551                 if(link->fromnode->flag & link->tonode->flag & NODE_SELECT) {
552                         BLI_remlink(&ntree->links, link);
553                         BLI_addtail(&ngroup->links, link);
554                 }
555         }
556         
557         /* now we can make own group typeinfo */
558         ntreeMakeOwnType(ngroup);
559         
560         /* make group node */
561         gnode= nodeAddNodeType(ntree, NODE_GROUP, ngroup, NULL);
562         gnode->locx= 0.5f*(min[0]+max[0]);
563         gnode->locy= 0.5f*(min[1]+max[1]);
564         
565         /* relink external sockets */
566         for(link= ntree->links.first; link; link= linkn) {
567                 linkn= link->next;
568                 
569                 if(link->tonode->flag & NODE_SELECT) {
570                         link->tonode= gnode;
571                         sock= groupnode_find_tosock(gnode, link->tosock->own_index);
572                         if(sock==NULL) {
573                                 nodeRemLink(ntree, link);       
574                                 printf("Removed link, cannot mix internal and external sockets in group\n");
575                         }
576                         else link->tosock= sock;
577                 }
578                 else if(link->fromnode->flag & NODE_SELECT) {
579                         link->fromnode= gnode;
580                         sock= groupnode_find_fromsock(gnode, link->fromsock->own_index);
581                         if(sock==NULL) {
582                                 nodeRemLink(ntree, link);       
583                                 printf("Removed link, cannot mix internal and external sockets in group\n");
584                         }
585                         else link->fromsock= sock;
586                 }
587         }
588         
589         /* initialize variables of unused input sockets */
590         for(node= ngroup->nodes.first; node; node= node->next) {
591                 for(sock= node->inputs.first; sock; sock= sock->next) {
592                         if(sock->intern==0) {
593                                 bNodeSocket *nsock= groupnode_find_tosock(gnode, sock->own_index);
594                                 if(nsock) {
595                                         QUATCOPY(nsock->ns.vec, sock->ns.vec);
596                                 }
597                         }
598                 }
599         }
600
601         /* update node levels */
602         ntreeSolveOrder(ntree);
603
604         return gnode;
605 }
606
607 /* note: ungroup: group_indices zero! */
608
609 /* here's a nasty little one, need to check users... */
610 /* should become callbackable... */
611 void nodeVerifyGroup(bNodeTree *ngroup)
612 {
613         
614         /* group changed, so we rebuild the type definition */
615         ntreeMakeOwnType(ngroup);
616         
617         if(ngroup->type==NTREE_SHADER) {
618                 Material *ma;
619                 for(ma= G.main->mat.first; ma; ma= ma->id.next) {
620                         if(ma->nodetree) {
621                                 bNode *node;
622                                 
623                                 /* find if group is in tree */
624                                 for(node= ma->nodetree->nodes.first; node; node= node->next)
625                                         if(node->id == (ID *)ngroup)
626                                                 break;
627                                 
628                                 if(node) {
629                                         /* set all type pointers OK */
630                                         ntreeInitTypes(ma->nodetree);
631                                         
632                                         for(node= ma->nodetree->nodes.first; node; node= node->next)
633                                                 if(node->id == (ID *)ngroup)
634                                                         nodeVerifyType(ma->nodetree, node);
635                                 }
636                         }
637                 }
638         }
639         else if(ngroup->type==NTREE_COMPOSIT) {
640                 Scene *sce;
641                 for(sce= G.main->scene.first; sce; sce= sce->id.next) {
642                         if(sce->nodetree) {
643                                 bNode *node;
644                                 
645                                 /* find if group is in tree */
646                                 for(node= sce->nodetree->nodes.first; node; node= node->next)
647                                         if(node->id == (ID *)ngroup)
648                                                 break;
649                                 
650                                 if(node) {
651                                         /* set all type pointers OK */
652                                         ntreeInitTypes(sce->nodetree);
653                                         
654                                         for(node= sce->nodetree->nodes.first; node; node= node->next)
655                                                 if(node->id == (ID *)ngroup)
656                                                         nodeVerifyType(sce->nodetree, node);
657                                 }
658                         }
659                 }
660         }
661 }
662
663 /* also to check all users of groups. Now only used in editor for hide/unhide */
664 /* should become callbackable? */
665 void nodeGroupSocketUseFlags(bNodeTree *ngroup)
666 {
667         bNode *node;
668         bNodeSocket *sock;
669
670         /* clear flags */
671         for(node= ngroup->nodes.first; node; node= node->next) {
672                 for(sock= node->inputs.first; sock; sock= sock->next)
673                         sock->flag &= ~SOCK_IN_USE;
674                 for(sock= node->outputs.first; sock; sock= sock->next)
675                         sock->flag &= ~SOCK_IN_USE;
676         }
677         
678         /* tag all thats in use */
679         if(ngroup->type==NTREE_SHADER) {
680                 Material *ma;
681                 for(ma= G.main->mat.first; ma; ma= ma->id.next) {
682                         if(ma->nodetree) {
683                                 for(node= ma->nodetree->nodes.first; node; node= node->next) {
684                                         if(node->id==(ID *)ngroup) {
685                                                 for(sock= node->inputs.first; sock; sock= sock->next)
686                                                         if(sock->link)
687                                                                 if(sock->tosock) 
688                                                                         sock->tosock->flag |= SOCK_IN_USE;
689                                                 for(sock= node->outputs.first; sock; sock= sock->next)
690                                                         if(nodeCountSocketLinks(ma->nodetree, sock))
691                                                                 if(sock->tosock) 
692                                                                         sock->tosock->flag |= SOCK_IN_USE;
693                                         }
694                                 }
695                         }
696                 }
697         }
698         else if(ngroup->type==NTREE_COMPOSIT) {
699                 Scene *sce;
700                 for(sce= G.main->scene.first; sce; sce= sce->id.next) {
701                         if(sce->nodetree) {
702                                 for(node= sce->nodetree->nodes.first; node; node= node->next) {
703                                         if(node->id==(ID *)ngroup) {
704                                                 for(sock= node->inputs.first; sock; sock= sock->next)
705                                                         if(sock->link)
706                                                                 if(sock->tosock) 
707                                                                         sock->tosock->flag |= SOCK_IN_USE;
708                                                 for(sock= node->outputs.first; sock; sock= sock->next)
709                                                         if(nodeCountSocketLinks(sce->nodetree, sock))
710                                                                 if(sock->tosock) 
711                                                                         sock->tosock->flag |= SOCK_IN_USE;
712                                         }
713                                 }
714                         }
715                 }
716         }
717 }
718
719 /* finds a node based on given socket */
720 int nodeFindNode(bNodeTree *ntree, bNodeSocket *sock, bNode **nodep, int *sockindex)
721 {
722         bNode *node;
723         bNodeSocket *tsock;
724         int index= 0;
725         
726         for(node= ntree->nodes.first; node; node= node->next) {
727                 for(index=0, tsock= node->inputs.first; tsock; tsock= tsock->next, index++)
728                         if(tsock==sock)
729                                 break;
730                 if(tsock)
731                         break;
732                 for(index=0, tsock= node->outputs.first; tsock; tsock= tsock->next, index++)
733                         if(tsock==sock)
734                                 break;
735                 if(tsock)
736                         break;
737         }
738
739         if(node) {
740                 *nodep= node;
741                 if(sockindex) *sockindex= index;
742                 return 1;
743         }
744         
745         *nodep= NULL;
746         return 0;
747 }
748
749 /* returns 1 if its OK */
750 int nodeGroupUnGroup(bNodeTree *ntree, bNode *gnode)
751 {
752         bNodeLink *link, *linkn;
753         bNode *node, *nextn;
754         bNodeTree *ngroup, *wgroup;
755         int index;
756         
757         ngroup= (bNodeTree *)gnode->id;
758         if(ngroup==NULL) return 0;
759         
760         /* clear new pointers, set in copytree */
761         for(node= ntree->nodes.first; node; node= node->next)
762                 node->new_node= NULL;
763
764         wgroup= ntreeCopyTree(ngroup, 0);
765         
766         /* add the nodes into the ntree */
767         for(node= wgroup->nodes.first; node; node= nextn) {
768                 nextn= node->next;
769                 BLI_remlink(&wgroup->nodes, node);
770                 BLI_addtail(&ntree->nodes, node);
771                 node->locx+= gnode->locx;
772                 node->locy+= gnode->locy;
773                 node->flag |= NODE_SELECT;
774         }
775         /* and the internal links */
776         for(link= wgroup->links.first; link; link= linkn) {
777                 linkn= link->next;
778                 BLI_remlink(&wgroup->links, link);
779                 BLI_addtail(&ntree->links, link);
780         }
781
782         /* restore links to and from the gnode */
783         for(link= ntree->links.first; link; link= link->next) {
784                 if(link->tonode==gnode) {
785                         /* link->tosock->tosock is on the node we look for */
786                         nodeFindNode(ngroup, link->tosock->tosock, &nextn, &index);
787                         if(nextn==NULL) printf("wrong stuff!\n");
788                         else if(nextn->new_node==NULL) printf("wrong stuff too!\n");
789                         else {
790                                 link->tonode= nextn->new_node;
791                                 link->tosock= BLI_findlink(&link->tonode->inputs, index);
792                         }
793                 }
794                 else if(link->fromnode==gnode) {
795                         /* link->fromsock->tosock is on the node we look for */
796                         nodeFindNode(ngroup, link->fromsock->tosock, &nextn, &index);
797                         if(nextn==NULL) printf("1 wrong stuff!\n");
798                         else if(nextn->new_node==NULL) printf("1 wrong stuff too!\n");
799                         else {
800                                 link->fromnode= nextn->new_node;
801                                 link->fromsock= BLI_findlink(&link->fromnode->outputs, index);
802                         }
803                 }
804         }
805         
806         /* remove the gnode & work tree */
807         free_libblock(&G.main->nodetree, wgroup);
808         
809         nodeFreeNode(ntree, gnode);
810         
811         /* solve order goes fine, but the level tags not... doing it twice works for now. solve this once */
812         ntreeSolveOrder(ntree);
813         ntreeSolveOrder(ntree);
814
815         return 1;
816 }
817
818 void nodeCopyGroup(bNode *gnode)
819 {
820         bNodeSocket *sock;
821
822         gnode->id->us--;
823         gnode->id= (ID *)ntreeCopyTree((bNodeTree *)gnode->id, 0);
824
825         /* new_sock was set in nodeCopyNode */
826         for(sock=gnode->inputs.first; sock; sock=sock->next)
827                 if(sock->tosock)
828                         sock->tosock= sock->tosock->new_sock;
829
830         for(sock=gnode->outputs.first; sock; sock=sock->next)
831                 if(sock->tosock)
832                         sock->tosock= sock->tosock->new_sock;
833 }
834
835 /* ************** Add stuff ********** */
836 void nodeAddSockets(bNode *node, bNodeType *ntype)
837 {
838         bNodeSocketType *stype;
839
840         if(ntype->inputs) {
841                 stype= ntype->inputs;
842                 while(stype->type != -1) {
843                         node_add_socket_type(&node->inputs, stype);
844                         stype++;
845                 }
846         }
847         if(ntype->outputs) {
848                 stype= ntype->outputs;
849                 while(stype->type != -1) {
850                         node_add_socket_type(&node->outputs, stype);
851                         stype++;
852                 }
853         }
854 }
855
856
857 bNode *nodeAddNodeType(bNodeTree *ntree, int type, bNodeTree *ngroup, ID *id)
858 {
859         bNode *node= NULL;
860         bNodeType *ntype= NULL;
861
862         if(type>=NODE_DYNAMIC_MENU) {
863                 int a=0, idx= type-NODE_DYNAMIC_MENU;
864                 ntype= ntree->alltypes.first;
865                 while(ntype) {
866                         if(ntype->type==NODE_DYNAMIC) {
867                                 if(a==idx)
868                                         break;
869                                 a++;
870                         }
871                         ntype= ntype->next;
872                 }
873         } else
874                 ntype= node_get_type(ntree, type, ngroup, id);
875
876         node= MEM_callocN(sizeof(bNode), "new node");
877         BLI_addtail(&ntree->nodes, node);
878         node->typeinfo= ntype;
879         if(type>=NODE_DYNAMIC_MENU)
880                 node->custom2= type; /* for node_dynamic_init */
881
882         if(ngroup)
883                 BLI_strncpy(node->name, ngroup->id.name+2, NODE_MAXSTR);
884         else if(type>NODE_DYNAMIC_MENU) {
885                 BLI_strncpy(node->name, ntype->id->name+2, NODE_MAXSTR);
886         }
887         else
888                 BLI_strncpy(node->name, ntype->name, NODE_MAXSTR);
889         node->type= ntype->type;
890         node->flag= NODE_SELECT|ntype->flag;
891         node->width= ntype->width;
892         node->miniwidth= 42.0f;         /* small value only, allows print of first chars */
893
894         if(type==NODE_GROUP)
895                 node->id= (ID *)ngroup;
896
897         /* need init handler later? */
898         /* got it-bob*/
899         if(ntype->initfunc!=NULL)
900                 ntype->initfunc(node);
901
902         nodeAddSockets(node, ntype);
903
904         return node;
905 }
906
907 void nodeMakeDynamicType(bNode *node)
908 {
909         /* find SH_DYNAMIC_NODE ntype */
910         bNodeType *ntype= node_all_shaders.first;
911         while(ntype) {
912                 if(ntype->type==NODE_DYNAMIC && ntype->id==NULL)
913                         break;
914                 ntype= ntype->next;
915         }
916
917         /* make own type struct to fill */
918         if(ntype) {
919                 /*node->typeinfo= MEM_dupallocN(ntype);*/
920                 bNodeType *newtype= MEM_callocN(sizeof(bNodeType), "dynamic bNodeType");
921                 *newtype= *ntype;
922                 newtype->name= BLI_strdup(ntype->name);
923                 node->typeinfo= newtype;
924         }
925 }
926
927 void nodeUpdateType(bNodeTree *ntree, bNode* node, bNodeType *ntype)
928 {
929         verify_socket_list(ntree, &node->inputs, ntype->inputs);
930         verify_socket_list(ntree, &node->outputs, ntype->outputs);
931 }
932
933 /* keep socket listorder identical, for copying links */
934 /* ntree is the target tree */
935 bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node, int internal)
936 {
937         bNode *nnode= MEM_callocN(sizeof(bNode), "dupli node");
938         bNodeSocket *sock, *oldsock;
939
940         *nnode= *node;
941         BLI_addtail(&ntree->nodes, nnode);
942         
943         duplicatelist(&nnode->inputs, &node->inputs);
944         oldsock= node->inputs.first;
945         for(sock= nnode->inputs.first; sock; sock= sock->next, oldsock= oldsock->next) {
946                 oldsock->new_sock= sock;
947                 if(internal)
948                         sock->own_index= 0;
949         }
950         
951         duplicatelist(&nnode->outputs, &node->outputs);
952         oldsock= node->outputs.first;
953         for(sock= nnode->outputs.first; sock; sock= sock->next, oldsock= oldsock->next) {
954                 if(internal)
955                         sock->own_index= 0;
956                 sock->stack_index= 0;
957                 sock->ns.data= NULL;
958                 oldsock->new_sock= sock;
959         }
960         
961         if(nnode->id)
962                 nnode->id->us++;
963         
964         if(node->typeinfo->copystoragefunc)
965                 node->typeinfo->copystoragefunc(node, nnode);
966         
967         node->new_node= nnode;
968         nnode->new_node= NULL;
969         nnode->preview= NULL;
970
971         return nnode;
972 }
973
974 bNodeLink *nodeAddLink(bNodeTree *ntree, bNode *fromnode, bNodeSocket *fromsock, bNode *tonode, bNodeSocket *tosock)
975 {
976         bNodeLink *link= MEM_callocN(sizeof(bNodeLink), "link");
977         
978         BLI_addtail(&ntree->links, link);
979         link->fromnode= fromnode;
980         link->fromsock= fromsock;
981         link->tonode= tonode;
982         link->tosock= tosock;
983         
984         return link;
985 }
986
987 void nodeRemLink(bNodeTree *ntree, bNodeLink *link)
988 {
989         BLI_remlink(&ntree->links, link);
990         if(link->tosock)
991                 link->tosock->link= NULL;
992         MEM_freeN(link);
993 }
994
995
996 bNodeTree *ntreeAddTree(int type)
997 {
998         bNodeTree *ntree= MEM_callocN(sizeof(bNodeTree), "new node tree");
999         ntree->type= type;
1000         ntree->alltypes.first = NULL;
1001         ntree->alltypes.last = NULL;
1002         
1003         ntreeInitTypes(ntree);
1004         return ntree;
1005 }
1006
1007 bNodeTree *ntreeCopyTree(bNodeTree *ntree, int internal_select)
1008 {
1009         bNodeTree *newtree;
1010         bNode *node, *nnode, *last;
1011         bNodeLink *link, *nlink;
1012         bNodeSocket *sock;
1013         int a;
1014         
1015         if(ntree==NULL) return NULL;
1016         
1017         if(internal_select==0) {
1018                 /* is ntree part of library? */
1019                 for(newtree=G.main->nodetree.first; newtree; newtree= newtree->id.next)
1020                         if(newtree==ntree) break;
1021                 if(newtree)
1022                         newtree= copy_libblock(ntree);
1023                 else
1024                         newtree= MEM_dupallocN(ntree);
1025                 newtree->nodes.first= newtree->nodes.last= NULL;
1026                 newtree->links.first= newtree->links.last= NULL;
1027         }
1028         else
1029                 newtree= ntree;
1030         
1031         last= ntree->nodes.last;
1032         for(node= ntree->nodes.first; node; node= node->next) {
1033                 
1034                 node->new_node= NULL;
1035                 if(internal_select==0 || (node->flag & NODE_SELECT)) {
1036                         nnode= nodeCopyNode(newtree, node, internal_select);    /* sets node->new */
1037                         if(internal_select) {
1038                                 node->flag &= ~NODE_SELECT;
1039                                 nnode->flag |= NODE_SELECT;
1040                         }
1041                         node->flag &= ~NODE_ACTIVE;
1042
1043                         /* deselect original sockets */
1044                         for(sock= node->inputs.first; sock; sock= sock->next) {
1045                                 if(sock->flag & SOCK_SEL) sock->flag&= ~SOCK_SEL;
1046                         }
1047                         for(sock= node->outputs.first; sock; sock= sock->next) {
1048                                 if(sock->flag & SOCK_SEL) sock->flag&= ~SOCK_SEL;
1049                         }
1050                         
1051                         /* set tree selin and selout to new sockets */
1052                         for(sock= nnode->inputs.first; sock; sock= sock->next) {
1053                                 if(sock->flag & SOCK_SEL) {
1054                                         ntree->selin= sock;
1055                                         break;
1056                                 }
1057                         }
1058                         for(sock= nnode->outputs.first; sock; sock= sock->next) {
1059                                 if(sock->flag & SOCK_SEL) {
1060                                         ntree->selout= sock;
1061                                         break;
1062                                 }
1063                         }
1064                 }
1065                 if(node==last) break;
1066         }
1067         
1068         /* check for copying links */
1069         for(link= ntree->links.first; link; link= link->next) {
1070                 if(link->fromnode->new_node && link->tonode->new_node) {
1071                         nlink= nodeAddLink(newtree, link->fromnode->new_node, NULL, link->tonode->new_node, NULL);
1072                         /* sockets were copied in order */
1073                         for(a=0, sock= link->fromnode->outputs.first; sock; sock= sock->next, a++) {
1074                                 if(sock==link->fromsock)
1075                                         break;
1076                         }
1077                         nlink->fromsock= BLI_findlink(&link->fromnode->new_node->outputs, a);
1078                         
1079                         for(a=0, sock= link->tonode->inputs.first; sock; sock= sock->next, a++) {
1080                                 if(sock==link->tosock)
1081                                         break;
1082                         }
1083                         nlink->tosock= BLI_findlink(&link->tonode->new_node->inputs, a);
1084                 }
1085         }
1086         
1087         /* own type definition for group usage */
1088         if(internal_select==0) {
1089                 if(ntree->owntype) {
1090                         newtree->owntype= MEM_dupallocN(ntree->owntype);
1091                         if(ntree->owntype->inputs)
1092                                 newtree->owntype->inputs= MEM_dupallocN(ntree->owntype->inputs);
1093                         if(ntree->owntype->outputs)
1094                                 newtree->owntype->outputs= MEM_dupallocN(ntree->owntype->outputs);
1095                 }
1096         }
1097         /* weird this is required... there seem to be link pointers wrong still? */
1098         /* anyhoo, doing this solves crashes on copying entire tree (copy scene) and delete nodes */
1099         ntreeSolveOrder(newtree);
1100
1101         return newtree;
1102 }
1103
1104 /* ************** Free stuff ********** */
1105
1106 /* goes over entire tree */
1107 void nodeUnlinkNode(bNodeTree *ntree, bNode *node)
1108 {
1109         bNodeLink *link, *next;
1110         bNodeSocket *sock;
1111         ListBase *lb;
1112         
1113         for(link= ntree->links.first; link; link= next) {
1114                 next= link->next;
1115                 
1116                 if(link->fromnode==node) {
1117                         lb= &node->outputs;
1118                         NodeTagChanged(ntree, link->tonode);
1119                 }
1120                 else if(link->tonode==node)
1121                         lb= &node->inputs;
1122                 else
1123                         lb= NULL;
1124
1125                 if(lb) {
1126                         for(sock= lb->first; sock; sock= sock->next) {
1127                                 if(link->fromsock==sock || link->tosock==sock)
1128                                         break;
1129                         }
1130                         if(sock) {
1131                                 nodeRemLink(ntree, link);
1132                         }
1133                 }
1134         }
1135 }
1136
1137 static void composit_free_node_cache(bNode *node)
1138 {
1139         bNodeSocket *sock;
1140         
1141         for(sock= node->outputs.first; sock; sock= sock->next) {
1142                 if(sock->ns.data) {
1143                         free_compbuf(sock->ns.data);
1144                         sock->ns.data= NULL;
1145                 }
1146         }
1147 }
1148
1149 void nodeFreeNode(bNodeTree *ntree, bNode *node)
1150 {
1151         nodeUnlinkNode(ntree, node);
1152         BLI_remlink(&ntree->nodes, node);
1153
1154         /* since it is called while free database, node->id is undefined */
1155         
1156         if(ntree->type==NTREE_COMPOSIT)
1157                 composit_free_node_cache(node);
1158         BLI_freelistN(&node->inputs);
1159         BLI_freelistN(&node->outputs);
1160         
1161         if(node->preview) {
1162                 if(node->preview->rect)
1163                         MEM_freeN(node->preview->rect);
1164                 MEM_freeN(node->preview);
1165         }
1166         if(node->typeinfo && node->typeinfo->freestoragefunc) {
1167                 node->typeinfo->freestoragefunc(node);
1168         }
1169
1170         MEM_freeN(node);
1171 }
1172
1173 /* do not free ntree itself here, free_libblock calls this function too */
1174 void ntreeFreeTree(bNodeTree *ntree)
1175 {
1176         bNode *node, *next;
1177         
1178         if(ntree==NULL) return;
1179         
1180         ntreeEndExecTree(ntree);        /* checks for if it is still initialized */
1181         
1182         BLI_freelistN(&ntree->links);   /* do first, then unlink_node goes fast */
1183         
1184         for(node= ntree->nodes.first; node; node= next) {
1185                 next= node->next;
1186                 nodeFreeNode(ntree, node);
1187         }
1188         
1189         if(ntree->owntype) {
1190                 if(ntree->owntype->inputs)
1191                         MEM_freeN(ntree->owntype->inputs);
1192                 if(ntree->owntype->outputs)
1193                         MEM_freeN(ntree->owntype->outputs);
1194                 MEM_freeN(ntree->owntype);
1195         }
1196 }
1197
1198 void ntreeFreeCache(bNodeTree *ntree)
1199 {
1200         bNode *node;
1201         
1202         if(ntree==NULL) return;
1203
1204         if(ntree->type==NTREE_COMPOSIT)
1205                 for(node= ntree->nodes.first; node; node= node->next)
1206                         composit_free_node_cache(node);
1207
1208 }
1209
1210 void ntreeMakeLocal(bNodeTree *ntree)
1211 {
1212         int local=0, lib=0;
1213         
1214         /* - only lib users: do nothing
1215             * - only local users: set flag
1216             * - mixed: make copy
1217             */
1218         
1219         if(ntree->id.lib==NULL) return;
1220         if(ntree->id.us==1) {
1221                 ntree->id.lib= 0;
1222                 ntree->id.flag= LIB_LOCAL;
1223                 new_id(0, (ID *)ntree, 0);
1224                 return;
1225         }
1226         
1227         /* now check users of groups... again typedepending, callback... */
1228         if(ntree->type==NTREE_SHADER) {
1229                 Material *ma;
1230                 for(ma= G.main->mat.first; ma; ma= ma->id.next) {
1231                         if(ma->nodetree) {
1232                                 bNode *node;
1233                                 
1234                                 /* find if group is in tree */
1235                                 for(node= ma->nodetree->nodes.first; node; node= node->next) {
1236                                         if(node->id == (ID *)ntree) {
1237                                                 if(ma->id.lib) lib= 1;
1238                                                 else local= 1;
1239                                         }
1240                                 }
1241                         }
1242                 }
1243         }
1244         else if(ntree->type==NTREE_COMPOSIT) {
1245                 Scene *sce;
1246                 for(sce= G.main->scene.first; sce; sce= sce->id.next) {
1247                         if(sce->nodetree) {
1248                                 bNode *node;
1249                                 
1250                                 /* find if group is in tree */
1251                                 for(node= sce->nodetree->nodes.first; node; node= node->next) {
1252                                         if(node->id == (ID *)ntree) {
1253                                                 if(sce->id.lib) lib= 1;
1254                                                 else local= 1;
1255                                         }
1256                                 }
1257                         }
1258                 }
1259         }
1260         
1261         /* if all users are local, we simply make tree local */
1262         if(local && lib==0) {
1263                 ntree->id.lib= NULL;
1264                 ntree->id.flag= LIB_LOCAL;
1265                 new_id(0, (ID *)ntree, 0);
1266         }
1267         else if(local && lib) {
1268                 /* this is the mixed case, we copy the tree and assign it to local users */
1269                 bNodeTree *newtree= ntreeCopyTree(ntree, 0);
1270                 
1271                 newtree->id.us= 0;
1272                 
1273                 if(ntree->type==NTREE_SHADER) {
1274                         Material *ma;
1275                         for(ma= G.main->mat.first; ma; ma= ma->id.next) {
1276                                 if(ma->nodetree) {
1277                                         bNode *node;
1278                                         
1279                                         /* find if group is in tree */
1280                                         for(node= ma->nodetree->nodes.first; node; node= node->next) {
1281                                                 if(node->id == (ID *)ntree) {
1282                                                         if(ma->id.lib==NULL) {
1283                                                                 node->id= &newtree->id;
1284                                                                 newtree->id.us++;
1285                                                                 ntree->id.us--;
1286                                                         }
1287                                                 }
1288                                         }
1289                                 }
1290                         }
1291                 }
1292                 else if(ntree->type==NTREE_COMPOSIT) {
1293                         Scene *sce;
1294                         for(sce= G.main->scene.first; sce; sce= sce->id.next) {
1295                                 if(sce->nodetree) {
1296                                         bNode *node;
1297                                         
1298                                         /* find if group is in tree */
1299                                         for(node= sce->nodetree->nodes.first; node; node= node->next) {
1300                                                 if(node->id == (ID *)ntree) {
1301                                                         if(sce->id.lib==NULL) {
1302                                                                 node->id= &newtree->id;
1303                                                                 newtree->id.us++;
1304                                                                 ntree->id.us--;
1305                                                         }
1306                                                 }
1307                                         }
1308                                 }
1309                         }
1310                 }
1311         }
1312 }
1313
1314
1315 /* ************ find stuff *************** */
1316
1317 static int ntreeHasType(bNodeTree *ntree, int type)
1318 {
1319         bNode *node;
1320         
1321         if(ntree)
1322                 for(node= ntree->nodes.first; node; node= node->next)
1323                         if(node->type == type)
1324                                 return 1;
1325         return 0;
1326 }
1327
1328 bNodeLink *nodeFindLink(bNodeTree *ntree, bNodeSocket *from, bNodeSocket *to)
1329 {
1330         bNodeLink *link;
1331         
1332         for(link= ntree->links.first; link; link= link->next) {
1333                 if(link->fromsock==from && link->tosock==to)
1334                         return link;
1335                 if(link->fromsock==to && link->tosock==from)    /* hrms? */
1336                         return link;
1337         }
1338         return NULL;
1339 }
1340
1341 int nodeCountSocketLinks(bNodeTree *ntree, bNodeSocket *sock)
1342 {
1343         bNodeLink *link;
1344         int tot= 0;
1345         
1346         for(link= ntree->links.first; link; link= link->next) {
1347                 if(link->fromsock==sock || link->tosock==sock)
1348                         tot++;
1349         }
1350         return tot;
1351 }
1352
1353 bNode *nodeGetActive(bNodeTree *ntree)
1354 {
1355         bNode *node;
1356         
1357         if(ntree==NULL) return NULL;
1358         
1359         for(node= ntree->nodes.first; node; node= node->next)
1360                 if(node->flag & NODE_ACTIVE)
1361                         break;
1362         return node;
1363 }
1364
1365 /* two active flags, ID nodes have special flag for buttons display */
1366 bNode *nodeGetActiveID(bNodeTree *ntree, short idtype)
1367 {
1368         bNode *node;
1369         
1370         if(ntree==NULL) return NULL;
1371
1372         /* check for group edit */
1373     for(node= ntree->nodes.first; node; node= node->next)
1374                 if(node->flag & NODE_GROUP_EDIT)
1375                         break;
1376
1377         if(node)
1378                 ntree= (bNodeTree*)node->id;
1379         
1380         /* now find active node with this id */
1381         for(node= ntree->nodes.first; node; node= node->next)
1382                 if(node->id && GS(node->id->name)==idtype)
1383                         if(node->flag & NODE_ACTIVE_ID)
1384                                 break;
1385
1386         return node;
1387 }
1388
1389 /* two active flags, ID nodes have special flag for buttons display */
1390 void nodeClearActiveID(bNodeTree *ntree, short idtype)
1391 {
1392         bNode *node;
1393         
1394         if(ntree==NULL) return;
1395         
1396         for(node= ntree->nodes.first; node; node= node->next)
1397                 if(node->id && GS(node->id->name)==idtype)
1398                         node->flag &= ~NODE_ACTIVE_ID;
1399 }
1400
1401 /* two active flags, ID nodes have special flag for buttons display */
1402 void nodeSetActive(bNodeTree *ntree, bNode *node)
1403 {
1404         bNode *tnode;
1405         
1406         /* make sure only one node is active, and only one per ID type */
1407         for(tnode= ntree->nodes.first; tnode; tnode= tnode->next) {
1408                 tnode->flag &= ~NODE_ACTIVE;
1409                 
1410                 if(node->id && tnode->id) {
1411                         if(GS(node->id->name) == GS(tnode->id->name))
1412                                 tnode->flag &= ~NODE_ACTIVE_ID;
1413                 }
1414         }
1415         
1416         node->flag |= NODE_ACTIVE;
1417         if(node->id)
1418                 node->flag |= NODE_ACTIVE_ID;
1419 }
1420
1421 /* use flags are not persistant yet, groups might need different tagging, so we do it each time
1422    when we need to get this info */
1423 void ntreeSocketUseFlags(bNodeTree *ntree)
1424 {
1425         bNode *node;
1426         bNodeSocket *sock;
1427         bNodeLink *link;
1428         
1429         /* clear flags */
1430         for(node= ntree->nodes.first; node; node= node->next) {
1431                 for(sock= node->inputs.first; sock; sock= sock->next)
1432                         sock->flag &= ~SOCK_IN_USE;
1433                 for(sock= node->outputs.first; sock; sock= sock->next)
1434                         sock->flag &= ~SOCK_IN_USE;
1435         }
1436         
1437         /* tag all thats in use */
1438         for(link= ntree->links.first; link; link= link->next) {
1439                 link->fromsock->flag |= SOCK_IN_USE;
1440                 link->tosock->flag |= SOCK_IN_USE;
1441         }
1442 }
1443
1444 /* ************** dependency stuff *********** */
1445
1446 /* node is guaranteed to be not checked before */
1447 static int node_recurs_check(bNode *node, bNode ***nsort, int level)
1448 {
1449         bNode *fromnode;
1450         bNodeSocket *sock;
1451         int has_inputlinks= 0;
1452         
1453         node->done= 1;
1454         level++;
1455         
1456         for(sock= node->inputs.first; sock; sock= sock->next) {
1457                 if(sock->link) {
1458                         has_inputlinks= 1;
1459                         fromnode= sock->link->fromnode;
1460                         if(fromnode->done==0) {
1461                                 fromnode->level= node_recurs_check(fromnode, nsort, level);
1462                         }
1463                 }
1464         }
1465 //      printf("node sort %s level %d\n", node->name, level);
1466         **nsort= node;
1467         (*nsort)++;
1468         
1469         if(has_inputlinks)
1470                 return level;
1471         else 
1472                 return 0xFFF;
1473 }
1474
1475 void ntreeSolveOrder(bNodeTree *ntree)
1476 {
1477         bNode *node, **nodesort, **nsort;
1478         bNodeSocket *sock;
1479         bNodeLink *link;
1480         int a, totnode=0;
1481         
1482         /* the solve-order is called on each tree change, so we should be sure no exec can be running */
1483         ntreeEndExecTree(ntree);
1484
1485         /* set links pointers the input sockets, to find dependencies */
1486         /* first clear data */
1487         for(node= ntree->nodes.first; node; node= node->next) {
1488                 node->done= 0;
1489                 totnode++;
1490                 for(sock= node->inputs.first; sock; sock= sock->next)
1491                         sock->link= NULL;
1492         }
1493         if(totnode==0)
1494                 return;
1495         
1496         for(link= ntree->links.first; link; link= link->next) {
1497                 link->tosock->link= link;
1498         }
1499         
1500         nsort= nodesort= MEM_callocN(totnode*sizeof(void *), "sorted node array");
1501         
1502         /* recursive check */
1503         for(node= ntree->nodes.first; node; node= node->next) {
1504                 if(node->done==0) {
1505                         node->level= node_recurs_check(node, &nsort, 0);
1506                 }
1507         }
1508         
1509         /* re-insert nodes in order, first a paranoia check */
1510         for(a=0; a<totnode; a++) {
1511                 if(nodesort[a]==NULL)
1512                         break;
1513         }
1514         if(a<totnode)
1515                 printf("sort error in node tree");
1516         else {
1517                 ntree->nodes.first= ntree->nodes.last= NULL;
1518                 for(a=0; a<totnode; a++)
1519                         BLI_addtail(&ntree->nodes, nodesort[a]);
1520         }
1521         
1522         MEM_freeN(nodesort);
1523         
1524         /* find the active outputs, might become tree type dependant handler */
1525         for(node= ntree->nodes.first; node; node= node->next) {
1526                 if(node->typeinfo->nclass==NODE_CLASS_OUTPUT) {
1527                         bNode *tnode;
1528                         int output= 0;
1529                         
1530                         /* we need a check for which output node should be tagged like this, below an exception */
1531                         if(node->type==CMP_NODE_OUTPUT_FILE)
1532                            continue;
1533                            
1534                         /* there is more types having output class, each one is checked */
1535                         for(tnode= ntree->nodes.first; tnode; tnode= tnode->next) {
1536                                 if(tnode->typeinfo->nclass==NODE_CLASS_OUTPUT) {
1537                                         if(tnode->type==node->type) {
1538                                                 if(tnode->flag & NODE_DO_OUTPUT) {
1539                                                         output++;
1540                                                         if(output>1)
1541                                                                 tnode->flag &= ~NODE_DO_OUTPUT;
1542                                                 }
1543                                         }
1544                                 }
1545                         }
1546                         if(output==0)
1547                                 node->flag |= NODE_DO_OUTPUT;
1548                 }
1549         }
1550         
1551         /* here we could recursively set which nodes have to be done,
1552                 might be different for editor or for "real" use... */
1553 }
1554
1555 /* should be callback! */
1556 void NodeTagChanged(bNodeTree *ntree, bNode *node)
1557 {
1558         if(ntree->type==NTREE_COMPOSIT) {
1559                 bNodeSocket *sock;
1560
1561                 for(sock= node->outputs.first; sock; sock= sock->next) {
1562                         if(sock->ns.data) {
1563                                 free_compbuf(sock->ns.data);
1564                                 sock->ns.data= NULL;
1565                                 
1566                                 //if(node->preview && node->preview->rect) {
1567                                 //      MEM_freeN(node->preview->rect);
1568                                 //      node->preview->rect= NULL;
1569                                 //}
1570                                         
1571                         }
1572                 }
1573                 node->need_exec= 1;
1574         }
1575 }
1576
1577 void NodeTagIDChanged(bNodeTree *ntree, ID *id)
1578 {
1579         if(id==NULL)
1580                 return;
1581         
1582         if(ntree->type==NTREE_COMPOSIT) {
1583                 bNode *node;
1584                 
1585                 for(node= ntree->nodes.first; node; node= node->next)
1586                         if(node->id==id)
1587                                 NodeTagChanged(ntree, node);
1588         }
1589 }
1590
1591
1592 /* *************** preview *********** */
1593
1594 /* if node->preview, then we assume the rect to exist */
1595
1596 static void nodeInitPreview(bNode *node, int xsize, int ysize)
1597 {
1598         
1599         if(node->preview==NULL) {
1600                 node->preview= MEM_callocN(sizeof(bNodePreview), "node preview");
1601 //              printf("added preview %s\n", node->name);
1602         }
1603         
1604         /* node previews can get added with variable size this way */
1605         if(xsize==0 || ysize==0)
1606                 return;
1607         
1608         /* sanity checks & initialize */
1609         if(node->preview->rect) {
1610                 if(node->preview->xsize!=xsize && node->preview->ysize!=ysize) {
1611                         MEM_freeN(node->preview->rect);
1612                         node->preview->rect= NULL;
1613                 }
1614         }
1615         
1616         if(node->preview->rect==NULL) {
1617                 node->preview->rect= MEM_callocN(4*xsize + xsize*ysize*sizeof(float)*4, "node preview rect");
1618                 node->preview->xsize= xsize;
1619                 node->preview->ysize= ysize;
1620         }
1621 }
1622
1623 void ntreeInitPreview(bNodeTree *ntree, int xsize, int ysize)
1624 {
1625         bNode *node;
1626         
1627         if(ntree==NULL)
1628                 return;
1629         
1630         for(node= ntree->nodes.first; node; node= node->next) {
1631                 if(node->typeinfo->flag & NODE_PREVIEW) /* hrms, check for closed nodes? */
1632                         nodeInitPreview(node, xsize, ysize);
1633                 if(node->type==NODE_GROUP && (node->flag & NODE_GROUP_EDIT))
1634                         ntreeInitPreview((bNodeTree *)node->id, xsize, ysize);
1635         }               
1636 }
1637
1638 static void nodeClearPreview(bNode *node)
1639 {
1640         if(node->preview && node->preview->rect)
1641                 memset(node->preview->rect, 0, MEM_allocN_len(node->preview->rect));
1642 }
1643
1644 /* use it to enforce clear */
1645 void ntreeClearPreview(bNodeTree *ntree)
1646 {
1647         bNode *node;
1648         
1649         if(ntree==NULL)
1650                 return;
1651         
1652         for(node= ntree->nodes.first; node; node= node->next) {
1653                 if(node->typeinfo->flag & NODE_PREVIEW)
1654                         nodeClearPreview(node);
1655                 if(node->type==NODE_GROUP && (node->flag & NODE_GROUP_EDIT))
1656                         ntreeClearPreview((bNodeTree *)node->id);
1657         }               
1658 }
1659
1660 /* hack warning! this function is only used for shader previews, and 
1661    since it gets called multiple times per pixel for Ztransp we only
1662    add the color once. Preview gets cleared before it starts render though */
1663 void nodeAddToPreview(bNode *node, float *col, int x, int y)
1664 {
1665         bNodePreview *preview= node->preview;
1666         if(preview) {
1667                 if(x>=0 && y>=0) {
1668                         if(x<preview->xsize && y<preview->ysize) {
1669                                 float *tar= preview->rect+ 4*((preview->xsize*y) + x);
1670                                 if(tar[0]==0.0f) {
1671                                         QUATCOPY(tar, col);
1672                                 }
1673                         }
1674                         //else printf("prv out bound x y %d %d\n", x, y);
1675                 }
1676                 //else printf("prv out bound x y %d %d\n", x, y);
1677         }
1678 }
1679
1680
1681
1682 /* ******************* executing ************* */
1683
1684 /* see notes at ntreeBeginExecTree */
1685 static void group_node_get_stack(bNode *node, bNodeStack *stack, bNodeStack **in, bNodeStack **out, bNodeStack **gin, bNodeStack **gout)
1686 {
1687         bNodeSocket *sock;
1688         
1689         /* build pointer stack */
1690         for(sock= node->inputs.first; sock; sock= sock->next) {
1691                 if(sock->intern) {
1692                         /* yep, intern can have link or is hidden socket */
1693                         if(sock->link)
1694                                 *(in++)= stack + sock->link->fromsock->stack_index;
1695                         else
1696                                 *(in++)= &sock->ns;
1697                 }
1698                 else
1699                         *(in++)= gin[sock->stack_index_ext];
1700         }
1701         
1702         for(sock= node->outputs.first; sock; sock= sock->next) {
1703                 if(sock->intern)
1704                         *(out++)= stack + sock->stack_index;
1705                 else
1706                         *(out++)= gout[sock->stack_index_ext];
1707         }
1708 }
1709
1710 static void node_group_execute(bNodeStack *stack, void *data, bNode *gnode, bNodeStack **in, bNodeStack **out)
1711 {
1712         bNode *node;
1713         bNodeTree *ntree= (bNodeTree *)gnode->id;
1714         bNodeStack *nsin[MAX_SOCKET];   /* arbitrary... watch this */
1715         bNodeStack *nsout[MAX_SOCKET];  /* arbitrary... watch this */
1716         
1717         if(ntree==NULL) return;
1718         
1719         stack+= gnode->stack_index;
1720                 
1721         for(node= ntree->nodes.first; node; node= node->next) {
1722                 if(node->typeinfo->execfunc) {
1723                         group_node_get_stack(node, stack, nsin, nsout, in, out);
1724                         
1725                         /* for groups, only execute outputs for edited group */
1726                         if(node->typeinfo->nclass==NODE_CLASS_OUTPUT) {
1727                                 if(gnode->flag & NODE_GROUP_EDIT)
1728                                         if(node->flag & NODE_DO_OUTPUT)
1729                                                 node->typeinfo->execfunc(data, node, nsin, nsout);
1730                         }
1731                         else
1732                                 node->typeinfo->execfunc(data, node, nsin, nsout);
1733                 }
1734         }
1735         
1736         /* free internal group output nodes */
1737         if(ntree->type==NTREE_COMPOSIT) {
1738                 for(node= ntree->nodes.first; node; node= node->next) {
1739                         if(node->typeinfo->execfunc) {
1740                                 bNodeSocket *sock;
1741                                 
1742                                 for(sock= node->outputs.first; sock; sock= sock->next) {
1743                                         if(sock->intern) {
1744                                                 bNodeStack *ns= stack + sock->stack_index;
1745                                                 if(ns->data) {
1746                                                         free_compbuf(ns->data);
1747                                                         ns->data= NULL;
1748                                                 }
1749                                         }
1750                                 }
1751                         }
1752                 }
1753         }
1754 }
1755
1756 /* recursively called for groups */
1757 /* we set all trees on own local indices, but put a total counter
1758    in the groups, so each instance of a group has own stack */
1759 static int ntree_begin_exec_tree(bNodeTree *ntree)
1760 {
1761         bNode *node;
1762         bNodeSocket *sock;
1763         int index= 0, index_in= 0, index_out= 0;
1764         
1765         if((ntree->init & NTREE_TYPE_INIT)==0)
1766                 ntreeInitTypes(ntree);
1767         
1768         /* create indices for stack, check preview */
1769         for(node= ntree->nodes.first; node; node= node->next) {
1770                 
1771                 for(sock= node->inputs.first; sock; sock= sock->next) {
1772                         if(sock->intern==0)
1773                                 sock->stack_index_ext= index_in++;
1774                 }
1775                 
1776                 for(sock= node->outputs.first; sock; sock= sock->next) {
1777                         sock->stack_index= index++;
1778                         if(sock->intern==0)
1779                                 sock->stack_index_ext= index_out++;
1780                 }
1781                 
1782                 if(node->type==NODE_GROUP) {
1783                         if(node->id) {
1784                                 node->stack_index= index;
1785                                 index+= ntree_begin_exec_tree((bNodeTree *)node->id);
1786                         }
1787                 }
1788         }
1789         
1790         return index;
1791 }
1792
1793 /* copy socket compbufs to stack, initialize usage of curve nodes */
1794 static void composit_begin_exec(bNodeTree *ntree, int is_group)
1795 {
1796         bNode *node;
1797         bNodeSocket *sock;
1798         
1799         for(node= ntree->nodes.first; node; node= node->next) {
1800                 
1801                 /* initialize needed for groups */
1802                 node->exec= 0;  
1803                 
1804                 if(is_group==0) {
1805                         for(sock= node->outputs.first; sock; sock= sock->next) {
1806                                 bNodeStack *ns= ntree->stack + sock->stack_index;
1807                                 
1808                                 if(sock->ns.data) {
1809                                         ns->data= sock->ns.data;
1810                                         sock->ns.data= NULL;
1811                                 }
1812                         }
1813                 }               
1814                 /* cannot initialize them while using in threads */
1815                 if(ELEM3(node->type, CMP_NODE_TIME, CMP_NODE_CURVE_VEC, CMP_NODE_CURVE_RGB)) {
1816                         curvemapping_initialize(node->storage);
1817                         if(node->type==CMP_NODE_CURVE_RGB)
1818                                 curvemapping_premultiply(node->storage, 0);
1819                 }
1820                 if(node->type==NODE_GROUP)
1821                         composit_begin_exec((bNodeTree *)node->id, 1);
1822
1823         }
1824 }
1825
1826 /* copy stack compbufs to sockets */
1827 static void composit_end_exec(bNodeTree *ntree, int is_group)
1828 {
1829         extern void print_compbuf(char *str, struct CompBuf *cbuf);
1830         bNode *node;
1831         bNodeStack *ns;
1832         int a;
1833
1834         for(node= ntree->nodes.first; node; node= node->next) {
1835                 if(is_group==0) {
1836                         bNodeSocket *sock;
1837                 
1838                         for(sock= node->outputs.first; sock; sock= sock->next) {
1839                                 ns= ntree->stack + sock->stack_index;
1840                                 if(ns->data) {
1841                                         sock->ns.data= ns->data;
1842                                         ns->data= NULL;
1843                                 }
1844                         }
1845                 }
1846                 if(node->type==CMP_NODE_CURVE_RGB)
1847                         curvemapping_premultiply(node->storage, 1);
1848                 
1849                 if(node->type==NODE_GROUP)
1850                         composit_end_exec((bNodeTree *)node->id, 1);
1851
1852                 node->need_exec= 0;
1853         }
1854         
1855         if(is_group==0) {
1856                 /* internally, group buffers are not stored */
1857                 for(ns= ntree->stack, a=0; a<ntree->stacksize; a++, ns++) {
1858                         if(ns->data) {
1859                                 printf("freed leftover buffer from stack\n");
1860                                 free_compbuf(ns->data);
1861                         }
1862                 }
1863         }
1864 }
1865
1866 static void group_tag_used_outputs(bNode *gnode, bNodeStack *stack)
1867 {
1868         bNodeTree *ntree= (bNodeTree *)gnode->id;
1869         bNode *node;
1870         
1871         stack+= gnode->stack_index;
1872         
1873         for(node= ntree->nodes.first; node; node= node->next) {
1874                 if(node->typeinfo->execfunc) {
1875                         bNodeSocket *sock;
1876                         
1877                         for(sock= node->inputs.first; sock; sock= sock->next) {
1878                                 if(sock->intern) {
1879                                         if(sock->link) {
1880                                                 bNodeStack *ns= stack + sock->link->fromsock->stack_index;
1881                                                 ns->hasoutput= 1;
1882                                                 ns->sockettype= sock->link->fromsock->type;
1883                                         }
1884                                         else
1885                                                 sock->ns.sockettype= sock->type;
1886                                 }
1887                         }
1888                 }
1889         }
1890 }
1891
1892 /* stack indices make sure all nodes only write in allocated data, for making it thread safe */
1893 /* only root tree gets the stack, to enable instances to have own stack entries */
1894 /* only two threads now! */
1895 /* per tree (and per group) unique indices are created */
1896 /* the index_ext we need to be able to map from groups to the group-node own stack */
1897
1898 typedef struct bNodeThreadStack {
1899         struct bNodeThreadStack *next, *prev;
1900         bNodeStack *stack;
1901         int used;
1902 } bNodeThreadStack;
1903
1904 static bNodeThreadStack *ntreeGetThreadStack(bNodeTree *ntree, int thread)
1905 {
1906         ListBase *lb= &ntree->threadstack[thread];
1907         bNodeThreadStack *nts;
1908
1909         for(nts=lb->first; nts; nts=nts->next) {
1910                 if(!nts->used) {
1911                         nts->used= 1;
1912                         return nts;
1913                 }
1914         }
1915         
1916         nts= MEM_callocN(sizeof(bNodeThreadStack), "bNodeThreadStack");
1917         nts->stack= MEM_dupallocN(ntree->stack);
1918         nts->used= 1;
1919         BLI_addtail(lb, nts);
1920
1921         return nts;
1922 }
1923
1924 static void ntreeReleaseThreadStack(bNodeThreadStack *nts)
1925 {
1926         nts->used= 0;
1927 }
1928
1929 void ntreeBeginExecTree(bNodeTree *ntree)
1930 {
1931         /* let's make it sure */
1932         if(ntree->init & NTREE_EXEC_INIT)
1933                 return;
1934
1935         /* allocate the thread stack listbase array */
1936         if(ntree->type!=NTREE_COMPOSIT)
1937                 ntree->threadstack= MEM_callocN(BLENDER_MAX_THREADS*sizeof(ListBase), "thread stack array");
1938
1939         /* goes recursive over all groups */
1940         ntree->stacksize= ntree_begin_exec_tree(ntree);
1941
1942         if(ntree->stacksize) {
1943                 bNode *node;
1944                 bNodeStack *ns;
1945                 int a;
1946                 
1947                 /* allocate the base stack */
1948                 ns=ntree->stack= MEM_callocN(ntree->stacksize*sizeof(bNodeStack), "node stack");
1949                 
1950                 /* tag inputs, the get_stack() gives own socket stackdata if not in use */
1951                 for(a=0; a<ntree->stacksize; a++, ns++) ns->hasinput= 1;
1952                 
1953                 /* tag used outputs, so we know when we can skip operations */
1954                 for(node= ntree->nodes.first; node; node= node->next) {
1955                         bNodeSocket *sock;
1956                         for(sock= node->inputs.first; sock; sock= sock->next) {
1957                                 if(sock->link) {
1958                                         ns= ntree->stack + sock->link->fromsock->stack_index;
1959                                         ns->hasoutput= 1;
1960                                         ns->sockettype= sock->link->fromsock->type;
1961                                 }
1962                                 else
1963                                         sock->ns.sockettype= sock->type;
1964                         }
1965                         if(node->type==NODE_GROUP && node->id)
1966                                 group_tag_used_outputs(node, ntree->stack);
1967                 }
1968                 
1969                 if(ntree->type==NTREE_COMPOSIT)
1970                         composit_begin_exec(ntree, 0);
1971         }
1972         
1973         ntree->init |= NTREE_EXEC_INIT;
1974 }
1975
1976 void ntreeEndExecTree(bNodeTree *ntree)
1977 {
1978         
1979         if(ntree->init & NTREE_EXEC_INIT) {
1980                 bNodeThreadStack *nts;
1981                 int a;
1982                 
1983                 /* another callback candidate! */
1984                 if(ntree->type==NTREE_COMPOSIT)
1985                         composit_end_exec(ntree, 0);
1986                 
1987                 if(ntree->stack) {
1988                         MEM_freeN(ntree->stack);
1989                         ntree->stack= NULL;
1990                 }
1991
1992                 if(ntree->threadstack) {
1993                         for(a=0; a<BLENDER_MAX_THREADS; a++) {
1994                                 for(nts=ntree->threadstack[a].first; nts; nts=nts->next)
1995                                         if (nts->stack) MEM_freeN(nts->stack);
1996                                 BLI_freelistN(&ntree->threadstack[a]);
1997                         }
1998
1999                         MEM_freeN(ntree->threadstack);
2000                         ntree->threadstack= NULL;
2001                 }
2002
2003                 ntree->init &= ~NTREE_EXEC_INIT;
2004         }
2005 }
2006
2007 static void node_get_stack(bNode *node, bNodeStack *stack, bNodeStack **in, bNodeStack **out)
2008 {
2009         bNodeSocket *sock;
2010         
2011         /* build pointer stack */
2012         for(sock= node->inputs.first; sock; sock= sock->next) {
2013                 if(sock->link)
2014                         *(in++)= stack + sock->link->fromsock->stack_index;
2015                 else
2016                         *(in++)= &sock->ns;
2017         }
2018         
2019         for(sock= node->outputs.first; sock; sock= sock->next) {
2020                 *(out++)= stack + sock->stack_index;
2021         }
2022 }
2023
2024 /* nodes are presorted, so exec is in order of list */
2025 void ntreeExecTree(bNodeTree *ntree, void *callerdata, int thread)
2026 {
2027         bNode *node;
2028         bNodeStack *nsin[MAX_SOCKET];   /* arbitrary... watch this */
2029         bNodeStack *nsout[MAX_SOCKET];  /* arbitrary... watch this */
2030         bNodeStack *stack;
2031         bNodeThreadStack *nts = NULL;
2032         
2033         /* only when initialized */
2034         if((ntree->init & NTREE_EXEC_INIT)==0)
2035                 ntreeBeginExecTree(ntree);
2036                 
2037         /* composite does 1 node per thread, so no multiple stacks needed */
2038         if(ntree->type==NTREE_COMPOSIT) {
2039                 stack= ntree->stack;
2040         }
2041         else {
2042                 nts= ntreeGetThreadStack(ntree, thread);
2043                 stack= nts->stack;
2044         }
2045         
2046         for(node= ntree->nodes.first; node; node= node->next) {
2047                 if(node->typeinfo->execfunc) {
2048                         node_get_stack(node, stack, nsin, nsout);
2049                         node->typeinfo->execfunc(callerdata, node, nsin, nsout);
2050                 }
2051                 else if(node->type==NODE_GROUP && node->id) {
2052                         node_get_stack(node, stack, nsin, nsout);
2053                         node_group_execute(stack, callerdata, node, nsin, nsout); 
2054                 }
2055         }
2056
2057         if(nts)
2058                 ntreeReleaseThreadStack(nts);
2059 }
2060
2061
2062 /* ***************************** threaded version for execute composite nodes ************* */
2063 /* these are nodes without input, only giving values */
2064 /* or nodes with only value inputs */
2065 static int node_only_value(bNode *node)
2066 {
2067         bNodeSocket *sock;
2068         
2069         if(ELEM3(node->type, CMP_NODE_TIME, CMP_NODE_VALUE, CMP_NODE_RGB))
2070                 return 1;
2071         
2072         /* doing this for all node types goes wrong. memory free errors */
2073         if(node->inputs.first && node->type==CMP_NODE_MAP_VALUE) {
2074                 int retval= 1;
2075                 for(sock= node->inputs.first; sock; sock= sock->next) {
2076                         if(sock->link)
2077                                 retval &= node_only_value(sock->link->fromnode);
2078                 }
2079                 return retval;
2080         }
2081         return 0;
2082 }
2083
2084
2085 /* not changing info, for thread callback */
2086 typedef struct ThreadData {
2087         bNodeStack *stack;
2088         RenderData *rd;
2089 } ThreadData;
2090
2091 static void *exec_composite_node(void *node_v)
2092 {
2093         bNodeStack *nsin[MAX_SOCKET];   /* arbitrary... watch this */
2094         bNodeStack *nsout[MAX_SOCKET];  /* arbitrary... watch this */
2095         bNode *node= node_v;
2096         ThreadData *thd= (ThreadData *)node->new_node; /* abuse */
2097         
2098         node_get_stack(node, thd->stack, nsin, nsout);
2099         
2100         if((node->flag & NODE_MUTED) && (!node_only_value(node))) {
2101                 /* viewers we execute, for feedback to user */
2102                 if(ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) 
2103                         node->typeinfo->execfunc(thd->rd, node, nsin, nsout);
2104                 else
2105                         node_compo_pass_on(node, nsin, nsout);
2106         }
2107         else if(node->typeinfo->execfunc) {
2108                 node->typeinfo->execfunc(thd->rd, node, nsin, nsout);
2109         }
2110         else if(node->type==NODE_GROUP && node->id) {
2111                 node_group_execute(thd->stack, thd->rd, node, nsin, nsout); 
2112         }
2113         
2114         node->exec |= NODE_READY;
2115         return 0;
2116 }
2117
2118 /* return total of executable nodes, for timecursor */
2119 /* only compositor uses it */
2120 static int setExecutableNodes(bNodeTree *ntree, ThreadData *thd)
2121 {
2122         bNodeStack *nsin[MAX_SOCKET];   /* arbitrary... watch this */
2123         bNodeStack *nsout[MAX_SOCKET];  /* arbitrary... watch this */
2124         bNode *node;
2125         bNodeSocket *sock;
2126         int totnode= 0, group_edit= 0;
2127         
2128         /* note; do not add a dependency sort here, the stack was created already */
2129         
2130         /* if we are in group edit, viewer nodes get skipped when group has viewer */
2131         for(node= ntree->nodes.first; node; node= node->next)
2132                 if(node->type==NODE_GROUP && (node->flag & NODE_GROUP_EDIT))
2133                         if(ntreeHasType((bNodeTree *)node->id, CMP_NODE_VIEWER))
2134                                 group_edit= 1;
2135         
2136         for(node= ntree->nodes.first; node; node= node->next) {
2137                 int a;
2138                 
2139                 node_get_stack(node, thd->stack, nsin, nsout);
2140                 
2141                 /* test the outputs */
2142                 /* skip value-only nodes (should be in type!) */
2143                 if(!node_only_value(node)) {
2144                         for(a=0, sock= node->outputs.first; sock; sock= sock->next, a++) {
2145                                 if(nsout[a]->data==NULL && nsout[a]->hasoutput) {
2146                                         node->need_exec= 1;
2147                                         break;
2148                                 }
2149                         }
2150                 }
2151                 
2152                 /* test the inputs */
2153                 for(a=0, sock= node->inputs.first; sock; sock= sock->next, a++) {
2154                         /* skip viewer nodes in bg render or group edit */
2155                         if( ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER) && (G.background || group_edit))
2156                                 node->need_exec= 0;
2157                         /* is sock in use? */
2158                         else if(sock->link) {
2159                                 bNodeLink *link= sock->link;
2160                                 /* this is the test for a cyclic case */
2161                                 if(link->fromnode->level >= link->tonode->level && link->tonode->level!=0xFFF) {
2162                                         if(link->fromnode->need_exec) {
2163                                                 node->need_exec= 1;
2164                                                 break;
2165                                         }
2166                                 }
2167                                 else {
2168                                         node->need_exec= 0;
2169                                         printf("Node %s skipped, cyclic dependency\n", node->name);
2170                                 }
2171                         }
2172                 }
2173                 
2174                 if(node->need_exec) {
2175                         
2176                         /* free output buffers */
2177                         for(a=0, sock= node->outputs.first; sock; sock= sock->next, a++) {
2178                                 if(nsout[a]->data) {
2179                                         free_compbuf(nsout[a]->data);
2180                                         nsout[a]->data= NULL;
2181                                 }
2182                         }
2183                         totnode++;
2184                         /* printf("node needs exec %s\n", node->name); */
2185                         
2186                         /* tag for getExecutableNode() */
2187                         node->exec= 0;
2188                 }
2189                 else {
2190                         /* tag for getExecutableNode() */
2191                         node->exec= NODE_READY|NODE_FINISHED;
2192                         
2193                 }
2194         }
2195         
2196         /* last step: set the stack values for only-value nodes */
2197         /* just does all now, compared to a full buffer exec this is nothing */
2198         if(totnode) {
2199                 for(node= ntree->nodes.first; node; node= node->next) {
2200                         if(node->need_exec==0 && node_only_value(node)) {
2201                                 if(node->typeinfo->execfunc) {
2202                                         node_get_stack(node, thd->stack, nsin, nsout);
2203                                         node->typeinfo->execfunc(thd->rd, node, nsin, nsout);
2204                                 }
2205                         }
2206                 }
2207         }
2208         
2209         return totnode;
2210 }
2211
2212 /* while executing tree, free buffers from nodes that are not needed anymore */
2213 static void freeExecutableNode(bNodeTree *ntree)
2214 {
2215         /* node outputs can be freed when:
2216         - not a render result or image node
2217         - when node outputs go to nodes all being set NODE_FINISHED
2218         */
2219         bNode *node;
2220         bNodeSocket *sock;
2221         
2222         /* set exec flag for finished nodes that might need freed */
2223         for(node= ntree->nodes.first; node; node= node->next) {
2224                 if(node->type!=CMP_NODE_R_LAYERS)
2225                         if(node->exec & NODE_FINISHED)
2226                                 node->exec |= NODE_FREEBUFS;
2227         }
2228         /* clear this flag for input links that are not done yet */
2229         for(node= ntree->nodes.first; node; node= node->next) {
2230                 if((node->exec & NODE_FINISHED)==0) {
2231                         for(sock= node->inputs.first; sock; sock= sock->next)
2232                                 if(sock->link)
2233                                         sock->link->fromnode->exec &= ~NODE_FREEBUFS;
2234                 }
2235         }
2236         /* now we can free buffers */
2237         for(node= ntree->nodes.first; node; node= node->next) {
2238                 if(node->exec & NODE_FREEBUFS) {
2239                         for(sock= node->outputs.first; sock; sock= sock->next) {
2240                                 bNodeStack *ns= ntree->stack + sock->stack_index;
2241                                 if(ns->data) {
2242                                         free_compbuf(ns->data);
2243                                         ns->data= NULL;
2244                                         // printf("freed buf node %s \n", node->name);
2245                                 }
2246                         }
2247                 }
2248         }
2249 }
2250
2251 static bNode *getExecutableNode(bNodeTree *ntree)
2252 {
2253         bNode *node;
2254         bNodeSocket *sock;
2255         
2256         for(node= ntree->nodes.first; node; node= node->next) {
2257                 if(node->exec==0) {
2258                         
2259                         /* input sockets should be ready */
2260                         for(sock= node->inputs.first; sock; sock= sock->next) {
2261                                 if(sock->link)
2262                                         if((sock->link->fromnode->exec & NODE_READY)==0)
2263                                                 break;
2264                         }
2265                         if(sock==NULL)
2266                                 return node;
2267                 }
2268         }
2269         return NULL;
2270 }
2271
2272
2273 /* optimized tree execute test for compositing */
2274 void ntreeCompositExecTree(bNodeTree *ntree, RenderData *rd, int do_preview)
2275 {
2276         bNode *node;
2277         ListBase threads;
2278         ThreadData thdata;
2279         int totnode, rendering= 1;
2280         
2281         if(ntree==NULL) return;
2282         
2283         if(do_preview)
2284                 ntreeInitPreview(ntree, 0, 0);
2285         
2286         ntreeBeginExecTree(ntree);
2287         
2288         /* prevent unlucky accidents */
2289         if(G.background)
2290                 rd->scemode &= ~R_COMP_CROP;
2291         
2292         /* setup callerdata for thread callback */
2293         thdata.rd= rd;
2294         thdata.stack= ntree->stack;
2295         
2296         /* fixed seed, for example noise texture */
2297         BLI_srandom(rd->cfra);
2298
2299         /* sets need_exec tags in nodes */
2300         totnode= setExecutableNodes(ntree, &thdata);
2301         
2302         BLI_init_threads(&threads, exec_composite_node, rd->threads);
2303         
2304         while(rendering) {
2305                 
2306                 if(BLI_available_threads(&threads)) {
2307                         node= getExecutableNode(ntree);
2308                         if(node) {
2309
2310                                 if(ntree->timecursor)
2311                                         ntree->timecursor(totnode);
2312                                 if(ntree->stats_draw) {
2313                                         char str[64];
2314                                         sprintf(str, "Compositing %d %s", totnode, node->name);
2315                                         ntree->stats_draw(str);
2316                                 }
2317                                 totnode--;
2318                                 
2319                                 node->new_node = (bNode *)&thdata;
2320                                 node->exec= NODE_PROCESSING;
2321                                 BLI_insert_thread(&threads, node);
2322                         }
2323                         else
2324                                 PIL_sleep_ms(50);
2325                 }
2326                 else
2327                         PIL_sleep_ms(50);
2328                 
2329                 rendering= 0;
2330                 /* test for ESC */
2331                 if(ntree->test_break && ntree->test_break()) {
2332                         for(node= ntree->nodes.first; node; node= node->next)
2333                                 node->exec |= NODE_READY;
2334                 }
2335                 
2336                 /* check for ready ones, and if we need to continue */
2337                 for(node= ntree->nodes.first; node; node= node->next) {
2338                         if(node->exec & NODE_READY) {
2339                                 if((node->exec & NODE_FINISHED)==0) {
2340                                         BLI_remove_thread(&threads, node); /* this waits for running thread to finish btw */
2341                                         node->exec |= NODE_FINISHED;
2342                                         
2343                                         /* freeing unused buffers */
2344                                         if(rd->scemode & R_COMP_FREE)
2345                                                 freeExecutableNode(ntree);
2346                                 }
2347                         }
2348                         else rendering= 1;
2349                 }
2350         }
2351         
2352         
2353         BLI_end_threads(&threads);
2354         
2355         ntreeEndExecTree(ntree);
2356 }
2357
2358 /* GPU material from shader nodes */
2359
2360 static void gpu_from_node_stack(ListBase *sockets, bNodeStack **ns, GPUNodeStack *gs)
2361 {
2362         bNodeSocket *sock;
2363         int i;
2364
2365         for (sock=sockets->first, i=0; sock; sock=sock->next, i++) {
2366                 memset(&gs[i], 0, sizeof(gs[i]));
2367
2368         QUATCOPY(gs[i].vec, ns[i]->vec);
2369                 gs[i].link= ns[i]->data;
2370
2371                 if (sock->type == SOCK_VALUE)
2372                         gs[i].type= GPU_FLOAT;
2373                 else if (sock->type == SOCK_VECTOR)
2374                         gs[i].type= GPU_VEC3;
2375                 else if (sock->type == SOCK_RGBA)
2376                         gs[i].type= GPU_VEC4;
2377                 else
2378                         gs[i].type= GPU_NONE;
2379
2380                 gs[i].name = "";
2381                 gs[i].hasinput= ns[i]->hasinput;
2382                 gs[i].hasoutput= ns[i]->hasinput;
2383                 gs[i].sockettype= ns[i]->sockettype;
2384         }
2385
2386         gs[i].type= GPU_NONE;
2387 }
2388
2389 static void data_from_gpu_stack(ListBase *sockets, bNodeStack **ns, GPUNodeStack *gs)
2390 {
2391         bNodeSocket *sock;
2392         int i;
2393
2394         for (sock=sockets->first, i=0; sock; sock=sock->next, i++) {
2395                 ns[i]->data= gs[i].link;
2396                 ns[i]->hasinput= gs[i].hasinput;
2397                 ns[i]->hasoutput= gs[i].hasoutput;
2398                 ns[i]->sockettype= gs[i].sockettype;
2399         }
2400 }
2401
2402 static void gpu_node_group_execute(bNodeStack *stack, GPUMaterial *mat, bNode *gnode, bNodeStack **in, bNodeStack **out)
2403 {
2404         bNode *node;
2405         bNodeTree *ntree= (bNodeTree *)gnode->id;
2406         bNodeStack *nsin[MAX_SOCKET];   /* arbitrary... watch this */
2407         bNodeStack *nsout[MAX_SOCKET];  /* arbitrary... watch this */
2408         GPUNodeStack gpuin[MAX_SOCKET+1], gpuout[MAX_SOCKET+1];
2409         int doit = 0;
2410         
2411         if(ntree==NULL) return;
2412         
2413         stack+= gnode->stack_index;
2414                 
2415         for(node= ntree->nodes.first; node; node= node->next) {
2416                 if(node->typeinfo->gpufunc) {
2417                         group_node_get_stack(node, stack, nsin, nsout, in, out);
2418
2419                         doit = 0;
2420                         
2421                         /* for groups, only execute outputs for edited group */
2422                         if(node->typeinfo->nclass==NODE_CLASS_OUTPUT) {
2423                                 if(gnode->flag & NODE_GROUP_EDIT)
2424                                         if(node->flag & NODE_DO_OUTPUT)
2425                                                 doit = 1;
2426                         }
2427                         else
2428                                 doit = 1;
2429
2430                         if(doit)  {
2431                                 gpu_from_node_stack(&node->inputs, nsin, gpuin);
2432                                 gpu_from_node_stack(&node->outputs, nsout, gpuout);
2433                                 if(node->typeinfo->gpufunc(mat, node, gpuin, gpuout))
2434                                         data_from_gpu_stack(&node->outputs, nsout, gpuout);
2435                         }
2436                 }
2437         }
2438 }
2439
2440 void ntreeGPUMaterialNodes(bNodeTree *ntree, GPUMaterial *mat)
2441 {
2442         bNode *node;
2443         bNodeStack *stack;
2444         bNodeStack *nsin[MAX_SOCKET];   /* arbitrary... watch this */
2445         bNodeStack *nsout[MAX_SOCKET];  /* arbitrary... watch this */
2446         GPUNodeStack gpuin[MAX_SOCKET+1], gpuout[MAX_SOCKET+1];
2447
2448         if((ntree->init & NTREE_EXEC_INIT)==0)
2449                 ntreeBeginExecTree(ntree);
2450
2451         stack= ntree->stack;
2452
2453         for(node= ntree->nodes.first; node; node= node->next) {
2454                 if(node->typeinfo->gpufunc) {
2455                         node_get_stack(node, stack, nsin, nsout);
2456                         gpu_from_node_stack(&node->inputs, nsin, gpuin);
2457                         gpu_from_node_stack(&node->outputs, nsout, gpuout);
2458                         if(node->typeinfo->gpufunc(mat, node, gpuin, gpuout))
2459                                 data_from_gpu_stack(&node->outputs, nsout, gpuout);
2460                 }
2461         else if(node->type==NODE_GROUP && node->id) {
2462                         node_get_stack(node, stack, nsin, nsout);
2463                         gpu_node_group_execute(stack, mat, node, nsin, nsout);
2464                 }
2465         }
2466
2467         ntreeEndExecTree(ntree);
2468 }
2469
2470 /* **************** call to switch lamploop for material node ************ */
2471
2472 void (*node_shader_lamp_loop)(struct ShadeInput *, struct ShadeResult *);
2473
2474 void set_node_shader_lamp_loop(void (*lamp_loop_func)(ShadeInput *, ShadeResult *))
2475 {
2476         node_shader_lamp_loop= lamp_loop_func;
2477 }
2478
2479 /* clumsy checking... should do dynamic outputs once */
2480 static void force_hidden_passes(bNode *node, int passflag)
2481 {
2482         bNodeSocket *sock;
2483         
2484         for(sock= node->outputs.first; sock; sock= sock->next)
2485                 sock->flag &= ~SOCK_UNAVAIL;
2486         
2487         sock= BLI_findlink(&node->outputs, RRES_OUT_Z);
2488         if(!(passflag & SCE_PASS_Z)) sock->flag |= SOCK_UNAVAIL;
2489         sock= BLI_findlink(&node->outputs, RRES_OUT_NORMAL);
2490         if(!(passflag & SCE_PASS_NORMAL)) sock->flag |= SOCK_UNAVAIL;
2491         sock= BLI_findlink(&node->outputs, RRES_OUT_VEC);
2492         if(!(passflag & SCE_PASS_VECTOR)) sock->flag |= SOCK_UNAVAIL;
2493         sock= BLI_findlink(&node->outputs, RRES_OUT_UV);
2494         if(!(passflag & SCE_PASS_UV)) sock->flag |= SOCK_UNAVAIL;
2495         sock= BLI_findlink(&node->outputs, RRES_OUT_RGBA);
2496         if(!(passflag & SCE_PASS_RGBA)) sock->flag |= SOCK_UNAVAIL;
2497         sock= BLI_findlink(&node->outputs, RRES_OUT_DIFF);
2498         if(!(passflag & SCE_PASS_DIFFUSE)) sock->flag |= SOCK_UNAVAIL;
2499         sock= BLI_findlink(&node->outputs, RRES_OUT_SPEC);
2500         if(!(passflag & SCE_PASS_SPEC)) sock->flag |= SOCK_UNAVAIL;
2501         sock= BLI_findlink(&node->outputs, RRES_OUT_SHADOW);
2502         if(!(passflag & SCE_PASS_SHADOW)) sock->flag |= SOCK_UNAVAIL;
2503         sock= BLI_findlink(&node->outputs, RRES_OUT_AO);
2504         if(!(passflag & SCE_PASS_AO)) sock->flag |= SOCK_UNAVAIL;
2505         sock= BLI_findlink(&node->outputs, RRES_OUT_REFLECT);
2506         if(!(passflag & SCE_PASS_REFLECT)) sock->flag |= SOCK_UNAVAIL;
2507         sock= BLI_findlink(&node->outputs, RRES_OUT_REFRACT);
2508         if(!(passflag & SCE_PASS_REFRACT)) sock->flag |= SOCK_UNAVAIL;
2509         sock= BLI_findlink(&node->outputs, RRES_OUT_RADIO);
2510         if(!(passflag & SCE_PASS_RADIO)) sock->flag |= SOCK_UNAVAIL;
2511         sock= BLI_findlink(&node->outputs, RRES_OUT_INDEXOB);
2512         if(!(passflag & SCE_PASS_INDEXOB)) sock->flag |= SOCK_UNAVAIL;
2513         sock= BLI_findlink(&node->outputs, RRES_OUT_MIST);
2514         if(!(passflag & SCE_PASS_MIST)) sock->flag |= SOCK_UNAVAIL;
2515         
2516 }
2517
2518 /* based on rules, force sockets hidden always */
2519 void ntreeCompositForceHidden(bNodeTree *ntree)
2520 {
2521         bNode *node;
2522         
2523         if(ntree==NULL) return;
2524         
2525         for(node= ntree->nodes.first; node; node= node->next) {
2526                 if( node->type==CMP_NODE_R_LAYERS) {
2527                         Scene *sce= node->id?(Scene *)node->id:G.scene; /* G.scene is WEAK! */
2528                         SceneRenderLayer *srl= BLI_findlink(&sce->r.layers, node->custom1);
2529                         if(srl)
2530                                 force_hidden_passes(node, srl->passflag);
2531                 }
2532                 else if( node->type==CMP_NODE_IMAGE) {
2533                         Image *ima= (Image *)node->id;
2534                         if(ima) {
2535                                 if(ima->rr) {
2536                                         ImageUser *iuser= node->storage;
2537                                         RenderLayer *rl= BLI_findlink(&ima->rr->layers, iuser->layer);
2538                                         if(rl)
2539                                                 force_hidden_passes(node, rl->passflag);
2540                                         else
2541                                                 force_hidden_passes(node, 0);
2542                                 }
2543                                 else if(ima->type!=IMA_TYPE_MULTILAYER) {       /* if ->rr not yet read we keep inputs */
2544                                         force_hidden_passes(node, RRES_OUT_Z);
2545                                 }
2546                                 else
2547                                         force_hidden_passes(node, 0);
2548                         }
2549                         else
2550                                 force_hidden_passes(node, 0);
2551                 }
2552         }
2553
2554 }
2555
2556 /* called from render pipeline, to tag render input and output */
2557 /* need to do all scenes, to prevent errors when you re-render 1 scene */
2558 void ntreeCompositTagRender(Scene *curscene)
2559 {
2560         Scene *sce;
2561         
2562         for(sce= G.main->scene.first; sce; sce= sce->id.next) {
2563                 if(sce->nodetree) {
2564                         bNode *node;
2565                         
2566                         for(node= sce->nodetree->nodes.first; node; node= node->next) {
2567                                 if(node->id==(ID *)curscene || node->type==CMP_NODE_COMPOSITE)
2568                                         NodeTagChanged(sce->nodetree, node);
2569                         }
2570                 }
2571         }
2572 }
2573
2574 /* tags nodes that have animation capabilities */
2575 int ntreeCompositTagAnimated(bNodeTree *ntree)
2576 {
2577         bNode *node;
2578         int tagged= 0;
2579         
2580         if(ntree==NULL) return 0;
2581         
2582         for(node= ntree->nodes.first; node; node= node->next) {
2583                 if(node->type==CMP_NODE_IMAGE) {
2584                         Image *ima= (Image *)node->id;
2585                         if(ima && ELEM(ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) {
2586                                 NodeTagChanged(ntree, node);
2587                                 tagged= 1;
2588                         }
2589                 }
2590                 else if(node->type==CMP_NODE_TIME) {
2591                         NodeTagChanged(ntree, node);
2592                         tagged= 1;
2593                 }
2594                 else if(node->type==CMP_NODE_R_LAYERS) {
2595                         NodeTagChanged(ntree, node);
2596                         tagged= 1;
2597                 }
2598                 else if(node->type==NODE_GROUP) {
2599                         if( ntreeCompositTagAnimated((bNodeTree *)node->id) ) {
2600                                 NodeTagChanged(ntree, node);
2601                         }
2602                 }
2603         }
2604         
2605         return tagged;
2606 }
2607
2608
2609 /* called from image window preview */
2610 void ntreeCompositTagGenerators(bNodeTree *ntree)
2611 {
2612         bNode *node;
2613         
2614         if(ntree==NULL) return;
2615         
2616         for(node= ntree->nodes.first; node; node= node->next) {
2617                 if( ELEM(node->type, CMP_NODE_R_LAYERS, CMP_NODE_IMAGE))
2618                         NodeTagChanged(ntree, node);
2619         }
2620 }
2621
2622 /* ************* node definition init ********** */
2623
2624 static bNodeType *is_nodetype_registered(ListBase *typelist, int type, ID *id) 
2625 {
2626         bNodeType *ntype= typelist->first;
2627         
2628         for(;ntype; ntype= ntype->next )
2629                 if(ntype->type==type && ntype->id==id)
2630                         return ntype;
2631         
2632         return NULL;
2633 }
2634
2635 /* type can be from a static array, we make copy for duplicate types (like group) */
2636 void nodeRegisterType(ListBase *typelist, const bNodeType *ntype) 
2637 {
2638         bNodeType *found= is_nodetype_registered(typelist, ntype->type, ntype->id);
2639         
2640         if(found==NULL) {
2641                 bNodeType *ntypen= MEM_callocN(sizeof(bNodeType), "node type");
2642                 *ntypen= *ntype;
2643                 BLI_addtail(typelist, ntypen);
2644         }
2645 }
2646
2647 static void registerCompositNodes(ListBase *ntypelist)
2648 {
2649         nodeRegisterType(ntypelist, &node_group_typeinfo);
2650         nodeRegisterType(ntypelist, &cmp_node_rlayers);
2651         nodeRegisterType(ntypelist, &cmp_node_image);
2652         nodeRegisterType(ntypelist, &cmp_node_texture);
2653         nodeRegisterType(ntypelist, &cmp_node_value);
2654         nodeRegisterType(ntypelist, &cmp_node_rgb);
2655         nodeRegisterType(ntypelist, &cmp_node_curve_time);
2656         
2657         nodeRegisterType(ntypelist, &cmp_node_composite);
2658         nodeRegisterType(ntypelist, &cmp_node_viewer);
2659         nodeRegisterType(ntypelist, &cmp_node_splitviewer);
2660         nodeRegisterType(ntypelist, &cmp_node_output_file);
2661         
2662         nodeRegisterType(ntypelist, &cmp_node_curve_rgb);
2663         nodeRegisterType(ntypelist, &cmp_node_mix_rgb);
2664         nodeRegisterType(ntypelist, &cmp_node_hue_sat);
2665         nodeRegisterType(ntypelist, &cmp_node_brightcontrast);
2666         nodeRegisterType(ntypelist, &cmp_node_gamma);
2667         nodeRegisterType(ntypelist, &cmp_node_invert);
2668         nodeRegisterType(ntypelist, &cmp_node_alphaover);
2669         nodeRegisterType(ntypelist, &cmp_node_zcombine);
2670         
2671         nodeRegisterType(ntypelist, &cmp_node_normal);
2672         nodeRegisterType(ntypelist, &cmp_node_curve_vec);
2673         nodeRegisterType(ntypelist, &cmp_node_map_value);
2674         nodeRegisterType(ntypelist, &cmp_node_normalize);
2675         
2676         nodeRegisterType(ntypelist, &cmp_node_filter);
2677         nodeRegisterType(ntypelist, &cmp_node_blur);
2678         nodeRegisterType(ntypelist, &cmp_node_dblur);
2679         nodeRegisterType(ntypelist, &cmp_node_bilateralblur);
2680         nodeRegisterType(ntypelist, &cmp_node_vecblur);
2681         nodeRegisterType(ntypelist, &cmp_node_dilateerode);
2682         nodeRegisterType(ntypelist, &cmp_node_defocus);
2683         
2684         nodeRegisterType(ntypelist, &cmp_node_valtorgb);
2685         nodeRegisterType(ntypelist, &cmp_node_rgbtobw);
2686         nodeRegisterType(ntypelist, &cmp_node_setalpha);
2687         nodeRegisterType(ntypelist, &cmp_node_idmask);
2688         nodeRegisterType(ntypelist, &cmp_node_math);
2689         nodeRegisterType(ntypelist, &cmp_node_seprgba);
2690         nodeRegisterType(ntypelist, &cmp_node_combrgba);
2691         nodeRegisterType(ntypelist, &cmp_node_sephsva);
2692         nodeRegisterType(ntypelist, &cmp_node_combhsva);
2693         nodeRegisterType(ntypelist, &cmp_node_sepyuva);
2694         nodeRegisterType(ntypelist, &cmp_node_combyuva);
2695         nodeRegisterType(ntypelist, &cmp_node_sepycca);
2696         nodeRegisterType(ntypelist, &cmp_node_combycca);
2697         nodeRegisterType(ntypelist, &cmp_node_premulkey);
2698         
2699         nodeRegisterType(ntypelist, &cmp_node_diff_matte);
2700         nodeRegisterType(ntypelist, &cmp_node_chroma);
2701         nodeRegisterType(ntypelist, &cmp_node_channel_matte);
2702         nodeRegisterType(ntypelist, &cmp_node_color_spill);
2703         nodeRegisterType(ntypelist, &cmp_node_luma_matte);
2704         
2705         nodeRegisterType(ntypelist, &cmp_node_translate);
2706         nodeRegisterType(ntypelist, &cmp_node_rotate);
2707         nodeRegisterType(ntypelist, &cmp_node_scale);
2708         nodeRegisterType(ntypelist, &cmp_node_flip);
2709         nodeRegisterType(ntypelist, &cmp_node_crop);
2710         nodeRegisterType(ntypelist, &cmp_node_displace);
2711         nodeRegisterType(ntypelist, &cmp_node_mapuv);
2712         nodeRegisterType(ntypelist, &cmp_node_glare);
2713         nodeRegisterType(ntypelist, &cmp_node_tonemap);
2714         nodeRegisterType(ntypelist, &cmp_node_lensdist);
2715 }
2716
2717 static void registerShaderNodes(ListBase *ntypelist) 
2718 {
2719         nodeRegisterType(ntypelist, &node_group_typeinfo);
2720         nodeRegisterType(ntypelist, &sh_node_output);
2721         nodeRegisterType(ntypelist, &sh_node_mix_rgb);
2722         nodeRegisterType(ntypelist, &sh_node_valtorgb);
2723         nodeRegisterType(ntypelist, &sh_node_rgbtobw);
2724         nodeRegisterType(ntypelist, &sh_node_normal);
2725         nodeRegisterType(ntypelist, &sh_node_geom);
2726         nodeRegisterType(ntypelist, &sh_node_mapping);
2727         nodeRegisterType(ntypelist, &sh_node_curve_vec);
2728         nodeRegisterType(ntypelist, &sh_node_curve_rgb);
2729         nodeRegisterType(ntypelist, &sh_node_math);
2730         nodeRegisterType(ntypelist, &sh_node_vect_math);
2731         nodeRegisterType(ntypelist, &sh_node_squeeze);
2732         nodeRegisterType(ntypelist, &sh_node_camera);
2733         nodeRegisterType(ntypelist, &sh_node_material);
2734         nodeRegisterType(ntypelist, &sh_node_material_ext);
2735         nodeRegisterType(ntypelist, &sh_node_value);
2736         nodeRegisterType(ntypelist, &sh_node_rgb);
2737         nodeRegisterType(ntypelist, &sh_node_texture);
2738         nodeRegisterType(ntypelist, &node_dynamic_typeinfo);
2739         nodeRegisterType(ntypelist, &sh_node_invert);
2740         nodeRegisterType(ntypelist, &sh_node_seprgb);
2741         nodeRegisterType(ntypelist, &sh_node_combrgb);
2742         nodeRegisterType(ntypelist, &sh_node_hue_sat);
2743 }
2744
2745 static void remove_dynamic_typeinfos(ListBase *list)
2746 {
2747         bNodeType *ntype= list->first;
2748         bNodeType *next= NULL;
2749         while(ntype) {
2750                 next= ntype->next;
2751                 if(ntype->type==NODE_DYNAMIC && ntype->id!=NULL) {
2752                         BLI_remlink(list, ntype);
2753                         if(ntype->inputs) {
2754                                 bNodeSocketType *sock= ntype->inputs;
2755                                 while(sock->type!=-1) {
2756                                         MEM_freeN(sock->name);
2757                                         sock++;
2758                                 }
2759                                 MEM_freeN(ntype->inputs);
2760                         }
2761                         if(ntype->outputs) {
2762                                 bNodeSocketType *sock= ntype->outputs;
2763                                 while(sock->type!=-1) {
2764                                         MEM_freeN(sock->name);
2765                                         sock++;
2766                                 }
2767                                 MEM_freeN(ntype->outputs);
2768                         }
2769                         if(ntype->name) {
2770                                 MEM_freeN(ntype->name);
2771                         }
2772                         MEM_freeN(ntype);
2773                 }
2774                 ntype= next;
2775         }
2776 }
2777
2778 void init_nodesystem(void) 
2779 {
2780         registerCompositNodes(&node_all_composit);
2781         registerShaderNodes(&node_all_shaders);
2782 }
2783
2784 void free_nodesystem(void) 
2785 {
2786         /*remove_dynamic_typeinfos(&node_all_composit);*/ /* unused for now */
2787         BLI_freelistN(&node_all_composit);
2788         remove_dynamic_typeinfos(&node_all_shaders);
2789         BLI_freelistN(&node_all_shaders);
2790 }