update to trunk r14199
[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 /* not very important, but the stack solver likes to know a maximum */
72 #define MAX_SOCKET      64
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                                         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
2359 /* **************** call to switch lamploop for material node ************ */
2360
2361 void (*node_shader_lamp_loop)(struct ShadeInput *, struct ShadeResult *);
2362
2363 void set_node_shader_lamp_loop(void (*lamp_loop_func)(ShadeInput *, ShadeResult *))
2364 {
2365         node_shader_lamp_loop= lamp_loop_func;
2366 }
2367
2368 /* clumsy checking... should do dynamic outputs once */
2369 static void force_hidden_passes(bNode *node, int passflag)
2370 {
2371         bNodeSocket *sock;
2372         
2373         for(sock= node->outputs.first; sock; sock= sock->next)
2374                 sock->flag &= ~SOCK_UNAVAIL;
2375         
2376         sock= BLI_findlink(&node->outputs, RRES_OUT_Z);
2377         if(!(passflag & SCE_PASS_Z)) sock->flag |= SOCK_UNAVAIL;
2378         sock= BLI_findlink(&node->outputs, RRES_OUT_NORMAL);
2379         if(!(passflag & SCE_PASS_NORMAL)) sock->flag |= SOCK_UNAVAIL;
2380         sock= BLI_findlink(&node->outputs, RRES_OUT_VEC);
2381         if(!(passflag & SCE_PASS_VECTOR)) sock->flag |= SOCK_UNAVAIL;
2382         sock= BLI_findlink(&node->outputs, RRES_OUT_UV);
2383         if(!(passflag & SCE_PASS_UV)) sock->flag |= SOCK_UNAVAIL;
2384         sock= BLI_findlink(&node->outputs, RRES_OUT_RGBA);
2385         if(!(passflag & SCE_PASS_RGBA)) sock->flag |= SOCK_UNAVAIL;
2386         sock= BLI_findlink(&node->outputs, RRES_OUT_DIFF);
2387         if(!(passflag & SCE_PASS_DIFFUSE)) sock->flag |= SOCK_UNAVAIL;
2388         sock= BLI_findlink(&node->outputs, RRES_OUT_SPEC);
2389         if(!(passflag & SCE_PASS_SPEC)) sock->flag |= SOCK_UNAVAIL;
2390         sock= BLI_findlink(&node->outputs, RRES_OUT_SHADOW);
2391         if(!(passflag & SCE_PASS_SHADOW)) sock->flag |= SOCK_UNAVAIL;
2392         sock= BLI_findlink(&node->outputs, RRES_OUT_AO);
2393         if(!(passflag & SCE_PASS_AO)) sock->flag |= SOCK_UNAVAIL;
2394         sock= BLI_findlink(&node->outputs, RRES_OUT_REFLECT);
2395         if(!(passflag & SCE_PASS_REFLECT)) sock->flag |= SOCK_UNAVAIL;
2396         sock= BLI_findlink(&node->outputs, RRES_OUT_REFRACT);
2397         if(!(passflag & SCE_PASS_REFRACT)) sock->flag |= SOCK_UNAVAIL;
2398         sock= BLI_findlink(&node->outputs, RRES_OUT_RADIO);
2399         if(!(passflag & SCE_PASS_RADIO)) sock->flag |= SOCK_UNAVAIL;
2400         sock= BLI_findlink(&node->outputs, RRES_OUT_INDEXOB);
2401         if(!(passflag & SCE_PASS_INDEXOB)) sock->flag |= SOCK_UNAVAIL;
2402         sock= BLI_findlink(&node->outputs, RRES_OUT_MIST);
2403         if(!(passflag & SCE_PASS_MIST)) sock->flag |= SOCK_UNAVAIL;
2404         
2405 }
2406
2407 /* based on rules, force sockets hidden always */
2408 void ntreeCompositForceHidden(bNodeTree *ntree)
2409 {
2410         bNode *node;
2411         
2412         if(ntree==NULL) return;
2413         
2414         for(node= ntree->nodes.first; node; node= node->next) {
2415                 if( node->type==CMP_NODE_R_LAYERS) {
2416                         Scene *sce= node->id?(Scene *)node->id:G.scene; /* G.scene is WEAK! */
2417                         SceneRenderLayer *srl= BLI_findlink(&sce->r.layers, node->custom1);
2418                         if(srl)
2419                                 force_hidden_passes(node, srl->passflag);
2420                 }
2421                 else if( node->type==CMP_NODE_IMAGE) {
2422                         Image *ima= (Image *)node->id;
2423                         if(ima) {
2424                                 if(ima->rr) {
2425                                         ImageUser *iuser= node->storage;
2426                                         RenderLayer *rl= BLI_findlink(&ima->rr->layers, iuser->layer);
2427                                         if(rl)
2428                                                 force_hidden_passes(node, rl->passflag);
2429                                         else
2430                                                 force_hidden_passes(node, 0);
2431                                 }
2432                                 else if(ima->type!=IMA_TYPE_MULTILAYER) {       /* if ->rr not yet read we keep inputs */
2433                                         force_hidden_passes(node, RRES_OUT_Z);
2434                                 }
2435                                 else
2436                                         force_hidden_passes(node, 0);
2437                         }
2438                         else
2439                                 force_hidden_passes(node, 0);
2440                 }
2441         }
2442
2443 }
2444
2445 /* called from render pipeline, to tag render input and output */
2446 /* need to do all scenes, to prevent errors when you re-render 1 scene */
2447 void ntreeCompositTagRender(Scene *curscene)
2448 {
2449         Scene *sce;
2450         
2451         for(sce= G.main->scene.first; sce; sce= sce->id.next) {
2452                 if(sce->nodetree) {
2453                         bNode *node;
2454                         
2455                         for(node= sce->nodetree->nodes.first; node; node= node->next) {
2456                                 if(node->id==(ID *)curscene || node->type==CMP_NODE_COMPOSITE)
2457                                         NodeTagChanged(sce->nodetree, node);
2458                         }
2459                 }
2460         }
2461 }
2462
2463 /* tags nodes that have animation capabilities */
2464 int ntreeCompositTagAnimated(bNodeTree *ntree)
2465 {
2466         bNode *node;
2467         int tagged= 0;
2468         
2469         if(ntree==NULL) return 0;
2470         
2471         for(node= ntree->nodes.first; node; node= node->next) {
2472                 if(node->type==CMP_NODE_IMAGE) {
2473                         Image *ima= (Image *)node->id;
2474                         if(ima && ELEM(ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) {
2475                                 NodeTagChanged(ntree, node);
2476                                 tagged= 1;
2477                         }
2478                 }
2479                 else if(node->type==CMP_NODE_TIME) {
2480                         NodeTagChanged(ntree, node);
2481                         tagged= 1;
2482                 }
2483                 else if(node->type==CMP_NODE_R_LAYERS) {
2484                         NodeTagChanged(ntree, node);
2485                         tagged= 1;
2486                 }
2487                 else if(node->type==NODE_GROUP) {
2488                         if( ntreeCompositTagAnimated((bNodeTree *)node->id) ) {
2489                                 NodeTagChanged(ntree, node);
2490                         }
2491                 }
2492         }
2493         
2494         return tagged;
2495 }
2496
2497
2498 /* called from image window preview */
2499 void ntreeCompositTagGenerators(bNodeTree *ntree)
2500 {
2501         bNode *node;
2502         
2503         if(ntree==NULL) return;
2504         
2505         for(node= ntree->nodes.first; node; node= node->next) {
2506                 if( ELEM(node->type, CMP_NODE_R_LAYERS, CMP_NODE_IMAGE))
2507                         NodeTagChanged(ntree, node);
2508         }
2509 }
2510
2511 /* ************* node definition init ********** */
2512
2513 static bNodeType *is_nodetype_registered(ListBase *typelist, int type, ID *id) 
2514 {
2515         bNodeType *ntype= typelist->first;
2516         
2517         for(;ntype; ntype= ntype->next )
2518                 if(ntype->type==type && ntype->id==id)
2519                         return ntype;
2520         
2521         return NULL;
2522 }
2523
2524 /* type can be from a static array, we make copy for duplicate types (like group) */
2525 void nodeRegisterType(ListBase *typelist, const bNodeType *ntype) 
2526 {
2527         bNodeType *found= is_nodetype_registered(typelist, ntype->type, ntype->id);
2528         
2529         if(found==NULL) {
2530                 bNodeType *ntypen= MEM_callocN(sizeof(bNodeType), "node type");
2531                 *ntypen= *ntype;
2532                 BLI_addtail(typelist, ntypen);
2533         }
2534 }
2535
2536 static void registerCompositNodes(ListBase *ntypelist)
2537 {
2538         nodeRegisterType(ntypelist, &node_group_typeinfo);
2539         nodeRegisterType(ntypelist, &cmp_node_rlayers);
2540         nodeRegisterType(ntypelist, &cmp_node_image);
2541         nodeRegisterType(ntypelist, &cmp_node_texture);
2542         nodeRegisterType(ntypelist, &cmp_node_value);
2543         nodeRegisterType(ntypelist, &cmp_node_rgb);
2544         nodeRegisterType(ntypelist, &cmp_node_curve_time);
2545         
2546         nodeRegisterType(ntypelist, &cmp_node_composite);
2547         nodeRegisterType(ntypelist, &cmp_node_viewer);
2548         nodeRegisterType(ntypelist, &cmp_node_splitviewer);
2549         nodeRegisterType(ntypelist, &cmp_node_output_file);
2550         
2551         nodeRegisterType(ntypelist, &cmp_node_curve_rgb);
2552         nodeRegisterType(ntypelist, &cmp_node_mix_rgb);
2553         nodeRegisterType(ntypelist, &cmp_node_hue_sat);
2554         nodeRegisterType(ntypelist, &cmp_node_brightcontrast);
2555         nodeRegisterType(ntypelist, &cmp_node_gamma);
2556         nodeRegisterType(ntypelist, &cmp_node_invert);
2557         nodeRegisterType(ntypelist, &cmp_node_alphaover);
2558         nodeRegisterType(ntypelist, &cmp_node_zcombine);
2559         
2560         nodeRegisterType(ntypelist, &cmp_node_normal);
2561         nodeRegisterType(ntypelist, &cmp_node_curve_vec);
2562         nodeRegisterType(ntypelist, &cmp_node_map_value);
2563         nodeRegisterType(ntypelist, &cmp_node_normalize);
2564         
2565         nodeRegisterType(ntypelist, &cmp_node_filter);
2566         nodeRegisterType(ntypelist, &cmp_node_blur);
2567         nodeRegisterType(ntypelist, &cmp_node_dblur);
2568         nodeRegisterType(ntypelist, &cmp_node_bilateralblur);
2569         nodeRegisterType(ntypelist, &cmp_node_vecblur);
2570         nodeRegisterType(ntypelist, &cmp_node_dilateerode);
2571         nodeRegisterType(ntypelist, &cmp_node_defocus);
2572         
2573         nodeRegisterType(ntypelist, &cmp_node_valtorgb);
2574         nodeRegisterType(ntypelist, &cmp_node_rgbtobw);
2575         nodeRegisterType(ntypelist, &cmp_node_setalpha);
2576         nodeRegisterType(ntypelist, &cmp_node_idmask);
2577         nodeRegisterType(ntypelist, &cmp_node_math);
2578         nodeRegisterType(ntypelist, &cmp_node_seprgba);
2579         nodeRegisterType(ntypelist, &cmp_node_combrgba);
2580         nodeRegisterType(ntypelist, &cmp_node_sephsva);
2581         nodeRegisterType(ntypelist, &cmp_node_combhsva);
2582         nodeRegisterType(ntypelist, &cmp_node_sepyuva);
2583         nodeRegisterType(ntypelist, &cmp_node_combyuva);
2584         nodeRegisterType(ntypelist, &cmp_node_sepycca);
2585         nodeRegisterType(ntypelist, &cmp_node_combycca);
2586         nodeRegisterType(ntypelist, &cmp_node_premulkey);
2587         
2588         nodeRegisterType(ntypelist, &cmp_node_diff_matte);
2589         nodeRegisterType(ntypelist, &cmp_node_chroma);
2590         nodeRegisterType(ntypelist, &cmp_node_channel_matte);
2591         nodeRegisterType(ntypelist, &cmp_node_color_spill);
2592         nodeRegisterType(ntypelist, &cmp_node_luma_matte);
2593         
2594         nodeRegisterType(ntypelist, &cmp_node_translate);
2595         nodeRegisterType(ntypelist, &cmp_node_rotate);
2596         nodeRegisterType(ntypelist, &cmp_node_scale);
2597         nodeRegisterType(ntypelist, &cmp_node_flip);
2598         nodeRegisterType(ntypelist, &cmp_node_crop);
2599         nodeRegisterType(ntypelist, &cmp_node_displace);
2600         nodeRegisterType(ntypelist, &cmp_node_mapuv);
2601         nodeRegisterType(ntypelist, &cmp_node_glare);
2602         nodeRegisterType(ntypelist, &cmp_node_tonemap);
2603         nodeRegisterType(ntypelist, &cmp_node_lensdist);
2604 }
2605
2606 static void registerShaderNodes(ListBase *ntypelist) 
2607 {
2608         nodeRegisterType(ntypelist, &node_group_typeinfo);
2609         nodeRegisterType(ntypelist, &sh_node_output);
2610         nodeRegisterType(ntypelist, &sh_node_mix_rgb);
2611         nodeRegisterType(ntypelist, &sh_node_valtorgb);
2612         nodeRegisterType(ntypelist, &sh_node_rgbtobw);
2613         nodeRegisterType(ntypelist, &sh_node_normal);
2614         nodeRegisterType(ntypelist, &sh_node_geom);
2615         nodeRegisterType(ntypelist, &sh_node_mapping);
2616         nodeRegisterType(ntypelist, &sh_node_curve_vec);
2617         nodeRegisterType(ntypelist, &sh_node_curve_rgb);
2618         nodeRegisterType(ntypelist, &sh_node_math);
2619         nodeRegisterType(ntypelist, &sh_node_vect_math);
2620         nodeRegisterType(ntypelist, &sh_node_squeeze);
2621         nodeRegisterType(ntypelist, &sh_node_camera);
2622         nodeRegisterType(ntypelist, &sh_node_material);
2623         nodeRegisterType(ntypelist, &sh_node_material_ext);
2624         nodeRegisterType(ntypelist, &sh_node_value);
2625         nodeRegisterType(ntypelist, &sh_node_rgb);
2626         nodeRegisterType(ntypelist, &sh_node_texture);
2627         nodeRegisterType(ntypelist, &node_dynamic_typeinfo);
2628         nodeRegisterType(ntypelist, &sh_node_invert);
2629         nodeRegisterType(ntypelist, &sh_node_seprgb);
2630         nodeRegisterType(ntypelist, &sh_node_combrgb);
2631         nodeRegisterType(ntypelist, &sh_node_hue_sat);
2632 }
2633
2634 static void remove_dynamic_typeinfos(ListBase *list)
2635 {
2636         bNodeType *ntype= list->first;
2637         bNodeType *next= NULL;
2638         while(ntype) {
2639                 next= ntype->next;
2640                 if(ntype->type==NODE_DYNAMIC && ntype->id!=NULL) {
2641                         BLI_remlink(list, ntype);
2642                         if(ntype->inputs) {
2643                                 bNodeSocketType *sock= ntype->inputs;
2644                                 while(sock->type!=-1) {
2645                                         MEM_freeN(sock->name);
2646                                         sock++;
2647                                 }
2648                                 MEM_freeN(ntype->inputs);
2649                         }
2650                         if(ntype->outputs) {
2651                                 bNodeSocketType *sock= ntype->outputs;
2652                                 while(sock->type!=-1) {
2653                                         MEM_freeN(sock->name);
2654                                         sock++;
2655                                 }
2656                                 MEM_freeN(ntype->outputs);
2657                         }
2658                         if(ntype->name) {
2659                                 MEM_freeN(ntype->name);
2660                         }
2661                         MEM_freeN(ntype);
2662                 }
2663                 ntype= next;
2664         }
2665 }
2666
2667 void init_nodesystem(void) 
2668 {
2669         registerCompositNodes(&node_all_composit);
2670         registerShaderNodes(&node_all_shaders);
2671 }
2672
2673 void free_nodesystem(void) 
2674 {
2675         /*remove_dynamic_typeinfos(&node_all_composit);*/ /* unused for now */
2676         BLI_freelistN(&node_all_composit);
2677         remove_dynamic_typeinfos(&node_all_shaders);
2678         BLI_freelistN(&node_all_shaders);
2679 }