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