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